3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 20:18:18 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-02-26 09:28:45 -08:00
parent f0689546f3
commit 915ff38f97
2 changed files with 43 additions and 32 deletions

View file

@ -891,6 +891,10 @@ namespace smt {
public: public:
void internalize_rec(expr * n, bool gate_ctx);
void internalize_deep(expr * n);
// helper function for trail // helper function for trail
void undo_th_case_split(literal l); void undo_th_case_split(literal l);

View file

@ -184,19 +184,7 @@ namespace smt {
#define DEEP_EXPR_THRESHOLD 1024 #define DEEP_EXPR_THRESHOLD 1024
void context::internalize_deep(expr* n) {
/**
\brief Internalize an expression asserted into the logical context using the given proof as a justification.
\remark pr is 0 if proofs are disabled.
*/
void context::internalize_assertion(expr * n, proof * pr, unsigned generation) {
TRACE("internalize_assertion", tout << mk_pp(n, m) << "\n";);
TRACE("internalize_assertion_ll", tout << mk_ll_pp(n, m) << "\n";);
TRACE("generation", tout << "generation: " << m_generation << "\n";);
TRACE("incompleteness_bug", tout << "[internalize-assertion]: #" << n->get_id() << "\n";);
flet<unsigned> l(m_generation, generation);
m_stats.m_max_generation = std::max(m_generation, m_stats.m_max_generation);
if (::get_depth(n) > DEEP_EXPR_THRESHOLD) { if (::get_depth(n) > DEEP_EXPR_THRESHOLD) {
// if the expression is deep, then execute topological sort to avoid // if the expression is deep, then execute topological sort to avoid
// stack overflow. // stack overflow.
@ -211,15 +199,30 @@ namespace smt {
if (!is_app(e) || if (!is_app(e) ||
to_app(e)->get_family_id() == null_family_id || to_app(e)->get_family_id() == null_family_id ||
to_app(e)->get_family_id() == m.get_basic_family_id()) to_app(e)->get_family_id() == m.get_basic_family_id())
internalize(e, kv.second); internalize_rec(e, kv.second);
} }
} }
}
/**
\brief Internalize an expression asserted into the logical context using the given proof as a justification.
\remark pr is 0 if proofs are disabled.
*/
void context::internalize_assertion(expr * n, proof * pr, unsigned generation) {
TRACE("internalize_assertion", tout << mk_pp(n, m) << "\n";);
TRACE("internalize_assertion_ll", tout << mk_ll_pp(n, m) << "\n";);
TRACE("generation", tout << "generation: " << m_generation << "\n";);
TRACE("incompleteness_bug", tout << "[internalize-assertion]: #" << n->get_id() << "\n";);
flet<unsigned> l(m_generation, generation);
m_stats.m_max_generation = std::max(m_generation, m_stats.m_max_generation);
internalize_deep(n);
SASSERT(m.is_bool(n)); SASSERT(m.is_bool(n));
if (is_gate(m, n)) { if (is_gate(m, n)) {
switch(to_app(n)->get_decl_kind()) { switch(to_app(n)->get_decl_kind()) {
case OP_AND: { case OP_AND: {
for (expr * arg : *to_app(n)) { for (expr * arg : *to_app(n)) {
internalize(arg, true); internalize_rec(arg, true);
literal lit = get_literal(arg); literal lit = get_literal(arg);
mk_root_clause(1, &lit, pr); mk_root_clause(1, &lit, pr);
} }
@ -228,7 +231,7 @@ namespace smt {
case OP_OR: { case OP_OR: {
literal_buffer lits; literal_buffer lits;
for (expr * arg : *to_app(n)) { for (expr * arg : *to_app(n)) {
internalize(arg, true); internalize_rec(arg, true);
lits.push_back(get_literal(arg)); lits.push_back(get_literal(arg));
} }
mk_root_clause(lits.size(), lits.c_ptr(), pr); mk_root_clause(lits.size(), lits.c_ptr(), pr);
@ -238,8 +241,8 @@ namespace smt {
case OP_EQ: { case OP_EQ: {
expr * lhs = to_app(n)->get_arg(0); expr * lhs = to_app(n)->get_arg(0);
expr * rhs = to_app(n)->get_arg(1); expr * rhs = to_app(n)->get_arg(1);
internalize(lhs, true); internalize_rec(lhs, true);
internalize(rhs, true); internalize_rec(rhs, true);
literal l1 = get_literal(lhs); literal l1 = get_literal(lhs);
literal l2 = get_literal(rhs); literal l2 = get_literal(rhs);
mk_root_clause(l1, ~l2, pr); mk_root_clause(l1, ~l2, pr);
@ -250,9 +253,9 @@ namespace smt {
expr * c = to_app(n)->get_arg(0); expr * c = to_app(n)->get_arg(0);
expr * t = to_app(n)->get_arg(1); expr * t = to_app(n)->get_arg(1);
expr * e = to_app(n)->get_arg(2); expr * e = to_app(n)->get_arg(2);
internalize(c, true); internalize_rec(c, true);
internalize(t, true); internalize_rec(t, true);
internalize(e, true); internalize_rec(e, true);
literal cl = get_literal(c); literal cl = get_literal(c);
literal tl = get_literal(t); literal tl = get_literal(t);
literal el = get_literal(e); literal el = get_literal(e);
@ -317,7 +320,7 @@ namespace smt {
void context::internalize(expr * n, bool gate_ctx, unsigned generation) { void context::internalize(expr * n, bool gate_ctx, unsigned generation) {
flet<unsigned> l(m_generation, generation); flet<unsigned> l(m_generation, generation);
m_stats.m_max_generation = std::max(m_generation, m_stats.m_max_generation); m_stats.m_max_generation = std::max(m_generation, m_stats.m_max_generation);
internalize(n, gate_ctx); internalize_rec(n, gate_ctx);
} }
void context::ensure_internalized(expr* e) { void context::ensure_internalized(expr* e) {
@ -332,6 +335,11 @@ namespace smt {
- gate_ctx is true if the expression is in the context of a logical gate. - gate_ctx is true if the expression is in the context of a logical gate.
*/ */
void context::internalize(expr * n, bool gate_ctx) { void context::internalize(expr * n, bool gate_ctx) {
internalize_deep(n);
internalize_rec(n, gate_ctx);
}
void context::internalize_rec(expr * n, bool gate_ctx) {
TRACE("internalize", tout << "internalizing:\n" << mk_pp(n, m) << "\n";); TRACE("internalize", tout << "internalizing:\n" << mk_pp(n, m) << "\n";);
TRACE("internalize_bug", tout << "internalizing:\n" << mk_bounded_pp(n, m) << "\n";); TRACE("internalize_bug", tout << "internalizing:\n" << mk_bounded_pp(n, m) << "\n";);
if (is_var(n)) { if (is_var(n)) {
@ -351,7 +359,6 @@ namespace smt {
} }
} }
/** /**
\brief Internalize the given formula into the logical context. \brief Internalize the given formula into the logical context.
*/ */
@ -364,7 +371,7 @@ namespace smt {
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.
internalize(to_app(n)->get_arg(0), true); internalize_rec(to_app(n)->get_arg(0), true);
return; return;
} }
@ -435,7 +442,7 @@ namespace smt {
SASSERT(!b_internalized(n)); SASSERT(!b_internalized(n));
SASSERT(m.is_distinct(n)); SASSERT(m.is_distinct(n));
expr_ref def(m.mk_distinct_expanded(n->get_num_args(), n->get_args()), m); expr_ref def(m.mk_distinct_expanded(n->get_num_args(), n->get_args()), m);
internalize(def, true); internalize_rec(def, true);
bool_var v = mk_bool_var(n); bool_var v = mk_bool_var(n);
literal l(v); literal l(v);
literal l_def = get_literal(def); literal l_def = get_literal(def);
@ -577,7 +584,7 @@ namespace smt {
bool _is_gate = is_gate(m, n) || m.is_not(n); bool _is_gate = is_gate(m, n) || m.is_not(n);
// process args // process args
for (expr * arg : *n) { for (expr * arg : *n) {
internalize(arg, _is_gate); internalize_rec(arg, _is_gate);
} }
CTRACE("internalize_bug", b_internalized(n), tout << mk_ll_pp(n, m) << "\n";); CTRACE("internalize_bug", b_internalized(n), tout << mk_ll_pp(n, m) << "\n";);
@ -788,11 +795,11 @@ namespace smt {
true /* suppress arguments, I don't want to apply CC on ite terms */, true /* suppress arguments, I don't want to apply CC on ite terms */,
false /* it is a term, so it should not be merged with true/false */, false /* it is a term, so it should not be merged with true/false */,
false /* CC is not enabled */); false /* CC is not enabled */);
internalize(c, true); internalize_rec(c, true);
internalize(t, false); internalize_rec(t, false);
internalize(e, false); internalize_rec(e, false);
internalize(eq1, true); internalize_rec(eq1, true);
internalize(eq2, true); internalize_rec(eq2, true);
literal c_lit = get_literal(c); literal c_lit = get_literal(c);
literal eq1_lit = get_literal(eq1); literal eq1_lit = get_literal(eq1);
literal eq2_lit = get_literal(eq2); literal eq2_lit = get_literal(eq2);
@ -836,7 +843,7 @@ namespace smt {
SASSERT(!e_internalized(n)); SASSERT(!e_internalized(n));
// process args // process args
for (expr * arg : *n) { for (expr * arg : *n) {
internalize(arg, false); internalize_rec(arg, false);
SASSERT(e_internalized(arg)); SASSERT(e_internalized(arg));
} }