Question about mechanism of blocking current assignments in theory_seq.cpp (final_check_eh()) #5662
-
Hello! I have a question about the mechanism of blocking current assignments in theory_seq.cpp. In final_check_eh(), we need to prevent the solver from guessing the same assignment again and again. There seems to be two ways to achieve this goal. Method 1: alan23273850@9ad4c0e final_check_status theory_seq::final_check_eh() {
print_formulas("Entering final check:");
add_axiom(mk_literal(m.mk_false()));
return FC_CONTINUE;
} Method 2: alan23273850@2df65fd final_check_status theory_seq::final_check_eh() {
print_formulas("Entering final check:");
DEBUG("block",__LINE__ << "[Refinement]\nformulas:\n";)
literal_vector lits;
for (const auto& eq : m_rep) {
if (eq.v && eq.v->get_sort()==m_util.mk_string_sort() &&
eq.e && eq.e->get_sort()==m_util.mk_string_sort()) {
expr *const e = m.mk_eq(eq.v, eq.e);
literal l = mk_literal(m.mk_not(e));
lits.push_back(l);
DEBUG("block", "[m_rep] "<<l<<"("<<mk_pp(m.mk_not(e),m)<<") \n";);
}
}
for (const auto& we : m_eqs) {
expr *const e = m.mk_eq(mk_concat(we.ls), mk_concat(we.rs));
literal l = mk_literal(m.mk_not(e));
lits.push_back(l);
DEBUG("block", "[m_eqs] "<<l<<"("<<mk_pp(m.mk_not(e),m)<<") \n";);
}
for (const auto& wi : m_nqs) {
expr *const e = m.mk_not(m.mk_eq(wi.l(), wi.r()));
literal l = mk_literal(m.mk_not(e));
lits.push_back(l);
DEBUG("block", "[m_nqs] "<<l<<"("<<mk_pp(m.mk_not(e),m)<<") \n";);
}
for (const auto& nc : m_ncs) {
expr *const e = m.mk_not(nc.contains());
literal l = mk_literal(m.mk_not(e));
lits.push_back(l);
DEBUG("block", "[m_ncs] "<<l<<"("<<mk_pp(m.mk_not(e),m)<<") \n";);
}
DEBUG("block", "block ";);
for(auto& lit:lits){
DEBUG("block", " "<<lit<<"("<<lit<<")";);
}
DEBUG("block", "\n";);
if (!lits.empty()) {
add_axiom(lits);
}
DEBUG("block",__LINE__ << " leave " << __FUNCTION__ << std::endl;)
return FC_CONTINUE;
} However, the results obtained from these two ways are different. We used the following file as our example. (declare-const x String)
(declare-const y String)
(assert (or (and (= (str.++ x "a" y) "abcd") (= (str.len x) (str.len y)))
(= x y)))
(check-sat) Method 1 produces the following result.
Method 2 produces the following result.
It is apparent that Method 1 ignores the possibility of guessing the branch |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Keep in mind that whatever is asserted by add_axiom is global. It is not scope dependent. The assertion should be valid regardless of scope. So if you add_axiom(false), then you are basically saying false was implied at base level of search. There are other weird things with your code. It uses m.mk_not(...) all over the place. YOu will likely run into reference counting bugs. You can negate literals using ~. So use literal l = ~mk_literal(e); |
Beta Was this translation helpful? Give feedback.
Keep in mind that whatever is asserted by add_axiom is global. It is not scope dependent. The assertion should be valid regardless of scope. So if you add_axiom(false), then you are basically saying false was implied at base level of search.
There are other weird things with your code. It uses m.mk_not(...) all over the place. YOu will likely run into reference counting bugs. You can negate literals using ~. So use
literal l = ~mk_literal(e);
instead of
literal l = mk_literal(m.mk_not(e));