mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
fix dotnet build
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
9f0b303263
commit
25106866b5
|
@ -227,7 +227,7 @@ namespace Microsoft.Z3
|
||||||
/// <returns>A string representation of the Goal.</returns>
|
/// <returns>A string representation of the Goal.</returns>
|
||||||
public string ToDimacs(bool include_names = true)
|
public string ToDimacs(bool include_names = true)
|
||||||
{
|
{
|
||||||
return Native.Z3_goal_to_dimacs_string(Context.nCtx, NativeObject, include_names);
|
return Native.Z3_goal_to_dimacs_string(Context.nCtx, NativeObject, (byte)(include_names ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -341,13 +341,7 @@ namespace euf {
|
||||||
n->invariant();
|
n->invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& egraph::display(std::ostream& out) const {
|
std::ostream& egraph::display(std::ostream& out, unsigned max_args, enode* n) const {
|
||||||
m_table.display(out);
|
|
||||||
unsigned max_args = 0;
|
|
||||||
for (enode* n : m_nodes)
|
|
||||||
max_args = std::max(max_args, n->num_args());
|
|
||||||
|
|
||||||
for (enode* n : m_nodes) {
|
|
||||||
out << std::setw(5)
|
out << std::setw(5)
|
||||||
<< n->get_owner_id() << " := ";
|
<< n->get_owner_id() << " := ";
|
||||||
out << n->get_root()->get_owner_id() << " ";
|
out << n->get_root()->get_owner_id() << " ";
|
||||||
|
@ -366,6 +360,17 @@ namespace euf {
|
||||||
for (enode* p : enode_parents(n))
|
for (enode* p : enode_parents(n))
|
||||||
out << p->get_owner_id() << " ";
|
out << p->get_owner_id() << " ";
|
||||||
out << "\n";
|
out << "\n";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& egraph::display(std::ostream& out) const {
|
||||||
|
m_table.display(out);
|
||||||
|
unsigned max_args = 0;
|
||||||
|
for (enode* n : m_nodes)
|
||||||
|
max_args = std::max(max_args, n->num_args());
|
||||||
|
|
||||||
|
for (enode* n : m_nodes) {
|
||||||
|
display(out, max_args, n);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -392,16 +397,16 @@ namespace euf {
|
||||||
}
|
}
|
||||||
expr* e2 = tr(e1);
|
expr* e2 = tr(e1);
|
||||||
enode* n2 = mk(e2, args.size(), args.c_ptr());
|
enode* n2 = mk(e2, args.size(), args.c_ptr());
|
||||||
m_exprs.push_back(e2);
|
|
||||||
m_nodes.push_back(n2);
|
|
||||||
old_expr2new_enode.setx(e1->get_id(), n2, nullptr);
|
old_expr2new_enode.setx(e1->get_id(), n2, nullptr);
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < src.m_nodes.size(); ++i) {
|
for (unsigned i = 0; i < src.m_nodes.size(); ++i) {
|
||||||
enode* n1 = src.m_nodes[i];
|
enode* n1 = src.m_nodes[i];
|
||||||
enode* n1t = n1->m_target;
|
enode* n1t = n1->m_target;
|
||||||
enode* n2 = m_nodes[i];
|
enode* n2 = m_nodes[i];
|
||||||
enode* n2t = n1t ? old_expr2new_enode[n1t->get_owner_id()] : nullptr;
|
enode* n2t = n1t ? old_expr2new_enode[n1->get_owner_id()] : nullptr;
|
||||||
SASSERT(!n1t || n2t);
|
SASSERT(!n1t || n2t);
|
||||||
|
SASSERT(!n1t || src.m.get_sort(n1->get_owner()) == src.m.get_sort(n1t->get_owner()));
|
||||||
|
SASSERT(!n1t || m.get_sort(n2->get_owner()) == m.get_sort(n2t->get_owner()));
|
||||||
if (n1t && n2->get_root() != n2t->get_root()) {
|
if (n1t && n2->get_root() != n2t->get_root()) {
|
||||||
merge(n2, n2t, n1->m_justification.copy(copy_justification));
|
merge(n2, n2t, n1->m_justification.copy(copy_justification));
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,8 @@ namespace euf {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void explain_todo(ptr_vector<T>& justifications);
|
void explain_todo(ptr_vector<T>& justifications);
|
||||||
|
|
||||||
|
std::ostream& display(std::ostream& out, unsigned max_args, enode* n) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
egraph(ast_manager& m): m(m), m_table(m), m_exprs(m) {}
|
egraph(ast_manager& m): m(m), m_table(m), m_exprs(m) {}
|
||||||
enode* find(expr* f) { return m_expr2enode.get(f->get_id(), nullptr); }
|
enode* find(expr* f) { return m_expr2enode.get(f->get_id(), nullptr); }
|
||||||
|
@ -140,9 +142,17 @@ namespace euf {
|
||||||
enode_vector const& nodes() const { return m_nodes; }
|
enode_vector const& nodes() const { return m_nodes; }
|
||||||
void invariant();
|
void invariant();
|
||||||
void copy_from(egraph const& src, std::function<void*(void*)>& copy_justification);
|
void copy_from(egraph const& src, std::function<void*(void*)>& copy_justification);
|
||||||
|
struct e_pp {
|
||||||
|
egraph const& g;
|
||||||
|
enode* n;
|
||||||
|
e_pp(egraph const& g, enode* n) : g(g), n(n) {}
|
||||||
|
std::ostream& display(std::ostream& out) const { return g.display(out, 0, n); }
|
||||||
|
};
|
||||||
|
e_pp pp(enode* n) const { return e_pp(*this, n); }
|
||||||
std::ostream& display(std::ostream& out) const;
|
std::ostream& display(std::ostream& out) const;
|
||||||
void collect_statistics(statistics& st) const;
|
void collect_statistics(statistics& st) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, egraph const& g) { return g.display(out); }
|
inline std::ostream& operator<<(std::ostream& out, egraph const& g) { return g.display(out); }
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, egraph::e_pp const& p) { return p.display(out); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,10 @@ namespace euf {
|
||||||
* retrieve extension that is associated with Boolean variable.
|
* retrieve extension that is associated with Boolean variable.
|
||||||
*/
|
*/
|
||||||
sat::th_solver* solver::get_solver(sat::bool_var v) {
|
sat::th_solver* solver::get_solver(sat::bool_var v) {
|
||||||
if (v >= m_var2node.size())
|
unsigned idx = literal(v, false).index();
|
||||||
|
if (idx >= m_lit2node.size())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
euf::enode* n = m_var2node[v].first;
|
euf::enode* n = m_lit2node[idx];
|
||||||
if (!n)
|
if (!n)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return get_solver(n->get_owner());
|
return get_solver(n->get_owner());
|
||||||
|
@ -53,6 +54,8 @@ namespace euf {
|
||||||
auto* ext = m_id2solver.get(fid, nullptr);
|
auto* ext = m_id2solver.get(fid, nullptr);
|
||||||
if (ext)
|
if (ext)
|
||||||
return ext;
|
return ext;
|
||||||
|
if (fid == m.get_basic_family_id())
|
||||||
|
return nullptr;
|
||||||
pb_util pb(m);
|
pb_util pb(m);
|
||||||
if (pb.get_family_id() == fid) {
|
if (pb.get_family_id() == fid) {
|
||||||
ext = alloc(sat::ba_solver, m, si);
|
ext = alloc(sat::ba_solver, m, si);
|
||||||
|
@ -74,8 +77,11 @@ namespace euf {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::unhandled_function(func_decl* f) {
|
void solver::unhandled_function(func_decl* f) {
|
||||||
|
if (m_unhandled_functions.contains(f))
|
||||||
|
return;
|
||||||
|
m_unhandled_functions.push_back(f);
|
||||||
|
m_trail.push_back(new (m_region) push_back_vector<solver, func_decl_ref_vector>(m_unhandled_functions));
|
||||||
IF_VERBOSE(0, verbose_stream() << mk_pp(f, m) << " not handled\n");
|
IF_VERBOSE(0, verbose_stream() << mk_pp(f, m) << " not handled\n");
|
||||||
// TBD: set some state with the unhandled function.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::propagate(literal l, ext_constraint_idx idx) {
|
bool solver::propagate(literal l, ext_constraint_idx idx) {
|
||||||
|
@ -88,7 +94,7 @@ namespace euf {
|
||||||
void solver::get_antecedents(literal l, ext_justification_idx idx, literal_vector& r) {
|
void solver::get_antecedents(literal l, ext_justification_idx idx, literal_vector& r) {
|
||||||
auto* ext = sat::constraint_base::to_extension(idx);
|
auto* ext = sat::constraint_base::to_extension(idx);
|
||||||
if (ext == this)
|
if (ext == this)
|
||||||
get_antecedents(l, *constraint::from_idx(idx), r);
|
get_antecedents(l, constraint::from_idx(idx), r);
|
||||||
else
|
else
|
||||||
ext->get_antecedents(l, idx, r);
|
ext->get_antecedents(l, idx, r);
|
||||||
}
|
}
|
||||||
|
@ -96,8 +102,6 @@ namespace euf {
|
||||||
void solver::get_antecedents(literal l, constraint& j, literal_vector& r) {
|
void solver::get_antecedents(literal l, constraint& j, literal_vector& r) {
|
||||||
m_explain.reset();
|
m_explain.reset();
|
||||||
euf::enode* n = nullptr;
|
euf::enode* n = nullptr;
|
||||||
bool sign = false;
|
|
||||||
enode_bool_pair p;
|
|
||||||
|
|
||||||
// init_ackerman();
|
// init_ackerman();
|
||||||
|
|
||||||
|
@ -107,20 +111,19 @@ namespace euf {
|
||||||
m_egraph.explain<unsigned>(m_explain);
|
m_egraph.explain<unsigned>(m_explain);
|
||||||
break;
|
break;
|
||||||
case constraint::kind_t::eq:
|
case constraint::kind_t::eq:
|
||||||
n = m_var2node[l.var()].first;
|
n = m_lit2node[l.index()];
|
||||||
SASSERT(n);
|
SASSERT(n);
|
||||||
SASSERT(m_egraph.is_equality(n));
|
SASSERT(m_egraph.is_equality(n));
|
||||||
m_egraph.explain_eq<unsigned>(m_explain, n->get_arg(0), n->get_arg(1), n->commutative());
|
m_egraph.explain_eq<unsigned>(m_explain, n->get_arg(0), n->get_arg(1), n->commutative());
|
||||||
break;
|
break;
|
||||||
case constraint::kind_t::lit:
|
case constraint::kind_t::lit:
|
||||||
p = m_var2node[l.var()];
|
n = m_lit2node[l.index()];
|
||||||
n = p.first;
|
|
||||||
sign = l.sign() != p.second;
|
|
||||||
SASSERT(n);
|
SASSERT(n);
|
||||||
SASSERT(m.is_bool(n->get_owner()));
|
SASSERT(m.is_bool(n->get_owner()));
|
||||||
m_egraph.explain_eq<unsigned>(m_explain, n, (sign ? mk_false() : mk_true()), false);
|
m_egraph.explain_eq<unsigned>(m_explain, n, (l.sign() ? mk_false() : mk_true()), false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
std::cout << (unsigned)j.kind() << "\n";
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
for (unsigned* idx : m_explain)
|
for (unsigned* idx : m_explain)
|
||||||
|
@ -135,12 +138,13 @@ namespace euf {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto p = m_var2node.get(l.var(), enode_bool_pair(nullptr, false));
|
bool sign = l.sign();
|
||||||
if (!p.first)
|
unsigned idx = sat::literal(l.var(), false).index();
|
||||||
|
auto n = m_lit2node.get(idx, nullptr);
|
||||||
|
if (!n)
|
||||||
return;
|
return;
|
||||||
force_push();
|
force_push();
|
||||||
bool sign = p.second != l.sign();
|
|
||||||
euf::enode* n = p.first;
|
|
||||||
expr* e = n->get_owner();
|
expr* e = n->get_owner();
|
||||||
if (m.is_eq(e) && !sign) {
|
if (m.is_eq(e) && !sign) {
|
||||||
euf::enode* na = n->get_arg(0);
|
euf::enode* na = n->get_arg(0);
|
||||||
|
@ -149,6 +153,7 @@ namespace euf {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
euf::enode* nb = sign ? mk_false() : mk_true();
|
euf::enode* nb = sign ? mk_false() : mk_true();
|
||||||
|
std::cout << "merge " << n->get_owner_id() << " " << sign << " " << nb->get_owner_id() << "\n";
|
||||||
m_egraph.merge(n, nb, base_ptr() + l.index());
|
m_egraph.merge(n, nb, base_ptr() + l.index());
|
||||||
}
|
}
|
||||||
// TBD: delay propagation?
|
// TBD: delay propagation?
|
||||||
|
@ -216,39 +221,36 @@ namespace euf {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::push() {
|
void solver::push() {
|
||||||
++m_num_scopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void solver::force_push() {
|
|
||||||
for (; m_num_scopes > 0; --m_num_scopes) {
|
|
||||||
scope s;
|
scope s;
|
||||||
s.m_bool_var_lim = m_bool_var_trail.size();
|
s.m_lit_lim = m_lit_trail.size();
|
||||||
s.m_trail_lim = m_trail.size();
|
s.m_trail_lim = m_trail.size();
|
||||||
m_scopes.push_back(s);
|
m_scopes.push_back(s);
|
||||||
|
m_region.push_scope();
|
||||||
for (auto* e : m_solvers)
|
for (auto* e : m_solvers)
|
||||||
e->push();
|
e->push();
|
||||||
m_egraph.push();
|
m_egraph.push();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solver::force_push() {
|
||||||
|
for (; m_num_scopes > 0; --m_num_scopes) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::pop(unsigned n) {
|
void solver::pop(unsigned n) {
|
||||||
if (n <= m_num_scopes) {
|
|
||||||
m_num_scopes -= n;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
n -= m_num_scopes;
|
|
||||||
m_egraph.pop(n);
|
m_egraph.pop(n);
|
||||||
for (auto* e : m_solvers)
|
for (auto* e : m_solvers)
|
||||||
e->pop(n);
|
e->pop(n);
|
||||||
|
|
||||||
scope & s = m_scopes[m_scopes.size() - n];
|
scope const & s = m_scopes[m_scopes.size() - n];
|
||||||
|
|
||||||
for (unsigned i = m_bool_var_trail.size(); i-- > s.m_bool_var_lim; )
|
for (unsigned i = m_lit_trail.size(); i-- > s.m_lit_lim; )
|
||||||
m_var2node[m_bool_var_trail[i]] = enode_bool_pair(nullptr, false);
|
m_lit2node[m_lit_trail[i]] = nullptr;
|
||||||
m_bool_var_trail.shrink(s.m_bool_var_lim);
|
m_lit_trail.shrink(s.m_lit_lim);
|
||||||
|
|
||||||
undo_trail_stack(*this, m_trail, s.m_trail_lim);
|
undo_trail_stack(*this, m_trail, s.m_trail_lim);
|
||||||
|
|
||||||
|
m_region.pop_scope(n);
|
||||||
m_scopes.shrink(m_scopes.size() - n);
|
m_scopes.shrink(m_scopes.size() - n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +280,10 @@ namespace euf {
|
||||||
|
|
||||||
std::ostream& solver::display(std::ostream& out) const {
|
std::ostream& solver::display(std::ostream& out) const {
|
||||||
m_egraph.display(out);
|
m_egraph.display(out);
|
||||||
|
for (unsigned idx : m_lit_trail) {
|
||||||
|
euf::enode* n = m_lit2node[idx];
|
||||||
|
out << sat::to_literal(idx) << ": " << m_egraph.pp(n);
|
||||||
|
}
|
||||||
for (auto* e : m_solvers)
|
for (auto* e : m_solvers)
|
||||||
e->display(out);
|
e->display(out);
|
||||||
return out;
|
return out;
|
||||||
|
@ -363,8 +369,8 @@ namespace euf {
|
||||||
unsigned solver::max_var(unsigned w) const {
|
unsigned solver::max_var(unsigned w) const {
|
||||||
for (auto* e : m_solvers)
|
for (auto* e : m_solvers)
|
||||||
w = e->max_var(w);
|
w = e->max_var(w);
|
||||||
for (unsigned sz = m_var2node.size(); sz-- > 0; ) {
|
for (unsigned sz = m_lit2node.size(); sz-- > 0; ) {
|
||||||
euf::enode* n = m_var2node[sz].first;
|
euf::enode* n = m_lit2node[sz];
|
||||||
if (n && m.is_bool(n->get_owner())) {
|
if (n && m.is_bool(n->get_owner())) {
|
||||||
w = std::max(w, sz);
|
w = std::max(w, sz);
|
||||||
break;
|
break;
|
||||||
|
@ -452,13 +458,12 @@ namespace euf {
|
||||||
return n;
|
return n;
|
||||||
if (si.is_bool_op(e)) {
|
if (si.is_bool_op(e)) {
|
||||||
sat::literal lit = si.internalize(e);
|
sat::literal lit = si.internalize(e);
|
||||||
enode_bool_pair bp(nullptr, false);
|
n = m_lit2node.get(lit.index(), nullptr);
|
||||||
n = m_var2node.get(lit.var(), bp).first;
|
|
||||||
if (n)
|
if (n)
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
n = m_egraph.mk(e, 0, nullptr);
|
n = m_egraph.mk(e, 0, nullptr);
|
||||||
attach_bool_var(lit.var(), lit.sign(), n);
|
attach_lit(lit, n);
|
||||||
if (!m.is_true(e) && !m.is_false(e))
|
if (!m.is_true(e) && !m.is_false(e))
|
||||||
s().set_external(lit.var());
|
s().set_external(lit.var());
|
||||||
return n;
|
return n;
|
||||||
|
@ -476,15 +481,16 @@ namespace euf {
|
||||||
expr* e = n->get_owner();
|
expr* e = n->get_owner();
|
||||||
if (m.is_bool(e)) {
|
if (m.is_bool(e)) {
|
||||||
sat::bool_var v = si.add_bool_var(e);
|
sat::bool_var v = si.add_bool_var(e);
|
||||||
attach_bool_var(v, false, n);
|
attach_lit(literal(v, false), n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::attach_bool_var(sat::bool_var v, bool sign, euf::enode* n) {
|
void solver::attach_lit(literal lit, euf::enode* n) {
|
||||||
m_var2node.reserve(v + 1, enode_bool_pair(nullptr, false));
|
unsigned v = lit.index();
|
||||||
SASSERT(m_var2node[v].first == nullptr);
|
m_lit2node.reserve(v + 1, nullptr);
|
||||||
m_var2node[v] = euf::enode_bool_pair(n, sign);
|
SASSERT(m_lit2node[v] == nullptr);
|
||||||
m_bool_var_trail.push_back(v);
|
m_lit2node[v] = n;
|
||||||
|
m_lit_trail.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) {
|
bool solver::to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) {
|
||||||
|
|
|
@ -42,7 +42,9 @@ namespace euf {
|
||||||
public:
|
public:
|
||||||
constraint(kind_t k) : m_kind(k) {}
|
constraint(kind_t k) : m_kind(k) {}
|
||||||
kind_t kind() const { return m_kind; }
|
kind_t kind() const { return m_kind; }
|
||||||
static constraint* from_idx(size_t z) { return reinterpret_cast<constraint*>(z); }
|
static constraint& from_idx(size_t z) {
|
||||||
|
return *reinterpret_cast<constraint*>(sat::constraint_base::idx2mem(z));
|
||||||
|
}
|
||||||
size_t to_index() const { return sat::constraint_base::mem2base(this); }
|
size_t to_index() const { return sat::constraint_base::mem2base(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ namespace euf {
|
||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
struct scope {
|
struct scope {
|
||||||
unsigned m_bool_var_lim;
|
unsigned m_lit_lim;
|
||||||
unsigned m_trail_lim;
|
unsigned m_trail_lim;
|
||||||
};
|
};
|
||||||
typedef ptr_vector<trail<solver> > trail_stack;
|
typedef ptr_vector<trail<solver> > trail_stack;
|
||||||
|
@ -66,7 +68,8 @@ namespace euf {
|
||||||
smt_params m_config;
|
smt_params m_config;
|
||||||
euf::egraph m_egraph;
|
euf::egraph m_egraph;
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
|
region m_region;
|
||||||
|
func_decl_ref_vector m_unhandled_functions;
|
||||||
trail_stack m_trail;
|
trail_stack m_trail;
|
||||||
|
|
||||||
sat::solver* m_solver { nullptr };
|
sat::solver* m_solver { nullptr };
|
||||||
|
@ -76,12 +79,12 @@ namespace euf {
|
||||||
sat::sat_internalizer* m_to_si;
|
sat::sat_internalizer* m_to_si;
|
||||||
scoped_ptr<euf::ackerman> m_ackerman;
|
scoped_ptr<euf::ackerman> m_ackerman;
|
||||||
|
|
||||||
svector<euf::enode_bool_pair> m_var2node;
|
ptr_vector<euf::enode> m_lit2node;
|
||||||
ptr_vector<unsigned> m_explain;
|
ptr_vector<unsigned> m_explain;
|
||||||
euf::enode_vector m_args;
|
euf::enode_vector m_args;
|
||||||
svector<sat::frame> m_stack;
|
svector<sat::frame> m_stack;
|
||||||
unsigned m_num_scopes { 0 };
|
unsigned m_num_scopes { 0 };
|
||||||
unsigned_vector m_bool_var_trail;
|
unsigned_vector m_lit_trail;
|
||||||
svector<scope> m_scopes;
|
svector<scope> m_scopes;
|
||||||
scoped_ptr_vector<sat::th_solver> m_solvers;
|
scoped_ptr_vector<sat::th_solver> m_solvers;
|
||||||
ptr_vector<sat::th_solver> m_id2solver;
|
ptr_vector<sat::th_solver> m_id2solver;
|
||||||
|
@ -96,7 +99,7 @@ namespace euf {
|
||||||
// internalization
|
// internalization
|
||||||
euf::enode* visit(expr* e);
|
euf::enode* visit(expr* e);
|
||||||
void attach_bool_var(euf::enode* n);
|
void attach_bool_var(euf::enode* n);
|
||||||
void attach_bool_var(sat::bool_var v, bool sign, euf::enode* n);
|
void attach_lit(sat::literal lit, euf::enode* n);
|
||||||
euf::enode* mk_true();
|
euf::enode* mk_true();
|
||||||
euf::enode* mk_false();
|
euf::enode* mk_false();
|
||||||
|
|
||||||
|
@ -131,6 +134,7 @@ namespace euf {
|
||||||
m_expr2var(expr2var),
|
m_expr2var(expr2var),
|
||||||
si(si),
|
si(si),
|
||||||
m_egraph(m),
|
m_egraph(m),
|
||||||
|
m_unhandled_functions(m),
|
||||||
m_solver(nullptr),
|
m_solver(nullptr),
|
||||||
m_lookahead(nullptr),
|
m_lookahead(nullptr),
|
||||||
m_to_m(&m),
|
m_to_m(&m),
|
||||||
|
@ -198,5 +202,7 @@ namespace euf {
|
||||||
sat::literal internalize(expr* e, bool sign, bool root) override;
|
sat::literal internalize(expr* e, bool sign, bool root) override;
|
||||||
void update_model(model_ref& mdl);
|
void update_model(model_ref& mdl);
|
||||||
|
|
||||||
|
func_decl_ref_vector const& unhandled_functions() { return m_unhandled_functions; }
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,5 +90,9 @@ namespace sat {
|
||||||
return reinterpret_cast<void*>(((unsigned char*) ptr) + ext_size());
|
return reinterpret_cast<void*>(((unsigned char*) ptr) + ext_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void* idx2mem(size_t idx) {
|
||||||
|
return ptr2mem(from_index(idx));
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
bool m_ite_extra;
|
bool m_ite_extra;
|
||||||
unsigned long long m_max_memory;
|
unsigned long long m_max_memory;
|
||||||
expr_ref_vector m_trail;
|
expr_ref_vector m_trail;
|
||||||
func_decl_ref_vector m_interpreted_funs;
|
func_decl_ref_vector m_unhandled_funs;
|
||||||
bool m_default_external;
|
bool m_default_external;
|
||||||
bool m_xor_solver;
|
bool m_xor_solver;
|
||||||
bool m_euf;
|
bool m_euf;
|
||||||
|
@ -80,7 +80,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
m_map(map),
|
m_map(map),
|
||||||
m_dep2asm(dep2asm),
|
m_dep2asm(dep2asm),
|
||||||
m_trail(m),
|
m_trail(m),
|
||||||
m_interpreted_funs(m),
|
m_unhandled_funs(m),
|
||||||
m_default_external(default_external) {
|
m_default_external(default_external) {
|
||||||
updt_params(p);
|
updt_params(p);
|
||||||
m_true = sat::null_literal;
|
m_true = sat::null_literal;
|
||||||
|
@ -174,7 +174,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_interpreted_funs.push_back(to_app(t)->get_decl());
|
m_unhandled_funs.push_back(to_app(t)->get_decl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,8 +398,8 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
SASSERT(t->get_num_args() == 2);
|
SASSERT(t->get_num_args() == 2);
|
||||||
unsigned sz = m_result_stack.size();
|
unsigned sz = m_result_stack.size();
|
||||||
SASSERT(sz >= 2);
|
SASSERT(sz >= 2);
|
||||||
sat::literal l1 = m_result_stack[sz - 1];
|
sat::literal l2 = m_result_stack[sz - 1];
|
||||||
sat::literal l2 = m_result_stack[sz - 2];
|
sat::literal l1 = m_result_stack[sz - 2];
|
||||||
if (root) {
|
if (root) {
|
||||||
SASSERT(sz == 2);
|
SASSERT(sz == 2);
|
||||||
if (sign) {
|
if (sign) {
|
||||||
|
@ -469,6 +469,13 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
convert_iff2(t, root, sign);
|
convert_iff2(t, root, sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func_decl_ref_vector const& interpreted_funs() {
|
||||||
|
auto* ext = dynamic_cast<euf::solver*>(m_solver.get_extension());
|
||||||
|
if (ext)
|
||||||
|
return ext->unhandled_functions();
|
||||||
|
return m_unhandled_funs;
|
||||||
|
}
|
||||||
|
|
||||||
void convert_euf(expr* e, bool root, bool sign) {
|
void convert_euf(expr* e, bool root, bool sign) {
|
||||||
sat::extension* ext = m_solver.get_extension();
|
sat::extension* ext = m_solver.get_extension();
|
||||||
euf::solver* euf = nullptr;
|
euf::solver* euf = nullptr;
|
||||||
|
@ -693,6 +700,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(goal const & g) {
|
void operator()(goal const & g) {
|
||||||
|
g.display(std::cout);
|
||||||
struct scoped_reset {
|
struct scoped_reset {
|
||||||
imp& i;
|
imp& i;
|
||||||
scoped_reset(imp& i) :i(i) {}
|
scoped_reset(imp& i) :i(i) {}
|
||||||
|
@ -741,6 +749,12 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_model(model_ref& mdl) {
|
||||||
|
auto* ext = dynamic_cast<euf::solver*>(m_solver.get_extension());
|
||||||
|
if (ext)
|
||||||
|
ext->update_model(mdl);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct unsupported_bool_proc {
|
struct unsupported_bool_proc {
|
||||||
|
@ -792,7 +806,7 @@ void goal2sat::operator()(goal const & g, params_ref const & p, sat::solver_core
|
||||||
|
|
||||||
(*m_imp)(g);
|
(*m_imp)(g);
|
||||||
|
|
||||||
if (!t.get_extension() && m_imp->m_interpreted_funs.empty()) {
|
if (!t.get_extension() && m_imp->interpreted_funs().empty()) {
|
||||||
dealloc(m_imp);
|
dealloc(m_imp);
|
||||||
m_imp = nullptr;
|
m_imp = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -801,12 +815,17 @@ void goal2sat::operator()(goal const & g, params_ref const & p, sat::solver_core
|
||||||
|
|
||||||
void goal2sat::get_interpreted_funs(func_decl_ref_vector& atoms) {
|
void goal2sat::get_interpreted_funs(func_decl_ref_vector& atoms) {
|
||||||
if (m_imp) {
|
if (m_imp) {
|
||||||
atoms.append(m_imp->m_interpreted_funs);
|
atoms.append(m_imp->interpreted_funs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool goal2sat::has_interpreted_funs() const {
|
bool goal2sat::has_interpreted_funs() const {
|
||||||
return m_imp && !m_imp->m_interpreted_funs.empty();
|
return m_imp && !m_imp->interpreted_funs().empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void goal2sat::update_model(model_ref& mdl) {
|
||||||
|
if (m_imp)
|
||||||
|
m_imp->update_model(mdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,12 +61,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void operator()(goal const & g, params_ref const & p, sat::solver_core & t, atom2bool_var & m, dep2asm_map& dep2asm, bool default_external = false);
|
void operator()(goal const & g, params_ref const & p, sat::solver_core & t, atom2bool_var & m, dep2asm_map& dep2asm, bool default_external = false);
|
||||||
|
|
||||||
void get_interpreted_funs(func_decl_ref_vector& atoms);
|
void get_interpreted_funs(func_decl_ref_vector& funs);
|
||||||
|
|
||||||
bool has_interpreted_funs() const;
|
bool has_interpreted_funs() const;
|
||||||
|
|
||||||
sat::sat_internalizer& si(ast_manager& m, params_ref const& p, sat::solver_core& t, atom2bool_var& a2b, dep2asm_map& dep2asm, bool default_external = false);
|
sat::sat_internalizer& si(ast_manager& m, params_ref const& p, sat::solver_core& t, atom2bool_var& a2b, dep2asm_map& dep2asm, bool default_external = false);
|
||||||
|
|
||||||
|
void update_model(model_ref& mdl);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,12 @@ class sat_tactic : public tactic {
|
||||||
obj_map<expr, sat::literal> dep2asm;
|
obj_map<expr, sat::literal> dep2asm;
|
||||||
sat::literal_vector assumptions;
|
sat::literal_vector assumptions;
|
||||||
m_goal2sat(*g, m_params, *m_solver, map, dep2asm);
|
m_goal2sat(*g, m_params, *m_solver, map, dep2asm);
|
||||||
TRACE("sat", tout << "interpreted_atoms: " << map.interpreted_atoms() << "\n";
|
TRACE("sat", tout << "interpreted_atoms: " << m_goal2sat.has_interpreted_funs() << "\n";
|
||||||
for (auto const& kv : map) {
|
func_decl_ref_vector funs(m);
|
||||||
if (!is_uninterp_const(kv.m_key))
|
m_goal2sat.get_interpreted_funs(funs);
|
||||||
tout << mk_ismt2_pp(kv.m_key, m) << "\n";
|
for (func_decl* f : funs)
|
||||||
});
|
tout << mk_ismt2_pp(f, m) << "\n";
|
||||||
|
);
|
||||||
g->reset();
|
g->reset();
|
||||||
g->m().compact_memory();
|
g->m().compact_memory();
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ class sat_tactic : public tactic {
|
||||||
}
|
}
|
||||||
g->assert_expr(m.mk_false(), nullptr, lcore);
|
g->assert_expr(m.mk_false(), nullptr, lcore);
|
||||||
}
|
}
|
||||||
else if (r == l_true && !map.interpreted_atoms()) {
|
else if (r == l_true && !m_goal2sat.has_interpreted_funs()) {
|
||||||
// register model
|
// register model
|
||||||
if (produce_models) {
|
if (produce_models) {
|
||||||
model_ref md = alloc(model, m);
|
model_ref md = alloc(model, m);
|
||||||
|
@ -99,6 +100,7 @@ class sat_tactic : public tactic {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_goal2sat.update_model(md);
|
||||||
TRACE("sat_tactic", model_v2_pp(tout, *md););
|
TRACE("sat_tactic", model_v2_pp(tout, *md););
|
||||||
g->add(model2model_converter(md.get()));
|
g->add(model2model_converter(md.get()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue