3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 09:34:08 +00:00

nra to nla

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2020-05-08 22:32:57 -07:00
parent e32a6714a5
commit 279d55a2c7
4 changed files with 90 additions and 13 deletions

View file

@ -38,7 +38,7 @@ lbool solver::check(vector<lemma>& l, lp::explanation& expl) {
lbool ret = m_core->check(l);
if (ret == l_undef) {
ret = run_nra(expl);
if (ret == l_true) {
if (ret == l_true || expl.size() > 0) {
set_use_nra_model(true);
}
}
@ -67,6 +67,9 @@ solver::~solver() {
std::ostream& solver::display(std::ostream& out) const {
m_core->print_monics(out);
if( use_nra_model()) {
return m_nra.display(out);
}
return out;
}

View file

@ -44,5 +44,10 @@ public:
std::ostream& display(std::ostream& out) const;
bool use_nra_model() const { return m_use_nra_model; }
core& get_core() { return *m_core; }
nlsat::anum_manager& am() { return m_nra.am(); }
nlsat::anum const& am_value(lp::var_index v) const {
SASSERT(use_nra_model());
return m_nra.value(v);
}
};
}

View file

@ -82,10 +82,10 @@ struct solver::imp {
add_constraint(ci);
}
// // add polynomial definitions.
// for (auto const& m : m_monics) {
// add_monic_eq(m);
// }
// add polynomial definitions.
for (auto const& m : m_nla_core.emons()) {
add_monic_eq(m);
}
// TBD: add variable bounds?
lbool r = l_undef;

View file

@ -288,7 +288,12 @@ class theory_lra::imp {
imp & m_th;
var_value_hash(imp & th):m_th(th) {}
unsigned operator()(theory_var v) const {
return (unsigned)std::hash<lp::impq>()(m_th.get_ivalue(v));
if (m_th.m_nla->use_nra_model()) {
return m_th.is_int(v);
}
else {
return (unsigned)std::hash<lp::impq>()(m_th.get_ivalue(v));
}
}
};
int_hashtable<var_value_hash, var_value_eq> m_model_eqs;
@ -1664,7 +1669,12 @@ public:
}
bool is_eq(theory_var v1, theory_var v2) {
return get_ivalue(v1) == get_ivalue(v2);
if (m_nla->use_nra_model()) {
return m_nla->am().eq(nl_value(v1, *m_a1), nl_value(v2, *m_a2));
}
else {
return get_ivalue(v1) == get_ivalue(v2);
}
}
bool has_delayed_constraints() const {
@ -2139,13 +2149,18 @@ public:
lbool check_nla_continue() {
m_a1 = nullptr; m_a2 = nullptr;
auto & lv = m_nla_lemma_vector;
m_explanation.clear();
lbool r = m_nla->check(lv, m_explanation);
if (m_explanation.size()) {
NOT_IMPLEMENTED_YET(); // the nra_solver worked
SASSERT(m_nla->use_nra_model());
SASSERT(r == l_false);
set_conflict();
return l_false;
}
switch (r) {
case l_false: {
SASSERT(m_explanation.size() == 0);
m_stats.m_nla_lemmas += lv.size();
for (const nla::lemma & l : lv) {
false_case_of_check_nla(l);
@ -2153,6 +2168,10 @@ public:
break;
}
case l_true:
if (m_nla->use_nra_model()) {
m_a1 = alloc(scoped_anum, m_nla->am());
m_a2 = alloc(scoped_anum, m_nla->am());
}
if (assume_eqs()) {
return l_false;
}
@ -3324,14 +3343,64 @@ public:
TRACE("arith", display(tout););
}
nlsat::anum const& nl_value(theory_var v, scoped_anum& r) {
SASSERT(m_nla->use_nra_model());
auto t = get_tv(v);
if (t.is_term()) {
m_todo_terms.push_back(std::make_pair(t, rational::one()));
TRACE("arith", tout << "v" << v << " := w" << t.to_string() << "\n";
lp().print_term(lp().get_term(t), tout) << "\n";);
m_nla->am().set(r, 0);
while (!m_todo_terms.empty()) {
rational wcoeff = m_todo_terms.back().second;
t = m_todo_terms.back().first;
m_todo_terms.pop_back();
lp::lar_term const& term = lp().get_term(t);
TRACE("arith", lp().print_term(term, tout) << "\n";);
scoped_anum r1(m_nla->am());
rational c1(0);
m_nla->am().set(r1, c1.to_mpq());
m_nla->am().add(r, r1, r);
for (auto const & arg : term) {
auto wi = lp().column2tv(arg.column());
c1 = arg.coeff() * wcoeff;
if (wi.is_term()) {
m_todo_terms.push_back(std::make_pair(wi, c1));
}
else {
m_nla->am().set(r1, c1.to_mpq());
m_nla->am().mul(m_nla->am_value(wi.id()), r1, r1);
m_nla->am().add(r1, r, r);
}
}
}
return r;
}
else {
return m_nla->am_value(t.id());
}
}
model_value_proc * mk_value(enode * n, model_generator & mg) {
theory_var v = n->get_th_var(get_id());
expr* o = n->get_owner();
rational r = get_value(v);
TRACE("arith", tout << mk_pp(o, m) << " v" << v << " := " << r << "\n";);
SASSERT("integer variables should have integer values: " && (!a.is_int(o) || r.is_int() || m.limit().get_cancel_flag()));
if (a.is_int(o) && !r.is_int()) r = floor(r);
return alloc(expr_wrapper_proc, m_factory->mk_value(r, m.get_sort(o)));
if (m_nla->use_nra_model()) {
anum const& an = nl_value(v, *m_a1);
if (a.is_int(o) && !m_nla->am().is_int(an)) {
return alloc(expr_wrapper_proc, a.mk_numeral(rational::zero(), a.is_int(o)));
}
return alloc(expr_wrapper_proc, a.mk_numeral(nl_value(v, *m_a1), a.is_int(o)));
}
else {
rational r = get_value(v);
TRACE("arith", tout << mk_pp(o, m) << " v" << v << " := " << r << "\n";);
SASSERT("integer variables should have integer values: " && (!a.is_int(o) || r.is_int() || m.limit().get_cancel_flag()));
if (a.is_int(o) && !r.is_int()) r = floor(r);
return alloc(expr_wrapper_proc, m_factory->mk_value(r, m.get_sort(o)));
}
}
bool get_value(enode* n, rational& val) {