3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

implement process_concat_eq_unroll, WIP

This commit is contained in:
Murphy Berzish 2016-06-30 04:55:11 -04:00
parent b53da182b6
commit 7d903ff1fa
2 changed files with 50 additions and 63 deletions

View file

@ -3440,80 +3440,66 @@ void theory_str::process_concat_eq_unroll(expr * concat, expr * unroll) {
TRACE("t_str_detail", tout << "concat = " << mk_pp(concat, mgr) << ", unroll = " << mk_pp(unroll, mgr) << std::endl;);
// TODO NEXT
NOT_IMPLEMENTED_YET();
/*
#ifdef DEBUGLOG
__debugPrint(logFile, ">> processConcatEqUnroll: \n");
__debugPrint(logFile, " * [concat] ");
printZ3Node(t, concat);
__debugPrint(logFile, "\n");
__debugPrint(logFile, " * [unroll] ");
printZ3Node(t, unroll);
__debugPrint(logFile, "\n\n");
#endif
std::pair<expr*, expr*> key = std::make_pair(concat, unroll);
expr_ref toAssert(mgr);
Z3_context ctx = Z3_theory_get_context(t);
std::pair<Z3_ast, Z3_ast> key = std::make_pair(concat, unroll);
Z3_ast toAssert = NULL;
if (concat_eq_unroll_ast_map.find(key) == concat_eq_unroll_ast_map.end()) {
expr_ref arg1(to_app(concat)->get_arg(0), mgr);
expr_ref arg2(to_app(concat)->get_arg(1), mgr);
expr_ref r1(to_app(unroll)->get_arg(0), mgr);
expr_ref t1(to_app(unroll)->get_arg(1), mgr);
if (concatEqUnroll_AstMap.find(key) == concatEqUnroll_AstMap.end()) {
Z3_ast arg1 = Z3_get_app_arg(ctx, Z3_to_app(ctx, concat), 0);
Z3_ast arg2 = Z3_get_app_arg(ctx, Z3_to_app(ctx, concat), 1);
Z3_ast r1 = Z3_get_app_arg(ctx, Z3_to_app(ctx, unroll), 0);
Z3_ast t1 = Z3_get_app_arg(ctx, Z3_to_app(ctx, unroll), 1);
expr_ref v1(mk_regex_rep_var(), mgr);
expr_ref v2(mk_regex_rep_var(), mgr);
expr_ref v3(mk_regex_rep_var(), mgr);
expr_ref v4(mk_regex_rep_var(), mgr);
expr_ref v5(mk_regex_rep_var(), mgr);
Z3_ast v1 = mk_regexRepVar(t);
Z3_ast v2 = mk_regexRepVar(t);
Z3_ast v3 = mk_regexRepVar(t);
Z3_ast v4 = mk_regexRepVar(t);
Z3_ast v5 = mk_regexRepVar(t);
expr_ref t2(mk_unroll_bound_var(), mgr);
expr_ref t3(mk_unroll_bound_var(), mgr);
expr_ref emptyStr(m_strutil.mk_string(""), mgr);
Z3_ast t2 = mk_unrollBoundVar(t);
Z3_ast t3 = mk_unrollBoundVar(t);
Z3_ast emptyStr = my_mk_str_value(t, "");
expr_ref unroll1(mk_unroll(r1, t2), mgr);
expr_ref unroll2(mk_unroll(r1, t3), mgr);
Z3_ast unroll1 = mk_unroll(t, r1, t2);
Z3_ast unroll2 = mk_unroll(t, r1, t3);
expr_ref op0(ctx.mk_eq_atom(t1, mk_int(0)), mgr);
expr_ref op1(m_autil.mk_ge(t1, mk_int(1)), mgr);
Z3_ast op0 = Z3_mk_eq(ctx, t1, mk_int(ctx, 0));
Z3_ast op1 = Z3_mk_ge(ctx, t1, mk_int(ctx, 1));
expr_ref_vector op1Items(mgr);
expr_ref_vector op2Items(mgr);
std::vector<Z3_ast> op1Items;
std::vector<Z3_ast> op2Items;
op1Items.push_back(ctx.mk_eq_atom(arg1, emptyStr));
op1Items.push_back(ctx.mk_eq_atom(arg2, emptyStr));
op1Items.push_back(ctx.mk_eq_atom(mk_strlen(arg1), mk_int(0)));
op1Items.push_back(ctx.mk_eq_atom(mk_strlen(arg2), mk_int(0)));
expr_ref opAnd1(ctx.mk_eq_atom(op0, mk_and(op1Items)), mgr);
op1Items.push_back(Z3_mk_eq(ctx, arg1, emptyStr));
op1Items.push_back(Z3_mk_eq(ctx, arg2, emptyStr));
op1Items.push_back(Z3_mk_eq(ctx, mk_length(t, arg1), mk_int(ctx, 0)));
op1Items.push_back(Z3_mk_eq(ctx, mk_length(t, arg2), mk_int(ctx, 0)));
Z3_ast opAnd1 = Z3_mk_eq(ctx, op0, mk_and_fromVector(t, op1Items));
expr_ref v1v2(mk_concat(v1, v2), mgr);
op2Items.push_back(ctx.mk_eq_atom(arg1, v1v2));
op2Items.push_back(ctx.mk_eq_atom(mk_strlen(arg1), m_autil.mk_add(mk_strlen(v1), mk_strlen(v2))));
expr_ref v3v4(mk_concat(v3, v4), mgr);
op2Items.push_back(ctx.mk_eq_atom(arg2, v3v4));
op2Items.push_back(ctx.mk_eq_atom(mk_strlen(arg2), m_autil.mk_add(mk_strlen(v3), mk_strlen(v4))));
Z3_ast v1v2 = mk_concat(t, v1, v2);
op2Items.push_back(Z3_mk_eq(ctx, arg1, v1v2));
op2Items.push_back(Z3_mk_eq(ctx, mk_length(t, arg1), mk_2_add(t, mk_length(t, v1), mk_length(t, v2))));
Z3_ast v3v4 = mk_concat(t, v3, v4);
op2Items.push_back(Z3_mk_eq(ctx, arg2, v3v4));
op2Items.push_back(Z3_mk_eq(ctx, mk_length(t, arg2), mk_2_add(t, mk_length(t, v3), mk_length(t, v4))));
op2Items.push_back(ctx.mk_eq_atom(v1, unroll1));
op2Items.push_back(ctx.mk_eq_atom(mk_strlen(v1), mk_strlen(unroll1)));
op2Items.push_back(ctx.mk_eq_atom(v4, unroll2));
op2Items.push_back(ctx.mk_eq_atom(mk_strlen(v4), mk_strlen(unroll2)));
expr_ref v2v3(mk_concat(v2, v3), mgr);
op2Items.push_back(ctx.mk_eq_atom(v5, v2v3));
reduce_virtual_regex_in(v5, r1, op2Items);
op2Items.push_back(ctx.mk_eq_atom(mk_strlen(v5), m_autil.mk_add(mk_strlen(v2), mk_strlen(v3))));
op2Items.push_back(ctx.mk_eq_atom(m_autil.mk_add(t2, t3), m_autil.mk_add(t1, mk_int(-1))));
expr_ref opAnd2(ctx.mk_eq_atom(op1, mk_and(op2Items)), mgr);
op2Items.push_back(Z3_mk_eq(ctx, v1, unroll1));
op2Items.push_back(Z3_mk_eq(ctx, mk_length(t, v1), mk_length(t, unroll1)));
op2Items.push_back(Z3_mk_eq(ctx, v4, unroll2));
op2Items.push_back(Z3_mk_eq(ctx, mk_length(t, v4), mk_length(t, unroll2)));
Z3_ast v2v3 = mk_concat(t, v2, v3);
op2Items.push_back(Z3_mk_eq(ctx, v5, v2v3));
reduceVirtualRegexIn(t, v5, r1, op2Items);
op2Items.push_back(Z3_mk_eq(ctx, mk_length(t, v5), mk_2_add(t, mk_length(t, v2), mk_length(t, v3))));
op2Items.push_back(Z3_mk_eq(ctx, mk_2_add(t, t2, t3), mk_2_sub(t, t1, mk_int(ctx, 1))));
Z3_ast opAnd2 = Z3_mk_eq(ctx, op1, mk_and_fromVector(t, op2Items));
toAssert = mgr.mk_and(opAnd1, opAnd2);
m_trail.push_back(toAssert);
concat_eq_unroll_ast_map[key] = toAssert;
} else {
toAssert = concat_eq_unroll_ast_map[key];
}
toAssert = mk_2_and(t, opAnd1, opAnd2);
concatEqUnroll_AstMap[key] = toAssert;
} else {
toAssert = concatEqUnroll_AstMap[key];
}
addAxiom(t, toAssert, __LINE__);
*/
assert_axiom(toAssert);
}
void theory_str::unroll_str2reg_constStr(expr * unrollFunc, expr * eqConstStr) {

View file

@ -163,6 +163,7 @@ namespace smt {
// we would need to modify the allocator so we pass in ast_manager
std::map<expr*, std::map<std::set<expr*>, ptr_vector<expr> > > unroll_tries_map;
std::map<expr*, expr*> unroll_var_map;
std::map<std::pair<expr*, expr*>, expr*> concat_eq_unroll_ast_map;
char * char_set;
std::map<char, int> charSetLookupTable;