3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-29 02:39:24 +00:00

move quantifier hoist routines to quant_hoist

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-03-19 15:00:23 -07:00
parent b0787024c7
commit 5455704af2
8 changed files with 335 additions and 53 deletions

View file

@ -107,41 +107,6 @@ namespace datalog {
mk_rule_core(fml1, rules, name);
}
//
// Hoist quantifier from rule (universal) or query (existential)
//
unsigned rule_manager::hoist_quantifier(bool is_forall, expr_ref& fml, svector<symbol>* names) {
unsigned index = var_counter().get_next_var(fml);
while (is_quantifier(fml) && (is_forall == to_quantifier(fml)->is_forall())) {
quantifier* q = to_quantifier(fml);
index += q->get_num_decls();
if (names) {
names->append(q->get_num_decls(), q->get_decl_names());
}
fml = q->get_expr();
}
if (!has_quantifiers(fml)) {
return index;
}
app_ref_vector vars(m);
quantifier_hoister qh(m);
qh.pull_quantifier(is_forall, fml, vars);
if (vars.empty()) {
return index;
}
// replace vars by de-bruijn indices
expr_safe_replace rep(m);
for (unsigned i = 0; i < vars.size(); ++i) {
app* v = vars[i].get();
if (names) {
names->push_back(v->get_decl()->get_name());
}
rep.insert(v, m.mk_var(index++,m.get_sort(v)));
}
rep(fml);
return index;
}
void rule_manager::mk_rule_core(expr* _fml, rule_ref_vector& rules, symbol const& name) {
app_ref_vector body(m);
@ -149,7 +114,8 @@ namespace datalog {
expr_ref e(m), fml(_fml, m);
svector<bool> is_negated;
TRACE("dl_rule", tout << mk_pp(fml, m) << "\n";);
unsigned index = hoist_quantifier(true, fml, 0);
quantifier_hoister qh(m);
unsigned index = qh.pull_quantifier(true, fml, 0);
check_app(fml);
head = to_app(fml);
@ -225,7 +191,8 @@ namespace datalog {
// Add implicit variables.
// Remove existential prefix.
bind_variables(query, false, q);
hoist_quantifier(false, q, &names);
quantifier_hoister qh(m);
qh.pull_quantifier(false, q, &names);
// retrieve free variables.
get_free_vars(q, vars);
if (vars.contains(static_cast<sort*>(0))) {
@ -1115,3 +1082,4 @@ namespace datalog {
};

View file

@ -81,8 +81,6 @@ namespace datalog {
void mk_rule_core(expr* fml, rule_ref_vector& rules, symbol const& name);
unsigned hoist_quantifier(bool is_forall, expr_ref& fml, svector<symbol>* names);
/**
\brief Perform cheap quantifier elimination to reduce the number of variables in the interpreted tail.
*/

View file

@ -1,102 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
expr_safe_replace.cpp
Abstract:
Version of expr_replace/expr_substitution that is safe for quantifiers.
Author:
Nikolaj Bjorner (nbjorner) 2012-11-30
Revision History:
--*/
#include "expr_safe_replace.h"
#include "rewriter.h"
void expr_safe_replace::insert(expr* src, expr* dst) {
m_src.push_back(src);
m_dst.push_back(dst);
m_subst.insert(src, dst);
}
void expr_safe_replace::operator()(expr* e, expr_ref& res) {
obj_map<expr,expr*> cache;
ptr_vector<expr> todo, args;
expr_ref_vector refs(m);
todo.push_back(e);
expr* a, *b, *d;
todo.push_back(e);
while (!todo.empty()) {
a = todo.back();
if (cache.contains(a)) {
todo.pop_back();
}
else if (m_subst.find(a, b)) {
cache.insert(a, b);
todo.pop_back();
}
else if (is_var(a)) {
cache.insert(a, a);
todo.pop_back();
}
else if (is_app(a)) {
app* c = to_app(a);
unsigned n = c->get_num_args();
args.reset();
for (unsigned i = 0; i < n; ++i) {
if (cache.find(c->get_arg(i), d)) {
args.push_back(d);
}
else {
todo.push_back(c->get_arg(i));
}
}
if (args.size() == n) {
b = m.mk_app(c->get_decl(), args.size(), args.c_ptr());
refs.push_back(b);
cache.insert(a, b);
todo.pop_back();
}
}
else {
SASSERT(is_quantifier(a));
quantifier* q = to_quantifier(a);
expr_safe_replace replace(m);
var_shifter shift(m);
expr_ref new_body(m), src(m), dst(m), tmp(m);
expr_ref_vector pats(m), nopats(m);
unsigned num_decls = q->get_num_decls();
for (unsigned i = 0; i < m_src.size(); ++i) {
shift(m_src[i].get(), num_decls, src);
shift(m_dst[i].get(), num_decls, dst);
replace.insert(src, dst);
}
unsigned np = q->get_num_patterns();
for (unsigned i = 0; i < np; ++i) {
replace(q->get_pattern(i), tmp);
pats.push_back(tmp);
}
np = q->get_num_no_patterns();
for (unsigned i = 0; i < np; ++i) {
replace(q->get_no_pattern(i), tmp);
nopats.push_back(tmp);
}
replace(q->get_expr(), new_body);
b = m.update_quantifier(q, pats.size(), pats.c_ptr(), nopats.size(), nopats.c_ptr(), new_body);
refs.push_back(b);
cache.insert(a, b);
todo.pop_back();
}
}
res = cache.find(e);
}

View file

@ -1,43 +0,0 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
expr_safe_replace.h
Abstract:
Version of expr_replace/expr_substitution that is safe for quantifiers.
Author:
Nikolaj Bjorner (nbjorner) 2012-11-30
Revision History:
--*/
#ifndef __EXPR_SAFE_REPLACE_H__
#define __EXPR_SAFE_REPLACE_H__
#include "ast.h"
class expr_safe_replace {
ast_manager& m;
expr_ref_vector m_src;
expr_ref_vector m_dst;
obj_map<expr, expr*> m_subst;
public:
expr_safe_replace(ast_manager& m): m(m), m_src(m), m_dst(m) {}
void insert(expr* src, expr* dst);
void operator()(expr_ref& e) { (*this)(e.get(), e); }
void operator()(expr* src, expr_ref& e);
};
#endif /* __EXPR_SAFE_REPLACE_H__ */