mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
switch to solve_eqs2 tactic
This commit is contained in:
parent
f769e2f1f6
commit
3a37cfca30
|
@ -924,6 +924,11 @@ void th_rewriter::get_param_descrs(param_descrs & r) {
|
||||||
rewriter_params::collect_param_descrs(r);
|
rewriter_params::collect_param_descrs(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void th_rewriter::set_flat_and_or(bool f) {
|
||||||
|
m_imp->cfg().m_b_rw.set_flat_and_or(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
th_rewriter::~th_rewriter() {
|
th_rewriter::~th_rewriter() {
|
||||||
dealloc(m_imp);
|
dealloc(m_imp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@ public:
|
||||||
|
|
||||||
void updt_params(params_ref const & p);
|
void updt_params(params_ref const & p);
|
||||||
static void get_param_descrs(param_descrs & r);
|
static void get_param_descrs(param_descrs & r);
|
||||||
|
|
||||||
|
void set_flat_and_or(bool f);
|
||||||
|
|
||||||
unsigned get_cache_size() const;
|
unsigned get_cache_size() const;
|
||||||
unsigned get_num_steps() const;
|
unsigned get_num_steps() const;
|
||||||
|
|
||||||
|
|
|
@ -29,16 +29,23 @@ namespace euf {
|
||||||
class basic_extract_eq : public extract_eq {
|
class basic_extract_eq : public extract_eq {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
bool m_ite_solver = true;
|
bool m_ite_solver = true;
|
||||||
|
bool m_allow_bool = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
basic_extract_eq(ast_manager& m) : m(m) {}
|
basic_extract_eq(ast_manager& m) : m(m) {}
|
||||||
|
|
||||||
|
virtual void set_allow_booleans(bool f) {
|
||||||
|
m_allow_bool = f;
|
||||||
|
}
|
||||||
|
|
||||||
void get_eqs(dependent_expr const& e, dep_eq_vector& eqs) override {
|
void get_eqs(dependent_expr const& e, dep_eq_vector& eqs) override {
|
||||||
auto [f, d] = e();
|
auto [f, d] = e();
|
||||||
expr* x, * y;
|
expr* x, * y;
|
||||||
if (m.is_eq(f, x, y)) {
|
if (m.is_eq(f, x, y)) {
|
||||||
if (x == y)
|
if (x == y)
|
||||||
return;
|
return;
|
||||||
|
if (!m_allow_bool && m.is_bool(x))
|
||||||
|
return;
|
||||||
if (is_uninterp_const(x))
|
if (is_uninterp_const(x))
|
||||||
eqs.push_back(dependent_eq(e.fml(), to_app(x), expr_ref(y, m), d));
|
eqs.push_back(dependent_eq(e.fml(), to_app(x), expr_ref(y, m), d));
|
||||||
if (is_uninterp_const(y))
|
if (is_uninterp_const(y))
|
||||||
|
@ -47,6 +54,8 @@ namespace euf {
|
||||||
expr* c, * th, * el, * x1, * y1, * x2, * y2;
|
expr* c, * th, * el, * x1, * y1, * x2, * y2;
|
||||||
if (m_ite_solver && m.is_ite(f, c, th, el)) {
|
if (m_ite_solver && m.is_ite(f, c, th, el)) {
|
||||||
if (m.is_eq(th, x1, y1) && m.is_eq(el, x2, y2)) {
|
if (m.is_eq(th, x1, y1) && m.is_eq(el, x2, y2)) {
|
||||||
|
if (!m_allow_bool && m.is_bool(x1))
|
||||||
|
return;
|
||||||
if (x1 == y2 && is_uninterp_const(x1))
|
if (x1 == y2 && is_uninterp_const(x1))
|
||||||
std::swap(x2, y2);
|
std::swap(x2, y2);
|
||||||
if (x2 == y2 && is_uninterp_const(x2))
|
if (x2 == y2 && is_uninterp_const(x2))
|
||||||
|
@ -57,6 +66,8 @@ namespace euf {
|
||||||
eqs.push_back(dependent_eq(e.fml(), to_app(x1), expr_ref(m.mk_ite(c, y1, y2), m), d));
|
eqs.push_back(dependent_eq(e.fml(), to_app(x1), expr_ref(m.mk_ite(c, y1, y2), m), d));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!m_allow_bool)
|
||||||
|
return;
|
||||||
if (is_uninterp_const(f))
|
if (is_uninterp_const(f))
|
||||||
eqs.push_back(dependent_eq(e.fml(), to_app(f), expr_ref(m.mk_true(), m), d));
|
eqs.push_back(dependent_eq(e.fml(), to_app(f), expr_ref(m.mk_true(), m), d));
|
||||||
if (m.is_not(f, x) && is_uninterp_const(x))
|
if (m.is_not(f, x) && is_uninterp_const(x))
|
||||||
|
|
|
@ -18,6 +18,7 @@ Author:
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ast/ast_pp.h"
|
||||||
#include "ast/simplifiers/dependent_expr_state.h"
|
#include "ast/simplifiers/dependent_expr_state.h"
|
||||||
#include "ast/rewriter/th_rewriter.h"
|
#include "ast/rewriter/th_rewriter.h"
|
||||||
#include "ast/expr_substitution.h"
|
#include "ast/expr_substitution.h"
|
||||||
|
@ -42,8 +43,13 @@ namespace euf {
|
||||||
virtual void get_eqs(dependent_expr const& e, dep_eq_vector& eqs) = 0;
|
virtual void get_eqs(dependent_expr const& e, dep_eq_vector& eqs) = 0;
|
||||||
virtual void pre_process(dependent_expr_state& fmls) {}
|
virtual void pre_process(dependent_expr_state& fmls) {}
|
||||||
virtual void updt_params(params_ref const& p) {}
|
virtual void updt_params(params_ref const& p) {}
|
||||||
|
virtual void set_allow_booleans(bool f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void register_extract_eqs(ast_manager& m, scoped_ptr_vector<extract_eq>& ex);
|
void register_extract_eqs(ast_manager& m, scoped_ptr_vector<extract_eq>& ex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, euf::dependent_eq const& eq) {
|
||||||
|
return out << mk_pp(eq.var, eq.term.m()) << " = " << eq.term << "\n";
|
||||||
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ void model_reconstruction_trail::replay(dependent_expr const& d, vector<dependen
|
||||||
|
|
||||||
added.push_back(d);
|
added.push_back(d);
|
||||||
|
|
||||||
|
|
||||||
for (auto& t : m_trail) {
|
for (auto& t : m_trail) {
|
||||||
if (!t->m_active)
|
if (!t->m_active)
|
||||||
continue;
|
continue;
|
||||||
|
@ -69,6 +68,7 @@ model_converter_ref model_reconstruction_trail::get_model_converter() {
|
||||||
// substituted variables by their terms.
|
// substituted variables by their terms.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m, false);
|
scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m, false);
|
||||||
expr_substitution subst(m, true, false);
|
expr_substitution subst(m, true, false);
|
||||||
rp->set_substitution(&subst);
|
rp->set_substitution(&subst);
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace euf {
|
||||||
if (!contains_v(f))
|
if (!contains_v(f))
|
||||||
return true;
|
return true;
|
||||||
signed_expressions conjuncts;
|
signed_expressions conjuncts;
|
||||||
if (contains_conjunctively(f, sign, e, conjuncts))
|
if (contains_conjunctively(f, sign, e, conjuncts))
|
||||||
return true;
|
return true;
|
||||||
if (recursion_depth > 3)
|
if (recursion_depth > 3)
|
||||||
return false;
|
return false;
|
||||||
|
@ -67,9 +67,9 @@ namespace euf {
|
||||||
/*
|
/*
|
||||||
* Every disjunction in f that contains v also contains the equation e.
|
* Every disjunction in f that contains v also contains the equation e.
|
||||||
*/
|
*/
|
||||||
bool solve_context_eqs::is_disjunctively_safe(unsigned recursion_depth, expr* f, bool sign, expr* e) {
|
bool solve_context_eqs::is_disjunctively_safe(unsigned recursion_depth, expr* f0, bool sign, expr* e) {
|
||||||
signed_expressions todo;
|
signed_expressions todo;
|
||||||
todo.push_back({sign, f});
|
todo.push_back({sign, f0});
|
||||||
while (!todo.empty()) {
|
while (!todo.empty()) {
|
||||||
auto [s, f] = todo.back();
|
auto [s, f] = todo.back();
|
||||||
todo.pop_back();
|
todo.pop_back();
|
||||||
|
@ -93,11 +93,21 @@ namespace euf {
|
||||||
todo.push_back({s, arg});
|
todo.push_back({s, arg});
|
||||||
else if (m.is_not(f, f))
|
else if (m.is_not(f, f))
|
||||||
todo.push_back({!s, f});
|
todo.push_back({!s, f});
|
||||||
|
else if (!is_conjunction(s, f))
|
||||||
|
return false;
|
||||||
else if (!is_safe_eq(recursion_depth + 1, f, s, e))
|
else if (!is_safe_eq(recursion_depth + 1, f, s, e))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool solve_context_eqs::is_conjunction(bool sign, expr* f) const {
|
||||||
|
if (!sign && m.is_and(f))
|
||||||
|
return true;
|
||||||
|
if (sign && m.is_or(f))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether some conjunction in f contains e.
|
* Determine whether some conjunction in f contains e.
|
||||||
|
@ -140,29 +150,43 @@ namespace euf {
|
||||||
for (unsigned i = m_solve_eqs.m_qhead; i < m_fmls.size(); ++i)
|
for (unsigned i = m_solve_eqs.m_qhead; i < m_fmls.size(); ++i)
|
||||||
collect_nested_equalities(m_fmls[i], visited, eqs);
|
collect_nested_equalities(m_fmls[i], visited, eqs);
|
||||||
|
|
||||||
|
std::stable_sort(eqs.begin(), eqs.end(), [&](dependent_eq const& e1, dependent_eq const& e2) {
|
||||||
|
return e1.var->get_id() < e2.var->get_id(); });
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
|
expr* last_var = nullptr;
|
||||||
for (auto const& eq : eqs) {
|
for (auto const& eq : eqs) {
|
||||||
|
|
||||||
m_contains_v.reset();
|
|
||||||
|
|
||||||
// first check if v is in term. If it is, then the substitution candidate is unsafe
|
SASSERT(!m.is_bool(eq.var));
|
||||||
m_todo.push_back(eq.term);
|
|
||||||
mark_occurs(m_todo, eq.var, m_contains_v);
|
if (eq.var != last_var) {
|
||||||
SASSERT(m_todo.empty());
|
|
||||||
if (m_contains_v.is_marked(eq.term))
|
m_contains_v.reset();
|
||||||
|
|
||||||
|
// first check if v is in term. If it is, then the substitution candidate is unsafe
|
||||||
|
m_todo.push_back(eq.term);
|
||||||
|
mark_occurs(m_todo, eq.var, m_contains_v);
|
||||||
|
SASSERT(m_todo.empty());
|
||||||
|
last_var = eq.var;
|
||||||
|
if (m_contains_v.is_marked(eq.term))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// then mark occurrences
|
||||||
|
for (unsigned i = 0; i < m_fmls.size(); ++i)
|
||||||
|
m_todo.push_back(m_fmls[i].fml());
|
||||||
|
mark_occurs(m_todo, eq.var, m_contains_v);
|
||||||
|
SASSERT(m_todo.empty());
|
||||||
|
}
|
||||||
|
else if (m_contains_v.is_marked(eq.term))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// then mark occurrences
|
|
||||||
for (unsigned i = 0; i < m_fmls.size(); ++i)
|
|
||||||
m_todo.push_back(m_fmls[i].fml());
|
|
||||||
mark_occurs(m_todo, eq.var, m_contains_v);
|
|
||||||
SASSERT(m_todo.empty());
|
|
||||||
|
|
||||||
// subject to occurrences, check if equality is safe
|
// subject to occurrences, check if equality is safe
|
||||||
if (is_safe_eq(eq.orig))
|
if (is_safe_eq(eq.orig))
|
||||||
eqs[j++] = eq;
|
eqs[j++] = eq;
|
||||||
}
|
}
|
||||||
eqs.shrink(j);
|
eqs.shrink(j);
|
||||||
|
TRACE("solve_eqs",
|
||||||
|
for (auto const& eq : eqs)
|
||||||
|
tout << eq << "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void solve_context_eqs::collect_nested_equalities(dependent_expr const& df, expr_mark& visited, dep_eq_vector& eqs) {
|
void solve_context_eqs::collect_nested_equalities(dependent_expr const& df, expr_mark& visited, dep_eq_vector& eqs) {
|
||||||
|
@ -204,8 +228,11 @@ namespace euf {
|
||||||
else if (m.is_not(f, f))
|
else if (m.is_not(f, f))
|
||||||
todo.push_back({ !s, depth, f });
|
todo.push_back({ !s, depth, f });
|
||||||
else if (!s && 1 == depth % 2) {
|
else if (!s && 1 == depth % 2) {
|
||||||
for (extract_eq* ex : m_solve_eqs.m_extract_plugins)
|
for (extract_eq* ex : m_solve_eqs.m_extract_plugins) {
|
||||||
|
ex->set_allow_booleans(false);
|
||||||
ex->get_eqs(dependent_expr(m, f, df.dep()), eqs);
|
ex->get_eqs(dependent_expr(m, f, df.dep()), eqs);
|
||||||
|
ex->set_allow_booleans(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace euf {
|
||||||
bool is_safe_eq(expr* f, expr* e) { return is_safe_eq(0, f, false, e); }
|
bool is_safe_eq(expr* f, expr* e) { return is_safe_eq(0, f, false, e); }
|
||||||
bool is_disjunctively_safe(unsigned recursion_depth, expr* f, bool sign, expr* e);
|
bool is_disjunctively_safe(unsigned recursion_depth, expr* f, bool sign, expr* e);
|
||||||
bool contains_conjunctively(expr* f, bool sign, expr* e, signed_expressions& conjuncts);
|
bool contains_conjunctively(expr* f, bool sign, expr* e, signed_expressions& conjuncts);
|
||||||
|
bool is_conjunction(bool sign, expr* f) const;
|
||||||
|
|
||||||
void collect_nested_equalities(dependent_expr const& f, expr_mark& visited, dep_eq_vector& eqs);
|
void collect_nested_equalities(dependent_expr const& f, expr_mark& visited, dep_eq_vector& eqs);
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,8 @@ namespace euf {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solve_eqs::normalize() {
|
void solve_eqs::normalize() {
|
||||||
|
if (m_subst_ids.empty())
|
||||||
|
return;
|
||||||
scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m, false);
|
scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m, false);
|
||||||
rp->set_substitution(m_subst.get());
|
rp->set_substitution(m_subst.get());
|
||||||
|
|
||||||
|
@ -152,15 +154,18 @@ namespace euf {
|
||||||
void solve_eqs::apply_subst(vector<dependent_expr>& old_fmls) {
|
void solve_eqs::apply_subst(vector<dependent_expr>& old_fmls) {
|
||||||
if (!m.inc())
|
if (!m.inc())
|
||||||
return;
|
return;
|
||||||
|
if (m_subst_ids.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m, false);
|
scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m, false);
|
||||||
rp->set_substitution(m_subst.get());
|
rp->set_substitution(m_subst.get());
|
||||||
|
|
||||||
for (unsigned i = m_qhead; i < m_fmls.size() && !m_fmls.inconsistent(); ++i) {
|
for (unsigned i = m_qhead; i < m_fmls.size() && !m_fmls.inconsistent(); ++i) {
|
||||||
auto [f, d] = m_fmls[i]();
|
auto [f, d] = m_fmls[i]();
|
||||||
auto [new_f, new_dep] = rp->replace_with_dep(f);
|
auto [new_f, new_dep] = rp->replace_with_dep(f);
|
||||||
|
m_rewriter(new_f);
|
||||||
if (new_f == f)
|
if (new_f == f)
|
||||||
continue;
|
continue;
|
||||||
m_rewriter(new_f);
|
|
||||||
new_dep = m.mk_join(d, new_dep);
|
new_dep = m.mk_join(d, new_dep);
|
||||||
old_fmls.push_back(m_fmls[i]);
|
old_fmls.push_back(m_fmls[i]);
|
||||||
m_fmls.update(i, dependent_expr(m, new_f, new_dep));
|
m_fmls.update(i, dependent_expr(m, new_f, new_dep));
|
||||||
|
@ -185,14 +190,13 @@ namespace euf {
|
||||||
normalize();
|
normalize();
|
||||||
apply_subst(old_fmls);
|
apply_subst(old_fmls);
|
||||||
++count;
|
++count;
|
||||||
|
save_subst({});
|
||||||
}
|
}
|
||||||
while (!m_subst_ids.empty() && count < 20 && m.inc());
|
while (!m_subst_ids.empty() && count < 20 && m.inc());
|
||||||
|
|
||||||
if (!m.inc())
|
if (!m.inc())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
save_subst({});
|
|
||||||
|
|
||||||
if (m_config.m_context_solve) {
|
if (m_config.m_context_solve) {
|
||||||
old_fmls.reset();
|
old_fmls.reset();
|
||||||
m_subst_ids.reset();
|
m_subst_ids.reset();
|
||||||
|
@ -211,7 +215,7 @@ namespace euf {
|
||||||
|
|
||||||
void solve_eqs::save_subst(vector<dependent_expr> const& old_fmls) {
|
void solve_eqs::save_subst(vector<dependent_expr> const& old_fmls) {
|
||||||
if (!m_subst->empty())
|
if (!m_subst->empty())
|
||||||
m_fmls.model_trail().push(m_subst.detach(), old_fmls);
|
m_fmls.model_trail().push(m_subst.detach(), old_fmls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solve_eqs::filter_unsafe_vars() {
|
void solve_eqs::filter_unsafe_vars() {
|
||||||
|
@ -222,11 +226,10 @@ namespace euf {
|
||||||
m_unsafe_vars.mark(term);
|
m_unsafe_vars.mark(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
solve_eqs::solve_eqs(ast_manager& m, dependent_expr_state& fmls) :
|
solve_eqs::solve_eqs(ast_manager& m, dependent_expr_state& fmls) :
|
||||||
dependent_expr_simplifier(m, fmls), m_rewriter(m) {
|
dependent_expr_simplifier(m, fmls), m_rewriter(m) {
|
||||||
register_extract_eqs(m, m_extract_plugins);
|
register_extract_eqs(m, m_extract_plugins);
|
||||||
|
m_rewriter.set_flat_and_or(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solve_eqs::updt_params(params_ref const& p) {
|
void solve_eqs::updt_params(params_ref const& p) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ Notes:
|
||||||
#include "tactic/core/elim_uncnstr_tactic.h"
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/elim_term_ite_tactic.h"
|
#include "tactic/core/elim_term_ite_tactic.h"
|
||||||
|
|
||||||
tactic * mk_qfnra_nlsat_tactic(ast_manager & m, params_ref const & p) {
|
tactic * mk_qfnra_nlsat_tactic(ast_manager & m, params_ref const & p) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ Notes:
|
||||||
#include "tactic/tactic.h"
|
#include "tactic/tactic.h"
|
||||||
#include "tactic/arith/lia2card_tactic.h"
|
#include "tactic/arith/lia2card_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
|
|
@ -29,13 +29,19 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline tactic * mk_solve_eqs2_tactic(ast_manager& m, params_ref const& p) {
|
inline tactic * mk_solve_eqs2_tactic(ast_manager& m, params_ref const& p = params_ref()) {
|
||||||
return alloc(dependent_expr_state_tactic, m, p, alloc(solve_eqs2_tactic_factory), "solve-eqs2");
|
return alloc(dependent_expr_state_tactic, m, p, alloc(solve_eqs2_tactic_factory), "solve-eqs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
inline tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p = params_ref()) {
|
||||||
|
return mk_solve_eqs2_tactic(m, p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ADD_TACTIC("solve-eqs2", "solve for variables.", "mk_solve_eqs2_tactic(m, p)")
|
ADD_TACTIC("solve-eqs", "solve for variables.", "mk_solve_eqs2_tactic(m, p)")
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -997,6 +997,8 @@ class solve_eqs_tactic : public tactic {
|
||||||
//
|
//
|
||||||
void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
void operator()(goal_ref const & g, goal_ref_buffer & result) {
|
||||||
model_converter_ref mc;
|
model_converter_ref mc;
|
||||||
|
std::function<void(statistics&)> coll = [&](statistics& st) { collect_statistics(st); };
|
||||||
|
statistics_report sreport(coll);
|
||||||
tactic_report report("solve_eqs", *g);
|
tactic_report report("solve_eqs", *g);
|
||||||
TRACE("goal", g->display(tout););
|
TRACE("goal", g->display(tout););
|
||||||
m_produce_models = g->models_enabled();
|
m_produce_models = g->models_enabled();
|
||||||
|
@ -1042,7 +1044,6 @@ class solve_eqs_tactic : public tactic {
|
||||||
result.push_back(g.get());
|
result.push_back(g.get());
|
||||||
|
|
||||||
|
|
||||||
IF_VERBOSE(10, statistics st; collect_statistics(st); st.display_smt2(verbose_stream()));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1103,6 +1104,6 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p) {
|
tactic * mk_solve_eqs1_tactic(ast_manager & m, params_ref const & p) {
|
||||||
return clean(alloc(solve_eqs_tactic, m, p, mk_expr_simp_replacer(m, p), true));
|
return clean(alloc(solve_eqs_tactic, m, p, mk_expr_simp_replacer(m, p), true));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,16 @@ Revision History:
|
||||||
class ast_manager;
|
class ast_manager;
|
||||||
class tactic;
|
class tactic;
|
||||||
|
|
||||||
tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p = params_ref());
|
tactic * mk_solve_eqs1_tactic(ast_manager & m, params_ref const & p = params_ref());
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
inline tactic * mk_solve_eqs_tactic(ast_manager & m, params_ref const & p = params_ref()) {
|
||||||
|
return mk_solve_eqs1_tactic(m, p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ADD_TACTIC("solve-eqs", "eliminate variables by solving equations.", "mk_solve_eqs_tactic(m, p)")
|
ADD_TACTIC("solve-eqs1", "eliminate variables by solving equations.", "mk_solve_eqs1_tactic(m, p)")
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,19 @@ class dependent_expr_state_tactic : public tactic, public dependent_expr_state {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
ref<dependent_expr_simplifier_factory> m_factory;
|
trail_stack m_trail;
|
||||||
scoped_ptr<dependent_expr_simplifier> m_simp;
|
|
||||||
trail_stack m_trail;
|
|
||||||
scoped_ptr<model_reconstruction_trail> m_model_trail;
|
|
||||||
goal_ref m_goal;
|
goal_ref m_goal;
|
||||||
dependent_expr m_dep;
|
dependent_expr m_dep;
|
||||||
|
statistics m_st;
|
||||||
|
ref<dependent_expr_simplifier_factory> m_factory;
|
||||||
|
scoped_ptr<dependent_expr_simplifier> m_simp;
|
||||||
|
scoped_ptr<model_reconstruction_trail> m_model_trail;
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
if (!m_simp)
|
if (!m_simp) {
|
||||||
m_simp = m_factory->mk(m, m_params, *this);
|
m_simp = m_factory->mk(m, m_params, *this);
|
||||||
|
m_st.reset();
|
||||||
|
}
|
||||||
if (!m_model_trail)
|
if (!m_model_trail)
|
||||||
m_model_trail = alloc(model_reconstruction_trail, m, m_trail);
|
m_model_trail = alloc(model_reconstruction_trail, m, m_trail);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +46,7 @@ public:
|
||||||
m_params(p),
|
m_params(p),
|
||||||
m_name(name),
|
m_name(name),
|
||||||
m_factory(f),
|
m_factory(f),
|
||||||
m_simp(f->mk(m, p, *this)),
|
m_simp(nullptr),
|
||||||
m_dep(m, m.mk_true(), nullptr)
|
m_dep(m, m.mk_true(), nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -86,30 +89,34 @@ public:
|
||||||
if (in->proofs_enabled())
|
if (in->proofs_enabled())
|
||||||
throw tactic_exception("tactic does not support low level proofs");
|
throw tactic_exception("tactic does not support low level proofs");
|
||||||
init();
|
init();
|
||||||
|
statistics_report sreport(*this);
|
||||||
tactic_report report(name(), *in);
|
tactic_report report(name(), *in);
|
||||||
m_goal = in.get();
|
m_goal = in.get();
|
||||||
m_simp->reduce();
|
m_simp->reduce();
|
||||||
m_goal->inc_depth();
|
m_goal->inc_depth();
|
||||||
if (in->models_enabled())
|
if (in->models_enabled())
|
||||||
in->set(m_model_trail->get_model_converter().get());
|
in->add(m_model_trail->get_model_converter().get());
|
||||||
result.push_back(in.get());
|
result.push_back(in.get());
|
||||||
|
|
||||||
statistics st;
|
|
||||||
collect_statistics(st);
|
|
||||||
IF_VERBOSE(10, st.display_smt2(verbose_stream()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup() override {
|
void cleanup() override {
|
||||||
|
if (m_simp)
|
||||||
|
m_simp->collect_statistics(m_st);
|
||||||
|
m_simp = nullptr;
|
||||||
|
m_model_trail = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_statistics(statistics & st) const override {
|
void collect_statistics(statistics & st) const override {
|
||||||
if (m_simp)
|
if (m_simp)
|
||||||
m_simp->collect_statistics(st);
|
m_simp->collect_statistics(st);
|
||||||
|
else
|
||||||
|
st.copy(m_st);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_statistics() override {
|
void reset_statistics() override {
|
||||||
if (m_simp)
|
if (m_simp)
|
||||||
m_simp->reset_statistics();
|
m_simp->reset_statistics();
|
||||||
|
m_st.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ Notes:
|
||||||
--*/
|
--*/
|
||||||
#include "ast/normal_forms/nnf.h"
|
#include "ast/normal_forms/nnf.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/bv/bv_size_reduction_tactic.h"
|
#include "tactic/bv/bv_size_reduction_tactic.h"
|
||||||
#include "tactic/bv/max_bv_sharing_tactic.h"
|
#include "tactic/bv/max_bv_sharing_tactic.h"
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
|
|
|
@ -17,6 +17,7 @@ Notes:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/bv/bit_blaster_tactic.h"
|
#include "tactic/bv/bit_blaster_tactic.h"
|
||||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/arith/propagate_ineqs_tactic.h"
|
#include "tactic/arith/propagate_ineqs_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/elim_uncnstr_tactic.h"
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
||||||
#include "tactic/smtlogics/smt_tactic.h"
|
#include "tactic/smtlogics/smt_tactic.h"
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ Notes:
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/elim_uncnstr_tactic.h"
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
||||||
#include "tactic/bv/bit_blaster_tactic.h"
|
#include "tactic/bv/bit_blaster_tactic.h"
|
||||||
#include "tactic/bv/bv1_blaster_tactic.h"
|
#include "tactic/bv/bv1_blaster_tactic.h"
|
||||||
|
@ -39,6 +40,9 @@ static tactic * mk_qfbv_preamble(ast_manager& m, params_ref const& p) {
|
||||||
// conservative gaussian elimination.
|
// conservative gaussian elimination.
|
||||||
solve_eq_p.set_uint("solve_eqs_max_occs", 2);
|
solve_eq_p.set_uint("solve_eqs_max_occs", 2);
|
||||||
|
|
||||||
|
params_ref flat_and_or_p = p;
|
||||||
|
flat_and_or_p.set_bool("flat_and_or", false);
|
||||||
|
|
||||||
params_ref simp2_p = p;
|
params_ref simp2_p = p;
|
||||||
simp2_p.set_bool("som", true);
|
simp2_p.set_bool("som", true);
|
||||||
simp2_p.set_bool("pull_cheap_ite", true);
|
simp2_p.set_bool("pull_cheap_ite", true);
|
||||||
|
@ -47,15 +51,17 @@ static tactic * mk_qfbv_preamble(ast_manager& m, params_ref const& p) {
|
||||||
simp2_p.set_uint("local_ctx_limit", 10000000);
|
simp2_p.set_uint("local_ctx_limit", 10000000);
|
||||||
simp2_p.set_bool("flat", true); // required by som
|
simp2_p.set_bool("flat", true); // required by som
|
||||||
simp2_p.set_bool("hoist_mul", false); // required by som
|
simp2_p.set_bool("hoist_mul", false); // required by som
|
||||||
|
simp2_p.set_bool("flat_and_or", false);
|
||||||
|
|
||||||
params_ref hoist_p;
|
params_ref hoist_p;
|
||||||
hoist_p.set_bool("hoist_mul", true);
|
hoist_p.set_bool("hoist_mul", true);
|
||||||
hoist_p.set_bool("som", false);
|
hoist_p.set_bool("som", false);
|
||||||
|
hoist_p.set_bool("flat_and_or", false);
|
||||||
|
|
||||||
return
|
return
|
||||||
and_then(
|
and_then(
|
||||||
mk_simplify_tactic(m),
|
using_params(mk_simplify_tactic(m), flat_and_or_p),
|
||||||
mk_propagate_values_tactic(m),
|
using_params(mk_propagate_values_tactic(m), flat_and_or_p),
|
||||||
using_params(mk_solve_eqs_tactic(m), solve_eq_p),
|
using_params(mk_solve_eqs_tactic(m), solve_eq_p),
|
||||||
mk_elim_uncnstr_tactic(m),
|
mk_elim_uncnstr_tactic(m),
|
||||||
if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))),
|
if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))),
|
||||||
|
@ -87,6 +93,7 @@ static tactic * mk_qfbv_tactic(ast_manager& m, params_ref const & p, tactic* sat
|
||||||
params_ref local_ctx_p = p;
|
params_ref local_ctx_p = p;
|
||||||
local_ctx_p.set_bool("local_ctx", true);
|
local_ctx_p.set_bool("local_ctx", true);
|
||||||
local_ctx_p.set_bool("flat", false);
|
local_ctx_p.set_bool("flat", false);
|
||||||
|
local_ctx_p.set_bool("flat_and_or", false);
|
||||||
|
|
||||||
params_ref solver_p;
|
params_ref solver_p;
|
||||||
solver_p.set_bool("preprocess", false); // preprocessor of smt::context is not needed.
|
solver_p.set_bool("preprocess", false); // preprocessor of smt::context is not needed.
|
||||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/arith/propagate_ineqs_tactic.h"
|
#include "tactic/arith/propagate_ineqs_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/elim_uncnstr_tactic.h"
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
||||||
#include "tactic/arith/normalize_bounds_tactic.h"
|
#include "tactic/arith/normalize_bounds_tactic.h"
|
||||||
#include "tactic/arith/fix_dl_var_tactic.h"
|
#include "tactic/arith/fix_dl_var_tactic.h"
|
||||||
|
|
|
@ -22,6 +22,7 @@ Notes:
|
||||||
#include "tactic/arith/propagate_ineqs_tactic.h"
|
#include "tactic/arith/propagate_ineqs_tactic.h"
|
||||||
#include "tactic/arith/normalize_bounds_tactic.h"
|
#include "tactic/arith/normalize_bounds_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/elim_uncnstr_tactic.h"
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
||||||
#include "tactic/arith/add_bounds_tactic.h"
|
#include "tactic/arith/add_bounds_tactic.h"
|
||||||
#include "tactic/arith/pb2bv_tactic.h"
|
#include "tactic/arith/pb2bv_tactic.h"
|
||||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
#include "tactic/core/symmetry_reduce_tactic.h"
|
#include "tactic/core/symmetry_reduce_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/smtlogics/smt_tactic.h"
|
#include "tactic/smtlogics/smt_tactic.h"
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/elim_uncnstr_tactic.h"
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
||||||
#include "tactic/bv/max_bv_sharing_tactic.h"
|
#include "tactic/bv/max_bv_sharing_tactic.h"
|
||||||
#include "tactic/bv/bv_size_reduction_tactic.h"
|
#include "tactic/bv/bv_size_reduction_tactic.h"
|
||||||
|
@ -136,22 +137,23 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
static tactic * mk_qfufbv_preamble1(ast_manager & m, params_ref const & p) {
|
static tactic * mk_qfufbv_preamble1(ast_manager & m, params_ref const & p) {
|
||||||
params_ref simp2_p = p;
|
params_ref simp2_p = p, flat_and_or_p = p;
|
||||||
|
flat_and_or_p.set_bool("flat_and_or", false);
|
||||||
simp2_p.set_bool("pull_cheap_ite", true);
|
simp2_p.set_bool("pull_cheap_ite", true);
|
||||||
simp2_p.set_bool("push_ite_bv", false);
|
simp2_p.set_bool("push_ite_bv", false);
|
||||||
simp2_p.set_bool("local_ctx", true);
|
simp2_p.set_bool("local_ctx", true);
|
||||||
simp2_p.set_uint("local_ctx_limit", 10000000);
|
simp2_p.set_uint("local_ctx_limit", 10000000);
|
||||||
|
|
||||||
simp2_p.set_bool("ite_extra_rules", true);
|
simp2_p.set_bool("ite_extra_rules", true);
|
||||||
simp2_p.set_bool("mul2concat", true);
|
simp2_p.set_bool("mul2concat", true);
|
||||||
|
simp2_p.set_bool("flat_and_or", false);
|
||||||
|
|
||||||
params_ref ctx_simp_p;
|
params_ref ctx_simp_p;
|
||||||
ctx_simp_p.set_uint("max_depth", 32);
|
ctx_simp_p.set_uint("max_depth", 32);
|
||||||
ctx_simp_p.set_uint("max_steps", 5000000);
|
ctx_simp_p.set_uint("max_steps", 5000000);
|
||||||
|
|
||||||
return and_then(
|
return and_then(
|
||||||
mk_simplify_tactic(m),
|
using_params(mk_simplify_tactic(m), flat_and_or_p),
|
||||||
mk_propagate_values_tactic(m),
|
using_params(mk_propagate_values_tactic(m), flat_and_or_p),
|
||||||
if_no_proofs(if_no_unsat_cores(mk_bv_bound_chk_tactic(m))),
|
if_no_proofs(if_no_unsat_cores(mk_bv_bound_chk_tactic(m))),
|
||||||
//using_params(mk_ctx_simplify_tactic(m_m), ctx_simp_p),
|
//using_params(mk_ctx_simplify_tactic(m_m), ctx_simp_p),
|
||||||
mk_solve_eqs_tactic(m),
|
mk_solve_eqs_tactic(m),
|
||||||
|
@ -163,8 +165,10 @@ static tactic * mk_qfufbv_preamble1(ast_manager & m, params_ref const & p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static tactic * mk_qfufbv_preamble(ast_manager & m, params_ref const & p) {
|
static tactic * mk_qfufbv_preamble(ast_manager & m, params_ref const & p) {
|
||||||
return and_then(mk_simplify_tactic(m),
|
params_ref simp2_p = p, flat_and_or_p = p;
|
||||||
mk_propagate_values_tactic(m),
|
flat_and_or_p.set_bool("flat_and_or", false);
|
||||||
|
return and_then(using_params(mk_simplify_tactic(m), flat_and_or_p),
|
||||||
|
using_params(mk_propagate_values_tactic(m), flat_and_or_p),
|
||||||
mk_solve_eqs_tactic(m),
|
mk_solve_eqs_tactic(m),
|
||||||
mk_elim_uncnstr_tactic(m),
|
mk_elim_uncnstr_tactic(m),
|
||||||
if_no_proofs(if_no_unsat_cores(mk_reduce_args_tactic(m))),
|
if_no_proofs(if_no_unsat_cores(mk_reduce_args_tactic(m))),
|
||||||
|
|
|
@ -20,6 +20,7 @@ Revision History:
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/elim_uncnstr_tactic.h"
|
#include "tactic/core/elim_uncnstr_tactic.h"
|
||||||
#include "qe/lite/qe_lite.h"
|
#include "qe/lite/qe_lite.h"
|
||||||
#include "qe/qsat.h"
|
#include "qe/qsat.h"
|
||||||
|
|
|
@ -20,6 +20,7 @@ Notes:
|
||||||
#include "tactic/core/simplify_tactic.h"
|
#include "tactic/core/simplify_tactic.h"
|
||||||
#include "tactic/core/propagate_values_tactic.h"
|
#include "tactic/core/propagate_values_tactic.h"
|
||||||
#include "tactic/core/solve_eqs_tactic.h"
|
#include "tactic/core/solve_eqs_tactic.h"
|
||||||
|
#include "tactic/core/solve_eqs2_tactic.h"
|
||||||
#include "tactic/core/distribute_forall_tactic.h"
|
#include "tactic/core/distribute_forall_tactic.h"
|
||||||
#include "tactic/core/der_tactic.h"
|
#include "tactic/core/der_tactic.h"
|
||||||
#include "tactic/core/reduce_args_tactic.h"
|
#include "tactic/core/reduce_args_tactic.h"
|
||||||
|
|
Loading…
Reference in a new issue