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:
parent
b0787024c7
commit
5455704af2
8 changed files with 335 additions and 53 deletions
|
|
@ -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 {
|
|||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue