3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-19 10:52:02 +00:00

Simplify code using C++11 conventions

This commit is contained in:
Arie Gurfinkel 2018-05-18 16:17:27 -07:00
parent 5a6bd5e782
commit 2f369d8d41
2 changed files with 100 additions and 121 deletions

View file

@ -1020,14 +1020,14 @@ void pred_transformer::add_reach_fact (reach_fact *fact)
<< mk_pp(fact->get (), m) << "\n";); << mk_pp(fact->get (), m) << "\n";);
// -- avoid duplicates // -- avoid duplicates
if (fact == nullptr || get_reach_fact(fact->get())) { return; } if (fact == nullptr || get_reach_fact(fact->get())) {return;}
// all initial facts are grouped together // all initial facts are grouped together
SASSERT (!fact->is_init () || m_reach_facts.empty () || SASSERT (!fact->is_init () || m_reach_facts.empty () ||
m_reach_facts.back ()->is_init ()); m_reach_facts.back ()->is_init ());
m_reach_facts.push_back (fact); m_reach_facts.push_back (fact);
if (fact->is_init()) { m_rf_init_sz++; } if (fact->is_init()) {m_rf_init_sz++;}
// update m_reach_ctx // update m_reach_ctx
@ -1035,9 +1035,9 @@ void pred_transformer::add_reach_fact (reach_fact *fact)
expr_ref new_var (m); expr_ref new_var (m);
expr_ref fml (m); expr_ref fml (m);
if (!m_reach_case_vars.empty()) { last_var = m_reach_case_vars.back(); } if (!m_reach_case_vars.empty()) {last_var = m_reach_case_vars.back();}
if (fact->is_init () || !ctx.get_params ().spacer_reach_as_init ()) if (fact->is_init () || !ctx.get_params ().spacer_reach_as_init ())
{ new_var = mk_fresh_reach_case_var(); } {new_var = mk_fresh_reach_case_var();}
else { else {
new_var = extend_initial (fact->get ())->get_arg (0); new_var = extend_initial (fact->get ())->get_arg (0);
m_reach_case_vars.push_back (new_var); m_reach_case_vars.push_back (new_var);
@ -1045,10 +1045,8 @@ void pred_transformer::add_reach_fact (reach_fact *fact)
SASSERT (m_reach_facts.size () == m_reach_case_vars.size ()); SASSERT (m_reach_facts.size () == m_reach_case_vars.size ());
if (last_var) if (last_var) {fml = m.mk_or(m.mk_not(last_var), fact->get(), new_var);}
{ fml = m.mk_or(m.mk_not(last_var), fact->get(), new_var); } else {fml = m.mk_or(fact->get(), new_var);}
else
{ fml = m.mk_or(fact->get(), new_var); }
m_reach_ctx->assert_expr (fml); m_reach_ctx->assert_expr (fml);
TRACE ("spacer", TRACE ("spacer",
@ -1056,9 +1054,8 @@ void pred_transformer::add_reach_fact (reach_fact *fact)
lemma lem(m, fml, infty_level()); lemma lem(m, fml, infty_level());
// update users; reach facts are independent of levels // update users; reach facts are independent of levels
for (unsigned i = 0; i < m_use.size(); ++i) { for (auto use : m_use)
m_use[i]->add_lemma_from_child (*this, &lem, infty_level ()); {use->add_lemma_from_child (*this, &lem, infty_level());}
}
} }
expr_ref pred_transformer::get_reachable() expr_ref pred_transformer::get_reachable()
@ -1503,13 +1500,12 @@ void pred_transformer::init_reach_facts ()
expr_ref_vector v(m); expr_ref_vector v(m);
reach_fact_ref fact; reach_fact_ref fact;
rule2expr::iterator it = m_rule2tag.begin (), end = m_rule2tag.end (); for (auto &entry : m_rule2tag) {
for (; it != end; ++it) { const datalog::rule* r = entry.m_key;
const datalog::rule* r = it->m_key;
if (r->get_uninterpreted_tail_size() == 0) { if (r->get_uninterpreted_tail_size() == 0) {
fact = alloc (reach_fact, m, *r, m_rule2transition.find (r), fact = alloc (reach_fact, m, *r, m_rule2transition.find(r),
get_aux_vars (*r), true); get_aux_vars(*r), true);
add_reach_fact (fact.get ()); add_reach_fact(fact.get ());
} }
} }
} }
@ -1517,59 +1513,54 @@ void pred_transformer::init_reach_facts ()
void pred_transformer::init_rules(decl2rel const& pts, expr_ref& init, expr_ref& transition) void pred_transformer::init_rules(decl2rel const& pts, expr_ref& init, expr_ref& transition)
{ {
expr_ref_vector transitions(m); expr_ref_vector transitions(m);
ptr_vector<datalog::rule const> tr_rules; ptr_vector<const datalog::rule> tr_rules;
datalog::rule const* rule; datalog::rule const* rule;
expr_ref_vector disj(m), init_conds (m); expr_ref_vector disj(m), init_conds (m);
app_ref pred(m); app_ref pred(m);
vector<bool> is_init; vector<bool> is_init;
for (unsigned i = 0; i < rules().size(); ++i) { for (auto r : m_rules) {init_rule(pts, *r, is_init, tr_rules, transitions);}
init_rule(pts, *rules()[i], is_init, tr_rules, transitions);
}
SASSERT (is_init.size () == transitions.size ()); SASSERT (is_init.size () == transitions.size ());
std::string name;
switch(transitions.size()) { switch(transitions.size()) {
case 0: case 0:
transition = m.mk_false(); transition = m.mk_false();
break; break;
case 1: { case 1:
std::stringstream name;
// create a dummy tag. // create a dummy tag.
name << head()->get_name() << "_dummy"; name = head()->get_name().str() + "_dummy";
pred = m.mk_const(symbol(name.str().c_str()), m.mk_bool_sort()); pred = m.mk_const(symbol(name.c_str()), m.mk_bool_sort());
rule = tr_rules[0]; rule = tr_rules[0];
m_tag2rule.insert(pred, rule); m_tag2rule.insert(pred, rule);
m_rule2tag.insert(rule, pred.get()); m_rule2tag.insert(rule, pred.get());
transitions [0] = m.mk_implies (pred, transitions.get (0)); transitions[0] = m.mk_implies (pred, transitions.get(0));
transitions.push_back (m.mk_or (pred, m_extend_lit->get_arg (0))); transitions.push_back (m.mk_or (pred, m_extend_lit->get_arg(0)));
if (!is_init [0]) { init_conds.push_back(m.mk_not(pred)); } if (!is_init[0]) {init_conds.push_back(m.mk_not(pred));}
transition = mk_and(transitions); transition = mk_and(transitions);
break; break;
}
default: default:
disj.push_back (m_extend_lit->get_arg (0)); disj.push_back (m_extend_lit->get_arg(0));
for (unsigned i = 0; i < transitions.size(); ++i) { for (unsigned i = 0; i < transitions.size(); ++i) {
std::stringstream name; name = head()->get_name().str() + "__tr" + std::to_string(i);
name << head()->get_name() << "_tr" << i; pred = m.mk_const(symbol(name.c_str()), m.mk_bool_sort());
pred = m.mk_const(symbol(name.str().c_str()), m.mk_bool_sort());
rule = tr_rules[i]; rule = tr_rules[i];
m_tag2rule.insert(pred, rule); m_tag2rule.insert(pred, rule);
m_rule2tag.insert(rule, pred); m_rule2tag.insert(rule, pred);
disj.push_back(pred); disj.push_back(pred);
transitions[i] = m.mk_implies(pred, transitions[i].get()); transitions[i] = m.mk_implies(pred, transitions[i].get());
// update init conds // update init conds
if (!is_init[i]) { if (!is_init[i]) {init_conds.push_back (m.mk_not (pred));}
init_conds.push_back (m.mk_not (pred));
}
} }
transitions.push_back(m.mk_or(disj.size(), disj.c_ptr())); transitions.push_back(m.mk_or(disj.size(), disj.c_ptr()));
transition = mk_and(transitions); transition = mk_and(transitions);
break; break;
} }
// mk init condition // mk init condition
init = mk_and (init_conds); init = mk_and(init_conds);
if (init_conds.empty ()) { // no rule has uninterpreted tail // no rule has uninterpreted tail
m_all_init = true; if (init_conds.empty ()) {m_all_init = true;}
}
} }
static bool is_all_non_null(app_ref_vector const& v) static bool is_all_non_null(app_ref_vector const& v)
@ -1580,109 +1571,100 @@ static bool is_all_non_null(app_ref_vector const& v)
return true; return true;
} }
void pred_transformer::init_rule( void pred_transformer::init_rule(decl2rel const& pts, datalog::rule const& rule,
decl2rel const& pts, vector<bool>& is_init,
datalog::rule const& rule, ptr_vector<datalog::rule const>& rules,
vector<bool>& is_init, expr_ref_vector& transitions) {
ptr_vector<datalog::rule const>& rules,
expr_ref_vector& transitions)
{
scoped_watch _t_(m_initialize_watch); scoped_watch _t_(m_initialize_watch);
// Predicates that are variable representatives. Other predicates at // Predicates that are variable representatives. Other predicates at
// positions the variables occur are made equivalent with these. // positions the variables occur are made equivalent with these.
expr_ref_vector conj(m); expr_ref_vector side(m);
app_ref_vector& var_reprs = *(alloc(app_ref_vector, m)); app_ref_vector* var_reprs = alloc(app_ref_vector, m);
SASSERT(var_reprs);
ptr_vector<app> aux_vars; ptr_vector<app> aux_vars;
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();
SASSERT(ut_size <= t_size); SASSERT(ut_size <= t_size);
init_atom(pts, rule.get_head(), var_reprs, conj, UINT_MAX); init_atom(pts, rule.get_head(), *var_reprs, side, UINT_MAX);
for (unsigned i = 0; i < ut_size; ++i) { for (unsigned i = 0; i < ut_size; ++i) {
if (rule.is_neg_tail(i)) { if (rule.is_neg_tail(i)) {
throw default_exception("SPACER does not support negated predicates in rule tails"); throw default_exception("SPACER does not support "
"negated predicates in rule tails");
} }
init_atom(pts, rule.get_tail(i), var_reprs, conj, i); init_atom(pts, rule.get_tail(i), *var_reprs, side, i);
} }
// -- substitute free variables // -- substitute free variables
expr_ref fml(m); expr_ref fml(m);
{ {
expr_ref_vector tail(m); expr_ref_vector tail(m);
for (unsigned i = ut_size; i < t_size; ++i) for (unsigned i = ut_size; i < t_size; ++i)
{ tail.push_back(rule.get_tail(i)); } {tail.push_back(rule.get_tail(i));}
fml = mk_and (tail); fml = mk_and (tail);
ground_free_vars (fml, var_reprs, aux_vars, ut_size == 0); ground_free_vars(fml, *var_reprs, aux_vars, ut_size == 0);
SASSERT(is_all_non_null(var_reprs)); SASSERT(is_all_non_null(*var_reprs));
expr_ref tmp(m); expr_ref tmp(m);
var_subst (m, false)(fml, var_subst (m, false)(fml, var_reprs->size (),
var_reprs.size (), (expr*const*)var_reprs.c_ptr(), tmp); (expr*const*)var_reprs->c_ptr(), tmp);
flatten_and (tmp, conj); flatten_and (tmp, side);
fml = mk_and(conj); fml = mk_and(side);
conj.reset (); side.reset ();
} }
// rewrite and simplify
th_rewriter rw(m); th_rewriter rw(m);
rw(fml); rw(fml);
if (ctx.get_params().spacer_blast_term_ite()) { if (ctx.get_params().spacer_blast_term_ite()) {blast_term_ite(fml); rw(fml);}
blast_term_ite (fml);
rw(fml);
}
TRACE("spacer", tout << mk_pp(fml, m) << "\n";); TRACE("spacer", tout << mk_pp(fml, m) << "\n";);
// allow quantifiers in init rule // allow quantifiers in init rule
SASSERT(ut_size == 0 || is_ground(fml)); SASSERT(ut_size == 0 || is_ground(fml));
if (m.is_false(fml)) { if (!m.is_false(fml)) {
// no-op.
} else {
is_init.push_back (ut_size == 0); is_init.push_back (ut_size == 0);
transitions.push_back(fml); transitions.push_back(fml);
m.inc_ref(fml);
m_rule2transition.insert(&rule, fml.get());
rules.push_back(&rule); rules.push_back(&rule);
m.inc_ref(fml);
m_rule2transition.insert(&rule, fml);
} }
m_rule2inst.insert(&rule,&var_reprs); // AG: shouldn't this be under the if-statement above?
m_rule2inst.insert(&rule, var_reprs);
m_rule2vars.insert(&rule, aux_vars); m_rule2vars.insert(&rule, aux_vars);
TRACE("spacer", TRACE("spacer",
tout << rule.get_decl()->get_name() << "\n"; tout << rule.get_decl()->get_name() << "\n";
for (unsigned i = 0; i < var_reprs.size(); ++i) { tout << *var_reprs << "\n";);
tout << mk_pp(var_reprs[i].get(), m) << " ";
}
tout << "\n";);
} }
// 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, void pred_transformer::ground_free_vars(expr* e, app_ref_vector& vars,
ptr_vector<app>& aux_vars, bool is_init) ptr_vector<app>& aux_vars, bool is_init) {
{
expr_free_vars fv; expr_free_vars fv;
fv(e); fv(e);
while (vars.size() < fv.size()) { while (vars.size() < fv.size()) {vars.push_back(nullptr);}
vars.push_back(nullptr);
}
for (unsigned i = 0; i < fv.size(); ++i) { for (unsigned i = 0; i < fv.size(); ++i) {
if (fv[i] && !vars[i].get()) { if (fv[i] && !vars[i].get()) {
vars[i] = m.mk_fresh_const("aux", fv[i]); // AG: is it useful to make names unique across rules?
vars[i] = m.mk_const (pm.get_n_pred (vars.get (i)->get_decl ())); app_ref v(m);
aux_vars.push_back(vars[i].get()); v = m.mk_fresh_const("aux", fv[i]);
v = m.mk_const (pm.get_n_pred(v->get_decl ()));
vars[i] = v;
aux_vars.push_back(v);
} }
} }
} }
// create names for variables used in relations. // create names for variables used in relations.
void pred_transformer::init_atom( void pred_transformer::init_atom(decl2rel const &pts, app *atom,
decl2rel const& pts, app_ref_vector &var_reprs,
app * atom, expr_ref_vector &side, unsigned tail_idx) {
app_ref_vector& var_reprs,
expr_ref_vector& conj,
unsigned tail_idx
)
{
unsigned arity = atom->get_num_args(); unsigned arity = atom->get_num_args();
func_decl* head = atom->get_decl(); func_decl* head = atom->get_decl();
pred_transformer& pt = *pts.find(head); pred_transformer& pt = *pts.find(head);
@ -1704,13 +1686,13 @@ void pred_transformer::init_atom(
} }
expr * repr = var_reprs[var_idx].get(); expr * repr = var_reprs[var_idx].get();
if (repr) { if (repr) {
conj.push_back(m.mk_eq(rep, repr)); side.push_back(m.mk_eq(rep, repr));
} else { } else {
var_reprs[var_idx] = rep; var_reprs[var_idx] = rep;
} }
} else { } else {
SASSERT(is_app(arg)); SASSERT(is_app(arg));
conj.push_back(m.mk_eq(rep, arg)); side.push_back(m.mk_eq(rep, arg));
} }
} }
} }
@ -2061,23 +2043,22 @@ void context::init_rules(datalog::rule_set& rules, decl2rel& rels)
{ {
scoped_watch _t_(m_init_rules_watch); scoped_watch _t_(m_init_rules_watch);
m_context = &rules.get_context(); m_context = &rules.get_context();
// Allocate collection of predicate transformers // Allocate collection of predicate transformers
datalog::rule_set::decl2rules::iterator dit = rules.begin_grouped_rules(), dend = rules.end_grouped_rules(); for (auto dit = rules.begin_grouped_rules(),
decl2rel::obj_map_entry* e; dend = rules.end_grouped_rules(); dit != dend; ++dit) {
for (; dit != dend; ++dit) {
func_decl* pred = dit->m_key; func_decl* pred = dit->m_key;
TRACE("spacer", tout << mk_pp(pred, m) << "\n";); TRACE("spacer", tout << mk_pp(pred, m) << "\n";);
SASSERT(!rels.contains(pred)); SASSERT(!rels.contains(pred));
e = rels.insert_if_not_there2(pred, alloc(pred_transformer, *this, auto *e = rels.insert_if_not_there2(pred, alloc(pred_transformer, *this,
get_manager(), pred)); get_manager(), pred));
datalog::rule_vector const& pred_rules = *dit->m_value; datalog::rule_vector const& pred_rules = *dit->m_value;
for (unsigned i = 0; i < pred_rules.size(); ++i) { for (auto rule : pred_rules) {e->get_data().m_value->add_rule(rule);}
e->get_data().m_value->add_rule(pred_rules[i]);
}
} }
datalog::rule_set::iterator rit = rules.begin(), rend = rules.end();
for (; rit != rend; ++rit) { // Allocate predicate transformers for predicates that are used
datalog::rule* r = *rit; // but don't have rules
for (auto *r : rules) {
pred_transformer* pt; pred_transformer* pt;
unsigned utz = r->get_uninterpreted_tail_size(); unsigned utz = r->get_uninterpreted_tail_size();
for (unsigned i = 0; i < utz; ++i) { for (unsigned i = 0; i < utz; ++i) {
@ -2088,32 +2069,28 @@ void context::init_rules(datalog::rule_set& rules, decl2rel& rels)
} }
} }
} }
// Initialize use list dependencies // Initialize use list dependencies
decl2rel::iterator it = rels.begin(), end = rels.end(); // for (auto it = rels.begin(), end = rels.end(); it != end; ++it) {
for (; it != end; ++it) { for (auto &entry : rels) {
func_decl* pred = it->m_key; func_decl* pred = entry.m_key;
pred_transformer* pt = it->m_value, *pt_user; pred_transformer* pt = entry.m_value, *pt_user;
obj_hashtable<func_decl> const& deps = rules.get_dependencies().get_deps(pred); for (auto dep : rules.get_dependencies().get_deps(pred)) {
obj_hashtable<func_decl>::iterator itf = deps.begin(), endf = deps.end(); TRACE("spacer", tout << mk_pp(pred, m) << " " << mk_pp(dep, m) << "\n";);
for (; itf != endf; ++itf) { rels.find(dep, pt_user);
TRACE("spacer", tout << mk_pp(pred, m) << " " << mk_pp(*itf, m) << "\n";);
pt_user = rels.find(*itf);
pt_user->add_use(pt); pt_user->add_use(pt);
} }
} }
// Initialize the predicate transformers. // Initialize the predicate transformers.
it = rels.begin(), end = rels.end(); for (auto &entry : rels) {
for (; it != end; ++it) { pred_transformer* rel = entry.m_value;
pred_transformer& rel = *it->m_value; rel->initialize(rels);
rel.initialize(rels); TRACE("spacer", rel->display(tout); );
TRACE("spacer", rel.display(tout); );
} }
// initialize reach facts // initialize reach facts
it = rels.begin (), end = rels.end (); for (auto &entry : rels) {entry.m_value->init_reach_facts();}
for (; it != end; ++it)
{ it->m_value->init_reach_facts(); }
} }
void context::update_rules(datalog::rule_set& rules) void context::update_rules(datalog::rule_set& rules)
@ -2861,6 +2838,7 @@ bool context::check_reachability ()
node = m_pob_queue.top (); node = m_pob_queue.top ();
m_pob_queue.pop(); m_pob_queue.pop();
unsigned old_sz = m_pob_queue.size(); unsigned old_sz = m_pob_queue.size();
(void)old_sz;
SASSERT (node->level () <= m_pob_queue.max_level ()); SASSERT (node->level () <= m_pob_queue.max_level ());
switch (expand_pob(*node, new_pobs)) { switch (expand_pob(*node, new_pobs)) {
case l_true: case l_true:

View file

@ -316,7 +316,8 @@ class pred_transformer {
void init_rules(decl2rel const& pts, expr_ref& init, expr_ref& transition); void init_rules(decl2rel const& pts, expr_ref& init, expr_ref& transition);
void init_rule(decl2rel const& pts, datalog::rule const& rule, vector<bool>& is_init, void init_rule(decl2rel const& pts, datalog::rule const& rule, vector<bool>& is_init,
ptr_vector<datalog::rule const>& rules, expr_ref_vector& transition); ptr_vector<datalog::rule const>& rules, expr_ref_vector& transition);
void init_atom(decl2rel const& pts, app * atom, app_ref_vector& var_reprs, expr_ref_vector& conj, unsigned tail_idx); void init_atom(decl2rel const& pts, app * atom, app_ref_vector& var_reprs,
expr_ref_vector& side, unsigned tail_idx);
void simplify_formulas(tactic& tac, expr_ref_vector& fmls); void simplify_formulas(tactic& tac, expr_ref_vector& fmls);