3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-22 11:07:51 +00:00
* Added function to select the next variable to split on

* Fixed typo

* Small fixes

* uint -> int

* Fixed missing assignment for binary clauses

* Memory leak in .NET user-propagator
The user-propagator object has to be manually disposed (IDisposable), otherwise it stays in memory forever, as it cannot be garbage collected automatically

* Throw an exception if variable passed to decide is already assigned instead of running in an assertion violation

* Update (not compiling yet)

* #6429

* remove ternary clause optimization

Removing ternary clause optimization from sat_solver simplifies special case handling of ternary clauses throughout the sat solver and dependent solvers (pb_solver). Benchmarking on QF_BV suggests the ternary clause optimization does not have any effect. While removing ternary clause optimization two bugs in unit propagation were also uncovered: it missed propagations when the only a single undef literal remained in the non-watched literals and it did not update blocked literals in cases where it could in the watch list. These performance bugs were for general clauses, ternary clause propagation did not miss propagations (and don't use blocked literals), but fixing these issues for general clauses appear to have made ternary clause optimization irrelevant based on what was measured.

* Update: Missing data-structures (still not compiling)

* Nearly compiling

* Some missing arguments

* Polishing

* Only conflicts/propagations/justifications are missing for making it compile

* Added propagation (justifications for them are still missing)

* Use the right deallocation

* Use Z3's memory allocation system

* Ported "seen"

* Polishing

* Added 64-bit "1" counting

* More polishing

* minor fixes

- ensure mk_extract performs simplification to distribute over extract and removing extract if the range is the entire bit-vector
- ensure bool_rewriter simplifeis disjunctions when applicable.

* adding simplifiers layer

simplifiers layer is a common substrate for global non-incremental and incremental processing.
The first two layers are new, but others are to be ported form tactics.

- bv::slice - rewrites equations to cut-dice-slice bit-vector extractions until they align. It creates opportunities for rewriting portions of bit-vectors to common sub-expressions, including values.
- euf::completion - generalizes the KB simplifcation from asserted formulas to use the E-graph to establish a global and order-independent canonization.

The interface dependent_expr_simplifier is amenable to forming tactics. Plugins for asserted-formulas is also possible but not yet realized.

* Create bv_slice_tactic.cpp

missing file

* adding virtual destructor

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Added 64-bit "1" counting (#6434)

* Memory leak in .NET user-propagator
The user-propagator object has to be manually disposed (IDisposable), otherwise it stays in memory forever, as it cannot be garbage collected automatically

* Throw an exception if variable passed to decide is already assigned instead of running in an assertion violation

* Added 64-bit "1" counting

* remove incorrect assertion

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Added limit to "visit" to allow detecting multiple visits (#6435)

* Memory leak in .NET user-propagator
The user-propagator object has to be manually disposed (IDisposable), otherwise it stays in memory forever, as it cannot be garbage collected automatically

* Throw an exception if variable passed to decide is already assigned instead of running in an assertion violation

* Added limit to "visit" to allow detecting multiple visits

* Putting visit in a separate class
(Reason: We will probably need two of them in the sat::solver)

* Bugfix

* init solve_eqs

* working on solve_eqs

* Update .gitignore

* wip - converting the equation solver as a simplifier

* make visited_helper independent of literals

re-introduce shorthands in sat::solver for visited and have them convert literals to unsigned.

* build fix

* move model and proof converters to self-contained module

* Create solve_eqs2_tactic.h

* add converters module to python build

* move tactic_params to params

* move more converters

* move horn_subsume_model_converter to ast/converters

* add initial stubs for model reconstruction trail

* fixing build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes #6439 #6436

* It's compiling (However, two important functions are commented out)

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Clemens Eisenhofer 2022-11-10 18:05:17 +01:00 committed by GitHub
parent b651e57ca2
commit 002d166f72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
165 changed files with 4849 additions and 846 deletions

View file

@ -1,25 +1,19 @@
z3_add_component(tactic
SOURCES
dependency_converter.cpp
equiv_proof_converter.cpp
generic_model_converter.cpp
goal.cpp
goal_num_occurs.cpp
goal_shared_occs.cpp
goal_util.cpp
horn_subsume_model_converter.cpp
model_converter.cpp
probe.cpp
proof_converter.cpp
replace_proof_converter.cpp
tactical.cpp
tactic.cpp
COMPONENT_DEPENDENCIES
ast
model
simplifiers
converters
TACTIC_HEADERS
probe.h
tactic.h
PYG_FILES
tactic_params.pyg
)

View file

@ -22,7 +22,7 @@ Notes:
#include "ast/rewriter/pb2bv_rewriter.h"
#include "ast/ast_util.h"
#include "ast/ast_pp.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
class card2bv_tactic : public tactic {
ast_manager & m;

View file

@ -20,7 +20,7 @@ Revision History:
--*/
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/arith_decl_plugin.h"
#include "tactic/core/simplify_tactic.h"
#include "ast/ast_smt2_pp.h"

View file

@ -23,7 +23,7 @@ Revision History:
--*/
#include "tactic/tactical.h"
#include "ast/rewriter/th_rewriter.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/arith_decl_plugin.h"
#include "ast/expr_substitution.h"
#include "ast/ast_smt2_pp.h"

View file

@ -25,7 +25,7 @@ Notes:
#include "ast/ast_pp_util.h"
#include "tactic/tactical.h"
#include "tactic/arith/bound_manager.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
class lia2card_tactic : public tactic {

View file

@ -20,7 +20,7 @@ Revision History:
#include "tactic/arith/bound_manager.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/for_each_expr.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/arith_decl_plugin.h"
#include "ast/expr_substitution.h"
#include "ast/ast_smt2_pp.h"

View file

@ -27,7 +27,7 @@ Notes:
#include "util/optional.h"
#include "tactic/arith/bv2int_rewriter.h"
#include "tactic/arith/bv2real_rewriter.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "tactic/arith/bound_manager.h"
#include "util/obj_pair_hashtable.h"
#include "ast/ast_smt2_pp.h"

View file

@ -21,7 +21,7 @@ Revision History:
#include "tactic/tactical.h"
#include "tactic/arith/bound_manager.h"
#include "ast/rewriter/th_rewriter.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/arith_decl_plugin.h"
#include "ast/expr_substitution.h"
#include "ast/ast_smt2_pp.h"

View file

@ -18,7 +18,7 @@ Notes:
--*/
#pragma once
#include "tactic/model_converter.h"
#include "ast/converters/model_converter.h"
#include "tactic/arith/bound_manager.h"
class pb2bv_model_converter : public model_converter {

View file

@ -29,7 +29,7 @@ Notes:
#include "ast/rewriter/pb2bv_rewriter.h"
#include "tactic/tactical.h"
#include "tactic/arith/bound_manager.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "tactic/arith/pb2bv_model_converter.h"
#include "tactic/arith/pb2bv_tactic.h"

View file

@ -27,7 +27,7 @@ Revision History:
#include "tactic/core/nnf_tactic.h"
#include "tactic/core/simplify_tactic.h"
#include "ast/rewriter/th_rewriter.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/ast_smt2_pp.h"
#include "ast/ast_pp.h"
#include "ast/rewriter/expr_replacer.h"

View file

@ -57,7 +57,7 @@ Revision History:
--*/
#include "tactic/tactical.h"
#include "ast/rewriter/th_rewriter.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/arith_decl_plugin.h"
#include "ast/expr_substitution.h"
#include "util/dec_ref_util.h"

View file

@ -8,6 +8,7 @@ z3_add_component(bv_tactics
bv_bound_chk_tactic.cpp
bv_bounds_tactic.cpp
bv_size_reduction_tactic.cpp
bv_slice_tactic.cpp
dt2bv_tactic.cpp
elim_small_bv_tactic.cpp
max_bv_sharing_tactic.cpp
@ -21,6 +22,7 @@ z3_add_component(bv_tactics
bv_bound_chk_tactic.h
bv_bounds_tactic.h
bv_size_reduction_tactic.h
bv_slice_tactic.h
bvarray2uf_tactic.h
dt2bv_tactic.h
elim_small_bv_tactic.h

View file

@ -18,7 +18,7 @@ Notes:
--*/
#include "model/model.h"
#include "model/model_pp.h"
#include "tactic/model_converter.h"
#include "ast/converters/model_converter.h"
#include "ast/bv_decl_plugin.h"
#include "ast/ast_smt2_pp.h"
#include "ast/ast_pp.h"

View file

@ -18,7 +18,7 @@ Notes:
--*/
#pragma once
#include "tactic/model_converter.h"
#include "ast/converters/model_converter.h"
model_converter * mk_bit_blaster_model_converter(ast_manager & m, obj_map<func_decl, expr*> const & const2bits, ptr_vector<func_decl> const& newbits);
model_converter * mk_bv1_blaster_model_converter(ast_manager & m, obj_map<func_decl, expr*> const & const2bits, ptr_vector<func_decl> const& newbits);

View file

@ -24,7 +24,7 @@ Notes:
#include "tactic/tactical.h"
#include "ast/bv_decl_plugin.h"
#include "ast/rewriter/expr_replacer.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/ast_smt2_pp.h"
namespace {

View file

@ -0,0 +1,33 @@
/*++
Copyright (c) 2022 Microsoft Corporation
Module Name:
bv_slice_tactic.cpp
Abstract:
Tactic for simplifying with bit-vector slices
Author:
Nikolaj Bjorner (nbjorner) 2022-10-30
--*/
#include "ast/simplifiers/bv_slice.h"
#include "tactic/tactic.h"
#include "tactic/dependent_expr_state_tactic.h"
#include "tactic/bv/bv_slice_tactic.h"
class bv_slice_factory : public dependent_expr_simplifier_factory {
public:
dependent_expr_simplifier* mk(ast_manager& m, params_ref const& p, dependent_expr_state& s) override {
return alloc(bv::slice, m, s);
}
};
tactic* mk_bv_slice_tactic(ast_manager& m, params_ref const& p) {
return alloc(dependent_expr_state_tactic, m, p, alloc(bv_slice_factory), "bv-slice");
}

View file

@ -0,0 +1,29 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
bv_slice_tactic.h
Abstract:
Tactic for simplifying with bit-vector slices
Author:
Nikolaj Bjorner (nbjorner) 2022-10-30
--*/
#pragma once
#include "util/params.h"
class ast_manager;
class tactic;
tactic * mk_bv_slice_tactic(ast_manager & m, params_ref const & p = params_ref());
/*
ADD_TACTIC("bv-slice", "simplify using bit-vector slices.", "mk_bv_slice_tactic(m, p)")
*/

View file

@ -20,7 +20,7 @@ Notes:
#pragma once
#include "ast/rewriter/rewriter.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
class bvarray2uf_rewriter_cfg : public default_rewriter_cfg {
ast_manager & m_manager;

View file

@ -20,7 +20,7 @@ Notes:
#include "tactic/tactical.h"
#include "ast/bv_decl_plugin.h"
#include "ast/rewriter/expr_replacer.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/ast_smt2_pp.h"
#include "tactic/bv/bvarray2uf_tactic.h"

View file

@ -21,7 +21,7 @@ Revision History:
#include "tactic/bv/dt2bv_tactic.h"
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/datatype_decl_plugin.h"
#include "ast/bv_decl_plugin.h"
#include "ast/rewriter/rewriter_def.h"

View file

@ -18,7 +18,7 @@ Revision History:
--*/
#include "tactic/tactical.h"
#include "ast/rewriter/rewriter_def.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/bv_decl_plugin.h"
#include "ast/used_vars.h"
#include "ast/well_sorted.h"

View file

@ -1,124 +0,0 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
converter.h
Abstract:
Abstract class and templates for proof and model converters.
Author:
Leonardo (leonardo) 2011-11-14
Notes:
--*/
#pragma once
#include "util/vector.h"
#include "util/ref.h"
#include "ast/ast_translation.h"
class converter {
unsigned m_ref_count;
public:
converter():m_ref_count(0) {}
virtual ~converter() = default;
void inc_ref() { ++m_ref_count; }
void dec_ref() {
--m_ref_count;
if (m_ref_count == 0) {
dealloc(this);
}
}
virtual void cancel() {}
virtual void display(std::ostream & out) = 0;
};
template<typename T>
class concat_converter : public T {
protected:
ref<T> m_c1;
ref<T> m_c2;
template<typename T2>
T * translate_core(ast_translation & translator) {
T * t1 = m_c1->translate(translator);
T * t2 = m_c2->translate(translator);
return alloc(T2, t1, t2);
}
public:
concat_converter(T * c1, T * c2):m_c1(c1), m_c2(c2) {}
void cancel() override {
m_c2->cancel();
m_c1->cancel();
}
virtual char const * get_name() const = 0;
void display(std::ostream & out) override {
m_c1->display(out);
m_c2->display(out);
}
};
template<typename T>
class concat_star_converter : public T {
protected:
ref<T> m_c1;
ptr_vector<T> m_c2s;
unsigned_vector m_szs;
template<typename T2>
T * translate_core(ast_translation & translator) {
T * t1 = m_c1 ? m_c1->translate(translator) : nullptr;
ptr_buffer<T> t2s;
for (T* c : m_c2s)
t2s.push_back(c ? c->translate(translator) : nullptr);
return alloc(T2, t1, m_c2s.size(), t2s.data(), m_szs.data());
}
public:
concat_star_converter(T * c1, unsigned num, T * const * c2s, unsigned * szs):
m_c1(c1) {
for (unsigned i = 0; i < num; i++) {
T * c2 = c2s[i];
if (c2)
c2->inc_ref();
m_c2s.push_back(c2);
m_szs.push_back(szs[i]);
}
}
~concat_star_converter() override {
for (T* c : m_c2s)
if (c) c->dec_ref();
}
void cancel() override {
if (m_c1)
m_c1->cancel();
for (T* c : m_c2s)
if (c) c->cancel();
}
virtual char const * get_name() const = 0;
void display(std::ostream & out) override {
if (m_c1)
m_c1->display(out);
for (T* c : m_c2s)
if (c) c->display(out);
}
};

View file

@ -10,6 +10,7 @@ z3_add_component(core_tactics
dom_simplify_tactic.cpp
elim_term_ite_tactic.cpp
elim_uncnstr_tactic.cpp
euf_completion_tactic.cpp
injectivity_tactic.cpp
nnf_tactic.cpp
occf_tactic.cpp
@ -38,6 +39,7 @@ z3_add_component(core_tactics
dom_simplify_tactic.h
elim_term_ite_tactic.h
elim_uncnstr_tactic.h
euf_completion_tactic.h
injectivity_tactic.h
nnf_tactic.h
occf_tactic.h

View file

@ -20,7 +20,7 @@ Notes:
#include "ast/rewriter/rewriter_def.h"
#include "ast/scoped_proof.h"
#include "tactic/tactical.h"
#include "tactic/tactic_params.hpp"
#include "params/tactic_params.hpp"

View file

@ -20,7 +20,7 @@ Notes:
#include "tactic/tactical.h"
#include "ast/normal_forms/defined_names.h"
#include "ast/rewriter/rewriter_def.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
class elim_term_ite_tactic : public tactic {

View file

@ -17,7 +17,7 @@ Notes:
--*/
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/rewriter/rewriter_def.h"
#include "ast/arith_decl_plugin.h"
#include "ast/bv_decl_plugin.h"

View file

@ -0,0 +1,32 @@
/*++
Copyright (c) 2022 Microsoft Corporation
Module Name:
euf_completion_tactic.cpp
Abstract:
Tactic for simplifying with equations.
Author:
Nikolaj Bjorner (nbjorner) 2022-10-30
--*/
#include "tactic/tactic.h"
#include "tactic/dependent_expr_state_tactic.h"
#include "ast/simplifiers/euf_completion.h"
#include "tactic/core/euf_completion_tactic.h"
class euf_completion_tactic_factory : public dependent_expr_simplifier_factory {
public:
dependent_expr_simplifier* mk(ast_manager& m, params_ref const& p, dependent_expr_state& s) override {
return alloc(euf::completion, m, s);
}
};
tactic * mk_euf_completion_tactic(ast_manager& m, params_ref const& p) {
return alloc(dependent_expr_state_tactic, m, p, alloc(euf_completion_tactic_factory), "euf-completion");
}

View file

@ -0,0 +1,29 @@
/*++
Copyright (c) 2022 Microsoft Corporation
Module Name:
euf_completion_tactic.h
Abstract:
Tactic for simplifying with equations.
Author:
Nikolaj Bjorner (nbjorner) 2022-10-30
--*/
#pragma once
#include "util/params.h"
class ast_manager;
class tactic;
tactic * mk_euf_completion_tactic(ast_manager & m, params_ref const & p = params_ref());
/*
ADD_TACTIC("euf-completion", "simplify using equalities.", "mk_euf_completion_tactic(m, p)")
*/

View file

@ -18,7 +18,7 @@ Revision History:
--*/
#include "ast/normal_forms/nnf.h"
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
class nnf_tactic : public tactic {
params_ref m_params;

View file

@ -23,7 +23,7 @@ Revision History:
--*/
#include "tactic/tactical.h"
#include "tactic/core/occf_tactic.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
class occf_tactic : public tactic {
struct imp {

View file

@ -33,7 +33,7 @@ Notes:
--*/
#include "tactic/core/pb_preprocess_tactic.h"
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/for_each_expr.h"
#include "ast/pb_decl_plugin.h"
#include "ast/rewriter/th_rewriter.h"

View file

@ -24,7 +24,7 @@ Revision History:
#include "ast/ast_pp.h"
#include "ast/expr_substitution.h"
#include "tactic/goal_shared_occs.h"
#include "tactic/tactic_params.hpp"
#include "params/tactic_params.hpp"
namespace {
class propagate_values_tactic : public tactic {

View file

@ -22,7 +22,7 @@ Notes:
#include "ast/has_free_vars.h"
#include "util/map.h"
#include "ast/rewriter/rewriter_def.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
/**
\brief Reduce the number of arguments in function applications.

View file

@ -29,7 +29,7 @@ Notes:
#include "tactic/tactic.h"
#include "tactic/core/reduce_invertible_tactic.h"
#include "tactic/core/collect_occs.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include <cstdint>
namespace {

View file

@ -0,0 +1,41 @@
/*++
Copyright (c) 2022 Microsoft Corporation
Module Name:
solve_eqs2_tactic.h
Abstract:
Tactic for solving variables
Author:
Nikolaj Bjorner (nbjorner) 2022-10-30
--*/
#pragma once
#include "util/params.h"
#include "tactic/tactic.h"
#include "tactic/dependent_expr_state_tactic.h"
#include "ast/simplifiers/solve_eqs.h"
class solve_eqs2_tactic_factory : public dependent_expr_simplifier_factory {
public:
dependent_expr_simplifier* mk(ast_manager& m, params_ref const& p, dependent_expr_state& s) override {
return alloc(euf::solve_eqs, m, s);
}
};
inline tactic * mk_solve_eqs2_tactic(ast_manager& m, params_ref const& p) {
return alloc(dependent_expr_state_tactic, m, p, alloc(solve_eqs2_tactic_factory), "solve-eqs2");
}
/*
ADD_TACTIC("solve-eqs2", "solve for variables.", "mk_solve_eqs2_tactic(m, p)")
*/

View file

@ -27,8 +27,8 @@ Revision History:
#include "ast/rewriter/hoist_rewriter.h"
#include "tactic/goal_shared_occs.h"
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "tactic/tactic_params.hpp"
#include "ast/converters/generic_model_converter.h"
#include "params/tactic_params.hpp"
class solve_eqs_tactic : public tactic {
struct imp {
@ -977,14 +977,8 @@ class solve_eqs_tactic : public tactic {
if (m_produce_models) {
if (!mc.get())
mc = alloc(gmc, m(), "solve-eqs");
for (app* v : m_ordered_vars) {
expr * def = nullptr;
proof * pr;
expr_dependency * dep = nullptr;
m_norm_subst->find(v, def, pr, dep);
SASSERT(def);
static_cast<gmc*>(mc.get())->add(v, def);
}
for (app* v : m_ordered_vars)
static_cast<gmc*>(mc.get())->add(v, m_norm_subst->find(v));
}
}
@ -1141,9 +1135,6 @@ public:
};
tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p, expr_replacer * r) {
if (r == nullptr)
return clean(alloc(solve_eqs_tactic, m, p, mk_expr_simp_replacer(m, p), true));
else
return clean(alloc(solve_eqs_tactic, m, p, r, false));
tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p) {
return clean(alloc(solve_eqs_tactic, m, p, mk_expr_simp_replacer(m, p), true));
}

View file

@ -21,9 +21,8 @@ Revision History:
#include "util/params.h"
class ast_manager;
class tactic;
class expr_replacer;
tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p = params_ref(), expr_replacer * r = nullptr);
tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p = params_ref());
/*
ADD_TACTIC("solve-eqs", "eliminate variables by solving equations.", "mk_solve_eqs_tactic(m, p)")

View file

@ -18,6 +18,7 @@ Notes:
--*/
#include "tactic/tactical.h"
#include "tactic/goal_proof_converter.h"
#include "tactic/core/split_clause_tactic.h"
class split_clause_tactic : public tactic {

View file

@ -25,6 +25,7 @@ Notes:
#include "ast/rewriter/expr_replacer.h"
#include "ast/rewriter/rewriter_def.h"
#include "ast/ast_pp.h"
#include "ast/ast_util.h"
class symmetry_reduce_tactic : public tactic {
class imp;
@ -608,12 +609,12 @@ private:
return (j == A.size())?0:A[j];
}
app* mk_member(app* t, term_set const& C) {
expr* mk_member(app* t, term_set const& C) {
expr_ref_vector eqs(m());
for (unsigned i = 0; i < C.size(); ++i) {
eqs.push_back(m().mk_eq(t, C[i]));
}
return m().mk_or(eqs.size(), eqs.data());
return mk_or(m(), eqs.size(), eqs.data());
}
};

View file

@ -52,7 +52,7 @@ Notes:
#include "ast/ast_pp.h"
#include "tactic/tactical.h"
#include "tactic/goal_shared_occs.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/rewriter/bool_rewriter.h"
#include "tactic/core/simplify_tactic.h"

View file

@ -22,7 +22,7 @@ Notes:
#include "util/ref.h"
#include "ast/ast_pp_util.h"
#include "model/model.h"
#include "tactic/converter.h"
#include "ast/converters/converter.h"
class goal;

View file

@ -0,0 +1,103 @@
/*++
Copyright (c) 2022 Microsoft Corporation
Module Name:
dependent_expr_state_tactic.h
Abstract:
The dependent_expr_state_tactic creates a tactic from a dependent_expr_simplifier.
It relies on a factory for building simplifiers.
Author:
Nikolaj Bjorner (nbjorner) 2022-11-2.
--*/
#include "tactic/tactic.h"
#include "ast/simplifiers/dependent_expr_state.h"
class dependent_expr_state_tactic : public tactic, public dependent_expr_state {
ast_manager& m;
params_ref m_params;
std::string m_name;
ref<dependent_expr_simplifier_factory> m_factory;
scoped_ptr<dependent_expr_simplifier> m_simp;
goal_ref m_goal;
dependent_expr m_dep;
void init() {
if (!m_simp)
m_simp = m_factory->mk(m, m_params, *this);
}
public:
dependent_expr_state_tactic(ast_manager& m, params_ref const& p, dependent_expr_simplifier_factory* f, char const* name):
m(m),
m_params(p),
m_name(name),
m_factory(f),
m_simp(f->mk(m, p, *this)),
m_dep(m, m.mk_true(), nullptr)
{}
/**
* size(), [](), update() and inconsisent() implement the abstract interface of dependent_expr_state
*/
unsigned size() const override { return m_goal->size(); }
dependent_expr const& operator[](unsigned i) override {
m_dep = dependent_expr(m, m_goal->form(i), m_goal->dep(i));
return m_dep;
}
void update(unsigned i, dependent_expr const& j) override {
auto [f, d] = j();
m_goal->update(i, f, nullptr, d);
}
bool inconsistent() override {
return m_goal->inconsistent();
}
char const* name() const override { return m_name.c_str(); }
void updt_params(params_ref const & p) override {
m_params.append(p);
init();
m_simp->updt_params(m_params);
}
tactic * translate(ast_manager & m) override {
return alloc(dependent_expr_state_tactic, m, m_params, m_factory.get(), name());
}
void operator()(goal_ref const & in,
goal_ref_buffer & result) override {
if (in->proofs_enabled())
throw tactic_exception("tactic does not support low level proofs");
init();
tactic_report report(name(), *in);
m_goal = in.get();
m_simp->reduce();
m_goal->inc_depth();
if (in->models_enabled())
in->set(m_simp->get_model_converter().get());
result.push_back(in.get());
}
void cleanup() override {
}
void collect_statistics(statistics & st) const override {
if (m_simp)
m_simp->collect_statistics(st);
}
void reset_statistics() override {
if (m_simp)
m_simp->reset_statistics();
}
};

View file

@ -1,35 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
equiv_proof_converter.cpp
Abstract:
Proof converter that applies equivalence rule to leaves.
Author:
Nikolaj Bjorner (nbjorner) 2012-11-23
Revision History:
--*/
#include "tactic/equiv_proof_converter.h"
#include "ast/ast_pp.h"
#include "ast/scoped_proof.h"
void equiv_proof_converter::insert(expr* fml1, expr* fml2) {
if (fml1 != fml2) {
scoped_proof _sp(m);
proof_ref p1(m), p2(m), p3(m);
p1 = m.mk_asserted(fml1);
p2 = m.mk_rewrite(fml1, fml2);
p3 = m.mk_modus_ponens(p1, p2);
TRACE("proof_converter", tout << mk_pp(p3.get(), m) << "\n";);
SASSERT(m.has_fact(p3));
m_replace.insert(p3);
}
}

View file

@ -1,49 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
equiv_proof_converter.h
Abstract:
Proof converter that applies equivalence rule to leaves.
Given a proof P with occurrences of [asserted fml]
replace [asserted fml] by a proof of the form
[mp [asserted fml'] [~ fml fml']]
Author:
Nikolaj Bjorner (nbjorner) 2012-11-23
Revision History:
--*/
#pragma once
#include "tactic/replace_proof_converter.h"
class equiv_proof_converter : public proof_converter {
ast_manager& m;
replace_proof_converter m_replace;
public:
equiv_proof_converter(ast_manager& m): m(m), m_replace(m) {}
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
return m_replace(m, num_source, source);
}
proof_converter * translate(ast_translation & translator) override {
return m_replace.translate(translator);
}
void insert(expr* fml1, expr* fml2);
ast_manager& get_manager() { return m; }
void display(std::ostream & out) override {}
};

View file

@ -20,7 +20,7 @@ Notes:
#include "solver/solver_na2as.h"
#include "tactic/tactic.h"
#include "ast/rewriter/pb2bv_rewriter.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/ast_pp.h"
#include "model/model_smt2_pp.h"
#include "tactic/arith/bound_manager.h"

View file

@ -26,7 +26,7 @@ Notes:
#include "ast/rewriter/enum2bv_rewriter.h"
#include "model/model_smt2_pp.h"
#include "tactic/tactic.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "tactic/fd_solver/enum2bv_solver.h"
#include "solver/solver_na2as.h"

View file

@ -22,7 +22,7 @@ Notes:
#include "ast/rewriter/th_rewriter.h"
#include "model/model_smt2_pp.h"
#include "tactic/tactic.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "solver/solver_na2as.h"
#include "tactic/fd_solver/pb2bv_solver.h"

View file

@ -19,7 +19,7 @@ Notes:
#pragma once
#include "ast/fpa/fpa2bv_converter.h"
#include "tactic/model_converter.h"
#include "ast/converters/model_converter.h"
#include "ast/fpa/bv2fpa_converter.h"
class fpa2bv_model_converter : public model_converter {

View file

@ -1,218 +0,0 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
generic_model_converter.cpp
Abstract:
Generic model converter that hides and adds entries.
It subsumes filter_model_converter and extension_model_converter.
Author:
Nikolaj Bjorner (nbjorner) 2017-10-29
Notes:
--*/
#include "ast/ast_pp.h"
#include "ast/ast_ll_pp.h"
#include "ast/for_each_expr.h"
#include "ast/ast_util.h"
#include "ast/occurs.h"
#include "ast/rewriter/expr_safe_replace.h"
#include "ast/rewriter/th_rewriter.h"
#include "tactic/generic_model_converter.h"
#include "model/model_v2_pp.h"
#include "model/model_evaluator.h"
generic_model_converter::~generic_model_converter() {
}
void generic_model_converter::add(func_decl * d, expr* e) {
VERIFY(e);
VERIFY(d->get_range() == e->get_sort());
m_first_idx.insert_if_not_there(d, m_entries.size());
m_entries.push_back(entry(d, e, m, ADD));
}
void generic_model_converter::operator()(model_ref & md) {
TRACE("model_converter", tout << "before generic_model_converter\n"; model_v2_pp(tout, *md); display(tout););
model_evaluator ev(*(md.get()));
ev.set_model_completion(true);
ev.set_expand_array_equalities(false);
expr_ref val(m);
unsigned arity;
bool reset_ev = false;
for (unsigned i = m_entries.size(); i-- > 0; ) {
entry const& e = m_entries[i];
switch (e.m_instruction) {
case instruction::HIDE:
md->unregister_decl(e.m_f);
break;
case instruction::ADD:
ev(e.m_def, val);
TRACE("model_converter", tout << e.m_f->get_name() << " ->\n" << e.m_def << "\n==>\n" << val << "\n";);
arity = e.m_f->get_arity();
reset_ev = false;
if (arity == 0) {
expr* old_val = md->get_const_interp(e.m_f);
if (old_val && old_val == val) {
// skip
}
else {
reset_ev = old_val != nullptr;
md->register_decl(e.m_f, val);
}
}
else {
func_interp * old_val = md->get_func_interp(e.m_f);
if (old_val && old_val->get_else() == val) {
// skip
}
else {
reset_ev = old_val != nullptr;
func_interp * new_fi = alloc(func_interp, m, arity);
new_fi->set_else(val);
md->register_decl(e.m_f, new_fi);
}
}
if (reset_ev) {
ev.reset();
ev.set_model_completion(true);
ev.set_expand_array_equalities(false);
}
break;
}
}
TRACE("model_converter", tout << "after generic_model_converter\n"; model_v2_pp(tout, *md););
}
void generic_model_converter::display(std::ostream & out) {
for (entry const& e : m_entries) {
switch (e.m_instruction) {
case instruction::HIDE:
display_del(out, e.m_f);
break;
case instruction::ADD:
display_add(out, m, e.m_f, e.m_def);
break;
}
}
}
generic_model_converter * generic_model_converter::copy(ast_translation & translator) {
ast_manager& to = translator.to();
generic_model_converter * res = alloc(generic_model_converter, to, m_orig.c_str());
for (entry const& e : m_entries) {
func_decl_ref d(translator(e.m_f.get()), to);
switch (e.m_instruction) {
case instruction::HIDE:
res->hide(d);
break;
case instruction::ADD: {
expr_ref def(translator(e.m_def.get()), to);
res->add(d, def);
break;
}
}
}
return res;
}
void generic_model_converter::set_env(ast_pp_util* visitor) {
if (!visitor) {
m_env = nullptr;
}
else {
m_env = &visitor->env();
for (entry const& e : m_entries) {
visitor->coll.visit_func(e.m_f);
if (e.m_def) visitor->coll.visit(e.m_def);
}
}
}
void generic_model_converter::get_units(obj_map<expr, bool>& units) {
th_rewriter rw(m);
expr_safe_replace rep(m);
expr_ref tmp(m);
for (auto const& kv : units) {
rep.insert(kv.m_key, kv.m_value ? m.mk_true() : m.mk_false());
}
for (unsigned i = m_entries.size(); i-- > 0;) {
entry const& e = m_entries[i];
switch (e.m_instruction) {
case HIDE:
tmp = m.mk_const(e.m_f);
if (units.contains(tmp)) {
m.dec_ref(tmp);
units.remove(tmp);
}
break;
case ADD:
if (e.m_f->get_arity() == 0 && m.is_bool(e.m_f->get_range())) {
tmp = m.mk_const(e.m_f);
if (units.contains(tmp)) {
break;
}
tmp = e.m_def;
rep(tmp);
rw(tmp);
if (m.is_true(tmp)) {
tmp = m.mk_const(e.m_f);
m.inc_ref(tmp);
units.insert(tmp, true);
rep.insert(tmp, m.mk_true());
}
else if (m.is_false(tmp)) {
tmp = m.mk_const(e.m_f);
m.inc_ref(tmp);
units.insert(tmp, false);
rep.insert(tmp, m.mk_false());
}
}
break;
}
}
}
/*
\brief simplify definition expansion from model converter in the case they come from blocked clauses.
In this case the definitions are of the form:
x <=> x or not (C)
or dually,
x <=> not (not x or not C)
in either case the definitions simplify to
x or C
*/
expr_ref generic_model_converter::simplify_def(entry const& e) {
expr_ref c(m.mk_const(e.m_f), m);
if (m.is_bool(c) && occurs(c, e.m_def)) {
expr_safe_replace rep(m);
expr_ref result1 = e.m_def;
expr_ref result2 = e.m_def;
rep.apply_substitution(c, m.mk_true(), result1);
rep.apply_substitution(c, m.mk_false(), result2);
th_rewriter rw(m);
expr_ref result(m.mk_and(m.mk_implies(result2, c), m.mk_implies(c, result1)), m);
rw(result);
return result;
}
else {
return expr_ref(m.mk_eq(c, e.m_def), m);
}
}

View file

@ -1,73 +0,0 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
generic_model_converter.h
Abstract:
Generic model converter that hides and adds entries.
It subsumes filter_model_converter and extension_model_converter.
Author:
Nikolaj Bjorner (nbjorner) 2017-10-29
Notes:
--*/
#pragma once
#include "tactic/model_converter.h"
class generic_model_converter : public model_converter {
enum instruction { HIDE, ADD };
struct entry {
func_decl_ref m_f;
expr_ref m_def;
instruction m_instruction;
entry(func_decl* f, expr* d, ast_manager& m, instruction i):
m_f(f, m), m_def(d, m), m_instruction(i) {}
};
ast_manager& m;
std::string m_orig;
vector<entry> m_entries;
obj_map<func_decl, unsigned> m_first_idx;
expr_ref simplify_def(entry const& e);
public:
generic_model_converter(ast_manager & m, char const* orig) : m(m), m_orig(orig) {}
~generic_model_converter() override;
void hide(expr* e) { SASSERT(is_app(e) && to_app(e)->get_num_args() == 0); hide(to_app(e)->get_decl()); }
void hide(func_decl * f) { m_entries.push_back(entry(f, nullptr, m, HIDE)); }
void add(func_decl * d, expr* e);
void add(expr * d, expr* e) { SASSERT(is_app(d) && to_app(d)->get_num_args() == 0); add(to_app(d)->get_decl(), e); }
void operator()(labels_vec & labels) override {}
void operator()(model_ref & md) override;
void operator()(expr_ref& fml) override { UNREACHABLE(); }
void cancel() override {}
void display(std::ostream & out) override;
model_converter * translate(ast_translation & translator) override { return copy(translator); }
generic_model_converter* copy(ast_translation & translator);
void set_env(ast_pp_util* visitor) override;
void get_units(obj_map<expr, bool>& units) override;
};
typedef ref<generic_model_converter> generic_model_converter_ref;

View file

@ -34,8 +34,8 @@ Revision History:
#include "util/ref.h"
#include "util/ref_vector.h"
#include "util/ref_buffer.h"
#include "tactic/model_converter.h"
#include "tactic/proof_converter.h"
#include "ast/converters/model_converter.h"
#include "ast/converters/proof_converter.h"
#include "tactic/dependency_converter.h"
class goal {

View file

@ -0,0 +1,63 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
goal_proof_converter.h
Abstract:
Proof converter for goals
Author:
Nikolaj Bjorner (nbjorner) 2012-11-23
--*/
#pragma once
#include "ast/converters/proof_converter.h"
class goal;
/**
\brief create a proof converter that takes a set of subgoals and converts their proofs to a proof of
the goal they were derived from.
*/
proof_converter * concat(proof_converter *pc1, unsigned n, goal* const* goals);
class subgoal_proof_converter : public proof_converter {
proof_converter_ref m_pc;
goal_ref_buffer m_goals;
public:
subgoal_proof_converter(proof_converter* pc, unsigned n, goal * const* goals):
m_pc(pc)
{
for (unsigned i = 0; i < n; ++i) m_goals.push_back(goals[i]);
}
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
// ignore the proofs from the arguments, instead obtain the proofs fromt he subgoals.
SASSERT(num_source == 0);
proof_converter_ref_buffer pc_buffer;
for (goal_ref g : m_goals) {
pc_buffer.push_back(g->pc());
}
return apply(m, m_pc, pc_buffer);
}
proof_converter* translate(ast_translation& tr) override {
proof_converter_ref pc1 = m_pc->translate(tr);
goal_ref_buffer goals;
for (goal_ref g : m_goals) goals.push_back(g->translate(tr));
return alloc(subgoal_proof_converter, pc1.get(), goals.size(), goals.data());
}
void display(std::ostream& out) override {}
};
inline proof_converter * concat(proof_converter *pc, unsigned n, goal* const* goals) {
return alloc(subgoal_proof_converter, pc, n, goals);
}

View file

@ -1,228 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
horn_subsume_model_converter.cpp
Abstract:
Model converter for redundant Horn clauses.
Author:
Nikolaj Bjorner (nbjorner) 2012-9-16
Revision History:
--*/
#include "tactic/horn_subsume_model_converter.h"
#include "ast/rewriter/var_subst.h"
#include "ast/ast_pp.h"
#include "model/model_smt2_pp.h"
#include "ast/rewriter/bool_rewriter.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/for_each_expr.h"
#include "ast/well_sorted.h"
void horn_subsume_model_converter::insert(app* head, expr* body) {
m_delay_head.push_back(head);
m_delay_body.push_back(body);
}
void horn_subsume_model_converter::insert(app* head, unsigned sz, expr* const* body) {
expr_ref b(m);
bool_rewriter(m).mk_and(sz, body, b);
insert(head, b.get());
}
bool horn_subsume_model_converter::mk_horn(
app* head, expr* body, func_decl_ref& pred, expr_ref& body_res) {
expr_ref_vector conjs(m), subst(m);
ptr_vector<sort> sorts2;
var_subst vs(m, false);
if (!is_uninterp(head)) {
return false;
}
pred = head->get_decl();
unsigned arity = head->get_num_args();
expr_free_vars fv;
fv(head);
fv.accumulate(body);
if (arity == 0 && fv.empty()) {
body_res = body;
return true;
}
fv.set_default_sort(m.mk_bool_sort());
svector<symbol> names;
for (unsigned i = 0; i < fv.size(); ++i) {
names.push_back(symbol(i));
}
names.reverse();
fv.reverse();
conjs.push_back(body);
for (unsigned i = 0; i < arity; ++i) {
expr* arg = head->get_arg(i);
var_ref v(m);
v = m.mk_var(fv.size()+i, arg->get_sort());
if (is_var(arg)) {
unsigned w = to_var(arg)->get_idx();
if (w >= subst.size()) {
subst.resize(w+1);
}
if (subst.get(w)) {
conjs.push_back(m.mk_eq(v, subst.get(w)));
}
else {
subst[w] = v;
}
}
else {
conjs.push_back(m.mk_eq(v, arg));
}
}
expr_ref body_expr(m);
body_expr = m.mk_and(conjs);
// substitute variables directly.
if (!subst.empty()) {
body_expr = vs(body_expr, subst);
}
if (fv.empty()) {
SASSERT(subst.empty());
body_res = body_expr;
}
else {
body_res = m.mk_exists(fv.size(), fv.data(), names.data(), body_expr.get());
m_rewrite(body_res);
}
TRACE("mc",
tout << mk_pp(head, m) << " :- " << mk_pp(body, m) << "\n";
tout << pred->get_name() << " :- " << mk_pp(body_res.get(), m) << "\n";);
return true;
}
bool horn_subsume_model_converter::mk_horn(
expr* clause, func_decl_ref& pred, expr_ref& body) {
// formula is closed.
DEBUG_CODE(expr_free_vars fv; fv(clause); SASSERT(fv.empty()););
while (is_quantifier(clause) && to_quantifier(clause)->get_kind() == forall_k) {
quantifier* q = to_quantifier(clause);
clause = q->get_expr();
}
expr* e1, *e2;
if (m.is_implies(clause, e1, e2)) {
if (!is_uninterp(e2)) {
return false;
}
return mk_horn(to_app(e2), e1, pred, body);
}
else if (m.is_or(clause)) {
// todo?
return false;
}
else {
return false;
}
}
void horn_subsume_model_converter::add_default_proc::operator()(app* n) {
//
// predicates that have not been assigned values
// in the Horn model are assumed false.
//
if (m.is_bool(n) &&
!m_md->has_interpretation(n->get_decl()) &&
(n->get_family_id() == null_family_id)) {
TRACE("mc", tout << "adding: " << n->get_decl()->get_name() << "\n";);
if (n->get_decl()->get_arity() == 0) {
m_md->register_decl(n->get_decl(), m.mk_false());
}
else {
func_interp* fi = alloc(func_interp, m, n->get_decl()->get_arity());
fi->set_else(m.mk_false());
m_md->register_decl(n->get_decl(), fi);
}
}
}
void horn_subsume_model_converter::add_default_false_interpretation(expr* e, model_ref& md) {
add_default_proc proc(m, md);
for_each_expr(proc, e);
}
void horn_subsume_model_converter::operator()(model_ref& mr) {
func_decl_ref pred(m);
expr_ref body_res(m);
for (unsigned i = 0; i < m_delay_head.size(); ++i) {
VERIFY(mk_horn(m_delay_head.get(i), m_delay_body.get(i), pred, body_res));
insert(pred.get(), body_res.get());
}
m_delay_head.reset();
m_delay_body.reset();
TRACE("mc", tout << m_funcs.size() << "\n"; model_smt2_pp(tout, m, *mr, 0););
for (unsigned i = m_funcs.size(); i-- > 0; ) {
func_decl* h = m_funcs.get(i);
expr_ref body(m_bodies.get(i), m);
unsigned arity = h->get_arity();
add_default_false_interpretation(body, mr);
SASSERT(m.is_bool(body));
TRACE("mc", tout << "eval: " << h->get_name() << "\n" << body << "\n";);
body = (*mr)(body);
TRACE("mc", tout << "to:\n" << body << "\n";);
if (arity == 0) {
expr* e = mr->get_const_interp(h);
if (e) {
body = m.mk_or(e, body);
}
m_rewrite(body);
mr->register_decl(h, body);
}
else {
func_interp* f = mr->get_func_interp(h);
if (f) {
expr* e = f->get_else();
body = m.mk_or(e, body);
}
else {
f = alloc(func_interp, m, arity);
mr->register_decl(h, f);
}
m_rewrite(body);
f->set_else(body);
}
}
}
model_converter* horn_subsume_model_converter::translate(ast_translation & translator) {
horn_subsume_model_converter* mc = alloc(horn_subsume_model_converter, translator.to());
for (unsigned i = 0; i < m_funcs.size(); ++i) {
mc->insert(translator(m_funcs[i].get()), translator(m_bodies[i].get()));
}
return mc;
}

View file

@ -1,84 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
horn_subsume_model_converter.h
Abstract:
Model converter for redundant Horn clauses.
Author:
Nikolaj Bjorner (nbjorner) 2012-9-16
Revision History:
Notes:
Subsumption transformation (remove Horn clause):
P(x) :- Body(x,y) Rules
----------------------------
Rules
Model converter:
P(x) := P(x) or (exists y. Body(x,y))
--*/
#pragma once
#include "tactic/model_converter.h"
#include "ast/rewriter/th_rewriter.h"
class horn_subsume_model_converter : public model_converter {
ast_manager& m;
func_decl_ref_vector m_funcs;
expr_ref_vector m_bodies;
th_rewriter m_rewrite;
app_ref_vector m_delay_head;
expr_ref_vector m_delay_body;
void add_default_false_interpretation(expr* e, model_ref& md);
struct add_default_proc {
ast_manager& m;
model_ref& m_md;
add_default_proc(ast_manager& m, model_ref& md): m(m), m_md(md) {}
void operator()(app* n);
void operator()(expr* n) {}
};
public:
horn_subsume_model_converter(ast_manager& m):
m(m), m_funcs(m), m_bodies(m), m_rewrite(m), m_delay_head(m), m_delay_body(m) {}
bool mk_horn(expr* clause, func_decl_ref& pred, expr_ref& body);
bool mk_horn(app* head, expr* body, func_decl_ref& pred, expr_ref& body_res);
void insert(app* head, expr* body);
void insert(app* head, unsigned sz, expr* const* body);
void insert(func_decl* p, expr* body) { m_funcs.push_back(p); m_bodies.push_back(body); }
void operator()(model_ref& _m) override;
model_converter * translate(ast_translation & translator) override;
ast_manager& get_manager() { return m; }
void display(std::ostream & out) override {}
void get_units(obj_map<expr, bool>& units) override { units.reset(); }
};

View file

@ -1,201 +0,0 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
model_converter.h
Abstract:
Abstract interface for converting models.
Author:
Leonardo (leonardo) 2011-04-21
Notes:
--*/
#include "tactic/model_converter.h"
#include "model/model_v2_pp.h"
#include "ast/ast_smt2_pp.h"
/*
* Add or overwrite value in model.
*/
void model_converter::display_add(std::ostream& out, smt2_pp_environment& env, ast_manager& m, func_decl* f, expr* e) {
VERIFY(e);
VERIFY(f->get_range() == e->get_sort());
ast_smt2_pp(out, f, e, env, params_ref(), 0, "model-add") << "\n";
}
void model_converter::display_add(std::ostream& out, ast_manager& m, func_decl* f, expr* e) const {
smt2_pp_environment_dbg dbgenv(m);
smt2_pp_environment& env = m_env ? *m_env : dbgenv;
display_add(out, env, m, f, e);
}
/*
* A value is removed from the model.
*/
void model_converter::display_del(std::ostream& out, func_decl* f) const {
if (m_env) {
ast_smt2_pp(out << "(model-del ", f->get_name(), f->is_skolem(), *m_env) << ")\n";
}
else {
out << "(model-del " << f->get_name() << ")\n";
}
}
void model_converter::set_env(ast_pp_util* visitor) {
if (visitor) {
m_env = &visitor->env();
}
else {
m_env = nullptr;
}
}
void model_converter::display_add(std::ostream& out, ast_manager& m) {
// default printer for converter that adds entries
model_ref mdl = alloc(model, m);
(*this)(mdl);
smt2_pp_environment_dbg dbgenv(m);
smt2_pp_environment& env = m_env ? *m_env : dbgenv;
display_add(out, env, *mdl);
}
void model_converter::display_add(std::ostream& out, smt2_pp_environment& env, model& mdl) {
ast_manager& m = mdl.get_manager();
for (unsigned i = 0, sz = mdl.get_num_constants(); i < sz; ++i) {
func_decl* f = mdl.get_constant(i);
display_add(out, env, m, f, mdl.get_const_interp(f));
}
for (unsigned i = 0, sz = mdl.get_num_functions(); i < sz; ++i) {
func_decl* f = mdl.get_function(i);
func_interp* fi = mdl.get_func_interp(f);
display_add(out, env, m, f, fi->get_interp());
}
}
class concat_model_converter : public concat_converter<model_converter> {
public:
concat_model_converter(model_converter * mc1, model_converter * mc2): concat_converter<model_converter>(mc1, mc2) {
VERIFY(m_c1 && m_c2);
}
void operator()(model_ref & m) override {
this->m_c2->operator()(m);
this->m_c1->operator()(m);
}
void operator()(expr_ref & fml) override {
this->m_c2->operator()(fml);
this->m_c1->operator()(fml);
}
void operator()(labels_vec & r) override {
this->m_c2->operator()(r);
this->m_c1->operator()(r);
}
void get_units(obj_map<expr, bool>& fmls) override {
m_c2->get_units(fmls);
m_c1->get_units(fmls);
}
char const * get_name() const override { return "concat-model-converter"; }
model_converter * translate(ast_translation & translator) override {
return this->translate_core<concat_model_converter>(translator);
}
void set_env(ast_pp_util* visitor) override {
this->m_c1->set_env(visitor);
this->m_c2->set_env(visitor);
}
};
model_converter * concat(model_converter * mc1, model_converter * mc2) {
if (mc1 == nullptr)
return mc2;
if (mc2 == nullptr)
return mc1;
return alloc(concat_model_converter, mc1, mc2);
}
class model2mc : public model_converter {
model_ref m_model;
labels_vec m_labels;
public:
model2mc(model * m):m_model(m) {}
model2mc(model * m, labels_vec const & r):m_model(m), m_labels(r) {}
void operator()(model_ref & m) override {
if (!m || !m_model) {
m = m_model;
return;
}
m->copy_const_interps(*m_model.get());
m->copy_func_interps(*m_model.get());
m->copy_usort_interps(*m_model.get());
}
void operator()(labels_vec & r) override {
r.append(m_labels.size(), m_labels.data());
}
void operator()(expr_ref& fml) override {
model::scoped_model_completion _scm(m_model, false);
fml = (*m_model)(fml);
}
void get_units(obj_map<expr, bool>& fmls) override {
// no-op
}
void cancel() override {
}
void display(std::ostream & out) override {
ast_manager& m = m_model->get_manager();
smt2_pp_environment_dbg dbgenv(m);
smt2_pp_environment& env = m_env ? *m_env : dbgenv;
model_converter::display_add(out, env, *m_model);
}
model_converter * translate(ast_translation & translator) override {
model * m = m_model->translate(translator);
return alloc(model2mc, m, m_labels);
}
};
model_converter * model2model_converter(model * m) {
if (!m) return nullptr;
return alloc(model2mc, m);
}
model_converter * model_and_labels2model_converter(model * m, labels_vec const & r) {
if (!m) return nullptr;
return alloc(model2mc, m, r);
}
void model_converter2model(ast_manager & mng, model_converter * mc, model_ref & m) {
if (mc) {
m = alloc(model, mng);
(*mc)(m);
}
}
void apply(model_converter_ref & mc, model_ref & m) {
if (mc) {
(*mc)(m);
}
}

View file

@ -1,112 +0,0 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
model_converter.h
Abstract:
Abstract interface for converting models.
Author:
Leonardo (leonardo) 2011-04-21
Notes:
A model converter, mc, can be used to convert a model for one
of a generated subgoal into a model for an initial goal or solver state.
For a goal or solver state that is decided, a model converter can be
a simple wrapper around a model.
Logically, given a formula F and subgoal formula F_s a model converter mc
for F_s relative to F has the property:
m |= F_s iff mc(m) |= F for every model m
For the evaluator associated with models, m, we expect
eval(m)(F_s) <=> eval(mc(m))(F)
This property holds for both eval, that decides on a fixed value
for constants that have no interpretation in m and for 'peval'
(partial eval) that returns just the constants that are unfixed.
(in the model evaluator one can control this behavior using a
configuration flag)
and more generally over the eval method have:
G => F_s iff peval(mc(e))(G) => F for every formula G
where e is the empty model (a model that does not evaluate any
When a model converter supports application to a formula it satisfies
the following property:
mc(G) & F_s is SAT iff G & F is SAT
For a model converter that is a sequence of definitions and removals
of functions we can obtain mc(G) by adding back or expanding definitions
that are required to interpret G fully in the context of F_s.
--*/
#pragma once
#include "util/ref.h"
#include "ast/ast_pp_util.h"
#include "model/model.h"
#include "tactic/converter.h"
class labels_vec : public svector<symbol> {};
class smt2_pp_environment;
class model_converter : public converter {
protected:
smt2_pp_environment* m_env;
static void display_add(std::ostream& out, smt2_pp_environment& env, ast_manager& m, func_decl* f, expr* e);
void display_add(std::ostream& out, ast_manager& m, func_decl* f, expr* e) const;
void display_del(std::ostream& out, func_decl* f) const;
void display_add(std::ostream& out, ast_manager& m);
public:
model_converter(): m_env(nullptr) {}
virtual void operator()(model_ref & m) = 0;
virtual void operator()(labels_vec & r) {}
virtual void operator()(expr_ref& fml) { UNREACHABLE(); }
virtual model_converter * translate(ast_translation & translator) = 0;
virtual void set_env(ast_pp_util* visitor);
/**
\brief we are adding a formula to the context of the model converter.
The operator has as side effect of adding definitions as assertions to the
formula and removing these definitions from the model converter.
*/
virtual void get_units(obj_map<expr, bool>& fmls) { UNREACHABLE(); }
static void display_add(std::ostream& out, smt2_pp_environment& env, model& mdl);
};
typedef ref<model_converter> model_converter_ref;
typedef sref_vector<model_converter> model_converter_ref_vector;
typedef sref_buffer<model_converter> model_converter_ref_buffer;
model_converter * concat(model_converter * mc1, model_converter * mc2);
model_converter * model2model_converter(model * m);
model_converter * model_and_labels2model_converter(model * m, labels_vec const &r);
void model_converter2model(ast_manager & mng, model_converter * mc, model_ref & m);
void apply(model_converter_ref & mc, model_ref & m);

View file

@ -44,7 +44,7 @@ Notes:
#include "solver/solver2tactic.h"
#include "solver/parallel_tactic.h"
#include "solver/parallel_params.hpp"
#include "tactic/tactic_params.hpp"
#include "params/tactic_params.hpp"
#include "parsers/smt2/smt2parser.h"

View file

@ -1,136 +0,0 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
proof_converter.cpp
Abstract:
Abstract interface for converting proofs, and basic combinators
Author:
Leonardo (leonardo) 2011-11-14
Notes:
--*/
#include "tactic/proof_converter.h"
#include "tactic/goal.h"
#include "ast/ast_smt2_pp.h"
class concat_proof_converter : public concat_converter<proof_converter> {
public:
concat_proof_converter(proof_converter * pc1, proof_converter * pc2):concat_converter<proof_converter>(pc1, pc2) {}
char const * get_name() const override { return "concat-proof-converter"; }
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
proof_ref tmp(m);
tmp = this->m_c2->operator()(m, num_source, source);
proof * new_source = tmp.get();
return this->m_c1->operator()(m, 1, &new_source);
}
proof_converter * translate(ast_translation & translator) override {
return this->translate_core<concat_proof_converter>(translator);
}
};
proof_converter * concat(proof_converter * pc1, proof_converter * pc2) {
if (pc1 == nullptr)
return pc2;
if (pc2 == nullptr)
return pc1;
return alloc(concat_proof_converter, pc1, pc2);
}
class subgoal_proof_converter : public proof_converter {
proof_converter_ref m_pc;
goal_ref_buffer m_goals;
public:
subgoal_proof_converter(proof_converter* pc, unsigned n, goal * const* goals):
m_pc(pc)
{
for (unsigned i = 0; i < n; ++i) m_goals.push_back(goals[i]);
}
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
// ignore the proofs from the arguments, instead obtain the proofs fromt he subgoals.
SASSERT(num_source == 0);
proof_converter_ref_buffer pc_buffer;
for (goal_ref g : m_goals) {
pc_buffer.push_back(g->pc());
}
return apply(m, m_pc, pc_buffer);
}
proof_converter* translate(ast_translation& tr) override {
proof_converter_ref pc1 = m_pc->translate(tr);
goal_ref_buffer goals;
for (goal_ref g : m_goals) goals.push_back(g->translate(tr));
return alloc(subgoal_proof_converter, pc1.get(), goals.size(), goals.data());
}
void display(std::ostream& out) override {}
};
proof_converter * concat(proof_converter *pc, unsigned n, goal* const* goals) {
return alloc(subgoal_proof_converter, pc, n, goals);
}
class proof2pc : public proof_converter {
proof_ref m_pr;
public:
proof2pc(ast_manager & m, proof * pr):m_pr(pr, m) {}
proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) override {
SASSERT(num_source == 0);
return m_pr;
}
proof_converter * translate(ast_translation & translator) override {
return alloc(proof2pc, translator.to(), translator(m_pr.get()));
}
void display(std::ostream & out) override {
out << "(proof->proof-converter-wrapper\n" << mk_ismt2_pp(m_pr.get(), m_pr.get_manager()) << ")\n";
}
};
proof_converter * proof2proof_converter(ast_manager & m, proof * pr) {
if (pr == nullptr)
return nullptr;
return alloc(proof2pc, m, pr);
}
void apply(ast_manager & m, proof_converter * pc, proof_ref & pr) {
if (pc) {
proof * _pr = pr.get();
pr = (*pc)(m, 1, &_pr);
}
}
/**
Let pc2s be a buffer of proof converters that are wrappers for proofs.
That is, they are functors of the form: unit -> Proof
Then, this function applies pc1 to the proofs produced by pc2s's and store
the resultant proof in result.
pc1 and pc2s must be different from 0.
*/
proof_ref apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s) {
SASSERT(pc1);
proof_ref_buffer prs(m);
unsigned sz = pc2s.size();
for (unsigned i = 0; i < sz; i++) {
proof_ref pr(m);
SASSERT(pc2s[i]); // proof production is enabled
pr = pc2s[i]->operator()(m, 0, nullptr);
prs.push_back(pr);
}
return (*pc1)(m, sz, prs.data());
}

View file

@ -1,50 +0,0 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
proof_converter.h
Abstract:
Abstract interface for converting proofs, and basic combinators.
Author:
Leonardo (leonardo) 2011-04-26
Notes:
--*/
#pragma once
#include "ast/ast.h"
#include "util/ref.h"
#include "tactic/converter.h"
class goal;
class proof_converter : public converter {
public:
virtual proof_ref operator()(ast_manager & m, unsigned num_source, proof * const * source) = 0;
virtual proof_converter * translate(ast_translation & translator) = 0;
};
typedef ref<proof_converter> proof_converter_ref;
typedef sref_vector<proof_converter> proof_converter_ref_vector;
typedef sref_buffer<proof_converter> proof_converter_ref_buffer;
proof_converter * concat(proof_converter * pc1, proof_converter * pc2);
/**
\brief create a proof converter that takes a set of subgoals and converts their proofs to a proof of
the goal they were derived from.
*/
proof_converter * concat(proof_converter *pc1, unsigned n, goal* const* goals);
proof_converter * proof2proof_converter(ast_manager & m, proof * pr);
void apply(ast_manager & m, proof_converter * pc, proof_ref & pr);
proof_ref apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s);

View file

@ -1,83 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
replace_proof_converter.cpp
Abstract:
Proof converter that replaces asserted by sub-proof.
Author:
Nikolaj Bjorner (nbjorner) 2012-9-16
Revision History:
--*/
#include "tactic/replace_proof_converter.h"
#include "ast/expr_functors.h"
#include "ast/ast_pp.h"
#include "ast/for_each_expr.h"
/**
\brief Replace expressions by other expressions.
replace_map is caching, so inserting src |-> dst has no effect if
src is a sub-expression of something that has already been visited.
The assumption is that proof replacements are inserted into
the replace_proof_converter in the order that they are introduced, so
there are no such clashes.
map_proc is used as expr_replacer behaves differently
when proof mode is turned on.
*/
class replace_map : public map_proc {
public:
replace_map(ast_manager& m): map_proc(m) {}
void insert(expr* src, expr* dst) {
m_map.insert(src, dst, nullptr);
}
void operator()(var* v) { visit(v); }
void operator()(app* a) { if (!get_expr(a)) { reconstruct(a); } }
void operator()(quantifier* q) { visit(q); }
void apply(expr_ref& e) {
for_each_expr(*this, e);
e = get_expr(e);
}
};
proof_ref replace_proof_converter::operator()(ast_manager & m, unsigned num_source, proof * const * source) {
SASSERT(num_source == 1);
replace_map replace(m);
proof_ref p(m);
expr_ref tmp(source[0], m), e(m), f(m);
// apply the substitution to the prefix before inserting it.
for (unsigned i = 0; i < m_proofs.size(); ++i) {
p = m_proofs[i].get();
e = p;
replace.apply(e);
f = m.mk_asserted(m.get_fact(p));
replace.insert(f, e);
TRACE("proof_converter", tout << f->get_id() << " " << mk_pp(f, m) <<
"\n|-> " << mk_pp(e, m) << "\n";);
}
replace.apply(tmp);
TRACE("proof_converter", tout << mk_pp(source[0], m) << "\n";
tout << mk_pp(tmp.get(), m) << "\n";);
return proof_ref(to_app(tmp), m);
}
proof_converter * replace_proof_converter::translate(ast_translation & translator) {
replace_proof_converter* rp = alloc(replace_proof_converter, m);
for (proof* p : m_proofs) rp->insert(translator(p));
return rp;
}

View file

@ -1,48 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
replace_proof_converter.h
Abstract:
Proof converter to replace asserted leaves by proofs.
Given a proof P with occurrences of [asserted fml]
Replace [asserted fml] by proofs whose conclusions are fml.
Author:
Nikolaj Bjorner (nbjorner) 2012-9-16
Revision History:
--*/
#pragma once
#include "tactic/proof_converter.h"
class replace_proof_converter : public proof_converter {
ast_manager& m;
proof_ref_vector m_proofs;
public:
replace_proof_converter(ast_manager& _m): m(_m), m_proofs(m) {}
proof_ref operator()(ast_manager & _m, unsigned num_source, proof * const * source) override;
proof_converter * translate(ast_translation & translator) override;
void insert(proof* p) { m_proofs.push_back(p); }
ast_manager& get_manager() { return m; }
// run the replacements the inverse direction.
void invert() { m_proofs.reverse(); }
void display(std::ostream & out) override {}
};

View file

@ -20,7 +20,7 @@ Notes:
#include "util/stopwatch.h"
#include "util/lbool.h"
#include "tactic/model_converter.h"
#include "ast/converters/model_converter.h"
#include "tactic/goal.h"
#include "tactic/sls/sls_tracker.h"

View file

@ -16,7 +16,7 @@
--*/
#pragma once
#include "tactic/model_converter.h"
#include "ast/converters/model_converter.h"
#include "ackermannization/ackr_info.h"
model_converter * mk_qfufbv_ackr_model_converter(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model);

View file

@ -1,22 +0,0 @@
def_module_params('tactic',
description='tactic parameters',
export=True,
params=(('solve_eqs.context_solve', BOOL, True, "solve equalities within disjunctions."),
('solve_eqs.theory_solver', BOOL, True, "use theory solvers."),
('solve_eqs.ite_solver', BOOL, True, "use if-then-else solvers."),
('solve_eqs.max_occs', UINT, UINT_MAX, "maximum number of occurrences for considering a variable for gaussian eliminations."),
('blast_term_ite.max_inflation', UINT, UINT_MAX, "multiplicative factor of initial term size."),
('blast_term_ite.max_steps', UINT, UINT_MAX, "maximal number of steps allowed for tactic."),
('propagate_values.max_rounds', UINT, 4, "maximal number of rounds to propagate values."),
('default_tactic', SYMBOL, '', "overwrite default tactic in strategic solver"),
# ('aig.per_assertion', BOOL, True, "process one assertion at a time"),
# ('add_bounds.lower, INT, -2, "lower bound to be added to unbounded variables."),
# ('add_bounds.upper, INT, 2, "upper bound to be added to unbounded variables."),
# ('fm.real_only', BOOL, True, "consider only real variables for FM"),
# ('fm.occ', BOOL, False, "consider inequalities occurring in clauses for FM."),
# ('fm.limit', UINT, 5000000, "maximal number of constraints, monomials, clauses visited during FM."),
# etc: lia2card, factor, nla2bv, normalize_bounds, pb2bv, purify_arith, bit_blaster, bv_bounds
))

View file

@ -20,6 +20,7 @@ Notes:
#include "util/cancel_eh.h"
#include "util/scoped_ptr_vector.h"
#include "tactic/tactical.h"
#include "tactic/goal_proof_converter.h"
#ifndef SINGLE_THREAD
#include <thread>
#endif

View file

@ -20,7 +20,7 @@ Notes:
#include "ast/recfun_decl_plugin.h"
#include "ast/macros/macro_manager.h"
#include "ast/macros/macro_finder.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "tactic/ufbv/macro_finder_tactic.h"
class macro_finder_tactic : public tactic {

View file

@ -17,7 +17,7 @@ Notes:
--*/
#include "tactic/tactical.h"
#include "tactic/generic_model_converter.h"
#include "ast/converters/generic_model_converter.h"
#include "ast/macros/macro_manager.h"
#include "ast/macros/macro_finder.h"
#include "ast/macros/quasi_macros.h"