3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

Replace rule API

This commit is contained in:
Arie Gurfinkel 2018-07-12 22:38:29 +03:00
parent 0035d9b8cb
commit 3a01fd791b
2 changed files with 46 additions and 26 deletions

View file

@ -31,7 +31,7 @@ namespace datalog {
rule_dependencies::rule_dependencies(const rule_dependencies & o, bool reversed): rule_dependencies::rule_dependencies(const rule_dependencies & o, bool reversed):
m_context(o.m_context) { m_context(o.m_context) {
if (reversed) { if (reversed) {
for (auto & kv : o) { for (auto & kv : o) {
func_decl * pred = kv.m_key; func_decl * pred = kv.m_key;
item_set & orig_items = *kv.get_value(); item_set & orig_items = *kv.get_value();
@ -114,8 +114,8 @@ namespace datalog {
app* a = to_app(e); app* a = to_app(e);
d = a->get_decl(); d = a->get_decl();
if (m_context.is_predicate(d)) { if (m_context.is_predicate(d)) {
// insert d and ensure the invariant // insert d and ensure the invariant
// that every predicate is present as // that every predicate is present as
// a key in m_data // a key in m_data
s.insert(d); s.insert(d);
ensure_key(d); ensure_key(d);
@ -148,7 +148,7 @@ namespace datalog {
item_set& itms = *kv.get_value(); item_set& itms = *kv.get_value();
set_intersection(itms, allowed); set_intersection(itms, allowed);
} }
for (func_decl* f : to_remove) for (func_decl* f : to_remove)
remove_m_data_entry(f); remove_m_data_entry(f);
} }
@ -253,18 +253,18 @@ namespace datalog {
// //
// ----------------------------------- // -----------------------------------
rule_set::rule_set(context & ctx) rule_set::rule_set(context & ctx)
: m_context(ctx), : m_context(ctx),
m_rule_manager(ctx.get_rule_manager()), m_rule_manager(ctx.get_rule_manager()),
m_rules(m_rule_manager), m_rules(m_rule_manager),
m_deps(ctx), m_deps(ctx),
m_stratifier(nullptr), m_stratifier(nullptr),
m_refs(ctx.get_manager()) { m_refs(ctx.get_manager()) {
} }
rule_set::rule_set(const rule_set & other) rule_set::rule_set(const rule_set & other)
: m_context(other.m_context), : m_context(other.m_context),
m_rule_manager(other.m_rule_manager), m_rule_manager(other.m_rule_manager),
m_rules(m_rule_manager), m_rules(m_rule_manager),
m_deps(other.m_context), m_deps(other.m_context),
m_stratifier(nullptr), m_stratifier(nullptr),
@ -353,10 +353,27 @@ namespace datalog {
break; \ break; \
} \ } \
} \ } \
DEL_VECTOR(*rules); DEL_VECTOR(*rules);
DEL_VECTOR(m_rules); DEL_VECTOR(m_rules);
} }
void rule_set::replace_rule(rule * r, rule * other) {
TRACE("dl", r->display(m_context, tout << "replace:"););
func_decl* d = r->get_decl();
rule_vector* rules = m_head2rules.find(d);
#define REPLACE_VECTOR(_v) \
for (unsigned i = (_v).size(); i > 0; ) { \
--i; \
if ((_v)[i] == r) { \
(_v)[i] = other; \
break; \
} \
} \
REPLACE_VECTOR(*rules);
REPLACE_VECTOR(m_rules);
}
void rule_set::ensure_closed() { void rule_set::ensure_closed() {
if (!is_closed()) { if (!is_closed()) {
@ -365,7 +382,7 @@ namespace datalog {
} }
bool rule_set::close() { bool rule_set::close() {
SASSERT(!is_closed()); //the rule_set is not already closed SASSERT(!is_closed()); //the rule_set is not already closed
m_deps.populate(*this); m_deps.populate(*this);
m_stratifier = alloc(rule_stratifier, m_deps); m_stratifier = alloc(rule_stratifier, m_deps);
if (!stratified_negation()) { if (!stratified_negation()) {
@ -426,7 +443,7 @@ namespace datalog {
inherit_predicates(src); inherit_predicates(src);
} }
const rule_vector & rule_set::get_predicate_rules(func_decl * pred) const { const rule_vector & rule_set::get_predicate_rules(func_decl * pred) const {
decl2rules::obj_map_entry * e = m_head2rules.find_core(pred); decl2rules::obj_map_entry * e = m_head2rules.find_core(pred);
if (!e) { if (!e) {
return m_empty_rule_vector; return m_empty_rule_vector;
@ -519,7 +536,7 @@ namespace datalog {
out << "\n"; out << "\n";
non_empty = false; non_empty = false;
} }
for (func_decl * first : *strat) { for (func_decl * first : *strat) {
const func_decl_set & deps = m_deps.get_deps(first); const func_decl_set & deps = m_deps.get_deps(first);
for (func_decl * dep : deps) { for (func_decl * dep : deps) {
@ -545,8 +562,8 @@ namespace datalog {
unsigned rule_stratifier::get_predicate_strat(func_decl * pred) const { unsigned rule_stratifier::get_predicate_strat(func_decl * pred) const {
unsigned num; unsigned num;
if (!m_pred_strat_nums.find(pred, num)) { if (!m_pred_strat_nums.find(pred, num)) {
//the number of the predicate is not stored, therefore it did not appear //the number of the predicate is not stored, therefore it did not appear
//in the algorithm and therefore it does not depend on anything and nothing //in the algorithm and therefore it does not depend on anything and nothing
//depends on it. So it is safe to assign zero strate to it, although it is //depends on it. So it is safe to assign zero strate to it, although it is
//not strictly true. //not strictly true.
num = 0; num = 0;
@ -641,7 +658,7 @@ namespace datalog {
} }
// We put components whose indegree is zero to m_strats and assign its // We put components whose indegree is zero to m_strats and assign its
// m_components entry to zero. // m_components entry to zero.
unsigned comp_cnt = m_components.size(); unsigned comp_cnt = m_components.size();
for (unsigned i = 0; i < comp_cnt; i++) { for (unsigned i = 0; i < comp_cnt; i++) {
@ -680,7 +697,7 @@ namespace datalog {
strats_index++; strats_index++;
} }
//we have managed to topologicaly order all the components //we have managed to topologicaly order all the components
SASSERT(std::find_if(m_components.begin(), m_components.end(), SASSERT(std::find_if(m_components.begin(), m_components.end(),
std::bind1st(std::not_equal_to<item_set*>(), (item_set*)0)) == m_components.end()); std::bind1st(std::not_equal_to<item_set*>(), (item_set*)0)) == m_components.end());
//reverse the strats array, so that the only the later components would depend on earlier ones //reverse the strats array, so that the only the later components would depend on earlier ones
@ -713,7 +730,7 @@ namespace datalog {
} }
out << "\n"; out << "\n";
} }
} }
}; };

View file

@ -77,7 +77,7 @@ namespace datalog {
\brief Number of predicates that depend on \c f. \brief Number of predicates that depend on \c f.
*/ */
unsigned out_degree(func_decl * f) const; unsigned out_degree(func_decl * f) const;
/** /**
\brief If the rependency graph is acyclic, put all elements into \c res \brief If the rependency graph is acyclic, put all elements into \c res
ordered so that elements can depend only on elements that are before them. ordered so that elements can depend only on elements that are before them.
@ -131,7 +131,7 @@ namespace datalog {
it must exist for the whole lifetime of the \c stratifier object. it must exist for the whole lifetime of the \c stratifier object.
*/ */
rule_stratifier(const rule_dependencies & deps) rule_stratifier(const rule_dependencies & deps)
: m_deps(deps), m_next_preorder(0) : m_deps(deps), m_next_preorder(0)
{ {
process(); process();
} }
@ -145,7 +145,7 @@ namespace datalog {
const comp_vector & get_strats() const { return m_strats; } const comp_vector & get_strats() const { return m_strats; }
unsigned get_predicate_strat(func_decl * pred) const; unsigned get_predicate_strat(func_decl * pred) const;
void display( std::ostream & out ) const; void display( std::ostream & out ) const;
}; };
@ -203,6 +203,10 @@ namespace datalog {
\brief Remove rule \c r from the rule set. \brief Remove rule \c r from the rule set.
*/ */
void del_rule(rule * r); void del_rule(rule * r);
/**
\brief Replace a rule \c r with the rule \c other
*/
void replace_rule(rule * r, rule * other);
/** /**
\brief Add all rules from a different rule_set. \brief Add all rules from a different rule_set.
@ -276,8 +280,7 @@ namespace datalog {
inline std::ostream& operator<<(std::ostream& out, rule_set const& r) { r.display(out); return out; } inline std::ostream& operator<<(std::ostream& out, rule_set const& r) { r.display(out); return out; }
}; };
#endif /* DL_RULE_SET_H_ */ #endif /* DL_RULE_SET_H_ */