diff --git a/src/smt/theory_nseq.cpp b/src/smt/theory_nseq.cpp index 19472cce6..68cf41557 100644 --- a/src/smt/theory_nseq.cpp +++ b/src/smt/theory_nseq.cpp @@ -83,15 +83,20 @@ namespace smt { m_axioms.set_ensure_digits(ensure_digit_axiom); m_axioms.set_mark_no_diseq(mark_no_diseq); + m_should_internalize = true; // delete this if using internalize as fallback std::function literal_if_false = [&](expr* e) { bool is_not = m.is_not(e, e); - if (!ctx.b_internalized(e)) + if (m_should_internalize && !ctx.b_internalized(e)) { // it can happen that the element is not internalized, but as soon as we do it, it becomes false. // In case we just skip one of those uninternalized expressions, // adding the Nielsen assumption later will fail // Alternatively, we could just retry Nielsen saturation in case // adding the Nielsen assumption yields the assumption being false after internalizing ctx.internalize(to_app(e), false); + } + + if (!ctx.b_internalized(e)) + return sat::null_literal; literal lit = ctx.get_literal(e); if (is_not) @@ -764,6 +769,8 @@ namespace smt { // this should not happen because nielsen checks for this before returning a satisfying path. TRACE(seq, tout << "nseq final_check: nielsen assumption " << c.fml << " is false; internalized - " << ctx.e_internalized(c.fml) << "\n"); std::cout << "False [" << lit << "]: " << mk_pp(c.fml, m) << std::endl; + ctx.push_trail(value_trail(m_should_internalize)); + m_should_internalize = true; break; } } diff --git a/src/smt/theory_nseq.h b/src/smt/theory_nseq.h index ad8bcdc66..616051ea8 100644 --- a/src/smt/theory_nseq.h +++ b/src/smt/theory_nseq.h @@ -50,6 +50,7 @@ namespace smt { seq::axioms m_axioms; seq::seq_regex m_regex; // regex membership pre-processing seq_model m_model; // model construction helper + bool m_should_internalize = false; // propagation queue items (variant over the distinct propagation cases) using eq_item = tracked_str_eq; // string equality