mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 03:15:50 +00:00
Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
3f9edad676
commit
e9eab22e5c
1186 changed files with 381859 additions and 0 deletions
260
lib/dl_rule_set.h
Normal file
260
lib/dl_rule_set.h
Normal file
|
@ -0,0 +1,260 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
dl_rule_set.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2010-05-17.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _DL_RULE_SET_H_
|
||||
#define _DL_RULE_SET_H_
|
||||
|
||||
#include"obj_hashtable.h"
|
||||
|
||||
#include"dl_rule.h"
|
||||
|
||||
namespace datalog {
|
||||
|
||||
class rule_set;
|
||||
|
||||
class rule_dependencies {
|
||||
public:
|
||||
typedef obj_hashtable<func_decl> item_set;
|
||||
typedef obj_map<func_decl, item_set * > deps_type;
|
||||
|
||||
typedef deps_type::iterator iterator;
|
||||
private:
|
||||
/**
|
||||
Map (dependent -> set of master objects)
|
||||
|
||||
Each master object is also present as a key of the map, even if its master set
|
||||
is empty.
|
||||
*/
|
||||
deps_type m_data;
|
||||
context & m_context;
|
||||
ptr_vector<expr> m_todo;
|
||||
ast_mark m_visited;
|
||||
|
||||
|
||||
//we need to take care with removing to aviod memory leaks
|
||||
void remove_m_data_entry(func_decl * key);
|
||||
|
||||
//sometimes we need to return reference to an empty set,
|
||||
//so we return reference to this one.
|
||||
item_set m_empty_item_set;
|
||||
|
||||
item_set & ensure_key(func_decl * pred);
|
||||
void insert(func_decl * depending, func_decl * master);
|
||||
void populate(rule const* r);
|
||||
public:
|
||||
rule_dependencies(context& ctx);
|
||||
rule_dependencies(const rule_dependencies & o, bool reversed = false);
|
||||
~rule_dependencies();
|
||||
void reset();
|
||||
|
||||
void populate(const rule_set & rules);
|
||||
void populate(unsigned n, rule * const * rules);
|
||||
void restrict(const item_set & allowed);
|
||||
void remove(func_decl * itm);
|
||||
void remove(const item_set & to_remove);
|
||||
|
||||
bool empty() const { return m_data.empty(); }
|
||||
const item_set & get_deps(func_decl * f) const;
|
||||
/**
|
||||
\brief Number of predicates \c f depends on.
|
||||
*/
|
||||
unsigned in_degree(func_decl * f) const { return get_deps(f).size(); }
|
||||
/**
|
||||
\brief Number of predicates that depend on \c f.
|
||||
*/
|
||||
unsigned out_degree(func_decl * f) const;
|
||||
|
||||
/**
|
||||
\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.
|
||||
If the graph is not acyclic, return false.
|
||||
*/
|
||||
bool sort_deps(ptr_vector<func_decl> & res);
|
||||
|
||||
iterator begin() const { return m_data.begin(); }
|
||||
iterator end() const { return m_data.end(); }
|
||||
|
||||
void display( std::ostream & out ) const;
|
||||
};
|
||||
|
||||
class rule_stratifier {
|
||||
public:
|
||||
typedef func_decl T;
|
||||
typedef obj_hashtable<T> item_set;
|
||||
typedef ptr_vector<item_set> comp_vector;
|
||||
typedef obj_map<T, item_set *> deps_type;
|
||||
private:
|
||||
|
||||
const rule_dependencies & m_deps;
|
||||
comp_vector m_strats;
|
||||
|
||||
obj_map<T, unsigned> m_preorder_nums;
|
||||
ptr_vector<T> m_stack_S;
|
||||
ptr_vector<T> m_stack_P;
|
||||
|
||||
obj_map<T, unsigned> m_component_nums;
|
||||
comp_vector m_components;
|
||||
obj_map<T, unsigned> m_pred_strat_nums;
|
||||
|
||||
unsigned m_next_preorder;
|
||||
unsigned m_first_preorder;
|
||||
|
||||
/**
|
||||
Finds strongly connected components using the Gabow's algorithm.
|
||||
*/
|
||||
void traverse(T* el);
|
||||
|
||||
/**
|
||||
Calls \c traverse to identify strognly connected components and then
|
||||
orders them using topological sorting.
|
||||
*/
|
||||
void process();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
\remark The \c stratifier object keeps a reference to the \c deps object, so
|
||||
it must exist for the whole lifetime of the \c stratifier object.
|
||||
*/
|
||||
rule_stratifier(const rule_dependencies & deps)
|
||||
: m_deps(deps), m_next_preorder(0)
|
||||
{
|
||||
process();
|
||||
}
|
||||
|
||||
~rule_stratifier();
|
||||
|
||||
/**
|
||||
Return vector of components ordered so that the only dependencies are from
|
||||
later components to earlier.
|
||||
*/
|
||||
const comp_vector & get_strats() const { return m_strats; }
|
||||
|
||||
unsigned get_predicate_strat(func_decl * pred) const;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Datalog "Program" (aka rule set).
|
||||
*/
|
||||
class rule_set {
|
||||
friend class rule_dependencies;
|
||||
public:
|
||||
typedef ptr_vector<func_decl_set> pred_set_vector;
|
||||
typedef obj_map<func_decl, rule_vector*> decl2rules;
|
||||
private:
|
||||
typedef obj_map<func_decl, func_decl_set*> decl2deps;
|
||||
|
||||
context & m_context;
|
||||
rule_manager & m_rule_manager;
|
||||
rule_ref_vector m_rules; //!< all rules
|
||||
decl2rules m_head2rules; //!< mapping from head symbol to rules.
|
||||
rule_dependencies m_deps; //!< dependencies
|
||||
scoped_ptr<rule_stratifier> m_stratifier; //!< contains stratifier object iff the rule_set is closed
|
||||
|
||||
|
||||
//sometimes we need to return reference to an empty rule_vector,
|
||||
//so we return reference to this one.
|
||||
rule_vector m_empty_rule_vector;
|
||||
|
||||
void compute_deps();
|
||||
void compute_tc_deps();
|
||||
bool stratified_negation();
|
||||
public:
|
||||
rule_set(context & ctx);
|
||||
rule_set(const rule_set & rs);
|
||||
~rule_set();
|
||||
|
||||
ast_manager & get_manager() const;
|
||||
rule_manager & get_rule_manager() const { return const_cast<rule_manager&>(m_rule_manager); }
|
||||
context& get_context() const { return m_context; }
|
||||
|
||||
/**
|
||||
\brief Add rule \c r to the rule set.
|
||||
*/
|
||||
void add_rule(rule * r);
|
||||
|
||||
/**
|
||||
\brief Remove rule \c r from the rule set.
|
||||
*/
|
||||
void del_rule(rule * r);
|
||||
|
||||
/**
|
||||
\brief Add all rules from a different rule_set.
|
||||
*/
|
||||
void add_rules(const rule_set& src);
|
||||
void add_rules(unsigned sz, rule * const * rules);
|
||||
|
||||
/**
|
||||
\brief This method should be invoked after all rules are added to the rule set.
|
||||
It will check if the negation is indeed stratified.
|
||||
Return true if succeeded.
|
||||
|
||||
\remark If new rules are added, the rule_set will be "reopen".
|
||||
*/
|
||||
bool close();
|
||||
void ensure_closed();
|
||||
/**
|
||||
\brief Undo the effect of the \c close() operation.
|
||||
*/
|
||||
void reopen();
|
||||
bool is_closed() const { return m_stratifier != 0; }
|
||||
|
||||
unsigned get_num_rules() const { return m_rules.size(); }
|
||||
|
||||
rule * get_rule(unsigned i) const { return m_rules[i]; }
|
||||
rule_ref_vector const& get_rules() const { return m_rules; }
|
||||
|
||||
const rule_vector & get_predicate_rules(func_decl * pred) const;
|
||||
|
||||
const rule_stratifier & get_stratifier() const {
|
||||
SASSERT(m_stratifier);
|
||||
return *m_stratifier;
|
||||
}
|
||||
const pred_set_vector & get_strats() const;
|
||||
unsigned get_predicate_strat(func_decl * pred) const;
|
||||
const rule_dependencies & get_dependencies() const { SASSERT(is_closed()); return m_deps; }
|
||||
|
||||
|
||||
void reset();
|
||||
|
||||
void display(std::ostream & out) const;
|
||||
|
||||
/**
|
||||
\brief Output rule dependencies.
|
||||
|
||||
The rule set must be closed before calling this function.
|
||||
*/
|
||||
void display_deps(std::ostream & out) const;
|
||||
|
||||
typedef rule * const * iterator;
|
||||
iterator begin() const { return m_rules.c_ptr(); }
|
||||
iterator end() const { return m_rules.c_ptr()+m_rules.size(); }
|
||||
|
||||
decl2rules::iterator begin_grouped_rules() const { return m_head2rules.begin(); }
|
||||
decl2rules::iterator end_grouped_rules() const { return m_head2rules.end(); }
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, rule_set const& r) { r.display(out); return out; }
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* _DL_RULE_SET_H_ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue