From e35fd58968ec08dd4184e20b639e81a6aa4a9aa6 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 13 May 2013 11:43:30 -0700 Subject: [PATCH] add rewriting option to simplify store equalities Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/array_rewriter.cpp | 38 ++++++++++++++++++++++ src/ast/rewriter/array_rewriter.h | 3 ++ src/ast/rewriter/array_rewriter_params.pyg | 1 + src/ast/rewriter/mk_simplified_app.cpp | 2 ++ src/ast/rewriter/th_rewriter.cpp | 4 ++- 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/ast/rewriter/array_rewriter.cpp b/src/ast/rewriter/array_rewriter.cpp index 0bb7378f4..1f4418fd5 100644 --- a/src/ast/rewriter/array_rewriter.cpp +++ b/src/ast/rewriter/array_rewriter.cpp @@ -25,6 +25,7 @@ void array_rewriter::updt_params(params_ref const & _p) { array_rewriter_params p(_p); m_sort_store = p.sort_store(); m_expand_select_store = p.expand_select_store(); + m_expand_store_eq = p.expand_store_eq(); } void array_rewriter::get_param_descrs(param_descrs & r) { @@ -365,3 +366,40 @@ br_status array_rewriter::mk_set_subset(expr * arg1, expr * arg2, expr_ref & res return BR_REWRITE3; } +br_status array_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) { + if (!m_expand_store_eq) { + return BR_FAILED; + } + expr* lhs1 = lhs; + while (m_util.is_store(lhs1)) { + lhs1 = to_app(lhs1)->get_arg(0); + } + expr* rhs1 = rhs; + while (m_util.is_store(rhs1)) { + rhs1 = to_app(rhs1)->get_arg(0); + } + if (lhs1 != rhs1) { + return BR_FAILED; + } + ptr_buffer fmls, args; + expr* e; + expr_ref tmp1(m()), tmp2(m()); +#define MK_EQ() \ + while (m_util.is_store(e)) { \ + args.push_back(lhs); \ + args.append(to_app(e)->get_num_args()-2,to_app(e)->get_args()+1); \ + mk_select(args.size(), args.c_ptr(), tmp1); \ + args[0] = rhs; \ + mk_select(args.size(), args.c_ptr(), tmp2); \ + fmls.push_back(m().mk_eq(tmp1, tmp2)); \ + e = to_app(e)->get_arg(0); \ + args.reset(); \ + } \ + + e = lhs; + MK_EQ(); + e = rhs; + MK_EQ(); + result = m().mk_and(fmls.size(), fmls.c_ptr()); + return BR_REWRITE_FULL; +} diff --git a/src/ast/rewriter/array_rewriter.h b/src/ast/rewriter/array_rewriter.h index f1362802d..5f20f61ba 100644 --- a/src/ast/rewriter/array_rewriter.h +++ b/src/ast/rewriter/array_rewriter.h @@ -31,12 +31,14 @@ class array_rewriter { array_util m_util; bool m_sort_store; bool m_expand_select_store; + bool m_expand_store_eq; template lbool compare_args(unsigned num_args, expr * const * args1, expr * const * args2); public: array_rewriter(ast_manager & m, params_ref const & p = params_ref()): m_util(m) { updt_params(p); + } ast_manager & m() const { return m_util.get_manager(); } family_id get_fid() const { return m_util.get_family_id(); } @@ -60,6 +62,7 @@ public: br_status mk_set_complement(expr * arg, expr_ref & result); br_status mk_set_difference(expr * arg1, expr * arg2, expr_ref & result); br_status mk_set_subset(expr * arg1, expr * arg2, expr_ref & result); + br_status mk_eq_core(expr * lhs, expr * rhs, expr_ref & result); }; #endif diff --git a/src/ast/rewriter/array_rewriter_params.pyg b/src/ast/rewriter/array_rewriter_params.pyg index 2e3ae9f6a..a43fadecf 100644 --- a/src/ast/rewriter/array_rewriter_params.pyg +++ b/src/ast/rewriter/array_rewriter_params.pyg @@ -2,4 +2,5 @@ def_module_params(module_name='rewriter', class_name='array_rewriter_params', export=True, params=(("expand_select_store", BOOL, False, "replace a (select (store ...) ...) term by an if-then-else term"), + ("expand_store_eq", BOOL, False, "reduce (store ...) = (store ...) with a common base into selects"), ("sort_store", BOOL, False, "sort nested stores when the indices are known to be different"))) diff --git a/src/ast/rewriter/mk_simplified_app.cpp b/src/ast/rewriter/mk_simplified_app.cpp index da615e195..a46e71582 100644 --- a/src/ast/rewriter/mk_simplified_app.cpp +++ b/src/ast/rewriter/mk_simplified_app.cpp @@ -62,6 +62,8 @@ struct mk_simplified_app::imp { st = m_dt_rw.mk_eq_core(args[0], args[1], result); else if (s_fid == m_f_rw.get_fid()) st = m_f_rw.mk_eq_core(args[0], args[1], result); + else if (s_fid == m_ar_rw.get_fid()) + st = m_ar_rw.mk_eq_core(args[0], args[1], result); if (st != BR_FAILED) return st; diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index 966544b78..5d19c53e3 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -169,7 +169,9 @@ struct th_rewriter_cfg : public default_rewriter_cfg { st = m_dt_rw.mk_eq_core(args[0], args[1], result); else if (s_fid == m_f_rw.get_fid()) st = m_f_rw.mk_eq_core(args[0], args[1], result); - + else if (s_fid == m_ar_rw.get_fid()) + st = m_ar_rw.mk_eq_core(args[0], args[1], result); + if (st != BR_FAILED) return st; }