3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-03 09:50:23 +00:00

Z3str3 Debug (#6000)

* z3str3 debug

* add comments of reference to bugs in the report

Co-authored-by: John Lu <z52lu@uwaterloo.ca>
This commit is contained in:
JohnLyu2 2022-04-27 06:37:07 -04:00 committed by GitHub
parent 99e299b90c
commit 5a9b0dd747
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 51 deletions

View file

@ -1100,9 +1100,10 @@ namespace smt {
TRACE("str", tout << "instantiate CharAt axiom for " << mk_pp(expr, m) << std::endl;); TRACE("str", tout << "instantiate CharAt axiom for " << mk_pp(expr, m) << std::endl;);
expr_ref ts0(mk_str_var("ts0"), m); // change subvaribale names to solve some invalide model problems
expr_ref ts1(mk_str_var("ts1"), m); expr_ref ts0(mk_str_var("ch_ts0"), m);
expr_ref ts2(mk_str_var("ts2"), m); expr_ref ts1(mk_str_var("ch_ts1"), m);
expr_ref ts2(mk_str_var("ch_ts2"), m);
expr_ref cond(m.mk_and( expr_ref cond(m.mk_and(
m_autil.mk_ge(arg1, mk_int(0)), m_autil.mk_ge(arg1, mk_int(0)),
@ -1134,8 +1135,9 @@ namespace smt {
TRACE("str", tout << "instantiate prefixof axiom for " << mk_pp(expr, m) << std::endl;); TRACE("str", tout << "instantiate prefixof axiom for " << mk_pp(expr, m) << std::endl;);
expr_ref ts0(mk_str_var("ts0"), m); // change subvaribale names to solve some invalide model problems
expr_ref ts1(mk_str_var("ts1"), m); expr_ref ts0(mk_str_var("p_ts0"), m);
expr_ref ts1(mk_str_var("p_ts1"), m);
expr_ref_vector innerItems(m); expr_ref_vector innerItems(m);
innerItems.push_back(ctx.mk_eq_atom(expr->get_arg(1), mk_concat(ts0, ts1))); innerItems.push_back(ctx.mk_eq_atom(expr->get_arg(1), mk_concat(ts0, ts1)));
@ -1170,8 +1172,9 @@ namespace smt {
TRACE("str", tout << "instantiate suffixof axiom for " << mk_pp(expr, m) << std::endl;); TRACE("str", tout << "instantiate suffixof axiom for " << mk_pp(expr, m) << std::endl;);
expr_ref ts0(mk_str_var("ts0"), m); // change subvaribale names to solve some invalide model problems
expr_ref ts1(mk_str_var("ts1"), m); expr_ref ts0(mk_str_var("s_ts0"), m);
expr_ref ts1(mk_str_var("s_ts1"), m);
expr_ref_vector innerItems(m); expr_ref_vector innerItems(m);
innerItems.push_back(ctx.mk_eq_atom(expr->get_arg(1), mk_concat(ts0, ts1))); innerItems.push_back(ctx.mk_eq_atom(expr->get_arg(1), mk_concat(ts0, ts1)));
@ -1235,8 +1238,9 @@ namespace smt {
TRACE("str", tout << "instantiate Contains axiom for " << mk_pp(ex, m) << std::endl;); TRACE("str", tout << "instantiate Contains axiom for " << mk_pp(ex, m) << std::endl;);
expr_ref ts0(mk_str_var("ts0"), m); // change subvaribale names to solve some invalide model problems
expr_ref ts1(mk_str_var("ts1"), m); expr_ref ts0(mk_str_var("c_ts0"), m);
expr_ref ts1(mk_str_var("c_ts1"), m);
expr_ref breakdownAssert(ctx.mk_eq_atom(ex, ctx.mk_eq_atom(ex->get_arg(0), mk_concat(ts0, mk_concat(ex->get_arg(1), ts1)))), m); expr_ref breakdownAssert(ctx.mk_eq_atom(ex, ctx.mk_eq_atom(ex->get_arg(0), mk_concat(ts0, mk_concat(ex->get_arg(1), ts1)))), m);
SASSERT(breakdownAssert); SASSERT(breakdownAssert);
@ -1287,8 +1291,9 @@ namespace smt {
TRACE("str", tout << "instantiate str.indexof axiom for " << mk_pp(ex, m) << std::endl;); TRACE("str", tout << "instantiate str.indexof axiom for " << mk_pp(ex, m) << std::endl;);
expr_ref x1(mk_str_var("x1"), m); // change subvaribale names to solve some invalide model problems
expr_ref x2(mk_str_var("x2"), m); expr_ref x1(mk_str_var("i_x1"), m);
expr_ref x2(mk_str_var("i_x2"), m);
expr_ref condAst1(mk_contains(exHaystack, exNeedle), m); expr_ref condAst1(mk_contains(exHaystack, exNeedle), m);
expr_ref condAst2(m.mk_not(ctx.mk_eq_atom(exNeedle, mk_string(""))), m); expr_ref condAst2(m.mk_not(ctx.mk_eq_atom(exNeedle, mk_string(""))), m);
@ -1305,8 +1310,9 @@ namespace smt {
// args[0] = x3 . x4 // args[0] = x3 . x4
// /\ |x3| = |x1| + |args[1]| - 1 // /\ |x3| = |x1| + |args[1]| - 1
// /\ ! contains(x3, args[1]) // /\ ! contains(x3, args[1])
expr_ref x3(mk_str_var("x3"), m); // change subvaribale names to solve some invalide model problems
expr_ref x4(mk_str_var("x4"), m); expr_ref x3(mk_str_var("i_x3"), m);
expr_ref x4(mk_str_var("i_x4"), m);
expr_ref tmpLen(m_autil.mk_add(ex, mk_strlen(ex->get_arg(1)), mk_int(-1)), m); expr_ref tmpLen(m_autil.mk_add(ex, mk_strlen(ex->get_arg(1)), mk_int(-1)), m);
SASSERT(tmpLen); SASSERT(tmpLen);
thenItems.push_back(ctx.mk_eq_atom(exHaystack, mk_concat(x3, x4))); thenItems.push_back(ctx.mk_eq_atom(exHaystack, mk_concat(x3, x4)));
@ -1501,8 +1507,9 @@ namespace smt {
TRACE("str", tout << "instantiate LastIndexof axiom for " << mk_pp(expr, m) << std::endl;); TRACE("str", tout << "instantiate LastIndexof axiom for " << mk_pp(expr, m) << std::endl;);
expr_ref x1(mk_str_var("x1"), m); // change subvaribale names to solve some invalide model problems
expr_ref x2(mk_str_var("x2"), m); expr_ref x1(mk_str_var("li_x1"), m);
expr_ref x2(mk_str_var("li_x2"), m);
expr_ref indexAst(mk_int_var("index"), m); expr_ref indexAst(mk_int_var("index"), m);
expr_ref_vector items(m); expr_ref_vector items(m);
@ -1532,8 +1539,9 @@ namespace smt {
if (!canSkip) { if (!canSkip) {
// args[0] = x3 . x4 /\ |x3| = |x1| + 1 /\ ! contains(x4, args[1]) // args[0] = x3 . x4 /\ |x3| = |x1| + 1 /\ ! contains(x4, args[1])
expr_ref x3(mk_str_var("x3"), m); // change subvaribale names to solve some invalide model problems
expr_ref x4(mk_str_var("x4"), m); expr_ref x3(mk_str_var("li_x3"), m);
expr_ref x4(mk_str_var("li_x4"), m);
expr_ref tmpLen(m_autil.mk_add(indexAst, mk_int(1)), m); expr_ref tmpLen(m_autil.mk_add(indexAst, mk_int(1)), m);
thenItems.push_back(ctx.mk_eq_atom(expr->get_arg(0), mk_concat(x3, x4))); thenItems.push_back(ctx.mk_eq_atom(expr->get_arg(0), mk_concat(x3, x4)));
thenItems.push_back(ctx.mk_eq_atom(mk_strlen(x3), tmpLen)); thenItems.push_back(ctx.mk_eq_atom(mk_strlen(x3), tmpLen));
@ -1690,10 +1698,11 @@ namespace smt {
TRACE("str", tout << "instantiate Replace axiom for " << mk_pp(ex, m) << std::endl;); TRACE("str", tout << "instantiate Replace axiom for " << mk_pp(ex, m) << std::endl;);
expr_ref x1(mk_str_var("x1"), m); // change subvaribale names to solve some invalide model problems
expr_ref x2(mk_str_var("x2"), m); expr_ref x1(mk_str_var("rp_x1"), m);
expr_ref x2(mk_str_var("rp_x2"), m);
expr_ref i1(mk_int_var("i1"), m); expr_ref i1(mk_int_var("i1"), m);
expr_ref result(mk_str_var("result"), m); expr_ref result(mk_str_var("rp_result"), m);
expr * replaceS = nullptr; expr * replaceS = nullptr;
expr * replaceT = nullptr; expr * replaceT = nullptr;
@ -1714,8 +1723,9 @@ namespace smt {
// i1 = |x1| // i1 = |x1|
thenItems.push_back(ctx.mk_eq_atom(i1, mk_strlen(x1))); thenItems.push_back(ctx.mk_eq_atom(i1, mk_strlen(x1)));
// args[0] = x3 . x4 /\ |x3| = |x1| + |args[1]| - 1 /\ ! contains(x3, args[1]) // args[0] = x3 . x4 /\ |x3| = |x1| + |args[1]| - 1 /\ ! contains(x3, args[1])
expr_ref x3(mk_str_var("x3"), m); // change subvaribale names to solve some invalide model problems
expr_ref x4(mk_str_var("x4"), m); expr_ref x3(mk_str_var("rp_x3"), m);
expr_ref x4(mk_str_var("rp_x4"), m);
expr_ref tmpLen(m_autil.mk_add(i1, mk_strlen(ex->get_arg(1)), mk_int(-1)), m); expr_ref tmpLen(m_autil.mk_add(i1, mk_strlen(ex->get_arg(1)), mk_int(-1)), m);
thenItems.push_back(ctx.mk_eq_atom(ex->get_arg(0), mk_concat(x3, x4))); thenItems.push_back(ctx.mk_eq_atom(ex->get_arg(0), mk_concat(x3, x4)));
thenItems.push_back(ctx.mk_eq_atom(mk_strlen(x3), tmpLen)); thenItems.push_back(ctx.mk_eq_atom(mk_strlen(x3), tmpLen));
@ -3245,7 +3255,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
assert_implication(ax_l, m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
assert_implication(ax_l, new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
} else if (splitType == 1) { } else if (splitType == 1) {
@ -3303,7 +3317,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
assert_implication(ax_l, m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
assert_implication(ax_l, new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
@ -3355,7 +3373,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
arrangement_disjunction.push_back(m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
arrangement_disjunction.push_back(new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
@ -3400,7 +3422,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
arrangement_disjunction.push_back(m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
arrangement_disjunction.push_back(new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
@ -3641,7 +3667,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
assert_implication(ax_l, m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
assert_implication(ax_l, new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
@ -3742,7 +3772,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
arrangement_disjunction.push_back(m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
arrangement_disjunction.push_back(new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
} }
@ -4037,7 +4071,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
assert_implication(ax_l, m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
assert_implication(ax_l, new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
} }
@ -4116,7 +4154,11 @@ namespace smt {
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
arrangement_disjunction.push_back(m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
arrangement_disjunction.push_back(new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
} }
} }
} }
@ -4513,7 +4555,11 @@ namespace smt {
// only add the overlap assumption one time // only add the overlap assumption one time
if (!overlapAssumptionUsed) { if (!overlapAssumptionUsed) {
arrangement_disjunction.push_back(m_theoryStrOverlapAssumption_term); // add context dependent formula overlap predicate and relate it to the global overlap predicate
sort * s = get_manager().mk_bool_sort();
expr_ref new_OverlapAssumption_term = expr_ref(mk_fresh_const(newOverlapStr, s), get_manager());
arrangement_disjunction.push_back(new_OverlapAssumption_term);
assert_implication(new_OverlapAssumption_term, m_theoryStrOverlapAssumption_term);
overlapAssumptionUsed = true; overlapAssumptionUsed = true;
} }
@ -4781,6 +4827,8 @@ namespace smt {
//} else if (getNodeType(t, node) == my_Z3_Func) { //} else if (getNodeType(t, node) == my_Z3_Func) {
} else if (is_app(node)) { } else if (is_app(node)) {
app * func_app = to_app(node); app * func_app = to_app(node);
// the following check is only valid when the operator is string concatenate
if (u.str.is_concat(func_app)) {
unsigned int argCount = func_app->get_num_args(); unsigned int argCount = func_app->get_num_args();
for (unsigned int i = 0; i < argCount; i++) { for (unsigned int i = 0; i < argCount; i++) {
expr * argAst = func_app->get_arg(i); expr * argAst = func_app->get_arg(i);
@ -4788,6 +4836,7 @@ namespace smt {
} }
} }
} }
}
void theory_str::check_contain_by_eqc_val(expr * varNode, expr * constNode) { void theory_str::check_contain_by_eqc_val(expr * varNode, expr * constNode) {
ast_manager & m = get_manager(); ast_manager & m = get_manager();

View file

@ -393,6 +393,8 @@ protected:
// does not introduce equalities when they weren't enforced. // does not introduce equalities when they weren't enforced.
unsigned m_unused_id; unsigned m_unused_id;
const char* newOverlapStr = "!!NewOverlapAssumption!!";
// terms we couldn't go through set_up_axioms() with because they weren't internalized // terms we couldn't go through set_up_axioms() with because they weren't internalized
expr_ref_vector m_delayed_axiom_setup_terms; expr_ref_vector m_delayed_axiom_setup_terms;
@ -777,4 +779,3 @@ protected:
}; };
}; };