3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-20 19:32:04 +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;); TRACE("t_str_detail", tout << "concat = " << mk_pp(concat, mgr) << ", unroll = " << mk_pp(unroll, mgr) << std::endl;);
// TODO NEXT std::pair<expr*, expr*> key = std::make_pair(concat, unroll);
NOT_IMPLEMENTED_YET(); expr_ref toAssert(mgr);
/*
#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
Z3_context ctx = Z3_theory_get_context(t); if (concat_eq_unroll_ast_map.find(key) == concat_eq_unroll_ast_map.end()) {
std::pair<Z3_ast, Z3_ast> key = std::make_pair(concat, unroll); expr_ref arg1(to_app(concat)->get_arg(0), mgr);
Z3_ast toAssert = NULL; 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()) { expr_ref v1(mk_regex_rep_var(), mgr);
Z3_ast arg1 = Z3_get_app_arg(ctx, Z3_to_app(ctx, concat), 0); expr_ref v2(mk_regex_rep_var(), mgr);
Z3_ast arg2 = Z3_get_app_arg(ctx, Z3_to_app(ctx, concat), 1); expr_ref v3(mk_regex_rep_var(), mgr);
Z3_ast r1 = Z3_get_app_arg(ctx, Z3_to_app(ctx, unroll), 0); expr_ref v4(mk_regex_rep_var(), mgr);
Z3_ast t1 = Z3_get_app_arg(ctx, Z3_to_app(ctx, unroll), 1); expr_ref v5(mk_regex_rep_var(), mgr);
Z3_ast v1 = mk_regexRepVar(t); expr_ref t2(mk_unroll_bound_var(), mgr);
Z3_ast v2 = mk_regexRepVar(t); expr_ref t3(mk_unroll_bound_var(), mgr);
Z3_ast v3 = mk_regexRepVar(t); expr_ref emptyStr(m_strutil.mk_string(""), mgr);
Z3_ast v4 = mk_regexRepVar(t);
Z3_ast v5 = mk_regexRepVar(t);
Z3_ast t2 = mk_unrollBoundVar(t); expr_ref unroll1(mk_unroll(r1, t2), mgr);
Z3_ast t3 = mk_unrollBoundVar(t); expr_ref unroll2(mk_unroll(r1, t3), mgr);
Z3_ast emptyStr = my_mk_str_value(t, "");
Z3_ast unroll1 = mk_unroll(t, r1, t2); expr_ref op0(ctx.mk_eq_atom(t1, mk_int(0)), mgr);
Z3_ast unroll2 = mk_unroll(t, r1, t3); expr_ref op1(m_autil.mk_ge(t1, mk_int(1)), mgr);
Z3_ast op0 = Z3_mk_eq(ctx, t1, mk_int(ctx, 0)); expr_ref_vector op1Items(mgr);
Z3_ast op1 = Z3_mk_ge(ctx, t1, mk_int(ctx, 1)); expr_ref_vector op2Items(mgr);
std::vector<Z3_ast> op1Items; op1Items.push_back(ctx.mk_eq_atom(arg1, emptyStr));
std::vector<Z3_ast> op2Items; 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)); expr_ref v1v2(mk_concat(v1, v2), mgr);
op1Items.push_back(Z3_mk_eq(ctx, arg2, emptyStr)); op2Items.push_back(ctx.mk_eq_atom(arg1, v1v2));
op1Items.push_back(Z3_mk_eq(ctx, mk_length(t, arg1), mk_int(ctx, 0))); op2Items.push_back(ctx.mk_eq_atom(mk_strlen(arg1), m_autil.mk_add(mk_strlen(v1), mk_strlen(v2))));
op1Items.push_back(Z3_mk_eq(ctx, mk_length(t, arg2), mk_int(ctx, 0))); expr_ref v3v4(mk_concat(v3, v4), mgr);
Z3_ast opAnd1 = Z3_mk_eq(ctx, op0, mk_and_fromVector(t, op1Items)); 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(ctx.mk_eq_atom(v1, unroll1));
op2Items.push_back(Z3_mk_eq(ctx, arg1, v1v2)); op2Items.push_back(ctx.mk_eq_atom(mk_strlen(v1), mk_strlen(unroll1)));
op2Items.push_back(Z3_mk_eq(ctx, mk_length(t, arg1), mk_2_add(t, mk_length(t, v1), mk_length(t, v2)))); op2Items.push_back(ctx.mk_eq_atom(v4, unroll2));
Z3_ast v3v4 = mk_concat(t, v3, v4); op2Items.push_back(ctx.mk_eq_atom(mk_strlen(v4), mk_strlen(unroll2)));
op2Items.push_back(Z3_mk_eq(ctx, arg2, v3v4)); expr_ref v2v3(mk_concat(v2, v3), mgr);
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(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)); toAssert = mgr.mk_and(opAnd1, opAnd2);
op2Items.push_back(Z3_mk_eq(ctx, mk_length(t, v1), mk_length(t, unroll1))); m_trail.push_back(toAssert);
op2Items.push_back(Z3_mk_eq(ctx, v4, unroll2)); concat_eq_unroll_ast_map[key] = toAssert;
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 = mk_2_and(t, opAnd1, opAnd2);
concatEqUnroll_AstMap[key] = toAssert;
} else { } else {
toAssert = concatEqUnroll_AstMap[key]; toAssert = concat_eq_unroll_ast_map[key];
} }
addAxiom(t, toAssert, __LINE__); assert_axiom(toAssert);
*/
} }
void theory_str::unroll_str2reg_constStr(expr * unrollFunc, expr * eqConstStr) { 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 // 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*, std::map<std::set<expr*>, ptr_vector<expr> > > unroll_tries_map;
std::map<expr*, expr*> unroll_var_map; std::map<expr*, expr*> unroll_var_map;
std::map<std::pair<expr*, expr*>, expr*> concat_eq_unroll_ast_map;
char * char_set; char * char_set;
std::map<char, int> charSetLookupTable; std::map<char, int> charSetLookupTable;