3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-07 06:33:23 +00:00

save state of arith

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2023-06-03 11:52:15 -07:00
parent ffd4323573
commit a7b3dae262
16 changed files with 267 additions and 37 deletions

View file

@ -25,6 +25,7 @@ z3_add_component(ast
expr_abstract.cpp expr_abstract.cpp
expr_functors.cpp expr_functors.cpp
expr_map.cpp expr_map.cpp
expr_polarities.cpp
expr_stat.cpp expr_stat.cpp
expr_substitution.cpp expr_substitution.cpp
for_each_ast.cpp for_each_ast.cpp

View file

@ -0,0 +1,86 @@
/*++
Copyright (c) 2023 Microsoft Corporation
Module Name:
expr_polarities.cpp
Abstract:
Extract polarities of expressions.
Author:
Nikolaj Bjorner (nbjorner) 2023-06-01
--*/
#pragma once
#include "ast/expr_polarities.h"
void expr_polarities::push() {
m_fresh_lim.push_back(m_fresh.size());
m_trail_lim.push_back(m_trail.size());
}
void expr_polarities::pop(unsigned n) {
unsigned sz = m_fresh_lim[m_fresh_lim.size() - n];
for (unsigned i = m_fresh_lim.size(); --i > sz; ) {
auto const & [e, p] = m_fresh[i];
if (p)
m_pos.mark(e, false);
else
m_neg.mark(e, false);
}
m_fresh.shrink(sz);
m_fresh_lim.shrink(m_fresh_lim.size() - n);
sz = m_trail_lim[m_trail_lim.size() - n];
m_trail.shrink(sz);
m_trail_lim.shrink(m_trail_lim.size() - n);
}
void expr_polarities::add(expr* e) {
if (m_pos.is_marked(e))
return;
m_trail.push_back(e);
buffer<std::pair<bool, expr*>> frames;
frames.push_back({true, e});
while (!frames.empty()) {
auto [p, e] = frames.back();
frames.pop_back();
if (p) {
if (m_pos.is_marked(e))
continue;
m_pos.mark(e, true);
}
else {
if (m_neg.is_marked(e))
continue;
m_neg.mark(e, true);
}
m_fresh.push_back({e, p});
if (m.is_and(e) || m.is_or(e)) {
for (expr* arg : *to_app(e))
frames.push_back({p, arg});
}
else if (m.is_not(e, e)) {
frames.push_back({!p, e});
}
else if (m.is_implies(e)) {
frames.push_back({!p, to_app(e)->get_arg(0)});
frames.push_back({p, to_app(e)->get_arg(1)});
}
else if (is_app(e)) {
for (expr* arg : *to_app(e)) {
frames.push_back({true, arg});
frames.push_back({false, arg});
}
}
else if (is_quantifier(e))
frames.push_back({p, to_quantifier(e)->get_expr()});
}
}

52
src/ast/expr_polarities.h Normal file
View file

@ -0,0 +1,52 @@
/*++
Copyright (c) 2023 Microsoft Corporation
Module Name:
expr_polarities.h
Abstract:
Extract polarities of expressions.
Author:
Nikolaj Bjorner (nbjorner) 2023-06-01
--*/
#pragma once
#include "ast/ast.h"
class expr_polarities {
ast_manager & m;
expr_ref_vector m_trail;
expr_mark m_pos, m_neg;
vector<std::pair<expr*, bool>> m_fresh;
unsigned_vector m_fresh_lim, m_trail_lim;
public:
expr_polarities(ast_manager & m) : m(m), m_trail(m) {}
void push();
void pop(unsigned n);
// add expressions to annotate with polarities
void add(expr* e);
void add(expr_ref_vector const& es) {
for (expr* e : es)
add(e);
}
bool has_negative(expr* e) const {
return m_neg.is_marked(e);
}
bool has_positive(expr* e) const {
return m_pos.is_marked(e);
}
};

View file

@ -51,7 +51,7 @@ class int_solver {
public: public:
patcher(int_solver& lia); patcher(int_solver& lia);
bool should_apply() const { return true; } bool should_apply() const { return true; }
lia_move operator()() { return patch_basic_columns(); } lia_move operator()() { return patch_nbasic_columns(); }
void patch_nbasic_column(unsigned j); void patch_nbasic_column(unsigned j);
bool patch_basic_column(unsigned v, row_cell<mpq> const& c); bool patch_basic_column(unsigned v, row_cell<mpq> const& c);
void patch_basic_column(unsigned j); void patch_basic_column(unsigned j);

View file

@ -46,9 +46,17 @@ namespace arith {
del_bounds(0); del_bounds(0);
} }
void solver::asserted(literal l) { void solver::asserted(literal lit) {
force_push(); force_push();
m_asserted.push_back(l); expr* e = ctx.bool_var2expr(lit.var());
if (lit.sign() && !ctx.is_neg(e)) {
//verbose_stream() << "not negative " << mk_pp(e, m) << "\n";
}
else if (!lit.sign() && !ctx.is_pos(e)) {
//verbose_stream() << "not positive " << mk_pp(e, m) << "\n";
}
else
m_asserted.push_back(lit);
} }
euf::th_solver* solver::clone(euf::solver& dst_ctx) { euf::th_solver* solver::clone(euf::solver& dst_ctx) {

View file

@ -34,6 +34,10 @@ Notes:
namespace euf { namespace euf {
void solver::add_polarities(expr* f) {
m_polarities.add(f);
}
void solver::internalize(expr* e) { void solver::internalize(expr* e) {
if (get_enode(e)) if (get_enode(e))
return; return;

View file

@ -48,6 +48,7 @@ namespace euf {
m_unhandled_functions(m), m_unhandled_functions(m),
m_to_m(&m), m_to_m(&m),
m_to_si(&si), m_to_si(&si),
m_polarities(m),
m_clause_visitor(m), m_clause_visitor(m),
m_smt_proof_checker(m, p), m_smt_proof_checker(m, p),
m_clause(m), m_clause(m),
@ -642,10 +643,13 @@ namespace euf {
e->push(); e->push();
m_egraph.push(); m_egraph.push();
m_relevancy.push(); m_relevancy.push();
m_polarities.push();
} }
void solver::pop(unsigned n) { void solver::pop(unsigned n) {
start_reinit(n); start_reinit(n);
m_polarities.pop(n);
m_trail.pop_scope(n); m_trail.pop_scope(n);
for (auto* e : m_solvers) for (auto* e : m_solvers)
e->pop(n); e->pop(n);

View file

@ -20,6 +20,7 @@ Author:
#include "util/trail.h" #include "util/trail.h"
#include "ast/ast_translation.h" #include "ast/ast_translation.h"
#include "ast/ast_util.h" #include "ast/ast_util.h"
#include "ast/expr_polarities.h"
#include "ast/euf/euf_egraph.h" #include "ast/euf/euf_egraph.h"
#include "ast/rewriter/th_rewriter.h" #include "ast/rewriter/th_rewriter.h"
#include "ast/converters/model_converter.h" #include "ast/converters/model_converter.h"
@ -152,6 +153,7 @@ namespace euf {
svector<scope> m_scopes; svector<scope> m_scopes;
scoped_ptr_vector<th_solver> m_solvers; scoped_ptr_vector<th_solver> m_solvers;
ptr_vector<th_solver> m_id2solver; ptr_vector<th_solver> m_id2solver;
expr_polarities m_polarities;
constraint* m_conflict = nullptr; constraint* m_conflict = nullptr;
constraint* m_eq = nullptr; constraint* m_eq = nullptr;
@ -451,6 +453,9 @@ namespace euf {
bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override; bool to_formulas(std::function<expr_ref(sat::literal)>& l2e, expr_ref_vector& fmls) override;
// internalize // internalize
void add_polarities(expr* f);
bool is_neg(expr* e) const { return m_polarities.has_negative(e); }
bool is_pos(expr* e) const { return m_polarities.has_positive(e); }
sat::literal internalize(expr* e, bool sign, bool root) override; sat::literal internalize(expr* e, bool sign, bool root) override;
void internalize(expr* e) override; void internalize(expr* e) override;
sat::literal mk_literal(expr* e); sat::literal mk_literal(expr* e);

View file

@ -47,6 +47,10 @@ namespace q {
if (l.sign() == is_forall(e)) { if (l.sign() == is_forall(e)) {
if (m_quantifiers_are_positive && is_forall(e)) if (m_quantifiers_are_positive && is_forall(e))
return; return;
if (is_forall(e) && ctx.is_pos(e)) {
verbose_stream() << "is positive\n";
return;
}
sat::literal lit = skolemize(q); sat::literal lit = skolemize(q);
add_clause(~l, lit); add_clause(~l, lit);
return; return;

View file

@ -224,7 +224,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
return v; return v;
} }
unsigned m_num_scopes{ 0 }; unsigned m_num_scopes = 0;
void force_push() { void force_push() {
for (; m_num_scopes > 0; --m_num_scopes) { for (; m_num_scopes > 0; --m_num_scopes) {
@ -785,6 +785,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
}; };
void process(expr* n, bool is_root) { void process(expr* n, bool is_root) {
TRACE("goal2sat", tout << "process-begin " << mk_bounded_pp(n, m, 2) TRACE("goal2sat", tout << "process-begin " << mk_bounded_pp(n, m, 2)
<< " root: " << is_root << " root: " << is_root
<< " result-stack: " << m_result_stack.size() << " result-stack: " << m_result_stack.size()
@ -840,6 +841,9 @@ struct goal2sat::imp : public sat::sat_internalizer {
} }
sat::literal internalize(expr* n) override { sat::literal internalize(expr* n) override {
auto* ext = dynamic_cast<euf::solver*>(m_solver.get_extension());
if (ext)
ext->add_polarities(n);
bool is_not = m.is_not(n, n); bool is_not = m.is_not(n, n);
flet<bool> _top(m_top_level, false); flet<bool> _top(m_top_level, false);
unsigned sz = m_result_stack.size(); unsigned sz = m_result_stack.size();
@ -889,6 +893,10 @@ struct goal2sat::imp : public sat::sat_internalizer {
} }
void process(expr * n) { void process(expr * n) {
auto* ext = dynamic_cast<euf::solver*>(m_solver.get_extension());
if (ext)
ext->add_polarities(n);
flet<bool> _top(m_top_level, true); flet<bool> _top(m_top_level, true);
VERIFY(m_result_stack.empty()); VERIFY(m_result_stack.empty());
TRACE("goal2sat", tout << "assert: " << mk_bounded_pp(n, m, 3) << "\n";); TRACE("goal2sat", tout << "assert: " << mk_bounded_pp(n, m, 3) << "\n";);

View file

@ -258,12 +258,11 @@ namespace smt {
TRACE("arith_eq_adapter", tout << "restart\n";); TRACE("arith_eq_adapter", tout << "restart\n";);
enode_pair_vector tmp(m_restart_pairs); enode_pair_vector tmp(m_restart_pairs);
m_restart_pairs.reset(); m_restart_pairs.reset();
for (auto const& p : tmp) { for (auto const& [a, b] : tmp) {
if (ctx.inconsistent()) if (ctx.inconsistent())
break; break;
TRACE("arith_eq_adapter", tout << "creating arith_eq_adapter axioms at the base level #" << p.first->get_owner_id() << " #" << TRACE("arith_eq_adapter", tout << "creating arith_eq_adapter axioms at the base level #" << a->get_owner_id() << " #" << b->get_owner_id() << "\n";);
p.second->get_owner_id() << "\n";); mk_axioms(a, b);
mk_axioms(p.first, p.second);
} }
} }

View file

@ -59,12 +59,9 @@ namespace smt {
m_relevancy_propagator(mk_relevancy_propagator(*this)), m_relevancy_propagator(mk_relevancy_propagator(*this)),
m_user_propagator(nullptr), m_user_propagator(nullptr),
m_random(p.m_random_seed), m_random(p.m_random_seed),
m_flushing(false),
m_lemma_id(0),
m_progress_callback(nullptr),
m_next_progress_sample(0),
m_clause_proof(*this), m_clause_proof(*this),
m_fingerprints(m, m_region), m_fingerprints(m, m_region),
m_polarities(m),
m_b_internalized_stack(m), m_b_internalized_stack(m),
m_e_internalized_stack(m), m_e_internalized_stack(m),
m_l_internalized_stack(m), m_l_internalized_stack(m),
@ -2975,6 +2972,7 @@ namespace smt {
// logical context became inconsistent during user PUSH // logical context became inconsistent during user PUSH
VERIFY(!resolve_conflict()); // build the proof VERIFY(!resolve_conflict()); // build the proof
} }
m_polarities.push();
push_scope(); push_scope();
m_base_scopes.push_back(base_scope()); m_base_scopes.push_back(base_scope());
base_scope & bs = m_base_scopes.back(); base_scope & bs = m_base_scopes.back();
@ -2988,9 +2986,11 @@ namespace smt {
void context::pop(unsigned num_scopes) { void context::pop(unsigned num_scopes) {
SASSERT (num_scopes > 0); SASSERT (num_scopes > 0);
if (num_scopes > m_scope_lvl) return; if (num_scopes > m_scope_lvl)
return;
pop_to_base_lvl(); pop_to_base_lvl();
pop_scope(num_scopes); pop_scope(num_scopes);
m_polarities.pop(num_scopes);
} }
/** /**

View file

@ -19,6 +19,7 @@ Revision History:
#pragma once #pragma once
#include "ast/quantifier_stat.h" #include "ast/quantifier_stat.h"
#include "ast/expr_polarities.h"
#include "smt/smt_clause.h" #include "smt/smt_clause.h"
#include "smt/smt_setup.h" #include "smt/smt_setup.h"
#include "smt/smt_enode.h" #include "smt/smt_enode.h"
@ -92,13 +93,14 @@ namespace smt {
scoped_ptr<relevancy_propagator> m_relevancy_propagator; scoped_ptr<relevancy_propagator> m_relevancy_propagator;
theory_user_propagator* m_user_propagator; theory_user_propagator* m_user_propagator;
random_gen m_random; random_gen m_random;
bool m_flushing; // (debug support) true when flushing bool m_flushing = false; // (debug support) true when flushing
mutable unsigned m_lemma_id; mutable unsigned m_lemma_id = 0;
progress_callback * m_progress_callback; progress_callback * m_progress_callback = nullptr;
unsigned m_next_progress_sample; unsigned m_next_progress_sample = 0;
clause_proof m_clause_proof; clause_proof m_clause_proof;
region m_region; region m_region;
fingerprint_set m_fingerprints; fingerprint_set m_fingerprints;
expr_polarities m_polarities;
expr_ref_vector m_b_internalized_stack; // stack of the boolean expressions already internalized. expr_ref_vector m_b_internalized_stack; // stack of the boolean expressions already internalized.
// Remark: boolean expressions can also be internalized as // Remark: boolean expressions can also be internalized as
@ -1550,6 +1552,7 @@ namespace smt {
// ----------------------------------- // -----------------------------------
void assert_expr_core(expr * e, proof * pr); void assert_expr_core(expr * e, proof * pr);
// copy plugins into a fresh context. // copy plugins into a fresh context.
void copy_plugins(context& src, context& dst); void copy_plugins(context& src, context& dst);
@ -1626,6 +1629,9 @@ namespace smt {
void assert_expr(expr * e, proof * pr); void assert_expr(expr * e, proof * pr);
bool is_positive(expr* e) const { return m_polarities.has_positive(e); }
bool is_negative(expr* e) const { return m_polarities.has_negative(e); }
void internalize_assertions(); void internalize_assertions();
void push(); void push();

View file

@ -392,6 +392,8 @@ namespace smt {
if (m.is_true(n) || m.is_false(n)) if (m.is_true(n) || m.is_false(n))
return; return;
m_polarities.add(n);
if (m.is_not(n) && gate_ctx) { if (m.is_not(n) && gate_ctx) {
// a boolean variable does not need to be created if n a NOT gate is in // a boolean variable does not need to be created if n a NOT gate is in
// the context of a gate. // the context of a gate.

View file

@ -1379,6 +1379,18 @@ namespace smt {
TRACE("arith_verbose", tout << "p" << v << " := " << (is_true?"true":"false") << "\n";); TRACE("arith_verbose", tout << "p" << v << " := " << (is_true?"true":"false") << "\n";);
atom * a = get_bv2a(v); atom * a = get_bv2a(v);
if (!a) return; if (!a) return;
#if 0
expr* f = ctx.bool_var2expr(v);
if (ctx.is_positive(f) || ctx.is_negative(f)) {
if (is_true && !ctx.is_positive(f)) {
return;
}
if (!is_true && !ctx.is_negative(f)) {
return;
}
}
#endif
SASSERT(ctx.get_assignment(a->get_bool_var()) != l_undef); SASSERT(ctx.get_assignment(a->get_bool_var()) != l_undef);
SASSERT((ctx.get_assignment(a->get_bool_var()) == l_true) == is_true); SASSERT((ctx.get_assignment(a->get_bool_var()) == l_true) == is_true);
a->assign_eh(is_true, get_epsilon(a->get_var())); a->assign_eh(is_true, get_epsilon(a->get_var()));
@ -1491,10 +1503,6 @@ namespace smt {
final_check_status result = FC_DONE; final_check_status result = FC_DONE;
final_check_status ok; final_check_status ok;
//display(verbose_stream());
//exit(0);
if (false) if (false)
{ {
verbose_stream() << "final\n"; verbose_stream() << "final\n";
@ -1514,6 +1522,7 @@ namespace smt {
switch (m_final_check_idx) { switch (m_final_check_idx) {
case 0: case 0:
ok = check_int_feasibility(); ok = check_int_feasibility();
if (ok != FC_DONE) verbose_stream() << "int-feas\n";
TRACE("arith", tout << "check_int_feasibility(), ok: " << ok << "\n";); TRACE("arith", tout << "check_int_feasibility(), ok: " << ok << "\n";);
break; break;
case 1: case 1:
@ -1521,6 +1530,7 @@ namespace smt {
ok = FC_CONTINUE; ok = FC_CONTINUE;
else else
ok = FC_DONE; ok = FC_DONE;
if (ok != FC_DONE) verbose_stream() << "assume-eqs\n";
TRACE("arith", tout << "assume_eqs(), ok: " << ok << "\n";); TRACE("arith", tout << "assume_eqs(), ok: " << ok << "\n";);
break; break;
default: default:
@ -1557,7 +1567,7 @@ namespace smt {
template<typename Ext> template<typename Ext>
final_check_status theory_arith<Ext>::final_check_eh() { final_check_status theory_arith<Ext>::final_check_eh() {
// verbose_stream() << "final " << ctx.get_scope_level() << " " << ctx.assigned_literals().size() << "\n"; verbose_stream() << "final " << ctx.get_scope_level() << " " << ctx.assigned_literals().size() << "\n";
// ctx.display(verbose_stream()); // ctx.display(verbose_stream());
// exit(0); // exit(0);
@ -1566,14 +1576,14 @@ namespace smt {
if (!propagate_core()) if (!propagate_core())
return FC_CONTINUE; return FC_CONTINUE;
if (delayed_assume_eqs()) if (delayed_assume_eqs()) {
verbose_stream() << "delayed-eqs\n";
return FC_CONTINUE; return FC_CONTINUE;
}
ctx.push_trail(value_trail<unsigned>(m_final_check_idx)); ctx.push_trail(value_trail<unsigned>(m_final_check_idx));
m_liberal_final_check = true; m_liberal_final_check = true;
m_changed_assignment = false; m_changed_assignment = false;
final_check_status result = final_check_core(); final_check_status result = final_check_core();
//display(verbose_stream());
//exit(0);
if (result != FC_DONE) if (result != FC_DONE)
return result; return result;
if (!m_changed_assignment) if (!m_changed_assignment)

View file

@ -1255,7 +1255,6 @@ public:
} }
void internalize_eq_eh(app * atom, bool_var) { void internalize_eq_eh(app * atom, bool_var) {
return;
if (!ctx().get_fparams().m_arith_eager_eq_axioms) if (!ctx().get_fparams().m_arith_eager_eq_axioms)
return; return;
expr* lhs = nullptr, *rhs = nullptr; expr* lhs = nullptr, *rhs = nullptr;
@ -1265,15 +1264,26 @@ public:
if (is_arith(n1) && is_arith(n2) && if (is_arith(n1) && is_arith(n2) &&
n1->get_th_var(get_id()) != null_theory_var && n1->get_th_var(get_id()) != null_theory_var &&
n2->get_th_var(get_id()) != null_theory_var && n1 != n2) { n2->get_th_var(get_id()) != null_theory_var && n1 != n2) {
verbose_stream() << "ineq\n"; // verbose_stream() << "ineq\n";
m_arith_eq_adapter.mk_axioms(n1, n2); m_arith_eq_adapter.mk_axioms(n1, n2);
} }
else // else
verbose_stream() << "skip\n"; // verbose_stream() << "skip\n";
} }
void assign_eh(bool_var v, bool is_true) { void assign_eh(bool_var v, bool is_true) {
TRACE("arith", tout << mk_bounded_pp(ctx().bool_var2expr(v), m) << " " << (literal(v, !is_true)) << "\n";); TRACE("arith", tout << mk_bounded_pp(ctx().bool_var2expr(v), m) << " " << (literal(v, !is_true)) << "\n";);
#if 0
expr* f = ctx().bool_var2expr(v);
if (ctx().is_positive(f) || ctx().is_negative(f)) {
if (is_true && !ctx().is_positive(f)) {
return;
}
if (!is_true && !ctx().is_negative(f)) {
return;
}
}
#endif
m_asserted_atoms.push_back(delayed_atom(v, is_true)); m_asserted_atoms.push_back(delayed_atom(v, is_true));
} }
@ -1305,7 +1315,11 @@ public:
if (!is_int(v1) && !is_real(v1)) if (!is_int(v1) && !is_real(v1))
return; return;
if (true) { if (false) {
m_deqs.push_back({v1, v2});
ctx().push_trail(push_back_vector(m_deqs));
}
else if (false) {
enode* n1 = get_enode(v1); enode* n1 = get_enode(v1);
enode* n2 = get_enode(v2); enode* n2 = get_enode(v2);
lpvar w1 = register_theory_var_in_lar_solver(v1); lpvar w1 = register_theory_var_in_lar_solver(v1);
@ -1342,6 +1356,7 @@ public:
m_arith_eq_adapter.new_diseq_eh(v1, v2); m_arith_eq_adapter.new_diseq_eh(v1, v2);
} }
// actually have to go over entire stack to ensure diseqs are respected after mutations
bool delayed_diseqs() { bool delayed_diseqs() {
if (m_diseqs_qhead == m_diseqs.size()) if (m_diseqs_qhead == m_diseqs.size())
return false; return false;
@ -1360,6 +1375,28 @@ public:
return has_eq; return has_eq;
} }
svector<std::pair<theory_var, theory_var>> m_deqs;
unsigned m_eqs_qhead = 0;
// actually have to go over entire stack to ensure eqs are respected after mutations
bool delayed_eqs() {
if (m_eqs_qhead == m_deqs.size())
return false;
ctx().push_trail(value_trail(m_eqs_qhead));
bool has_eq = false;
while (m_eqs_qhead < m_deqs.size()) {
auto [v1,v2] = m_deqs[m_eqs_qhead];
if (!is_eq(v1, v2)) {
//verbose_stream() << "bad diseq " << m_diseqs_qhead << "\n";
m_arith_eq_adapter.new_eq_eh(v1, v2);
has_eq = true;
}
++m_eqs_qhead;
}
return has_eq;
}
void apply_sort_cnstr(enode* n, sort*) { void apply_sort_cnstr(enode* n, sort*) {
TRACE("arith", tout << "sort constraint: " << enode_pp(n, ctx()) << "\n";); TRACE("arith", tout << "sort constraint: " << enode_pp(n, ctx()) << "\n";);
#if 0 #if 0
@ -1846,6 +1883,9 @@ public:
if (delayed_diseqs()) if (delayed_diseqs())
return true; return true;
if (delayed_eqs())
return true;
theory_var sz = static_cast<theory_var>(th.get_num_vars()); theory_var sz = static_cast<theory_var>(th.get_num_vars());
unsigned old_sz = m_assume_eq_candidates.size(); unsigned old_sz = m_assume_eq_candidates.size();
@ -1989,7 +2029,7 @@ public:
final_check_status final_check_eh() { final_check_status final_check_eh() {
// verbose_stream() << "final " << ctx().get_scope_level() << " " << ctx().assigned_literals().size() << "\n"; verbose_stream() << "final " << ctx().get_scope_level() << " " << ctx().assigned_literals().size() << "\n";
//ctx().display(verbose_stream()); //ctx().display(verbose_stream());
//exit(0); //exit(0);
@ -1998,14 +2038,14 @@ public:
if (propagate_core()) if (propagate_core())
return FC_CONTINUE; return FC_CONTINUE;
if (delayed_assume_eqs()) if (delayed_assume_eqs()) {
verbose_stream() << "delayed-eqs\n";
return FC_CONTINUE; return FC_CONTINUE;
}
m_liberal_final_check = true; m_liberal_final_check = true;
m_changed_assignment = false; m_changed_assignment = false;
ctx().push_trail(value_trail<unsigned>(m_final_check_idx)); ctx().push_trail(value_trail<unsigned>(m_final_check_idx));
final_check_status result = final_check_core(); final_check_status result = final_check_core();
//display(verbose_stream());
//exit(0);
if (result != FC_DONE) if (result != FC_DONE)
return result; return result;
if (!m_changed_assignment) if (!m_changed_assignment)
@ -2019,7 +2059,6 @@ public:
final_check_status final_check_core() { final_check_status final_check_core() {
if (false) if (false)
{ {
verbose_stream() << "final\n"; verbose_stream() << "final\n";
@ -2094,10 +2133,12 @@ public:
switch (m_final_check_idx) { switch (m_final_check_idx) {
case 0: case 0:
st = check_lia(); st = check_lia();
if (st != FC_DONE) verbose_stream() << "check-lia\n";
break; break;
case 1: case 1:
if (assume_eqs()) if (assume_eqs())
st = FC_CONTINUE; st = FC_CONTINUE;
if (st != FC_DONE) verbose_stream() << "assume-eqs\n";
break; break;
case 2: case 2:
st = check_nla(); st = check_nla();