3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

postpone rule flushing dependent on engine

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-05-06 01:33:40 +02:00
parent 0959be0acc
commit 622484929f
5 changed files with 66 additions and 47 deletions

View file

@ -585,6 +585,9 @@ class FuncDeclRef(AstRef):
def as_ast(self): def as_ast(self):
return Z3_func_decl_to_ast(self.ctx_ref(), self.ast) return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
def as_func_decl(self):
return self.ast
def name(self): def name(self):
"""Return the name of the function declaration `self`. """Return the name of the function declaration `self`.

View file

@ -234,6 +234,7 @@ namespace datalog {
m_vars(m), m_vars(m),
m_rule_set(*this), m_rule_set(*this),
m_transformed_rule_set(*this), m_transformed_rule_set(*this),
m_rule_fmls_head(0),
m_rule_fmls(m), m_rule_fmls(m),
m_background(m), m_background(m),
m_mc(0), m_mc(0),
@ -243,8 +244,6 @@ namespace datalog {
m_last_answer(m), m_last_answer(m),
m_engine(LAST_ENGINE), m_engine(LAST_ENGINE),
m_cancel(false) { m_cancel(false) {
//register plugins for builtin tables
} }
context::~context() { context::~context() {
@ -254,6 +253,9 @@ namespace datalog {
void context::reset() { void context::reset() {
m_trail.reset(); m_trail.reset();
m_rule_set.reset(); m_rule_set.reset();
m_rule_fmls_head = 0;
m_rule_fmls.reset();
m_rule_names.reset();
m_argument_var_names.reset(); m_argument_var_names.reset();
m_preds.reset(); m_preds.reset();
m_preds_by_name.reset(); m_preds_by_name.reset();
@ -457,13 +459,18 @@ namespace datalog {
void context::flush_add_rules() { void context::flush_add_rules() {
datalog::rule_manager& rm = get_rule_manager(); datalog::rule_manager& rm = get_rule_manager();
scoped_proof_mode _scp(m, generate_proof_trace()?PGM_FINE:PGM_DISABLED); scoped_proof_mode _scp(m, generate_proof_trace()?PGM_FINE:PGM_DISABLED);
for (unsigned i = 0; i < m_rule_fmls.size(); ++i) { while (m_rule_fmls_head < m_rule_fmls.size()) {
expr* fml = m_rule_fmls[i].get(); expr* fml = m_rule_fmls[m_rule_fmls_head].get();
proof* p = generate_proof_trace()?m.mk_asserted(fml):0; proof* p = generate_proof_trace()?m.mk_asserted(fml):0;
rm.mk_rule(fml, p, m_rule_set, m_rule_names[i]); rm.mk_rule(fml, p, m_rule_set, m_rule_names[m_rule_fmls_head]);
++m_rule_fmls_head;
}
rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end();
rule_ref r(m_rule_manager);
for (; it != end; ++it) {
r = *it;
check_rule(r);
} }
m_rule_fmls.reset();
m_rule_names.reset();
} }
// //
@ -958,18 +965,21 @@ namespace datalog {
engine_type_proc(ast_manager& m): m(m), a(m), dt(m), m_engine(DATALOG_ENGINE) {} engine_type_proc(ast_manager& m): m(m), a(m), dt(m), m_engine(DATALOG_ENGINE) {}
DL_ENGINE get_engine() const { return m_engine; } DL_ENGINE get_engine() const { return m_engine; }
void operator()(expr* e) { void operator()(expr* e) {
if (is_quantifier(e)) { if (is_quantifier(e)) {
m_engine = QPDR_ENGINE; m_engine = QPDR_ENGINE;
} }
else if (a.is_int_real(e) && m_engine != QPDR_ENGINE) { else if (m_engine != QPDR_ENGINE) {
m_engine = PDR_ENGINE; if (a.is_int_real(e)) {
} m_engine = PDR_ENGINE;
else if (is_var(e) && m.is_bool(e)) { }
m_engine = PDR_ENGINE; else if (is_var(e) && m.is_bool(e)) {
} m_engine = PDR_ENGINE;
else if (dt.is_datatype(m.get_sort(e))) { }
m_engine = PDR_ENGINE; else if (dt.is_datatype(m.get_sort(e))) {
m_engine = PDR_ENGINE;
}
} }
} }
}; };
@ -1002,7 +1012,7 @@ namespace datalog {
if (m_engine == LAST_ENGINE) { if (m_engine == LAST_ENGINE) {
expr_fast_mark1 mark; expr_fast_mark1 mark;
engine_type_proc proc(m); engine_type_proc proc(m);
m_engine = DATALOG_ENGINE; m_engine = DATALOG_ENGINE;
for (unsigned i = 0; m_engine == DATALOG_ENGINE && i < m_rule_set.get_num_rules(); ++i) { for (unsigned i = 0; m_engine == DATALOG_ENGINE && i < m_rule_set.get_num_rules(); ++i) {
rule * r = m_rule_set.get_rule(i); rule * r = m_rule_set.get_rule(i);
quick_for_each_expr(proc, mark, r->get_head()); quick_for_each_expr(proc, mark, r->get_head());
@ -1011,29 +1021,38 @@ namespace datalog {
} }
m_engine = proc.get_engine(); m_engine = proc.get_engine();
} }
for (unsigned i = m_rule_fmls_head; m_engine == DATALOG_ENGINE && i < m_rule_fmls.size(); ++i) {
expr* fml = m_rule_fmls[i].get();
while (is_quantifier(fml)) {
fml = to_quantifier(fml)->get_expr();
}
quick_for_each_expr(proc, mark, fml);
m_engine = proc.get_engine();
}
} }
} }
lbool context::query(expr* query) { lbool context::query(expr* query) {
new_query(); m_mc = mk_skip_model_converter();
rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end(); m_last_status = OK;
rule_ref r(m_rule_manager); m_last_answer = 0;
for (; it != end; ++it) { switch (get_engine()) {
r = *it;
check_rule(r);
}
switch(get_engine()) {
case DATALOG_ENGINE: case DATALOG_ENGINE:
flush_add_rules();
return rel_query(query); return rel_query(query);
case PDR_ENGINE: case PDR_ENGINE:
case QPDR_ENGINE: case QPDR_ENGINE:
flush_add_rules();
return pdr_query(query); return pdr_query(query);
case BMC_ENGINE: case BMC_ENGINE:
case QBMC_ENGINE: case QBMC_ENGINE:
flush_add_rules();
return bmc_query(query); return bmc_query(query);
case TAB_ENGINE: case TAB_ENGINE:
flush_add_rules();
return tab_query(query); return tab_query(query);
case CLP_ENGINE: case CLP_ENGINE:
flush_add_rules();
return clp_query(query); return clp_query(query);
default: default:
UNREACHABLE(); UNREACHABLE();
@ -1041,14 +1060,6 @@ namespace datalog {
} }
} }
void context::new_query() {
m_mc = mk_skip_model_converter();
flush_add_rules();
m_last_status = OK;
m_last_answer = 0;
}
model_ref context::get_model() { model_ref context::get_model() {
switch(get_engine()) { switch(get_engine()) {
case PDR_ENGINE: case PDR_ENGINE:
@ -1277,7 +1288,7 @@ namespace datalog {
datalog::rule_manager& rm = get_rule_manager(); datalog::rule_manager& rm = get_rule_manager();
// ensure that rules are all using bound variables. // ensure that rules are all using bound variables.
for (unsigned i = 0; i < m_rule_fmls.size(); ++i) { for (unsigned i = m_rule_fmls_head; i < m_rule_fmls.size(); ++i) {
ptr_vector<sort> sorts; ptr_vector<sort> sorts;
get_free_vars(m_rule_fmls[i].get(), sorts); get_free_vars(m_rule_fmls[i].get(), sorts);
if (!sorts.empty()) { if (!sorts.empty()) {
@ -1295,7 +1306,7 @@ namespace datalog {
rules.push_back(fml); rules.push_back(fml);
names.push_back((*it)->name()); names.push_back((*it)->name());
} }
for (unsigned i = 0; i < m_rule_fmls.size(); ++i) { for (unsigned i = m_rule_fmls_head; i < m_rule_fmls.size(); ++i) {
rules.push_back(m_rule_fmls[i].get()); rules.push_back(m_rule_fmls[i].get());
names.push_back(m_rule_names[i]); names.push_back(m_rule_names[i]);
} }

View file

@ -114,6 +114,7 @@ namespace datalog {
pred2syms m_argument_var_names; pred2syms m_argument_var_names;
rule_set m_rule_set; rule_set m_rule_set;
rule_set m_transformed_rule_set; rule_set m_transformed_rule_set;
unsigned m_rule_fmls_head;
expr_ref_vector m_rule_fmls; expr_ref_vector m_rule_fmls;
svector<symbol> m_rule_names; svector<symbol> m_rule_names;
expr_ref_vector m_background; expr_ref_vector m_background;
@ -482,8 +483,6 @@ namespace datalog {
void ensure_rel(); void ensure_rel();
void new_query();
lbool rel_query(expr* query); lbool rel_query(expr* query);
lbool pdr_query(expr* query); lbool pdr_query(expr* query);

View file

@ -120,12 +120,11 @@ namespace datalog {
obj_map<rule, rule*>::iterator end = m_rule2slice.end(); obj_map<rule, rule*>::iterator end = m_rule2slice.end();
expr_ref fml(m); expr_ref fml(m);
for (; it != end; ++it) { for (; it != end; ++it) {
TRACE("dl",
it->m_key->display(m_ctx, tout << "orig:\n");
it->m_value->display(m_ctx, tout << "new:\n"););
it->m_value->to_formula(fml); it->m_value->to_formula(fml);
m_pinned_exprs.push_back(fml); m_pinned_exprs.push_back(fml);
TRACE("dl",
tout << "orig: " << mk_pp(fml, m) << "\n";
it->m_value->display(m_ctx, tout << "new:\n"););
m_sliceform2rule.insert(fml, it->m_key); m_sliceform2rule.insert(fml, it->m_key);
} }
} }
@ -202,9 +201,10 @@ namespace datalog {
proof* p0_new = m_new_proof.find(p0); proof* p0_new = m_new_proof.find(p0);
expr* fact0 = m.get_fact(p0); expr* fact0 = m.get_fact(p0);
TRACE("dl", tout << "fact0: " << mk_pp(fact0, m) << "\n";); TRACE("dl", tout << "fact0: " << mk_pp(fact0, m) << "\n";);
rule* orig0 = m_sliceform2rule.find(fact0); rule* orig0;
/* rule* slice0 = */ m_rule2slice.find(orig0); if (!m_sliceform2rule.find(fact0, orig0)) {
/* unsigned_vector const& renaming0 = m_renaming.find(orig0); */ return false;
}
premises.push_back(p0_new); premises.push_back(p0_new);
rule_ref r1(rm), r2(rm), r3(rm); rule_ref r1(rm), r2(rm), r3(rm);
r1 = orig0; r1 = orig0;
@ -214,9 +214,10 @@ namespace datalog {
proof* p1_new = m_new_proof.find(p1); proof* p1_new = m_new_proof.find(p1);
expr* fact1 = m.get_fact(p1); expr* fact1 = m.get_fact(p1);
TRACE("dl", tout << "fact1: " << mk_pp(fact1, m) << "\n";); TRACE("dl", tout << "fact1: " << mk_pp(fact1, m) << "\n";);
rule* orig1 = m_sliceform2rule.find(fact1); rule* orig1 = 0;
/* rule* slice1 = */ m_rule2slice.find(orig1); if (!m_sliceform2rule.find(fact1, orig1)) {
/* unsigned_vector const& renaming1 = m_renaming.find(orig1); TBD */ return false;
}
premises.push_back(p1_new); premises.push_back(p1_new);
// TODO: work with substitutions. // TODO: work with substitutions.
@ -241,6 +242,9 @@ namespace datalog {
proof* new_p = m.mk_hyper_resolve(premises.size(), premises.c_ptr(), concl, positions, substs); proof* new_p = m.mk_hyper_resolve(premises.size(), premises.c_ptr(), concl, positions, substs);
m_pinned_exprs.push_back(new_p); m_pinned_exprs.push_back(new_p);
m_pinned_rules.push_back(r1.get()); m_pinned_rules.push_back(r1.get());
TRACE("dl",
tout << "orig: " << mk_pp(slice_concl, m) << "\n";
r1->display(m_ctx, tout << "new:"););
m_sliceform2rule.insert(slice_concl, r1.get()); m_sliceform2rule.insert(slice_concl, r1.get());
m_rule2slice.insert(r1.get(), 0); m_rule2slice.insert(r1.get(), 0);
m_renaming.insert(r1.get(), unsigned_vector()); m_renaming.insert(r1.get(), unsigned_vector());

View file

@ -32,6 +32,7 @@ Revision History:
#include "dl_mk_slice.h" #include "dl_mk_slice.h"
#include "dl_mk_unfold.h" #include "dl_mk_unfold.h"
#include "dl_mk_coalesce.h" #include "dl_mk_coalesce.h"
#include "model_smt2_pp.h"
using namespace pdr; using namespace pdr;
@ -134,10 +135,10 @@ lbool dl_interface::query(expr * query) {
} }
query_pred = m_ctx.get_rules().get_output_predicate(); query_pred = m_ctx.get_rules().get_output_predicate();
IF_VERBOSE(2, m_ctx.display_rules(verbose_stream());); IF_VERBOSE(2, m_ctx.display_rules(verbose_stream()););
m_pdr_rules.replace_rules(m_ctx.get_rules()); m_pdr_rules.replace_rules(m_ctx.get_rules());
m_pdr_rules.close(); m_pdr_rules.close();
m_ctx.record_transformed_rules();
m_ctx.reopen(); m_ctx.reopen();
m_ctx.replace_rules(old_rules); m_ctx.replace_rules(old_rules);
@ -151,6 +152,7 @@ lbool dl_interface::query(expr * query) {
if (m_pdr_rules.get_rules().empty()) { if (m_pdr_rules.get_rules().empty()) {
m_context->set_unsat(); m_context->set_unsat();
IF_VERBOSE(1, model_smt2_pp(verbose_stream(), m, *m_context->get_model(),0););
return l_false; return l_false;
} }