3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 12:08:18 +00:00

have free variable utility use a class for more efficient re-use

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-09-15 16:14:22 -07:00
parent 73070585b8
commit c09903288f
39 changed files with 300 additions and 303 deletions

View file

@ -18,12 +18,9 @@ Revision History:
--*/ --*/
#include "ast_counter.h" #include "ast_counter.h"
#include "var_subst.h"
void counter::update(unsigned el, int delta) { void counter::update(unsigned el, int delta) {
int & counter = get(el); int & counter = get(el);
SASSERT(!m_stay_non_negative || counter>=0);
SASSERT(!m_stay_non_negative || static_cast<int>(counter)>=-delta);
counter += delta; counter += delta;
} }
@ -92,16 +89,14 @@ int counter::get_max_counter_value() const {
void var_counter::count_vars(ast_manager & m, const app * pred, int coef) { void var_counter::count_vars(ast_manager & m, const app * pred, int coef) {
unsigned n = pred->get_num_args(); unsigned n = pred->get_num_args();
for (unsigned i = 0; i < n; i++) { for (unsigned i = 0; i < n; i++) {
m_sorts.reset(); m_fv(pred->get_arg(i));
m_todo.reset(); for (unsigned j = 0; j < m_fv.size(); ++j) {
m_mark.reset(); if (m_fv[j]) {
::get_free_vars(m_mark, m_todo, pred->get_arg(i), m_sorts);
for (unsigned j = 0; j < m_sorts.size(); ++j) {
if (m_sorts[j]) {
update(j, coef); update(j, coef);
} }
} }
} }
m_fv.reset();
} }

View file

@ -27,16 +27,16 @@ Revision History:
#include "ast.h" #include "ast.h"
#include "map.h" #include "map.h"
#include "uint_set.h" #include "uint_set.h"
#include "var_subst.h"
class counter { class counter {
protected: protected:
typedef u_map<int> map_impl; typedef u_map<int> map_impl;
map_impl m_data; map_impl m_data;
const bool m_stay_non_negative;
public: public:
typedef map_impl::iterator iterator; typedef map_impl::iterator iterator;
counter(bool stay_non_negative = true) : m_stay_non_negative(stay_non_negative) {} counter() {}
void reset() { m_data.reset(); } void reset() { m_data.reset(); }
iterator begin() const { return m_data.begin(); } iterator begin() const { return m_data.begin(); }
@ -69,14 +69,13 @@ public:
class var_counter : public counter { class var_counter : public counter {
protected: protected:
ptr_vector<sort> m_sorts;
expr_fast_mark1 m_visited; expr_fast_mark1 m_visited;
expr_free_vars m_fv;
ptr_vector<expr> m_todo; ptr_vector<expr> m_todo;
ast_mark m_mark;
unsigned_vector m_scopes; unsigned_vector m_scopes;
unsigned get_max_var(bool & has_var); unsigned get_max_var(bool & has_var);
public: public:
var_counter(bool stay_non_negative = true): counter(stay_non_negative) {} var_counter() {}
void count_vars(ast_manager & m, const app * t, int coef = 1); void count_vars(ast_manager & m, const app * t, int coef = 1);
unsigned get_max_var(expr* e); unsigned get_max_var(expr* e);
unsigned get_next_var(expr* e); unsigned get_next_var(expr* e);
@ -85,11 +84,10 @@ public:
class ast_counter { class ast_counter {
typedef obj_map<ast, int> map_impl; typedef obj_map<ast, int> map_impl;
map_impl m_data; map_impl m_data;
bool m_stay_non_negative;
public: public:
typedef map_impl::iterator iterator; typedef map_impl::iterator iterator;
ast_counter(bool stay_non_negative = true) : m_stay_non_negative(stay_non_negative) {} ast_counter() {}
iterator begin() const { return m_data.begin(); } iterator begin() const { return m_data.begin(); }
iterator end() const { return m_data.end(); } iterator end() const { return m_data.end(); }
@ -99,7 +97,6 @@ class ast_counter {
} }
void update(ast * el, int delta){ void update(ast * el, int delta){
get(el) += delta; get(el) += delta;
SASSERT(!m_stay_non_negative || get(el) >= 0);
} }
void inc(ast * el) { update(el, 1); } void inc(ast * el) { update(el, 1); }

View file

@ -164,7 +164,7 @@ void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref
tout << "\n----->\n" << mk_ismt2_pp(result, m) << "\n";); tout << "\n----->\n" << mk_ismt2_pp(result, m) << "\n";);
} }
static void get_free_vars_offset(ast_mark& mark, ptr_vector<expr>& todo, unsigned offset, expr* e, ptr_vector<sort>& sorts) { static void get_free_vars_offset(expr_sparse_mark& mark, ptr_vector<expr>& todo, unsigned offset, expr* e, ptr_vector<sort>& sorts) {
todo.push_back(e); todo.push_back(e);
while (!todo.empty()) { while (!todo.empty()) {
e = todo.back(); e = todo.back();
@ -176,7 +176,7 @@ static void get_free_vars_offset(ast_mark& mark, ptr_vector<expr>& todo, unsigne
switch(e->get_kind()) { switch(e->get_kind()) {
case AST_QUANTIFIER: { case AST_QUANTIFIER: {
quantifier* q = to_quantifier(e); quantifier* q = to_quantifier(e);
ast_mark mark1; expr_sparse_mark mark1;
ptr_vector<expr> todo1; ptr_vector<expr> todo1;
get_free_vars_offset(mark1, todo1, offset+q->get_num_decls(), q->get_expr(), sorts); get_free_vars_offset(mark1, todo1, offset+q->get_num_decls(), q->get_expr(), sorts);
break; break;
@ -210,11 +210,33 @@ static void get_free_vars_offset(ast_mark& mark, ptr_vector<expr>& todo, unsigne
void get_free_vars(expr* e, ptr_vector<sort>& sorts) { void get_free_vars(expr* e, ptr_vector<sort>& sorts) {
ast_mark mark; expr_sparse_mark mark;
ptr_vector<expr> todo; ptr_vector<expr> todo;
get_free_vars_offset(mark, todo, 0, e, sorts); get_free_vars_offset(mark, todo, 0, e, sorts);
} }
void get_free_vars(ast_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts) { void get_free_vars(expr_sparse_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts) {
get_free_vars_offset(mark, todo, 0, e, sorts); get_free_vars_offset(mark, todo, 0, e, sorts);
} }
void expr_free_vars::reset() {
m_mark.reset();
m_sorts.reset();
SASSERT(m_todo.empty());
}
void expr_free_vars::set_default_sort(sort *s) {
for (unsigned i = 0; i < m_sorts.size(); ++i) {
if (!m_sorts[i]) m_sorts[i] = s;
}
}
void expr_free_vars::operator()(expr* e) {
reset();
get_free_vars_offset(m_mark, m_todo, 0, e, m_sorts);
}
void expr_free_vars::accumulate(expr* e) {
SASSERT(m_todo.empty());
get_free_vars_offset(m_mark, m_todo, 0, e, m_sorts);
}

View file

@ -81,9 +81,23 @@ void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref
Return the sorts of the free variables. Return the sorts of the free variables.
*/ */
void get_free_vars(expr* e, ptr_vector<sort>& sorts);
void get_free_vars(ast_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts); class expr_free_vars {
expr_sparse_mark m_mark;
ptr_vector<sort> m_sorts;
ptr_vector<expr> m_todo;
public:
void reset();
void operator()(expr* e);
void accumulate(expr* e);
bool empty() const { return m_sorts.empty(); }
unsigned size() const { return m_sorts.size(); }
sort* operator[](unsigned idx) const { return m_sorts[idx]; }
bool contains(unsigned idx) const { return idx < m_sorts.size() && m_sorts[idx] != 0; }
void set_default_sort(sort* s);
void reverse() { m_sorts.reverse(); }
sort*const* c_ptr() const { return m_sorts.c_ptr(); }
};
#endif #endif

View file

@ -334,21 +334,13 @@ namespace datalog {
else { else {
m_names.reset(); m_names.reset();
m_abstractor(0, vars.size(), reinterpret_cast<expr*const*>(vars.c_ptr()), fml, result); m_abstractor(0, vars.size(), reinterpret_cast<expr*const*>(vars.c_ptr()), fml, result);
rm.collect_vars(result); m_free_vars(result);
ptr_vector<sort>& sorts = rm.get_var_sorts(); if (m_free_vars.empty()) {
if (sorts.empty()) {
result = fml; result = fml;
} }
else { else {
for (unsigned i = 0; i < sorts.size(); ++i) { m_free_vars.set_default_sort(m.mk_bool_sort());
if (!sorts[i]) { for (unsigned i = 0; i < m_free_vars.size(); ++i) {
if (i < vars.size()) {
sorts[i] = vars[i]->get_decl()->get_range();
}
else {
sorts[i] = m.mk_bool_sort();
}
}
if (i < vars.size()) { if (i < vars.size()) {
m_names.push_back(vars[i]->get_decl()->get_name()); m_names.push_back(vars[i]->get_decl()->get_name());
} }
@ -357,8 +349,8 @@ namespace datalog {
} }
} }
quantifier_ref q(m); quantifier_ref q(m);
sorts.reverse(); m_free_vars.reverse();
q = m.mk_quantifier(is_forall, sorts.size(), sorts.c_ptr(), m_names.c_ptr(), result); q = m.mk_quantifier(is_forall, m_free_vars.size(), m_free_vars.c_ptr(), m_names.c_ptr(), result);
m_elim_unused_vars(q, result); m_elim_unused_vars(q, result);
} }
} }
@ -604,7 +596,7 @@ namespace datalog {
unsigned ut_size = r.get_uninterpreted_tail_size(); unsigned ut_size = r.get_uninterpreted_tail_size();
unsigned t_size = r.get_tail_size(); unsigned t_size = r.get_tail_size();
TRACE("dl", r.display_smt2(get_manager(), tout); tout << "\n";); TRACE("dl", get_rule_manager().display_smt2(r, tout); tout << "\n";);
for (unsigned i = ut_size; i < t_size; ++i) { for (unsigned i = ut_size; i < t_size; ++i) {
app* t = r.get_tail(i); app* t = r.get_tail(i);
TRACE("dl", tout << "checking: " << mk_ismt2_pp(t, get_manager()) << "\n";); TRACE("dl", tout << "checking: " << mk_ismt2_pp(t, get_manager()) << "\n";);
@ -1121,13 +1113,13 @@ namespace datalog {
void context::get_rules_as_formulas(expr_ref_vector& rules, expr_ref_vector& queries, svector<symbol>& names) { void context::get_rules_as_formulas(expr_ref_vector& rules, expr_ref_vector& queries, svector<symbol>& names) {
expr_ref fml(m); expr_ref fml(m);
datalog::rule_manager& rm = get_rule_manager(); 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 = m_rule_fmls_head; 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); m_free_vars(m_rule_fmls[i].get());
if (!sorts.empty()) { if (!m_free_vars.empty()) {
rm.mk_rule(m_rule_fmls[i].get(), 0, m_rule_set, m_rule_names[i]); rm.mk_rule(m_rule_fmls[i].get(), 0, m_rule_set, m_rule_names[i]);
m_rule_fmls[i] = m_rule_fmls.back(); m_rule_fmls[i] = m_rule_fmls.back();
m_rule_names[i] = m_rule_names.back(); m_rule_names[i] = m_rule_names.back();
@ -1139,7 +1131,7 @@ namespace datalog {
rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end(); rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end();
for (; it != end; ++it) { for (; it != end; ++it) {
rule* r = *it; rule* r = *it;
r->to_formula(fml); rm.to_formula(*r, fml);
func_decl* h = r->get_decl(); func_decl* h = r->get_decl();
if (m_rule_set.is_output_predicate(h)) { if (m_rule_set.is_output_predicate(h)) {
expr* body = fml; expr* body = fml;

View file

@ -191,6 +191,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;
expr_free_vars m_free_vars;
unsigned m_rule_fmls_head; 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;

View file

@ -111,16 +111,14 @@ namespace datalog {
} }
void rule_manager::reset_collect_vars() { void rule_manager::reset_collect_vars() {
m_vars.reset();
m_var_idx.reset(); m_var_idx.reset();
m_todo.reset(); m_free_vars.reset();
m_mark.reset();
} }
var_idx_set& rule_manager::finalize_collect_vars() { var_idx_set& rule_manager::finalize_collect_vars() {
unsigned sz = m_vars.size(); unsigned sz = m_free_vars.size();
for (unsigned i=0; i<sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
if (m_vars[i]) m_var_idx.insert(i); if (m_free_vars[i]) m_var_idx.insert(i);
} }
return m_var_idx; return m_var_idx;
} }
@ -157,7 +155,7 @@ namespace datalog {
} }
void rule_manager::accumulate_vars(expr* e) { void rule_manager::accumulate_vars(expr* e) {
::get_free_vars(m_mark, m_todo, e, m_vars); m_free_vars.accumulate(e);
} }
@ -188,8 +186,6 @@ namespace datalog {
} }
void rule_manager::mk_rule_core(expr* fml, proof* p, rule_set& rules, symbol const& name) { void rule_manager::mk_rule_core(expr* fml, proof* p, rule_set& rules, symbol const& name) {
DEBUG_CODE(ptr_vector<sort> sorts;
::get_free_vars(fml, sorts); );
expr_ref_vector fmls(m); expr_ref_vector fmls(m);
proof_ref_vector prs(m); proof_ref_vector prs(m);
m_hnf.reset(); m_hnf.reset();
@ -200,8 +196,6 @@ namespace datalog {
m_ctx.register_predicate(m_hnf.get_fresh_predicates()[i], false); m_ctx.register_predicate(m_hnf.get_fresh_predicates()[i], false);
} }
for (unsigned i = 0; i < fmls.size(); ++i) { for (unsigned i = 0; i < fmls.size(); ++i) {
DEBUG_CODE(ptr_vector<sort> sorts;
::get_free_vars(fmls[i].get(), sorts); );
mk_horn_rule(fmls[i].get(), prs[i].get(), rules, name); mk_horn_rule(fmls[i].get(), prs[i].get(), rules, name);
} }
} }
@ -228,7 +222,7 @@ namespace datalog {
expr_ref fml1(m); expr_ref fml1(m);
if (p) { if (p) {
r->to_formula(fml1); to_formula(*r, fml1);
if (fml1 == fml) { if (fml1 == fml) {
// no-op. // no-op.
} }
@ -246,7 +240,7 @@ namespace datalog {
if (p) { if (p) {
expr_ref fml2(m); expr_ref fml2(m);
r->to_formula(fml2); to_formula(*r, fml2);
if (fml1 != fml2) { if (fml1 != fml2) {
p = m.mk_modus_ponens(p, m.mk_rewrite(fml1, fml2)); p = m.mk_modus_ponens(p, m.mk_rewrite(fml1, fml2));
} }
@ -299,7 +293,8 @@ namespace datalog {
quantifier_hoister qh(m); quantifier_hoister qh(m);
qh.pull_quantifier(false, q, 0, &names); qh.pull_quantifier(false, q, 0, &names);
// retrieve free variables. // retrieve free variables.
get_free_vars(q, vars); m_free_vars(q);
vars.append(m_free_vars.size(), m_free_vars.c_ptr());
if (vars.contains(static_cast<sort*>(0))) { if (vars.contains(static_cast<sort*>(0))) {
var_subst sub(m, false); var_subst sub(m, false);
expr_ref_vector args(m); expr_ref_vector args(m);
@ -316,7 +311,8 @@ namespace datalog {
} }
sub(q, args.size(), args.c_ptr(), q); sub(q, args.size(), args.c_ptr(), q);
vars.reset(); vars.reset();
get_free_vars(q, vars); m_free_vars(q);
vars.append(m_free_vars.size(), m_free_vars.c_ptr());
} }
SASSERT(!vars.contains(static_cast<sort*>(0)) && "Unused variables have been eliminated"); SASSERT(!vars.contains(static_cast<sort*>(0)) && "Unused variables have been eliminated");
@ -498,11 +494,6 @@ namespace datalog {
app * * uninterp_tail = r->m_tail; //grows upwards app * * uninterp_tail = r->m_tail; //grows upwards
app * * interp_tail = r->m_tail+n; //grows downwards app * * interp_tail = r->m_tail+n; //grows downwards
DEBUG_CODE(ptr_vector<sort> sorts;
::get_free_vars(head, sorts);
for (unsigned i = 0; i < n; ++i) {
::get_free_vars(tail[i], sorts);
});
bool has_neg = false; bool has_neg = false;
@ -556,11 +547,6 @@ namespace datalog {
if (normalize) { if (normalize) {
r->norm_vars(*this); r->norm_vars(*this);
} }
DEBUG_CODE(ptr_vector<sort> sorts;
::get_free_vars(head, sorts);
for (unsigned i = 0; i < n; ++i) {
::get_free_vars(tail[i], sorts);
});
return r; return r;
} }
@ -587,6 +573,55 @@ namespace datalog {
return r; return r;
} }
void rule_manager::to_formula(rule const& r, expr_ref& fml) {
ast_manager & m = fml.get_manager();
expr_ref_vector body(m);
for (unsigned i = 0; i < r.get_tail_size(); i++) {
body.push_back(r.get_tail(i));
if (r.is_neg_tail(i)) {
body[body.size()-1] = m.mk_not(body.back());
}
}
fml = r.get_head();
switch (body.size()) {
case 0: break;
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;
}
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) {
for (char c = 'A'; i < m_free_vars.size() && c <= 'Z'; ++c) {
func_decl_ref f(m);
std::stringstream _name;
_name << c;
if (j > 0) _name << j;
symbol name(_name.str().c_str());
if (!us.contains(name)) {
names.push_back(name);
++i;
}
}
}
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) {
expr_ref fml(m);
to_formula(r, fml);
return out << mk_ismt2_pp(fml, m);
}
void rule_manager::reduce_unbound_vars(rule_ref& r) { void rule_manager::reduce_unbound_vars(rule_ref& r) {
unsigned ut_len = r->get_uninterpreted_tail_size(); unsigned ut_len = r->get_uninterpreted_tail_size();
unsigned t_len = r->get_tail_size(); unsigned t_len = r->get_tail_size();
@ -647,9 +682,7 @@ namespace datalog {
svector<bool> tail_neg; svector<bool> tail_neg;
app_ref head(r->get_head(), m); app_ref head(r->get_head(), m);
collect_rule_vars(r);
vctr.count_vars(m, head); vctr.count_vars(m, head);
ptr_vector<sort>& free_rule_vars = m_vars;
for (unsigned i = 0; i < ut_len; i++) { for (unsigned i = 0; i < ut_len; i++) {
app * t = r->get_tail(i); app * t = r->get_tail(i);
@ -658,18 +691,16 @@ namespace datalog {
tail_neg.push_back(r->is_neg_tail(i)); tail_neg.push_back(r->is_neg_tail(i));
} }
ptr_vector<sort> interp_vars;
var_idx_set unbound_vars; var_idx_set unbound_vars;
expr_ref_vector tails_with_unbound(m); expr_ref_vector tails_with_unbound(m);
for (unsigned i = ut_len; i < t_len; i++) { for (unsigned i = ut_len; i < t_len; i++) {
app * t = r->get_tail(i); app * t = r->get_tail(i);
interp_vars.reset(); m_free_vars(t);
::get_free_vars(t, interp_vars);
bool has_unbound = false; bool has_unbound = false;
unsigned iv_size = interp_vars.size(); unsigned iv_size = m_free_vars.size();
for (unsigned i=0; i<iv_size; i++) { for (unsigned i=0; i<iv_size; i++) {
if (!interp_vars[i]) { continue; } if (!m_free_vars[i]) { continue; }
if (vctr.get(i)==0) { if (vctr.get(i)==0) {
has_unbound = true; has_unbound = true;
unbound_vars.insert(i); unbound_vars.insert(i);
@ -693,16 +724,15 @@ namespace datalog {
bool_rewriter(m).mk_and(tails_with_unbound.size(), tails_with_unbound.c_ptr(), unbound_tail); bool_rewriter(m).mk_and(tails_with_unbound.size(), tails_with_unbound.c_ptr(), unbound_tail);
unsigned q_var_cnt = unbound_vars.num_elems(); unsigned q_var_cnt = unbound_vars.num_elems();
unsigned max_var = m_counter.get_max_rule_var(*r);
collect_rule_vars(r);
expr_ref_vector subst(m); expr_ref_vector subst(m);
ptr_vector<sort> qsorts; ptr_vector<sort> qsorts;
qsorts.resize(q_var_cnt); qsorts.resize(q_var_cnt);
unsigned q_idx = 0; unsigned q_idx = 0;
for (unsigned v = 0; v <= max_var; ++v) { for (unsigned v = 0; v < m_free_vars.size(); ++v) {
sort * v_sort = free_rule_vars[v]; sort * v_sort = m_free_vars[v];
if (!v_sort) { if (!v_sort) {
//this variable index is not used //this variable index is not used
continue; continue;
@ -780,7 +810,7 @@ namespace datalog {
!new_rule.get_proof() && !new_rule.get_proof() &&
old_rule.get_proof()) { old_rule.get_proof()) {
expr_ref fml(m); expr_ref fml(m);
new_rule.to_formula(fml); to_formula(new_rule, fml);
scoped_proof _sc(m); scoped_proof _sc(m);
proof* p = m.mk_rewrite(m.get_fact(old_rule.get_proof()), fml); 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));
@ -791,7 +821,7 @@ namespace datalog {
if (m_ctx.generate_proof_trace()) { if (m_ctx.generate_proof_trace()) {
scoped_proof _scp(m); scoped_proof _scp(m);
expr_ref fml(m); expr_ref fml(m);
r.to_formula(fml); to_formula(r, fml);
r.set_proof(m, m.mk_asserted(fml)); r.set_proof(m, m.mk_asserted(fml));
} }
} }
@ -1066,57 +1096,6 @@ namespace datalog {
} }
} }
void rule::to_formula(expr_ref& fml) const {
ast_manager & m = fml.get_manager();
expr_ref_vector body(m);
for (unsigned i = 0; i < m_tail_size; i++) {
body.push_back(get_tail(i));
if (is_neg_tail(i)) {
body[body.size()-1] = m.mk_not(body.back());
}
}
switch(body.size()) {
case 0: fml = m_head; break;
case 1: fml = m.mk_implies(body[0].get(), m_head); break;
default: fml = m.mk_implies(m.mk_and(body.size(), body.c_ptr()), m_head); break;
}
ptr_vector<sort> sorts;
get_free_vars(fml, sorts);
if (sorts.empty()) {
return;
}
svector<symbol> names;
used_symbols<> us;
for (unsigned i = 0; i < sorts.size(); ++i) {
if (!sorts[i]) {
sorts[i] = m.mk_bool_sort();
}
}
us(fml);
sorts.reverse();
for (unsigned j = 0, i = 0; i < sorts.size(); ++j) {
for (char c = 'A'; i < sorts.size() && c <= 'Z'; ++c) {
func_decl_ref f(m);
std::stringstream _name;
_name << c;
if (j > 0) _name << j;
symbol name(_name.str().c_str());
if (!us.contains(name)) {
names.push_back(name);
++i;
}
}
}
fml = m.mk_forall(sorts.size(), sorts.c_ptr(), names.c_ptr(), fml);
}
std::ostream& rule::display_smt2(ast_manager& m, std::ostream & out) const {
expr_ref fml(m);
to_formula(fml);
return out << mk_ismt2_pp(fml, m);
}
bool rule_eq_proc::operator()(const rule * r1, const rule * r2) const { bool rule_eq_proc::operator()(const rule * r1, const rule * r2) const {
if (r1->get_head()!=r2->get_head()) { return false; } if (r1->get_head()!=r2->get_head()) { return false; }

View file

@ -30,6 +30,7 @@ Revision History:
#include"rewriter.h" #include"rewriter.h"
#include"hnf.h" #include"hnf.h"
#include"qe_lite.h" #include"qe_lite.h"
#include"var_subst.h"
namespace datalog { namespace datalog {
@ -64,10 +65,8 @@ namespace datalog {
context& m_ctx; context& m_ctx;
rule_counter m_counter; rule_counter m_counter;
used_vars m_used; used_vars m_used;
ptr_vector<sort> m_vars;
var_idx_set m_var_idx; var_idx_set m_var_idx;
ptr_vector<expr> m_todo; expr_free_vars m_free_vars;
ast_mark m_mark;
app_ref_vector m_body; app_ref_vector m_body;
app_ref m_head; app_ref m_head;
expr_ref_vector m_args; expr_ref_vector m_args;
@ -143,7 +142,7 @@ namespace datalog {
void accumulate_vars(expr* pred); void accumulate_vars(expr* pred);
ptr_vector<sort>& get_var_sorts() { return m_vars; } // ptr_vector<sort>& get_var_sorts() { return m_vars; }
var_idx_set& get_var_idx() { return m_var_idx; } var_idx_set& get_var_idx() { return m_var_idx; }
@ -213,11 +212,14 @@ namespace datalog {
*/ */
bool is_fact(app * head) const; bool is_fact(app * head) const;
static bool is_forall(ast_manager& m, expr* e, quantifier*& q); static bool is_forall(ast_manager& m, expr* e, quantifier*& q);
rule_counter& get_counter() { return m_counter; } rule_counter& get_counter() { return m_counter; }
void to_formula(rule const& r, expr_ref& result);
std::ostream& display_smt2(rule const& r, std::ostream & out);
}; };
class rule : public accounted_object { class rule : public accounted_object {
@ -306,12 +308,8 @@ namespace datalog {
void get_vars(ast_manager& m, ptr_vector<sort>& sorts) const; void get_vars(ast_manager& m, ptr_vector<sort>& sorts) const;
void to_formula(expr_ref& result) const;
void display(context & ctx, std::ostream & out) const; void display(context & ctx, std::ostream & out) const;
std::ostream& display_smt2(ast_manager& m, std::ostream & out) const;
symbol const& name() const { return m_name; } symbol const& name() const { return m_name; }
unsigned hash() const; unsigned hash() const;

View file

@ -39,10 +39,10 @@ namespace datalog {
Each master object is also present as a key of the map, even if its master set Each master object is also present as a key of the map, even if its master set
is empty. is empty.
*/ */
deps_type m_data; deps_type m_data;
context & m_context; context & m_context;
ptr_vector<expr> m_todo; ptr_vector<expr> m_todo;
ast_mark m_visited; expr_sparse_mark m_visited;
//we need to take care with removing to avoid memory leaks //we need to take care with removing to avoid memory leaks

View file

@ -56,9 +56,9 @@ namespace datalog {
bool contains_var(expr * trm, unsigned var_idx) { bool contains_var(expr * trm, unsigned var_idx) {
ptr_vector<sort> vars; expr_free_vars fv;
::get_free_vars(trm, vars); fv(trm);
return var_idx < vars.size() && vars[var_idx] != 0; return fv.contains(var_idx);
} }
unsigned count_variable_arguments(app * pred) unsigned count_variable_arguments(app * pred)
@ -300,14 +300,15 @@ namespace datalog {
} }
void resolve_rule(replace_proof_converter* pc, rule const& r1, rule const& r2, unsigned idx, void resolve_rule(rule_manager& rm,
replace_proof_converter* pc, rule const& r1, rule const& r2, unsigned idx,
expr_ref_vector const& s1, expr_ref_vector const& s2, rule const& res) { expr_ref_vector const& s1, expr_ref_vector const& s2, rule const& res) {
if (!pc) return; if (!pc) return;
ast_manager& m = s1.get_manager(); ast_manager& m = s1.get_manager();
expr_ref fml1(m), fml2(m), fml3(m); expr_ref fml1(m), fml2(m), fml3(m);
r1.to_formula(fml1); rm.to_formula(r1, fml1);
r2.to_formula(fml2); rm.to_formula(r2, fml2);
res.to_formula(fml3); rm.to_formula(res, fml3);
vector<expr_ref_vector> substs; vector<expr_ref_vector> substs;
svector<std::pair<unsigned, unsigned> > positions; svector<std::pair<unsigned, unsigned> > positions;
substs.push_back(s1); substs.push_back(s1);
@ -337,7 +338,7 @@ namespace datalog {
pc->insert(pr); pc->insert(pr);
} }
void resolve_rule(rule const& r1, rule const& r2, unsigned idx, void resolve_rule(rule_manager& rm, rule const& r1, rule const& r2, unsigned idx,
expr_ref_vector const& s1, expr_ref_vector const& s2, rule& res) { expr_ref_vector const& s1, expr_ref_vector const& s2, rule& res) {
if (!r1.get_proof()) { if (!r1.get_proof()) {
return; return;
@ -345,7 +346,7 @@ namespace datalog {
SASSERT(r2.get_proof()); SASSERT(r2.get_proof());
ast_manager& m = s1.get_manager(); ast_manager& m = s1.get_manager();
expr_ref fml(m); expr_ref fml(m);
res.to_formula(fml); rm.to_formula(res, fml);
vector<expr_ref_vector> substs; vector<expr_ref_vector> substs;
svector<std::pair<unsigned, unsigned> > positions; svector<std::pair<unsigned, unsigned> > positions;
substs.push_back(s1); substs.push_back(s1);

View file

@ -41,6 +41,7 @@ namespace datalog {
class pentagon_relation; class pentagon_relation;
class relation_fact; class relation_fact;
class relation_signature; class relation_signature;
class rule_manager;
class verbose_action { class verbose_action {
unsigned m_lvl; unsigned m_lvl;
@ -345,17 +346,19 @@ namespace datalog {
class rule_counter : public var_counter { class rule_counter : public var_counter {
public: public:
rule_counter(bool stay_non_negative = true): var_counter(stay_non_negative) {} rule_counter(){}
void count_rule_vars(ast_manager & m, const rule * r, int coef = 1); void count_rule_vars(ast_manager & m, const rule * r, int coef = 1);
unsigned get_max_rule_var(const rule& r); unsigned get_max_rule_var(const rule& r);
}; };
void del_rule(horn_subsume_model_converter* mc, rule& r); void del_rule(horn_subsume_model_converter* mc, rule& r);
void resolve_rule(replace_proof_converter* pc, rule const& r1, rule const& r2, unsigned idx, void resolve_rule(rule_manager& rm,
replace_proof_converter* pc, rule const& r1, rule const& r2, unsigned idx,
expr_ref_vector const& s1, expr_ref_vector const& s2, rule const& res); expr_ref_vector const& s1, expr_ref_vector const& s2, rule const& res);
void resolve_rule(rule const& r1, rule const& r2, unsigned idx, void resolve_rule(rule_manager& rm,
rule const& r1, rule const& r2, unsigned idx,
expr_ref_vector const& s1, expr_ref_vector const& s2, rule& res); expr_ref_vector const& s1, expr_ref_vector const& s2, rule& res);
model_converter* mk_skip_model_converter(); model_converter* mk_skip_model_converter();

View file

@ -87,6 +87,7 @@ class hnf::imp {
expr_ref_vector m_body; expr_ref_vector m_body;
proof_ref_vector m_defs; proof_ref_vector m_defs;
contains_predicate_proc m_proc; contains_predicate_proc m_proc;
expr_free_vars m_free_vars;
public: public:
@ -350,13 +351,13 @@ private:
} }
app_ref mk_fresh_head(expr* e) { app_ref mk_fresh_head(expr* e) {
ptr_vector<sort> sorts0, sorts1; ptr_vector<sort> sorts1;
get_free_vars(e, sorts0); m_free_vars(e);
expr_ref_vector args(m); expr_ref_vector args(m);
for (unsigned i = 0; i < sorts0.size(); ++i) { for (unsigned i = 0; i < m_free_vars.size(); ++i) {
if (sorts0[i]) { if (m_free_vars[i]) {
args.push_back(m.mk_var(i, sorts0[i])); args.push_back(m.mk_var(i, m_free_vars[i]));
sorts1.push_back(sorts0[i]); sorts1.push_back(m_free_vars[i]);
} }
} }
func_decl_ref f(m); func_decl_ref f(m);

View file

@ -297,7 +297,7 @@ namespace datalog {
vector<expr_ref_vector> substs; vector<expr_ref_vector> substs;
expr_ref fml(m), concl(m); expr_ref fml(m), concl(m);
r->to_formula(fml); rm.to_formula(*r, fml);
r2 = r; r2 = r;
rm.substitute(r2, sub.size(), sub.c_ptr()); rm.substitute(r2, sub.size(), sub.c_ptr());
proof_ref p(m); proof_ref p(m);
@ -307,7 +307,7 @@ namespace datalog {
expr_ref_vector sub2 = unifier.get_rule_subst(*r2.get(), false); expr_ref_vector sub2 = unifier.get_rule_subst(*r2.get(), false);
apply_subst(sub, sub2); apply_subst(sub, sub2);
unifier.apply(*r0.get(), 0, *r2.get(), r1); unifier.apply(*r0.get(), 0, *r2.get(), r1);
r1->to_formula(concl); rm.to_formula(*r1.get(), concl);
scoped_proof _sp(m); scoped_proof _sp(m);
p = r->get_proof(); p = r->get_proof();
@ -324,7 +324,7 @@ namespace datalog {
r0 = r1; r0 = r1;
} }
else { else {
r2->to_formula(concl); rm.to_formula(*r, concl);
scoped_proof _sp(m); scoped_proof _sp(m);
p = r->get_proof(); p = r->get_proof();
if (!p) { if (!p) {
@ -488,7 +488,7 @@ namespace datalog {
return proof_ref(0, m); return proof_ref(0, m);
} }
TRACE("bmc", tout << "Predicate: " << pred->get_name() << "\n";); TRACE("bmc", tout << "Predicate: " << pred->get_name() << "\n";);
rule_manager& rm = b.m_ctx.get_rule_manager();
expr_ref prop_r(m), prop_v(m), fml(m), prop_body(m), tmp(m), body(m); expr_ref prop_r(m), prop_v(m), fml(m), prop_body(m), tmp(m), body(m);
expr_ref_vector args(m); expr_ref_vector args(m);
proof_ref_vector prs(m); proof_ref_vector prs(m);
@ -508,7 +508,7 @@ namespace datalog {
} }
} }
SASSERT(r); SASSERT(r);
r->to_formula(fml); rm.to_formula(*r, fml);
IF_VERBOSE(1, verbose_stream() << mk_pp(fml, m) << "\n";); IF_VERBOSE(1, verbose_stream() << mk_pp(fml, m) << "\n";);
prs.push_back(r->get_proof()); prs.push_back(r->get_proof());
unsigned sz = r->get_uninterpreted_tail_size(); unsigned sz = r->get_uninterpreted_tail_size();
@ -624,11 +624,12 @@ namespace datalog {
} }
expr_ref bind_vars(expr* e, expr* pat) { expr_ref bind_vars(expr* e, expr* pat) {
ptr_vector<sort> vars, sorts; ptr_vector<sort> sorts;
svector<symbol> names; svector<symbol> names;
expr_ref_vector binding(m), patterns(m); expr_ref_vector binding(m), patterns(m);
expr_ref tmp(m), head(m); expr_ref tmp(m), head(m);
get_free_vars(e, vars); expr_free_vars vars;
vars(e);
for (unsigned i = 0; i < vars.size(); ++i) { for (unsigned i = 0; i < vars.size(); ++i) {
if (vars[i]) { if (vars[i]) {
binding.push_back(m.mk_var(sorts.size(), vars[i])); binding.push_back(m.mk_var(sorts.size(), vars[i]));
@ -1028,6 +1029,7 @@ namespace datalog {
proof_ref get_proof(model_ref& md, app* trace, app* path) { proof_ref get_proof(model_ref& md, app* trace, app* path) {
datatype_util dtu(m); datatype_util dtu(m);
rule_manager& rm = b.m_ctx.get_rule_manager();
sort* trace_sort = m.get_sort(trace); sort* trace_sort = m.get_sort(trace);
func_decl* p = m_sort2pred.find(trace_sort); func_decl* p = m_sort2pred.find(trace_sort);
datalog::rule_vector const& rules = b.m_rules.get_predicate_rules(p); datalog::rule_vector const& rules = b.m_rules.get_predicate_rules(p);
@ -1046,7 +1048,7 @@ namespace datalog {
var_subst vs(m, false); var_subst vs(m, false);
mk_subst(*rules[i], path, trace, sub); mk_subst(*rules[i], path, trace, sub);
rules[i]->to_formula(fml); rm.to_formula(*rules[i], fml);
prs.push_back(rules[i]->get_proof()); prs.push_back(rules[i]->get_proof());
unsigned sz = trace->get_num_args(); unsigned sz = trace->get_num_args();
if (sub.empty() && sz == 0) { if (sub.empty() && sz == 0) {
@ -1219,7 +1221,7 @@ namespace datalog {
vector<expr_ref_vector> substs; vector<expr_ref_vector> substs;
expr_ref fml(m), concl(m); expr_ref fml(m), concl(m);
r->to_formula(fml); rm.to_formula(*r, fml);
r2 = r; r2 = r;
rm.substitute(r2, sub.size(), sub.c_ptr()); rm.substitute(r2, sub.size(), sub.c_ptr());
proof_ref p(m); proof_ref p(m);
@ -1237,7 +1239,7 @@ namespace datalog {
expr_ref_vector sub2 = unifier.get_rule_subst(*r2.get(), false); expr_ref_vector sub2 = unifier.get_rule_subst(*r2.get(), false);
apply_subst(sub, sub2); apply_subst(sub, sub2);
unifier.apply(*r0.get(), 0, *r2.get(), r1); unifier.apply(*r0.get(), 0, *r2.get(), r1);
r1->to_formula(concl); rm.to_formula(*r1.get(), concl);
scoped_proof _sp(m); scoped_proof _sp(m);
proof* premises[2] = { pr, p }; proof* premises[2] = { pr, p };
@ -1250,7 +1252,7 @@ namespace datalog {
r0 = r1; r0 = r1;
} }
else { else {
r2->to_formula(concl); rm.to_formula(*r2.get(), concl);
scoped_proof _sp(m); scoped_proof _sp(m);
if (sub.empty()) { if (sub.empty()) {
pr = p; pr = p;

View file

@ -123,14 +123,14 @@ namespace datalog {
} }
void ground(expr_ref& e) { void ground(expr_ref& e) {
ptr_vector<sort> sorts; expr_free_vars fv;
get_free_vars(e, sorts); fv(e);
if (m_ground.size() < sorts.size()) { if (m_ground.size() < fv.size()) {
m_ground.resize(sorts.size()); m_ground.resize(fv.size());
} }
for (unsigned i = 0; i < sorts.size(); ++i) { for (unsigned i = 0; i < fv.size(); ++i) {
if (sorts[i] && !m_ground[i].get()) { if (fv[i] && !m_ground[i].get()) {
m_ground[i] = m.mk_fresh_const("c",sorts[i]); m_ground[i] = m.mk_fresh_const("c", fv[i]);
} }
} }
m_var_subst(e, m_ground.size(), m_ground.c_ptr(), e); m_var_subst(e, m_ground.size(), m_ground.c_ptr(), e);

View file

@ -516,13 +516,15 @@ namespace datalog {
rule_set& old_rules = m_ctx.get_rules(); rule_set& old_rules = m_ctx.get_rules();
rm.mk_query(query, old_rules); rm.mk_query(query, old_rules);
rule_set new_rules(m_ctx); rule_set new_rules(m_ctx);
IF_VERBOSE(10, verbose_stream() << "(ddnf.preprocess)\n";);
if (!pre_process_rules(old_rules)) { if (!pre_process_rules(old_rules)) {
return l_undef; return l_undef;
} }
IF_VERBOSE(10, verbose_stream() << "(ddnf.compile)\n";);
if (!compile_rules1(old_rules, new_rules)) { if (!compile_rules1(old_rules, new_rules)) {
return l_undef; return l_undef;
} }
IF_VERBOSE(2, m_ddnfs.display(verbose_stream());); IF_VERBOSE(15, m_ddnfs.display(verbose_stream()););
dump_rules(new_rules); dump_rules(new_rules);
return l_undef; return l_undef;
@ -728,7 +730,7 @@ namespace datalog {
} }
rule* r_new = rm.mk(head, body.size(), body.c_ptr(), 0, r.name(), false); rule* r_new = rm.mk(head, body.size(), body.c_ptr(), 0, r.name(), false);
new_rules.add_rule(r_new); new_rules.add_rule(r_new);
IF_VERBOSE(2, r_new->display(m_ctx, verbose_stream());); IF_VERBOSE(20, r_new->display(m_ctx, verbose_stream()););
if (old_rules.is_output_predicate(r.get_decl())) { if (old_rules.is_output_predicate(r.get_decl())) {
new_rules.set_output_predicate(r_new->get_decl()); new_rules.set_output_predicate(r_new->get_decl());
} }

View file

@ -226,6 +226,7 @@ public:
bool query_exn = false; bool query_exn = false;
lbool status = l_undef; lbool status = l_undef;
{ {
IF_VERBOSE(10, verbose_stream() << "(query)\n";);
scoped_ctrl_c ctrlc(eh); scoped_ctrl_c ctrlc(eh);
scoped_timer timer(timeout, &eh); scoped_timer timer(timeout, &eh);
cmd_context::scoped_watch sw(ctx); cmd_context::scoped_watch sw(ctx);

View file

@ -334,7 +334,7 @@ class horn_tactic : public tactic {
datalog::rule_set::iterator it = rules.begin(), end = rules.end(); datalog::rule_set::iterator it = rules.begin(), end = rules.end();
for (; it != end; ++it) { for (; it != end; ++it) {
datalog::rule* r = *it; datalog::rule* r = *it;
r->to_formula(fml); m_ctx.get_rule_manager().to_formula(*r, fml);
(*rep)(fml); (*rep)(fml);
g->assert_expr(fml); g->assert_expr(fml);
} }

View file

@ -97,8 +97,9 @@ namespace pdr {
std::ostream& pred_transformer::display(std::ostream& out) const { std::ostream& pred_transformer::display(std::ostream& out) const {
if (!rules().empty()) out << "rules\n"; if (!rules().empty()) out << "rules\n";
datalog::rule_manager& rm = ctx.get_context().get_rule_manager();
for (unsigned i = 0; i < rules().size(); ++i) { for (unsigned i = 0; i < rules().size(); ++i) {
rules()[i]->display_smt2(m, out) << "\n"; rm.display_smt2(*rules()[i], out) << "\n";
} }
out << "transition\n" << mk_pp(transition(), m) << "\n"; out << "transition\n" << mk_pp(transition(), m) << "\n";
return out; return out;
@ -149,12 +150,13 @@ namespace pdr {
} }
datalog::rule const& pred_transformer::find_rule(model_core const& model) const { datalog::rule const& pred_transformer::find_rule(model_core const& model) const {
datalog::rule_manager& rm = ctx.get_context().get_rule_manager();
obj_map<expr, datalog::rule const*>::iterator it = m_tag2rule.begin(), end = m_tag2rule.end(); obj_map<expr, datalog::rule const*>::iterator it = m_tag2rule.begin(), end = m_tag2rule.end();
TRACE("pdr_verbose", TRACE("pdr_verbose",
for (; it != end; ++it) { for (; it != end; ++it) {
expr* pred = it->m_key; expr* pred = it->m_key;
tout << mk_pp(pred, m) << ":\n"; tout << mk_pp(pred, m) << ":\n";
if (it->m_value) it->m_value->display_smt2(m, tout) << "\n"; if (it->m_value) rm.display_smt2(*it->m_value, tout) << "\n";
} }
); );
@ -639,14 +641,14 @@ namespace pdr {
// create constants for free variables in tail. // create constants for free variables in tail.
void pred_transformer::ground_free_vars(expr* e, app_ref_vector& vars, ptr_vector<app>& aux_vars) { void pred_transformer::ground_free_vars(expr* e, app_ref_vector& vars, ptr_vector<app>& aux_vars) {
ptr_vector<sort> sorts; expr_free_vars fv;
get_free_vars(e, sorts); fv(e);
while (vars.size() < sorts.size()) { while (vars.size() < fv.size()) {
vars.push_back(0); vars.push_back(0);
} }
for (unsigned i = 0; i < sorts.size(); ++i) { for (unsigned i = 0; i < fv.size(); ++i) {
if (sorts[i] && !vars[i].get()) { if (fv[i] && !vars[i].get()) {
vars[i] = m.mk_fresh_const("aux", sorts[i]); vars[i] = m.mk_fresh_const("aux", fv[i]);
aux_vars.push_back(vars[i].get()); aux_vars.push_back(vars[i].get());
} }
} }
@ -1226,7 +1228,7 @@ namespace pdr {
} }
expr_ref fml_concl(m); expr_ref fml_concl(m);
reduced_rule->to_formula(fml_concl); rm.to_formula(*reduced_rule.get(), fml_concl);
p1 = m.mk_hyper_resolve(pfs.size(), pfs.c_ptr(), fml_concl, positions, substs); p1 = m.mk_hyper_resolve(pfs.size(), pfs.c_ptr(), fml_concl, positions, substs);
} }
@ -1558,6 +1560,7 @@ namespace pdr {
ex.to_model(model); ex.to_model(model);
decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); decl2rel::iterator it = m_rels.begin(), end = m_rels.end();
var_subst vs(m, false); var_subst vs(m, false);
expr_free_vars fv;
for (; it != end; ++it) { for (; it != end; ++it) {
ptr_vector<datalog::rule> const& rules = it->m_value->rules(); ptr_vector<datalog::rule> const& rules = it->m_value->rules();
for (unsigned i = 0; i < rules.size(); ++i) { for (unsigned i = 0; i < rules.size(); ++i) {
@ -1575,18 +1578,15 @@ namespace pdr {
fmls.push_back(r.get_tail(j)); fmls.push_back(r.get_tail(j));
} }
tmp = m.mk_and(fmls.size(), fmls.c_ptr()); tmp = m.mk_and(fmls.size(), fmls.c_ptr());
ptr_vector<sort> sorts;
svector<symbol> names; svector<symbol> names;
get_free_vars(tmp, sorts); fv(tmp);
for (unsigned i = 0; i < sorts.size(); ++i) { fv.set_default_sort(m.mk_bool_sort());
if (!sorts[i]) { for (unsigned i = 0; i < fv.size(); ++i) {
sorts[i] = m.mk_bool_sort();
}
names.push_back(symbol(i)); names.push_back(symbol(i));
} }
sorts.reverse(); fv.reverse();
if (!sorts.empty()) { if (!fv.empty()) {
tmp = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), tmp); tmp = m.mk_exists(fv.size(), fv.c_ptr(), names.c_ptr(), tmp);
} }
smt::kernel solver(m, get_fparams()); smt::kernel solver(m, get_fparams());
solver.assert_expr(tmp); solver.assert_expr(tmp);

View file

@ -558,7 +558,6 @@ namespace pdr {
{ {
expr_ref_vector conj(m), sub(m); expr_ref_vector conj(m), sub(m);
expr_ref result(m); expr_ref result(m);
ptr_vector<sort> sorts;
svector<symbol> names; svector<symbol> names;
unsigned ut_size = rule.get_uninterpreted_tail_size(); unsigned ut_size = rule.get_uninterpreted_tail_size();
unsigned t_size = rule.get_tail_size(); unsigned t_size = rule.get_tail_size();
@ -599,16 +598,15 @@ namespace pdr {
expr_ref tmp = result; expr_ref tmp = result;
var_subst(m, false)(tmp, sub.size(), sub.c_ptr(), result); var_subst(m, false)(tmp, sub.size(), sub.c_ptr(), result);
} }
get_free_vars(result, sorts); expr_free_vars fv;
for (unsigned i = 0; i < sorts.size(); ++i) { fv(result);
if (!sorts[i]) { fv.set_default_sort(m.mk_bool_sort());
sorts[i] = m.mk_bool_sort(); for (unsigned i = 0; i < fv.size(); ++i) {
} names.push_back(symbol(fv.size() - i - 1));
names.push_back(symbol(sorts.size() - i - 1));
} }
if (!sorts.empty()) { if (!fv.empty()) {
sorts.reverse(); fv.reverse();
result = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), result); result = m.mk_exists(fv.size(), fv.c_ptr(), names.c_ptr(), result);
} }
return result; return result;
} }

View file

@ -119,7 +119,7 @@ namespace pdr {
} }
void inductive_property::display(ptr_vector<datalog::rule> const& rules, std::ostream& out) const { void inductive_property::display(datalog::rule_manager& rm, ptr_vector<datalog::rule> const& rules, std::ostream& out) const {
func_decl_set bound_decls, aux_decls; func_decl_set bound_decls, aux_decls;
collect_decls_proc collect_decls(bound_decls, aux_decls); collect_decls_proc collect_decls(bound_decls, aux_decls);
@ -153,7 +153,7 @@ namespace pdr {
for (unsigned i = 0; i < rules.size(); ++i) { for (unsigned i = 0; i < rules.size(); ++i) {
out << "(push)\n"; out << "(push)\n";
out << "(assert (not\n"; out << "(assert (not\n";
rules[i]->display_smt2(m, out); rm.display_smt2(*rules[i], out);
out << "))\n"; out << "))\n";
out << "(check-sat)\n"; out << "(check-sat)\n";
out << "(pop)\n"; out << "(pop)\n";

View file

@ -70,8 +70,8 @@ namespace pdr {
expr_ref to_expr() const; expr_ref to_expr() const;
void to_model(model_ref& md) const; void to_model(model_ref& md) const;
void display(ptr_vector<datalog::rule> const& rules, std::ostream& out) const; void display(datalog::rule_manager& rm, ptr_vector<datalog::rule> const& rules, std::ostream& out) const;
}; };
class manager class manager

View file

@ -184,7 +184,7 @@ namespace datalog {
TRACE("dl", tout << "Adding unbound column " << mk_pp(pred, m_context.get_manager()) << "\n";); TRACE("dl", tout << "Adding unbound column " << mk_pp(pred, m_context.get_manager()) << "\n";);
IF_VERBOSE(3, { IF_VERBOSE(3, {
expr_ref e(m_context.get_manager()); expr_ref e(m_context.get_manager());
compiled_rule->to_formula(e); m_context.get_rule_manager().to_formula(*compiled_rule, e);
verbose_stream() << "Compiling unsafe rule column " << col_idx << "\n" verbose_stream() << "Compiling unsafe rule column " << col_idx << "\n"
<< mk_ismt2_pp(e, m_context.get_manager()) << "\n"; << mk_ismt2_pp(e, m_context.get_manager()) << "\n";
}); });
@ -641,14 +641,14 @@ namespace datalog {
if (!tail.empty()) { if (!tail.empty()) {
app_ref filter_cond(tail.size() == 1 ? to_app(tail.back()) : m.mk_and(tail.size(), tail.c_ptr()), m); app_ref filter_cond(tail.size() == 1 ? to_app(tail.back()) : m.mk_and(tail.size(), tail.c_ptr()), m);
ptr_vector<sort> filter_vars; ptr_vector<sort> filter_vars;
get_free_vars(filter_cond, filter_vars); m_free_vars(filter_cond);
// create binding // create binding
expr_ref_vector binding(m); expr_ref_vector binding(m);
binding.resize(filter_vars.size()+1); binding.resize(m_free_vars.size()+1);
for (unsigned v = 0; v < filter_vars.size(); ++v) { for (unsigned v = 0; v < m_free_vars.size(); ++v) {
if (!filter_vars[v]) if (!m_free_vars[v])
continue; continue;
int2ints::entry * entry = var_indexes.find_core(v); int2ints::entry * entry = var_indexes.find_core(v);
@ -657,7 +657,7 @@ namespace datalog {
src_col = entry->get_data().m_value.back(); src_col = entry->get_data().m_value.back();
} else { } else {
// we have an unbound variable, so we add an unbound column for it // we have an unbound variable, so we add an unbound column for it
relation_sort unbound_sort = filter_vars[v]; relation_sort unbound_sort = m_free_vars[v];
reg_idx new_reg; reg_idx new_reg;
bool new_dealloc; bool new_dealloc;
@ -674,19 +674,18 @@ namespace datalog {
entry->get_data().m_value.push_back(src_col); entry->get_data().m_value.push_back(src_col);
} }
relation_sort var_sort = m_reg_signatures[filtered_res][src_col]; relation_sort var_sort = m_reg_signatures[filtered_res][src_col];
binding[filter_vars.size()-v] = m.mk_var(src_col, var_sort); binding[m_free_vars.size()-v] = m.mk_var(src_col, var_sort);
} }
// check if there are any columns to remove // check if there are any columns to remove
unsigned_vector remove_columns; unsigned_vector remove_columns;
{ {
unsigned_vector var_idx_to_remove; unsigned_vector var_idx_to_remove;
ptr_vector<sort> vars; m_free_vars(r->get_head());
get_free_vars(r->get_head(), vars);
for (int2ints::iterator I = var_indexes.begin(), E = var_indexes.end(); for (int2ints::iterator I = var_indexes.begin(), E = var_indexes.end();
I != E; ++I) { I != E; ++I) {
unsigned var_idx = I->m_key; unsigned var_idx = I->m_key;
if (!vars.get(var_idx, 0)) { if (!m_free_vars.contains(var_idx)) {
unsigned_vector & cols = I->m_value; unsigned_vector & cols = I->m_value;
for (unsigned i = 0; i < cols.size(); ++i) { for (unsigned i = 0; i < cols.size(); ++i) {
remove_columns.push_back(cols[i]); remove_columns.push_back(cols[i]);
@ -745,10 +744,9 @@ namespace datalog {
unsigned ft_len=r->get_tail_size(); //full tail unsigned ft_len=r->get_tail_size(); //full tail
for(unsigned tail_index=ut_len; tail_index<ft_len; tail_index++) { for(unsigned tail_index=ut_len; tail_index<ft_len; tail_index++) {
app * t = r->get_tail(tail_index); app * t = r->get_tail(tail_index);
ptr_vector<sort> t_vars; m_free_vars(t);
::get_free_vars(t, t_vars);
if(t_vars.empty()) { if (m_free_vars.empty()) {
expr_ref simplified(m); expr_ref simplified(m);
m_context.get_rewriter()(t, simplified); m_context.get_rewriter()(t, simplified);
if(m.is_true(simplified)) { if(m.is_true(simplified)) {
@ -761,23 +759,22 @@ namespace datalog {
} }
//determine binding size //determine binding size
while (!t_vars.back()) {
t_vars.pop_back(); unsigned max_var = m_free_vars.size();
} while (max_var > 0 && !m_free_vars[max_var-1]) --max_var;
unsigned max_var = t_vars.size();
//create binding //create binding
expr_ref_vector binding(m); expr_ref_vector binding(m);
binding.resize(max_var+1); binding.resize(max_var);
for(unsigned v = 0; v < t_vars.size(); ++v) { for(unsigned v = 0; v < max_var; ++v) {
if (!t_vars[v]) { if (!m_free_vars[v]) {
continue; continue;
} }
int2ints::entry * e = var_indexes.find_core(v); int2ints::entry * e = var_indexes.find_core(v);
if(!e) { if(!e) {
//we have an unbound variable, so we add an unbound column for it //we have an unbound variable, so we add an unbound column for it
relation_sort unbound_sort = t_vars[v]; relation_sort unbound_sort = m_free_vars[v];
reg_idx new_reg; reg_idx new_reg;
TRACE("dl", tout << mk_pp(head_pred, m_context.get_manager()) << "\n";); TRACE("dl", tout << mk_pp(head_pred, m_context.get_manager()) << "\n";);

View file

@ -111,12 +111,13 @@ namespace datalog {
*/ */
instruction_block & m_top_level_code; instruction_block & m_top_level_code;
pred2idx m_pred_regs; pred2idx m_pred_regs;
reg_idx m_new_reg; reg_idx m_new_reg;
vector<relation_signature> m_reg_signatures; vector<relation_signature> m_reg_signatures;
obj_pair_map<sort, app, reg_idx> m_constant_registers; obj_pair_map<sort, app, reg_idx> m_constant_registers;
obj_pair_map<sort, decl, reg_idx> m_total_registers; obj_pair_map<sort, decl, reg_idx> m_total_registers;
obj_map<decl, reg_idx> m_empty_tables_registers; obj_map<decl, reg_idx> m_empty_tables_registers;
instruction_observer m_instruction_observer; instruction_observer m_instruction_observer;
expr_free_vars m_free_vars;
/** /**
If true, the union operation on the underlying structure only provides the information If true, the union operation on the underlying structure only provides the information

View file

@ -326,7 +326,7 @@ namespace datalog {
for(unsigned i=0; i<pos_tail_size; i++) { for(unsigned i=0; i<pos_tail_size; i++) {
rule_content.push_back(r->get_tail(i)); rule_content.push_back(r->get_tail(i));
} }
for(unsigned i=0; i<pos_tail_size; i++) { for(unsigned i=0; i+1 < pos_tail_size; i++) {
app * t1 = r->get_tail(i); app * t1 = r->get_tail(i);
var_idx_set t1_vars = rm.collect_vars(t1); var_idx_set t1_vars = rm.collect_vars(t1);
counter.count_vars(m, t1, -1); //temporarily remove t1 variables from counter counter.count_vars(m, t1, -1); //temporarily remove t1 variables from counter

View file

@ -1405,7 +1405,7 @@ namespace datalog {
dl_decl_util & m_decl_util; dl_decl_util & m_decl_util;
th_rewriter & m_simp; th_rewriter & m_simp;
app_ref m_condition; app_ref m_condition;
ptr_vector<sort> m_var_sorts; expr_free_vars m_free_vars;
expr_ref_vector m_args; expr_ref_vector m_args;
public: public:
default_table_filter_interpreted_fn(context & ctx, unsigned col_cnt, app* condition) default_table_filter_interpreted_fn(context & ctx, unsigned col_cnt, app* condition)
@ -1415,8 +1415,7 @@ namespace datalog {
m_simp(ctx.get_rewriter()), m_simp(ctx.get_rewriter()),
m_condition(condition, ctx.get_manager()), m_condition(condition, ctx.get_manager()),
m_args(ctx.get_manager()) { m_args(ctx.get_manager()) {
m_var_sorts.resize(col_cnt); m_free_vars(m_condition);
get_free_vars(m_condition, m_var_sorts);
} }
virtual bool should_remove(const table_fact & f) const { virtual bool should_remove(const table_fact & f) const {
@ -1426,14 +1425,13 @@ namespace datalog {
//arguments need to be in reverse order for the substitution //arguments need to be in reverse order for the substitution
unsigned col_cnt = f.size(); unsigned col_cnt = f.size();
for(int i=col_cnt-1;i>=0;i--) { for(int i=col_cnt-1;i>=0;i--) {
sort * var_sort = m_var_sorts[i]; if(!m_free_vars.contains(i)) {
if(!var_sort) {
args.push_back(0); args.push_back(0);
continue; //this variable does not occur in the condition; continue; //this variable does not occur in the condition;
} }
table_element el = f[i]; table_element el = f[i];
args.push_back(m_decl_util.mk_numeral(el, var_sort)); args.push_back(m_decl_util.mk_numeral(el, m_free_vars[i]));
} }
expr_ref ground(m_ast_manager); expr_ref ground(m_ast_manager);

View file

@ -216,11 +216,13 @@ namespace tb {
} }
void get_free_vars(ptr_vector<sort>& vars) const { void get_free_vars(ptr_vector<sort>& vars) const {
::get_free_vars(m_head, vars); expr_free_vars fv;
fv(m_head);
for (unsigned i = 0; i < m_predicates.size(); ++i) { for (unsigned i = 0; i < m_predicates.size(); ++i) {
::get_free_vars(m_predicates[i], vars); fv.accumulate(m_predicates[i]);
} }
::get_free_vars(m_constraint, vars); fv.accumulate(m_constraint);
vars.append(fv.size(), fv.c_ptr());
} }
expr_ref to_formula() const { expr_ref to_formula() const {
@ -1107,16 +1109,16 @@ namespace tb {
m_S1.apply(2, delta, expr_offset(tgt.get_constraint(), 0), 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); m_S1.apply(2, delta, expr_offset(src.get_constraint(), 1), tmp2);
constraint = m.mk_and(tmp, tmp2); constraint = m.mk_and(tmp, tmp2);
ptr_vector<sort> vars;
// perform trival quantifier-elimination: // perform trival quantifier-elimination:
uint_set index_set; uint_set index_set;
get_free_vars(head, vars); expr_free_vars fv;
fv(head);
for (unsigned i = 0; i < predicates.size(); ++i) { for (unsigned i = 0; i < predicates.size(); ++i) {
get_free_vars(predicates[i].get(), vars); fv.accumulate(predicates[i].get());
} }
for (unsigned i = 0; i < vars.size(); ++i) { for (unsigned i = 0; i < fv.size(); ++i) {
if (vars[i]) { if (fv[i]) {
index_set.insert(i); index_set.insert(i);
} }
} }
@ -1127,7 +1129,7 @@ namespace tb {
// initialize rule. // initialize rule.
result->init(head, predicates, constraint); result->init(head, predicates, constraint);
vars.reset(); ptr_vector<sort> vars;
result->get_free_vars(vars); result->get_free_vars(vars);
bool change = false; bool change = false;
var_ref w(m); var_ref w(m);

View file

@ -294,7 +294,7 @@ namespace datalog {
if (m_simplifier.transform_rule(new_rules.last(), new_rule)) { if (m_simplifier.transform_rule(new_rules.last(), new_rule)) {
if (r.get_proof()) { if (r.get_proof()) {
scoped_proof _sc(m); scoped_proof _sc(m);
r.to_formula(fml1); rm.to_formula(r, fml1);
p = m.mk_rewrite(fml1, fml2); p = m.mk_rewrite(fml1, fml2);
p = m.mk_modus_ponens(r.get_proof(), p); p = m.mk_modus_ponens(r.get_proof(), p);
new_rule->set_proof(m, p); new_rule->set_proof(m, p);

View file

@ -225,7 +225,6 @@ namespace datalog {
mk_interp_tail_simplifier m_simplifier; mk_interp_tail_simplifier m_simplifier;
bit_blaster_rewriter m_blaster; bit_blaster_rewriter m_blaster;
expand_mkbv m_rewriter; expand_mkbv m_rewriter;
bool blast(rule *r, expr_ref& fml) { bool blast(rule *r, expr_ref& fml) {
proof_ref pr(m); proof_ref pr(m);
@ -235,7 +234,7 @@ namespace datalog {
if (!m_simplifier.transform_rule(r, r2)) { if (!m_simplifier.transform_rule(r, r2)) {
r2 = r; r2 = r;
} }
r2->to_formula(fml1); m_context.get_rule_manager().to_formula(*r2.get(), fml1);
m_blaster(fml1, fml2, pr); m_blaster(fml1, fml2, pr);
m_rewriter(fml2, fml3); m_rewriter(fml2, fml3);
TRACE("dl", tout << mk_pp(fml, m) << " -> " << mk_pp(fml2, m) << " -> " << mk_pp(fml3, m) << "\n";); TRACE("dl", tout << mk_pp(fml, m) << " -> " << mk_pp(fml2, m) << " -> " << mk_pp(fml3, m) << "\n";);
@ -274,7 +273,7 @@ namespace datalog {
m_rewriter.m_cfg.set_dst(result); m_rewriter.m_cfg.set_dst(result);
for (unsigned i = 0; !m_context.canceled() && i < sz; ++i) { for (unsigned i = 0; !m_context.canceled() && i < sz; ++i) {
rule * r = source.get_rule(i); rule * r = source.get_rule(i);
r->to_formula(fml); rm.to_formula(*r, fml);
if (blast(r, fml)) { if (blast(r, fml)) {
proof_ref pr(m); proof_ref pr(m);
if (r->get_proof()) { if (r->get_proof()) {

View file

@ -134,9 +134,9 @@ namespace datalog {
is_neg.push_back(false); is_neg.push_back(false);
res = rm.mk(head, tail.size(), tail.c_ptr(), is_neg.c_ptr(), tgt->name()); res = rm.mk(head, tail.size(), tail.c_ptr(), is_neg.c_ptr(), tgt->name());
if (m_ctx.generate_proof_trace()) { if (m_ctx.generate_proof_trace()) {
src.to_formula(fml1); rm.to_formula(src, fml1);
tgt->to_formula(fml2); rm.to_formula(*tgt.get(),fml2);
res->to_formula(fml); rm.to_formula(*res.get(),fml);
#if 0 #if 0
sort* ps = m.mk_proof_sort(); sort* ps = m.mk_proof_sort();
sort* domain[3] = { ps, ps, m.mk_bool_sort() }; sort* domain[3] = { ps, ps, m.mk_bool_sort() };

View file

@ -238,7 +238,7 @@ namespace datalog {
proof* p1 = r.get_proof(); proof* p1 = r.get_proof();
for (unsigned i = 0; i < added_rules.get_num_rules(); ++i) { for (unsigned i = 0; i < added_rules.get_num_rules(); ++i) {
rule* r2 = added_rules.get_rule(i); rule* r2 = added_rules.get_rule(i);
r2->to_formula(fml); rm.to_formula(*r2, fml);
pr = m.mk_modus_ponens(m.mk_def_axiom(m.mk_implies(m.get_fact(p1), fml)), p1); pr = m.mk_modus_ponens(m.mk_def_axiom(m.mk_implies(m.get_fact(p1), fml)), p1);
r2->set_proof(m, pr); r2->set_proof(m, pr);
} }

View file

@ -179,7 +179,7 @@ namespace datalog {
if (m_context.generate_proof_trace()) { if (m_context.generate_proof_trace()) {
expr_ref_vector s1 = m_unifier.get_rule_subst(tgt, true); expr_ref_vector s1 = m_unifier.get_rule_subst(tgt, true);
expr_ref_vector s2 = m_unifier.get_rule_subst(src, false); expr_ref_vector s2 = m_unifier.get_rule_subst(src, false);
datalog::resolve_rule(tgt, src, tail_index, s1, s2, *res.get()); datalog::resolve_rule(m_rm, tgt, src, tail_index, s1, s2, *res.get());
} }
return true; return true;
} }

View file

@ -37,10 +37,10 @@ namespace datalog {
void mk_separate_negated_tails::get_private_vars(rule const& r, unsigned j) { void mk_separate_negated_tails::get_private_vars(rule const& r, unsigned j) {
m_vars.reset(); m_vars.reset();
m_fv.reset(); m_fv.reset();
get_free_vars(r.get_head(), m_fv); m_fv(r.get_head());
for (unsigned i = 0; i < r.get_tail_size(); ++i) { for (unsigned i = 0; i < r.get_tail_size(); ++i) {
if (i != j) { if (i != j) {
get_free_vars(r.get_tail(i), m_fv); m_fv.accumulate(r.get_tail(i));
} }
} }
@ -49,7 +49,7 @@ namespace datalog {
expr* v = p->get_arg(i); expr* v = p->get_arg(i);
if (is_var(v)) { if (is_var(v)) {
unsigned idx = to_var(v)->get_idx(); unsigned idx = to_var(v)->get_idx();
if (idx >= m_fv.size() || !m_fv[idx]) { if (!m_fv.contains(idx)) {
m_vars.push_back(v); m_vars.push_back(v);
} }
} }

View file

@ -42,7 +42,7 @@ namespace datalog {
rule_manager& rm; rule_manager& rm;
context & m_ctx; context & m_ctx;
ptr_vector<expr> m_vars; ptr_vector<expr> m_vars;
ptr_vector<sort> m_fv; expr_free_vars m_fv;
bool has_private_vars(rule const& r, unsigned j); bool has_private_vars(rule const& r, unsigned j);
void get_private_vars(rule const& r, unsigned j); void get_private_vars(rule const& r, unsigned j);

View file

@ -120,7 +120,7 @@ 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) {
it->m_value->to_formula(fml); rm.to_formula(*it->m_value, fml);
m_pinned_exprs.push_back(fml); m_pinned_exprs.push_back(fml);
TRACE("dl", TRACE("dl",
tout << "orig: " << mk_pp(fml, m) << "\n"; tout << "orig: " << mk_pp(fml, m) << "\n";
@ -238,7 +238,7 @@ namespace datalog {
r3->display(m_ctx, tout << "res:");); r3->display(m_ctx, tout << "res:"););
r1 = r3; r1 = r3;
} }
r1->to_formula(concl); rm.to_formula(*r1.get(), concl);
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());
@ -676,10 +676,10 @@ namespace datalog {
} }
void mk_slice::add_free_vars(uint_set& result, expr* e) { void mk_slice::add_free_vars(uint_set& result, expr* e) {
ptr_vector<sort> sorts; expr_free_vars fv;
get_free_vars(e, sorts); fv(e);
for (unsigned i = 0; i < sorts.size(); ++i) { for (unsigned i = 0; i < fv.size(); ++i) {
if (sorts[i]) { if (fv[i]) {
result.insert(i); result.insert(i);
} }
} }
@ -773,14 +773,11 @@ namespace datalog {
init_vars(r); init_vars(r);
app_ref_vector tail(m); app_ref_vector tail(m);
app_ref head(m); app_ref head(m);
ptr_vector<sort> sorts;
update_predicate(r.get_head(), head); update_predicate(r.get_head(), head);
get_free_vars(head.get(), sorts);
for (unsigned i = 0; i < r.get_uninterpreted_tail_size(); ++i) { for (unsigned i = 0; i < r.get_uninterpreted_tail_size(); ++i) {
app_ref t(m); app_ref t(m);
update_predicate(r.get_tail(i), t); update_predicate(r.get_tail(i), t);
tail.push_back(t); tail.push_back(t);
get_free_vars(t, sorts);
} }
expr_ref_vector conjs = get_tail_conjs(r); expr_ref_vector conjs = get_tail_conjs(r);

View file

@ -43,7 +43,7 @@ namespace datalog {
m_unify.apply(r, tail_idx, r2, new_rule)) { m_unify.apply(r, tail_idx, r2, new_rule)) {
expr_ref_vector s1 = m_unify.get_rule_subst(r, true); expr_ref_vector s1 = m_unify.get_rule_subst(r, true);
expr_ref_vector s2 = m_unify.get_rule_subst(r2, false); expr_ref_vector s2 = m_unify.get_rule_subst(r2, false);
resolve_rule(r, r2, tail_idx, s1, s2, *new_rule.get()); resolve_rule(rm, r, r2, tail_idx, s1, s2, *new_rule.get());
expand_tail(*new_rule.get(), tail_idx+r2.get_uninterpreted_tail_size(), src, dst); expand_tail(*new_rule.get(), tail_idx+r2.get_uninterpreted_tail_size(), src, dst);
} }
} }

View file

@ -2271,17 +2271,14 @@ namespace qe {
void expr_quant_elim::instantiate_expr(expr_ref_vector& bound, expr_ref& fml) { void expr_quant_elim::instantiate_expr(expr_ref_vector& bound, expr_ref& fml) {
ptr_vector<sort> sorts; expr_free_vars fv;
get_free_vars(fml, sorts); fv(fml);
if (!sorts.empty()) { fv.set_default_sort(m.mk_bool_sort());
if (!fv.empty()) {
expr_ref tmp(m); expr_ref tmp(m);
for (unsigned i = sorts.size(); i > 0;) { for (unsigned i = fv.size(); i > 0;) {
--i; --i;
sort* s = sorts[i]; bound.push_back(m.mk_fresh_const("bound", fv[i]));
if (!s) {
s = m.mk_bool_sort();
}
bound.push_back(m.mk_fresh_const("bound", s));
} }
var_subst subst(m); var_subst subst(m);
subst(fml, bound.size(), bound.c_ptr(), tmp); subst(fml, bound.size(), bound.c_ptr(), tmp);

View file

@ -87,6 +87,7 @@ namespace smt {
typedef typename Ext::numeral numeral; typedef typename Ext::numeral numeral;
typedef typename Ext::inf_numeral inf_numeral; typedef typename Ext::inf_numeral inf_numeral;
typedef vector<numeral> numeral_vector; typedef vector<numeral> numeral_vector;
typedef map<rational, theory_var, obj_hash<rational>, default_eq<rational> > rational2var;
static const int dead_row_id = -1; static const int dead_row_id = -1;
protected: protected:

View file

@ -2993,7 +2993,6 @@ namespace smt {
*/ */
template<typename Ext> template<typename Ext>
void theory_arith<Ext>::refine_epsilon() { void theory_arith<Ext>::refine_epsilon() {
typedef map<rational, theory_var, obj_hash<rational>, default_eq<rational> > rational2var;
while (true) { while (true) {
rational2var mapping; rational2var mapping;
theory_var num = get_num_vars(); theory_var num = get_num_vars();
@ -3001,6 +3000,8 @@ namespace smt {
for (theory_var v = 0; v < num; v++) { for (theory_var v = 0; v < num; v++) {
if (is_int(v)) if (is_int(v))
continue; continue;
if (!get_context().is_shared(get_enode(v)))
continue;
inf_numeral const & val = get_value(v); inf_numeral const & val = get_value(v);
if (Ext::is_infinite(val)) { if (Ext::is_infinite(val)) {
continue; continue;

View file

@ -43,7 +43,7 @@ bool horn_subsume_model_converter::mk_horn(
app* head, expr* body, func_decl_ref& pred, expr_ref& body_res) { app* head, expr* body, func_decl_ref& pred, expr_ref& body_res) {
expr_ref_vector conjs(m), subst(m); expr_ref_vector conjs(m), subst(m);
ptr_vector<sort> sorts, sorts2; ptr_vector<sort> sorts2;
var_subst vs(m, false); var_subst vs(m, false);
if (!is_uninterp(head)) { if (!is_uninterp(head)) {
@ -53,28 +53,27 @@ bool horn_subsume_model_converter::mk_horn(
pred = head->get_decl(); pred = head->get_decl();
unsigned arity = head->get_num_args(); unsigned arity = head->get_num_args();
get_free_vars(head, sorts); expr_free_vars fv;
get_free_vars(body, sorts); fv(head);
fv.accumulate(body);
if (arity == 0 && sorts.empty()) { if (arity == 0 && fv.empty()) {
body_res = body; body_res = body;
return true; return true;
} }
fv.set_default_sort(m.mk_bool_sort());
svector<symbol> names; svector<symbol> names;
for (unsigned i = 0; i < sorts.size(); ++i) { for (unsigned i = 0; i < fv.size(); ++i) {
if (!sorts[i]) {
sorts[i] = m.mk_bool_sort();
}
names.push_back(symbol(i)); names.push_back(symbol(i));
} }
names.reverse(); names.reverse();
sorts.reverse(); fv.reverse();
conjs.push_back(body); conjs.push_back(body);
for (unsigned i = 0; i < arity; ++i) { for (unsigned i = 0; i < arity; ++i) {
expr* arg = head->get_arg(i); expr* arg = head->get_arg(i);
var_ref v(m); var_ref v(m);
v = m.mk_var(sorts.size()+i, m.get_sort(arg)); v = m.mk_var(fv.size()+i, m.get_sort(arg));
if (is_var(arg)) { if (is_var(arg)) {
unsigned w = to_var(arg)->get_idx(); unsigned w = to_var(arg)->get_idx();
@ -101,12 +100,12 @@ bool horn_subsume_model_converter::mk_horn(
vs(tmp, subst.size(), subst.c_ptr(), body_expr); vs(tmp, subst.size(), subst.c_ptr(), body_expr);
} }
if (sorts.empty()) { if (fv.empty()) {
SASSERT(subst.empty()); SASSERT(subst.empty());
body_res = body_expr; body_res = body_expr;
} }
else { else {
body_res = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), body_expr.get()); body_res = m.mk_exists(fv.size(), fv.c_ptr(), names.c_ptr(), body_expr.get());
m_rewrite(body_res); m_rewrite(body_res);
} }
@ -120,10 +119,9 @@ bool horn_subsume_model_converter::mk_horn(
bool horn_subsume_model_converter::mk_horn( bool horn_subsume_model_converter::mk_horn(
expr* clause, func_decl_ref& pred, expr_ref& body) { expr* clause, func_decl_ref& pred, expr_ref& body) {
ptr_vector<sort> sorts;
// formula is closed. // formula is closed.
DEBUG_CODE(get_free_vars(clause, sorts); SASSERT(sorts.empty());); DEBUG_CODE(expr_free_vars fv; fv(clause); SASSERT(fv.empty()););
while (is_quantifier(clause) && to_quantifier(clause)->is_forall()) { while (is_quantifier(clause) && to_quantifier(clause)->is_forall()) {
quantifier* q = to_quantifier(clause); quantifier* q = to_quantifier(clause);