mirror of
https://github.com/Z3Prover/z3
synced 2025-10-06 07:53:59 +00:00
integrate lambda expressions
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
bf4edef761
commit
520ce9a5ee
139 changed files with 2243 additions and 1506 deletions
|
@ -38,7 +38,7 @@ expr_ref bind_variables::operator()(expr* fml, bool is_forall) {
|
|||
if (!m_names.empty()) {
|
||||
m_bound.reverse();
|
||||
m_names.reverse();
|
||||
result = m.mk_quantifier(is_forall, m_bound.size(), m_bound.c_ptr(), m_names.c_ptr(), result);
|
||||
result = m.mk_quantifier(is_forall ? forall_k : exists_k, m_bound.size(), m_bound.c_ptr(), m_names.c_ptr(), result);
|
||||
}
|
||||
m_pinned.reset();
|
||||
m_cache.reset();
|
||||
|
|
|
@ -1044,7 +1044,7 @@ namespace datalog {
|
|||
quantifier* q = to_quantifier(body);
|
||||
expr* e = q->get_expr();
|
||||
if (m.is_implies(e, body, e2)) {
|
||||
fml = m.mk_quantifier(false, q->get_num_decls(),
|
||||
fml = m.mk_quantifier(exists_k, q->get_num_decls(),
|
||||
q->get_decl_sorts(), q->get_decl_names(),
|
||||
body);
|
||||
}
|
||||
|
@ -1251,13 +1251,10 @@ namespace datalog {
|
|||
obj_map<sort, unsigned> max_vars;
|
||||
for (unsigned i = 0; i < rules.size(); ++i) {
|
||||
expr* r = rules[i].get();
|
||||
if (!is_quantifier(r)) {
|
||||
if (!is_forall(r)) {
|
||||
continue;
|
||||
}
|
||||
quantifier* q = to_quantifier(r);
|
||||
if (!q->is_forall()) {
|
||||
continue;
|
||||
}
|
||||
if (has_quantifiers(q->get_expr())) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1292,7 +1289,7 @@ namespace datalog {
|
|||
subst.push_back(fresh_vars[vars[max_var]].get());
|
||||
}
|
||||
|
||||
vsubst(q->get_expr(), subst.size(), subst.c_ptr(), res);
|
||||
res = vsubst(q->get_expr(), subst.size(), subst.c_ptr());
|
||||
rules[i] = res.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ namespace datalog {
|
|||
args.push_back(m.mk_var(0, m.mk_bool_sort()));
|
||||
}
|
||||
}
|
||||
sub(q, args.size(), args.c_ptr(), q);
|
||||
q = sub(q, args.size(), args.c_ptr());
|
||||
vars.reset();
|
||||
m_free_vars(q);
|
||||
vars.append(m_free_vars.size(), m_free_vars.c_ptr());
|
||||
|
@ -438,11 +438,7 @@ namespace datalog {
|
|||
e = e2;
|
||||
}
|
||||
}
|
||||
if (is_quantifier(e)) {
|
||||
q = to_quantifier(e);
|
||||
return q->is_forall();
|
||||
}
|
||||
return false;
|
||||
return ::is_forall(e);
|
||||
}
|
||||
|
||||
|
||||
|
@ -745,7 +741,7 @@ namespace datalog {
|
|||
expr_ref unbound_tail_pre_quant(m), fixed_tail(m), quant_tail(m);
|
||||
|
||||
var_subst vs(m, false);
|
||||
vs(unbound_tail, subst.size(), subst.c_ptr(), unbound_tail_pre_quant);
|
||||
unbound_tail_pre_quant = vs(unbound_tail, subst.size(), subst.c_ptr());
|
||||
|
||||
quant_tail = m.mk_exists(q_var_cnt, qsorts.c_ptr(), qnames.c_ptr(), unbound_tail_pre_quant);
|
||||
|
||||
|
@ -816,10 +812,10 @@ namespace datalog {
|
|||
app_ref_vector new_tail(m);
|
||||
svector<bool> tail_neg;
|
||||
var_subst vs(m, false);
|
||||
vs(r->get_head(), sz, es, tmp);
|
||||
tmp = vs(r->get_head(), sz, es);
|
||||
new_head = to_app(tmp);
|
||||
for (unsigned i = 0; i < r->get_tail_size(); ++i) {
|
||||
vs(r->get_tail(i), sz, es, tmp);
|
||||
tmp = vs(r->get_tail(i), sz, es);
|
||||
new_tail.push_back(to_app(tmp));
|
||||
tail_neg.push_back(r->is_neg_tail(i));
|
||||
}
|
||||
|
@ -984,8 +980,7 @@ namespace datalog {
|
|||
|
||||
var_subst vs(m, false);
|
||||
|
||||
expr_ref new_head_e(m);
|
||||
vs(m_head, subst_vals.size(), subst_vals.c_ptr(), new_head_e);
|
||||
expr_ref new_head_e = vs(m_head, subst_vals.size(), subst_vals.c_ptr());
|
||||
|
||||
m.inc_ref(new_head_e);
|
||||
m.dec_ref(m_head);
|
||||
|
@ -993,8 +988,7 @@ namespace datalog {
|
|||
|
||||
for (unsigned i = 0; i < m_tail_size; i++) {
|
||||
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);
|
||||
expr_ref new_tail_e = vs(old_tail, subst_vals.size(), subst_vals.c_ptr());
|
||||
bool sign = is_neg_tail(i);
|
||||
m.inc_ref(new_tail_e);
|
||||
m.dec_ref(old_tail);
|
||||
|
|
|
@ -82,12 +82,10 @@ namespace datalog {
|
|||
quantifier_finder_proc() : m_exist(false), m_univ(false) {}
|
||||
void operator()(var * n) { }
|
||||
void operator()(quantifier * n) {
|
||||
if (n->is_forall()) {
|
||||
m_univ = true;
|
||||
}
|
||||
else {
|
||||
SASSERT(n->is_exists());
|
||||
m_exist = true;
|
||||
switch (n->get_kind()) {
|
||||
case forall_k: m_univ = true; break;
|
||||
case exists_k: m_exist = true; break;
|
||||
case lambda_k: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
void operator()(app * n) { }
|
||||
|
|
|
@ -31,27 +31,20 @@ namespace datalog {
|
|||
rule_dependencies::rule_dependencies(const rule_dependencies & o, bool reversed):
|
||||
m_context(o.m_context) {
|
||||
if (reversed) {
|
||||
iterator oit = o.begin();
|
||||
iterator oend = o.end();
|
||||
for (; oit!=oend; ++oit) {
|
||||
func_decl * pred = oit->m_key;
|
||||
item_set & orig_items = *oit->get_value();
|
||||
for (auto & kv : o) {
|
||||
func_decl * pred = kv.m_key;
|
||||
item_set & orig_items = *kv.get_value();
|
||||
|
||||
ensure_key(pred);
|
||||
item_set::iterator dit = orig_items.begin();
|
||||
item_set::iterator dend = orig_items.end();
|
||||
for (; dit!=dend; ++dit) {
|
||||
func_decl * master_pred = *dit;
|
||||
for (func_decl * master_pred : orig_items) {
|
||||
insert(master_pred, pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
iterator oit = o.begin();
|
||||
iterator oend = o.end();
|
||||
for (; oit!=oend; ++oit) {
|
||||
func_decl * pred = oit->m_key;
|
||||
item_set & orig_items = *oit->get_value();
|
||||
for (auto & kv : o) {
|
||||
func_decl * pred = kv.m_key;
|
||||
item_set & orig_items = *kv.get_value();
|
||||
m_data.insert(pred, alloc(item_set, orig_items));
|
||||
}
|
||||
}
|
||||
|
@ -86,14 +79,10 @@ namespace datalog {
|
|||
|
||||
void rule_dependencies::populate(const rule_set & rules) {
|
||||
SASSERT(m_data.empty());
|
||||
rule_set::decl2rules::iterator it = rules.m_head2rules.begin();
|
||||
rule_set::decl2rules::iterator end = rules.m_head2rules.end();
|
||||
for (; it != end; ++it) {
|
||||
ptr_vector<rule> * rules = it->m_value;
|
||||
ptr_vector<rule>::iterator it2 = rules->begin();
|
||||
ptr_vector<rule>::iterator end2 = rules->end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
populate(*it2);
|
||||
for (auto & kv : rules.m_head2rules) {
|
||||
ptr_vector<rule> * rules = kv.m_value;
|
||||
for (rule* r : *rules) {
|
||||
populate(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,54 +139,41 @@ namespace datalog {
|
|||
|
||||
void rule_dependencies::restrict(const item_set & allowed) {
|
||||
ptr_vector<func_decl> to_remove;
|
||||
iterator pit = begin();
|
||||
iterator pend = end();
|
||||
for (; pit!=pend; ++pit) {
|
||||
func_decl * pred = pit->m_key;
|
||||
for (auto const& kv : *this) {
|
||||
func_decl * pred = kv.m_key;
|
||||
if (!allowed.contains(pred)) {
|
||||
to_remove.insert(pred);
|
||||
continue;
|
||||
}
|
||||
item_set& itms = *pit->get_value();
|
||||
item_set& itms = *kv.get_value();
|
||||
set_intersection(itms, allowed);
|
||||
}
|
||||
ptr_vector<func_decl>::iterator rit = to_remove.begin();
|
||||
ptr_vector<func_decl>::iterator rend = to_remove.end();
|
||||
for (; rit != rend; ++rit) {
|
||||
remove_m_data_entry(*rit);
|
||||
}
|
||||
for (func_decl* f : to_remove)
|
||||
remove_m_data_entry(f);
|
||||
}
|
||||
|
||||
void rule_dependencies::remove(func_decl * itm) {
|
||||
remove_m_data_entry(itm);
|
||||
iterator pit = begin();
|
||||
iterator pend = end();
|
||||
for (; pit != pend; ++pit) {
|
||||
item_set & itms = *pit->get_value();
|
||||
for (auto const& kv : *this) {
|
||||
item_set & itms = *kv.get_value();
|
||||
itms.remove(itm);
|
||||
}
|
||||
}
|
||||
|
||||
void rule_dependencies::remove(const item_set & to_remove) {
|
||||
item_set::iterator rit = to_remove.begin();
|
||||
item_set::iterator rend = to_remove.end();
|
||||
for (; rit!=rend; ++rit) {
|
||||
remove_m_data_entry(*rit);
|
||||
for (auto * item : to_remove) {
|
||||
remove_m_data_entry(item);
|
||||
}
|
||||
iterator pit = begin();
|
||||
iterator pend = end();
|
||||
for (; pit!=pend; ++pit) {
|
||||
item_set * itms = pit->get_value();
|
||||
for (auto & kv : *this) {
|
||||
item_set * itms = kv.get_value();
|
||||
set_difference(*itms, to_remove);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned rule_dependencies::out_degree(func_decl * f) const {
|
||||
unsigned res = 0;
|
||||
iterator pit = begin();
|
||||
iterator pend = end();
|
||||
for (; pit!=pend; ++pit) {
|
||||
item_set & itms = *pit->get_value();
|
||||
for (auto & kv : *this) {
|
||||
item_set & itms = *kv.get_value();
|
||||
if (itms.contains(f)) {
|
||||
res++;
|
||||
}
|
||||
|
@ -333,19 +309,11 @@ namespace datalog {
|
|||
void rule_set::inherit_predicates(rule_set const& other) {
|
||||
m_refs.append(other.m_refs);
|
||||
set_union(m_output_preds, other.m_output_preds);
|
||||
{
|
||||
obj_map<func_decl, func_decl*>::iterator it = other.m_orig2pred.begin();
|
||||
obj_map<func_decl, func_decl*>::iterator end = other.m_orig2pred.end();
|
||||
for (; it != end; ++it) {
|
||||
m_orig2pred.insert(it->m_key, it->m_value);
|
||||
}
|
||||
for (auto & kv : other.m_orig2pred) {
|
||||
m_orig2pred.insert(kv.m_key, kv.m_value);
|
||||
}
|
||||
{
|
||||
obj_map<func_decl, func_decl*>::iterator it = other.m_pred2orig.begin();
|
||||
obj_map<func_decl, func_decl*>::iterator end = other.m_pred2orig.end();
|
||||
for (; it != end; ++it) {
|
||||
m_pred2orig.insert(it->m_key, it->m_value);
|
||||
}
|
||||
for (auto & kv : other.m_pred2orig) {
|
||||
m_pred2orig.insert(kv.m_key, kv.m_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,26 +505,19 @@ namespace datalog {
|
|||
void rule_set::display_deps( std::ostream & out ) const
|
||||
{
|
||||
const pred_set_vector & strats = get_strats();
|
||||
pred_set_vector::const_iterator sit = strats.begin();
|
||||
pred_set_vector::const_iterator send = strats.end();
|
||||
for (; sit!=send; ++sit) {
|
||||
func_decl_set & strat = **sit;
|
||||
func_decl_set::iterator fit=strat.begin();
|
||||
func_decl_set::iterator fend=strat.end();
|
||||
bool non_empty = false;
|
||||
for (; fit!=fend; ++fit) {
|
||||
func_decl * first = *fit;
|
||||
const func_decl_set & deps = m_deps.get_deps(first);
|
||||
func_decl_set::iterator dit=deps.begin();
|
||||
func_decl_set::iterator dend=deps.end();
|
||||
for (; dit!=dend; ++dit) {
|
||||
non_empty = true;
|
||||
func_decl * dep = *dit;
|
||||
out<<first->get_name()<<" -> "<<dep->get_name()<<"\n";
|
||||
}
|
||||
}
|
||||
if (non_empty && sit!=send) {
|
||||
bool non_empty = false;
|
||||
for (func_decl_set* strat : strats) {
|
||||
if (non_empty) {
|
||||
out << "\n";
|
||||
non_empty = false;
|
||||
}
|
||||
|
||||
for (func_decl * first : *strat) {
|
||||
const func_decl_set & deps = m_deps.get_deps(first);
|
||||
for (func_decl * dep : deps) {
|
||||
non_empty = true;
|
||||
out<<first->get_name()<<" -> " <<dep->get_name()<<"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -568,11 +529,8 @@ namespace datalog {
|
|||
// -----------------------------------
|
||||
|
||||
rule_stratifier::~rule_stratifier() {
|
||||
comp_vector::iterator it = m_strats.begin();
|
||||
comp_vector::iterator end = m_strats.end();
|
||||
for (; it!=end; ++it) {
|
||||
SASSERT(*it);
|
||||
dealloc(*it);
|
||||
for (auto * t : m_strats) {
|
||||
dealloc(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -617,10 +575,8 @@ namespace datalog {
|
|||
m_stack_P.push_back(el);
|
||||
|
||||
const item_set & children = m_deps.get_deps(el);
|
||||
item_set::iterator cit=children.begin();
|
||||
item_set::iterator cend=children.end();
|
||||
for (; cit!=cend; ++cit) {
|
||||
traverse(*cit);
|
||||
for (T* ch : children) {
|
||||
traverse(ch);
|
||||
}
|
||||
|
||||
if (el == m_stack_P.back()) {
|
||||
|
@ -646,10 +602,8 @@ namespace datalog {
|
|||
}
|
||||
|
||||
//detect strong components
|
||||
rule_dependencies::iterator it = m_deps.begin();
|
||||
rule_dependencies::iterator end = m_deps.end();
|
||||
for (; it!=end; ++it) {
|
||||
T * el = it->m_key;
|
||||
for (auto const& kv : m_deps) {
|
||||
T * el = kv.m_key;
|
||||
//we take a note of the preorder number with which this sweep started
|
||||
m_first_preorder = m_next_preorder;
|
||||
traverse(el);
|
||||
|
@ -662,19 +616,13 @@ namespace datalog {
|
|||
in_degrees.resize(m_components.size());
|
||||
|
||||
//init in_degrees
|
||||
it = m_deps.begin();
|
||||
end = m_deps.end();
|
||||
for (; it != end; ++it) {
|
||||
T * el = it->m_key;
|
||||
item_set * out_edges = it->m_value;
|
||||
for (auto const& kv : m_deps) {
|
||||
T * el = kv.m_key;
|
||||
item_set * out_edges = kv.m_value;
|
||||
|
||||
unsigned el_comp = 0;
|
||||
VERIFY( m_component_nums.find(el, el_comp) );
|
||||
unsigned el_comp = m_component_nums[el];
|
||||
|
||||
item_set::iterator eit = out_edges->begin();
|
||||
item_set::iterator eend = out_edges->end();
|
||||
for (; eit!=eend; ++eit) {
|
||||
T * tgt = *eit;
|
||||
for (T * tgt : *out_edges) {
|
||||
|
||||
unsigned tgt_comp = m_component_nums.find(tgt);
|
||||
|
||||
|
@ -701,15 +649,9 @@ namespace datalog {
|
|||
unsigned strats_index = 0;
|
||||
while (strats_index < m_strats.size()) { //m_strats.size() changes inside the loop!
|
||||
item_set * comp = m_strats[strats_index];
|
||||
item_set::iterator cit=comp->begin();
|
||||
item_set::iterator cend=comp->end();
|
||||
for (; cit!=cend; ++cit) {
|
||||
T * el = *cit;
|
||||
for (T * el : *comp) {
|
||||
const item_set & deps = m_deps.get_deps(el);
|
||||
item_set::iterator eit=deps.begin();
|
||||
item_set::iterator eend=deps.end();
|
||||
for (; eit!=eend; ++eit) {
|
||||
T * tgt = *eit;
|
||||
for (T * tgt : deps) {
|
||||
unsigned tgt_comp = 0;
|
||||
VERIFY( m_component_nums.find(tgt, tgt_comp) );
|
||||
|
||||
|
@ -724,7 +666,7 @@ namespace datalog {
|
|||
m_components[tgt_comp] = 0;
|
||||
}
|
||||
}
|
||||
traverse(*cit);
|
||||
traverse(el);
|
||||
}
|
||||
}
|
||||
strats_index++;
|
||||
|
@ -738,12 +680,9 @@ namespace datalog {
|
|||
|
||||
SASSERT(m_pred_strat_nums.empty());
|
||||
unsigned strat_cnt = m_strats.size();
|
||||
for (unsigned strat_index=0; strat_index<strat_cnt; strat_index++) {
|
||||
for (unsigned strat_index=0; strat_index < strat_cnt; strat_index++) {
|
||||
item_set * comp = m_strats[strat_index];
|
||||
item_set::iterator cit=comp->begin();
|
||||
item_set::iterator cend=comp->end();
|
||||
for (; cit != cend; ++cit) {
|
||||
T * el = *cit;
|
||||
for (T * el : *comp) {
|
||||
m_pred_strat_nums.insert(el, strat_index);
|
||||
}
|
||||
}
|
||||
|
@ -761,10 +700,8 @@ namespace datalog {
|
|||
m_deps.display(out << "dependencies\n");
|
||||
out << "strata\n";
|
||||
for (unsigned i = 0; i < m_strats.size(); ++i) {
|
||||
item_set::iterator it = m_strats[i]->begin();
|
||||
item_set::iterator end = m_strats[i]->end();
|
||||
for (; it != end; ++it) {
|
||||
out << (*it)->get_name() << " ";
|
||||
for (auto * item : *m_strats[i]) {
|
||||
out << item->get_name() << " ";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
|
|
|
@ -115,8 +115,7 @@ namespace datalog {
|
|||
expr_ref tmp(m);
|
||||
for (unsigned i = 0; i < tgt.size(); ++i) {
|
||||
if (tgt[i].get()) {
|
||||
vs(tgt[i].get(), sub.size(), sub.c_ptr(), tmp);
|
||||
tgt[i] = tmp;
|
||||
tgt[i] = vs(tgt[i].get(), sub.size(), sub.c_ptr());
|
||||
}
|
||||
else {
|
||||
tgt[i] = sub[i];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue