3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-09-05 09:37:44 +00:00

Added rewriter.ignore_patterns_on_ground_qbody option to disable simplification of quantifiers that have their universals appear only in patterns, but otherwise have a ground body.

This commit is contained in:
Christoph M. Wintersteiger 2017-04-07 21:19:20 +01:00
parent 9a757ffffe
commit 27a1758857
19 changed files with 795 additions and 776 deletions

View file

@ -47,14 +47,14 @@ Revision History:
namespace datalog {
rule_manager::rule_manager(context& ctx)
rule_manager::rule_manager(context& ctx)
: m(ctx.get_manager()),
m_ctx(ctx),
m_body(m),
m_head(m),
m_args(m),
m_hnf(m),
m_qe(m),
m_qe(m, params_ref()),
m_rwr(m),
m_ufproc(m) {}
@ -98,7 +98,7 @@ namespace datalog {
var_idx_set& rule_manager::finalize_collect_vars() {
unsigned sz = m_free_vars.size();
for (unsigned i = 0; i < sz; ++i) {
if (m_free_vars[i]) m_var_idx.insert(i);
if (m_free_vars[i]) m_var_idx.insert(i);
}
return m_var_idx;
}
@ -139,7 +139,7 @@ namespace datalog {
}
void rule_manager::mk_rule(expr* fml, proof* p, rule_set& rules, symbol const& name) {
void rule_manager::mk_rule(expr* fml, proof* p, rule_set& rules, symbol const& name) {
scoped_proof_mode _sc(m, m_ctx.generate_proof_trace()?PGM_FINE:PGM_DISABLED);
proof_ref pr(p, m);
expr_ref fml1(m);
@ -147,7 +147,7 @@ namespace datalog {
if (fml1 != fml && pr) {
pr = m.mk_asserted(fml1);
}
remove_labels(fml1, pr);
remove_labels(fml1, pr);
mk_rule_core(fml1, pr, rules, name);
}
@ -162,7 +162,7 @@ namespace datalog {
else {
is_negated.push_back(false);
}
}
}
}
void rule_manager::mk_rule_core(expr* fml, proof* p, rule_set& rules, symbol const& name) {
@ -170,7 +170,7 @@ namespace datalog {
proof_ref_vector prs(m);
m_hnf.reset();
m_hnf.set_name(name);
m_hnf(fml, p, fmls, prs);
for (unsigned i = 0; i < m_hnf.get_fresh_predicates().size(); ++i) {
m_ctx.register_predicate(m_hnf.get_fresh_predicates()[i], false);
@ -181,7 +181,7 @@ namespace datalog {
}
void rule_manager::mk_horn_rule(expr* fml, proof* p, rule_set& rules, symbol const& name) {
m_body.reset();
m_neg.reset();
unsigned index = extract_horn(fml, m_body, m_head);
@ -208,13 +208,13 @@ namespace datalog {
}
else if (is_quantifier(fml1)) {
p = m.mk_modus_ponens(p, m.mk_symmetry(m.mk_der(to_quantifier(fml1), fml)));
}
}
else {
p = m.mk_modus_ponens(p, m.mk_rewrite(fml, fml1));
}
}
if (m_ctx.fix_unbound_vars()) {
if (m_ctx.fix_unbound_vars()) {
fix_unbound_vars(r, true);
}
@ -242,10 +242,10 @@ namespace datalog {
for (unsigned i = 0; i < m_args.size(); ++i) {
body.push_back(ensure_app(m_args[i].get()));
}
}
}
else {
head = ensure_app(fml);
}
}
return index;
}
@ -262,12 +262,12 @@ namespace datalog {
func_decl* rule_manager::mk_query(expr* query, rule_set& rules) {
TRACE("dl", tout << mk_pp(query, m) << "\n";);
ptr_vector<sort> vars;
svector<symbol> names;
app_ref_vector body(m);
expr_ref q(m);
// Add implicit variables.
// Remove existential prefix.
bind_variables(query, false, q);
@ -278,7 +278,7 @@ namespace datalog {
m_free_vars(q);
vars.append(m_free_vars.size(), m_free_vars.c_ptr());
if (vars.contains(static_cast<sort*>(0))) {
var_subst sub(m, false);
var_subst sub(m, false);
expr_ref_vector args(m);
// [s0, 0, s2, ..]
// [0 -> 0, 1 -> x, 2 -> 1, ..]
@ -313,7 +313,7 @@ namespace datalog {
}
}
// we want outermost declared variable first to
// we want outermost declared variable first to
// follow order of quantified variables so we reverse vars.
while (vars.size() > names.size()) {
names.push_back(symbol(names.size()));
@ -321,9 +321,9 @@ namespace datalog {
vars.reverse();
names.reverse();
func_decl* qpred = m_ctx.mk_fresh_head_predicate(symbol("query"), symbol(), vars.size(), vars.c_ptr(), body_pred);
m_ctx.register_predicate(qpred, false);
m_ctx.register_predicate(qpred, false);
rules.set_output_predicate(qpred);
if (m_ctx.get_model_converter()) {
filter_model_converter* mc = alloc(filter_model_converter, m);
mc->insert(qpred);
@ -366,7 +366,7 @@ namespace datalog {
for (unsigned i = 0; i < r.size(); ++i) {
body.push_back(ensure_app(r[i].get()));
}
}
}
void rule_manager::hoist_compound(unsigned& num_bound, app_ref& fml, app_ref_vector& body) {
@ -440,7 +440,7 @@ namespace datalog {
if (is_quantifier(e)) {
q = to_quantifier(e);
return q->is_forall();
}
}
return false;
}
@ -454,7 +454,7 @@ namespace datalog {
return app_ref(m.mk_eq(e, m.mk_true()), m);
}
}
void rule_manager::check_app(expr* e) {
if (!is_app(e)) {
std::ostringstream out;
@ -481,7 +481,7 @@ namespace datalog {
bool has_neg = false;
for (unsigned i = 0; i < n; i++) {
bool is_neg = (is_negated != 0 && is_negated[i]);
bool is_neg = (is_negated != 0 && is_negated[i]);
app * curr = tail[i];
if (is_neg && !m_ctx.is_predicate(curr)) {
@ -571,7 +571,7 @@ namespace datalog {
case 1: fml = m.mk_implies(body[0].get(), fml); break;
default: fml = m.mk_implies(m.mk_and(body.size(), body.c_ptr()), fml); break;
}
m_free_vars(fml);
if (m_free_vars.empty()) {
return;
@ -579,7 +579,7 @@ namespace datalog {
svector<symbol> names;
used_symbols<> us;
m_free_vars.set_default_sort(m.mk_bool_sort());
us(fml);
m_free_vars.reverse();
for (unsigned j = 0, i = 0; i < m_free_vars.size(); ++j) {
@ -594,8 +594,8 @@ namespace datalog {
++i;
}
}
}
fml = m.mk_forall(m_free_vars.size(), m_free_vars.c_ptr(), names.c_ptr(), fml);
}
fml = m.mk_forall(m_free_vars.size(), m_free_vars.c_ptr(), names.c_ptr(), fml);
}
std::ostream& rule_manager::display_smt2(rule const& r, std::ostream & out) {
@ -749,7 +749,7 @@ namespace datalog {
quant_tail = m.mk_exists(q_var_cnt, qsorts.c_ptr(), qnames.c_ptr(), unbound_tail_pre_quant);
if (try_quantifier_elimination) {
TRACE("dl_rule_unbound_fix_pre_qe",
TRACE("dl_rule_unbound_fix_pre_qe",
tout<<"rule: ";
r->display(m_ctx, tout);
tout<<"tail with unbound vars: "<<mk_pp(unbound_tail, m)<<"\n";
@ -764,7 +764,7 @@ namespace datalog {
fixed_tail = quant_tail;
}
TRACE("dl_rule_unbound_fix",
TRACE("dl_rule_unbound_fix",
tout<<"rule: ";
r->display(m_ctx, tout);
tout<<"tail with unbound vars: "<<mk_pp(unbound_tail, m)<<"\n";
@ -796,7 +796,7 @@ namespace datalog {
to_formula(new_rule, fml);
scoped_proof _sc(m);
proof* p = m.mk_rewrite(m.get_fact(old_rule.get_proof()), fml);
new_rule.set_proof(m, m.mk_modus_ponens(old_rule.get_proof(), p));
new_rule.set_proof(m, m.mk_modus_ponens(old_rule.get_proof(), p));
}
}
@ -824,7 +824,7 @@ namespace datalog {
}
r = mk(new_head.get(), new_tail.size(), new_tail.c_ptr(), tail_neg.c_ptr(), r->name(), false);
// keep old variable indices around so we can compose with substitutions.
// keep old variable indices around so we can compose with substitutions.
// r->norm_vars(*this);
}
@ -835,7 +835,7 @@ namespace datalog {
void rule_manager::check_valid_head(expr * head) const {
SASSERT(head);
if (!m_ctx.is_predicate(head)) {
std::ostringstream out;
out << "Illegal head. The head predicate needs to be uninterpreted and registered (as recursive) " << mk_pp(head, m);
@ -874,14 +874,14 @@ namespace datalog {
m.get_allocator().deallocate(get_obj_size(n), this);
}
void rule::set_proof(ast_manager& m, proof* p) {
void rule::set_proof(ast_manager& m, proof* p) {
if (p) {
m.inc_ref(p);
m.inc_ref(p);
}
if (m_proof) {
m.dec_ref(m_proof);
m.dec_ref(m_proof);
}
m_proof = p;
m_proof = p;
}
bool rule::is_in_tail(const func_decl * p, bool only_positive) const {
@ -896,7 +896,7 @@ namespace datalog {
//
// non-predicates may appear only in the interpreted tail, it is therefore
// non-predicates may appear only in the interpreted tail, it is therefore
// sufficient only to check the tail.
//
bool rule_manager::has_uninterpreted_non_predicates(rule const& r, func_decl*& f) const {
@ -911,7 +911,7 @@ namespace datalog {
//
// Quantifiers may appear only in the interpreted tail, it is therefore
// Quantifiers may appear only in the interpreted tail, it is therefore
// sufficient only to check the interpreted tail.
//
void rule_manager::has_quantifiers(rule const& r, bool& existential, bool& universal) const {
@ -945,7 +945,7 @@ namespace datalog {
unsigned sz = get_tail_size();
for (unsigned i = 0; i < sz; ++i) {
used.process(get_tail(i));
}
}
}
void rule::get_vars(ast_manager& m, ptr_vector<sort>& sorts) const {
@ -994,13 +994,13 @@ namespace datalog {
app * old_tail = get_tail(i);
expr_ref new_tail_e(m);
vs(old_tail, subst_vals.size(), subst_vals.c_ptr(), new_tail_e);
bool sign = is_neg_tail(i);
bool sign = is_neg_tail(i);
m.inc_ref(new_tail_e);
m.dec_ref(old_tail);
m_tail[i] = TAG(app *, to_app(new_tail_e), sign);
}
}
void rule::display(context & ctx, std::ostream & out) const {
ast_manager & m = ctx.get_manager();
//out << mk_pp(m_head, m);
@ -1068,7 +1068,7 @@ namespace datalog {
}
};