From ca74b2d6cf05bdcef9daeea99c062762d523abbc Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner <nbjorner@microsoft.com> Date: Fri, 1 Feb 2013 10:36:23 -0800 Subject: [PATCH] towards acceleration Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> --- src/muz_qe/tab_context.cpp | 79 ++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index 333a96de0..72727bea8 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -1048,7 +1048,6 @@ namespace tb { class unifier { ast_manager& m; - datalog::context& m_ctx; ::unifier m_unifier; substitution m_S1; var_subst m_S2; @@ -1056,9 +1055,8 @@ namespace tb { expr_ref_vector m_sub1; expr_ref_vector m_sub2; public: - unifier(ast_manager& m, datalog::context& ctx): + unifier(ast_manager& m): m(m), - m_ctx(ctx), m_unifier(m), m_S1(m), m_S2(m, false), @@ -1066,8 +1064,8 @@ namespace tb { m_sub1(m), m_sub2(m) {} - bool operator()(ref<clause>& tgt, ref<clause>& src, bool compute_subst, ref<clause>& result) { - return unify(*tgt, *src, compute_subst, result); + bool operator()(ref<clause>& tgt, unsigned idx, ref<clause>& src, bool compute_subst, ref<clause>& result) { + return unify(*tgt, idx, *src, compute_subst, result); } expr_ref_vector get_rule_subst(bool is_tgt) { @@ -1079,10 +1077,9 @@ namespace tb { } } - bool unify(clause const& tgt, clause const& src, bool compute_subst, ref<clause>& result) { + bool unify(clause const& tgt, unsigned idx, clause const& src, bool compute_subst, ref<clause>& result) { qe_lite qe(m); reset(); - unsigned idx = tgt.get_predicate_index(); SASSERT(tgt.get_predicate(idx)->get_decl() == src.get_head()->get_decl()); unsigned var_cnt = std::max(tgt.get_num_vars(), src.get_num_vars()); m_S1.reserve(2, var_cnt); @@ -1101,10 +1098,12 @@ namespace tb { m_S1.apply(2, delta, expr_offset(tgt.get_predicate(i), 0), tmp); predicates.push_back(to_app(tmp)); } - } - for (unsigned i = 0; i < src.get_num_predicates(); ++i) { - m_S1.apply(2, delta, expr_offset(src.get_predicate(i), 1), tmp); - predicates.push_back(to_app(tmp)); + else { + for (unsigned j = 0; j < src.get_num_predicates(); ++j) { + m_S1.apply(2, delta, expr_offset(src.get_predicate(j), 1), tmp); + predicates.push_back(to_app(tmp)); + } + } } m_S1.apply(2, delta, expr_offset(tgt.get_constraint(), 0), tmp); m_S1.apply(2, delta, expr_offset(src.get_constraint(), 1), tmp2); @@ -1200,23 +1199,28 @@ namespace tb { } }; - // - // Given a clause - // P(s) :- P(t), Phi(x). - // Compute the clauses: - // acc: P(s) :- Delta(z,t), P(z), Phi(x). - // delta1: Delta(z,z). - // delta2: Delta(z,s) :- Delta(z,t), Phi(x). - // + class extract_delta { ast_manager& m; + unifier m_unifier; public: extract_delta(ast_manager& m): - m(m) + m(m), + m_unifier(m) {} - void operator()(clause const& g, ref<clause>& acc, ref<clause>& delta1, ref<clause>& delta2) { + + // + // Given a clause + // P(s) :- P(t), Phi(x). + // Compute the clauses: + // acc: P(s) :- Delta(z,t), P(z), Phi(x). + // delta1: Delta(z,z). + // delta2: Delta(z,s) :- Delta(z,t), Phi(x). + // + + void mk_delta_clauses(clause const& g, ref<clause>& acc, ref<clause>& delta1, ref<clause>& delta2) { SASSERT(g.get_num_predicates() > 0); app* p = g.get_head(); app* q = g.get_predicate(0); @@ -1260,6 +1264,31 @@ namespace tb { acc->display(verbose_stream() << "acc:\n");); } + // + // Given a sequence of clauses and inference rules + // compute a super-predicate and auxiliary clauses. + // + // P1(x) :- P2(y), R(z) + // P2(y) :- P3(z), T(u) + // P3(z) :- P1(x), U(v) + // => + // P1(x) :- P1(x), R(z), T(u), U(v) + // + + ref<clause> resolve_rules(unsigned num_clauses, clause*const* clauses, unsigned const* positions) { + ref<clause> result = clauses[0]; + ref<clause> tmp; + unsigned offset = 0; + for (unsigned i = 0; i + 1 < num_clauses; ++i) { + clause const& cl = *clauses[i+1]; + offset += positions[i]; + VERIFY (m_unifier.unify(*result, offset, cl, false, tmp)); + result = tmp; + } + return result; + } + + private: expr_ref_vector mk_fresh_vars(clause const& g) { @@ -1330,7 +1359,7 @@ namespace datalog { m_index(m), m_selection(ctx), m_solver(m, m_fparams), - m_unifier(m, ctx), + m_unifier(m), m_rules(), m_seqno(0), m_instruction(tb::SELECT_PREDICATE), @@ -1427,8 +1456,8 @@ namespace datalog { void apply_rule(ref<tb::clause>& r) { ref<tb::clause> clause = get_clause(); - ref<tb::clause> next_clause; - if (m_unifier(clause, r, false, next_clause) && + ref<tb::clause> next_clause; + if (m_unifier(clause, clause->get_predicate_index(), r, false, next_clause) && !query_is_tautology(*next_clause)) { init_clause(next_clause); unsigned subsumer = 0; @@ -1585,7 +1614,7 @@ namespace datalog { unsigned pi = parent->get_predicate_index(); func_decl* pred = parent->get_predicate(pi)->get_decl(); ref<tb::clause> rl = m_rules.get_rule(pred, p_rule); - VERIFY(m_unifier(parent, rl, true, replayed_clause)); + VERIFY(m_unifier(parent, parent->get_predicate_index(), rl, true, replayed_clause)); expr_ref_vector s1(m_unifier.get_rule_subst(true)); expr_ref_vector s2(m_unifier.get_rule_subst(false)); resolve_rule(pc, *parent, *rl, s1, s2, *clause);