summaryrefslogtreecommitdiff
path: root/src/theory/uf/equality_engine.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/uf/equality_engine.h')
-rw-r--r--src/theory/uf/equality_engine.h261
1 files changed, 24 insertions, 237 deletions
diff --git a/src/theory/uf/equality_engine.h b/src/theory/uf/equality_engine.h
index c59436aaf..8fc57eb48 100644
--- a/src/theory/uf/equality_engine.h
+++ b/src/theory/uf/equality_engine.h
@@ -24,7 +24,6 @@
#include <queue>
#include <vector>
#include <ext/hash_map>
-#include <sstream>
#include "expr/node.h"
#include "expr/kind_map.h"
@@ -34,186 +33,12 @@
#include "theory/rewriter.h"
#include "theory/theory.h"
+#include "theory/uf/equality_engine_types.h"
+
namespace CVC4 {
namespace theory {
namespace eq {
-/** Id of the node */
-typedef size_t EqualityNodeId;
-
-/** Id of the use list */
-typedef size_t UseListNodeId;
-
-/** The trigger ids */
-typedef size_t TriggerId;
-
-/** The equality edge ids */
-typedef size_t EqualityEdgeId;
-
-/** The null node */
-static const EqualityNodeId null_id = (size_t)(-1);
-
-/** The null use list node */
-static const EqualityNodeId null_uselist_id = (size_t)(-1);
-
-/** The null trigger */
-static const TriggerId null_trigger = (size_t)(-1);
-
-/** The null edge id */
-static const EqualityEdgeId null_edge = (size_t)(-1);
-
-/**
- * A reason for a merge. Either an equality x = y, or a merge of two
- * function applications f(x1, x2), f(y1, y2)
- */
-enum MergeReasonType {
- MERGED_THROUGH_CONGRUENCE,
- MERGED_THROUGH_EQUALITY
-};
-
-inline std::ostream& operator << (std::ostream& out, MergeReasonType reason) {
- switch (reason) {
- case MERGED_THROUGH_CONGRUENCE:
- out << "c";
- break;
- case MERGED_THROUGH_EQUALITY:
- out << "e";
- break;
- default:
- Unreachable();
- }
- return out;
-}
-
-/** A node in the uselist */
-class UseListNode {
-
-private:
-
- /** The id of the application node where this representative is at */
- EqualityNodeId d_applicationId;
-
- /** The next one in the class */
- UseListNodeId d_nextUseListNodeId;
-
-public:
-
- /**
- * Creates a new node, which is in a list of it's own.
- */
- UseListNode(EqualityNodeId nodeId = null_id, UseListNodeId nextId = null_uselist_id)
- : d_applicationId(nodeId), d_nextUseListNodeId(nextId) {}
-
- /**
- * Returns the next node in the circular list.
- */
- UseListNodeId getNext() const {
- return d_nextUseListNodeId;
- }
-
- /**
- * Returns the id of the function application.
- */
- EqualityNodeId getApplicationId() const {
- return d_applicationId;
- }
-};
-
-
-class EqualityNode {
-
-private:
-
- /** The size of this equivalence class (if it's a representative) */
- size_t d_size;
-
- /** The id (in the eq-manager) of the representative equality node */
- EqualityNodeId d_findId;
-
- /** The next equality node in this class */
- EqualityNodeId d_nextId;
-
- /** The use list of this node */
- UseListNodeId d_useList;
-
-public:
-
- /**
- * Creates a new node, which is in a list of it's own.
- */
- EqualityNode(EqualityNodeId nodeId = null_id)
- : d_size(1),
- d_findId(nodeId),
- d_nextId(nodeId),
- d_useList(null_uselist_id)
- {}
-
- /**
- * Retuerns the uselist.
- */
- UseListNodeId getUseList() const {
- return d_useList;
- }
-
- /**
- * Returns the next node in the class circular list.
- */
- EqualityNodeId getNext() const {
- return d_nextId;
- }
-
- /**
- * Returns the size of this equivalence class (only valid if this is the representative).
- */
- size_t getSize() const {
- return d_size;
- }
-
- /**
- * Merges the two lists. If add size is true the size of this node is increased by the size of
- * the other node, otherwise the size is decreased by the size of the other node.
- */
- template<bool addSize>
- void merge(EqualityNode& other) {
- EqualityNodeId tmp = d_nextId; d_nextId = other.d_nextId; other.d_nextId = tmp;
- if (addSize) {
- d_size += other.d_size;
- } else {
- d_size -= other.d_size;
- }
- }
-
- /**
- * Returns the class representative.
- */
- EqualityNodeId getFind() const { return d_findId; }
-
- /**
- * Set the class representative.
- */
- void setFind(EqualityNodeId findId) { d_findId = findId; }
-
- /**
- * Note that this node is used in a function a application funId.
- */
- template<typename memory_class>
- void usedIn(EqualityNodeId funId, memory_class& memory) {
- UseListNodeId newUseId = memory.size();
- memory.push_back(UseListNode(funId, d_useList));
- d_useList = newUseId;
- }
-
- /**
- * For backtracking: remove the first element from the uselist and pop the memory.
- */
- template<typename memory_class>
- void removeTopFromUseList(memory_class& memory) {
- Assert ((int)d_useList == (int)memory.size() - 1);
- d_useList = memory.back().getNext();
- memory.pop_back();
- }
-};
-
/**
* Interface for equality engine notifications. All the notifications
* are safe as TNodes, but not necessarily for negations.
@@ -317,30 +142,6 @@ public:
};
/**
- * f(a,b)
- */
- struct FunctionApplication {
- EqualityNodeId a, b;
- FunctionApplication(EqualityNodeId a = null_id, EqualityNodeId b = null_id):
- a(a), b(b) {}
- bool operator == (const FunctionApplication& other) const {
- return a == other.a && b == other.b;
- }
- bool isApplication() const {
- return a != null_id && b != null_id;
- }
- };
-
- struct FunctionApplicationHashFunction {
- size_t operator () (const FunctionApplication& app) const {
- size_t hash = 0;
- hash = 0x9e3779b9 + app.a;
- hash ^= 0x9e3779b9 + app.b + (hash << 6) + (hash >> 2);
- return hash;
- }
- };
-
- /**
* Store the application lookup, with enough information to backtrack
*/
void storeApplicationLookup(FunctionApplication& funNormalized, EqualityNodeId funId);
@@ -350,6 +151,9 @@ private:
/** The context we are using */
context::Context* d_context;
+ /** If we are done, we don't except any new assertions */
+ context::CDO<bool> d_done;
+
/** Whether to notify or not (temporarily disabled on equality checks) */
bool d_performNotify;
@@ -375,13 +179,13 @@ private:
std::vector<FunctionApplication> d_applicationLookups;
/** Number of application lookups, for backtracking. */
- context::CDO<size_t> d_applicationLookupsCount;
+ context::CDO<DefaultSizeType> d_applicationLookupsCount;
/** Map from ids to the nodes (these need to be nodes as we pick-up the opreators) */
std::vector<Node> d_nodes;
/** A context-dependents count of nodes */
- context::CDO<size_t> d_nodesCount;
+ context::CDO<DefaultSizeType> d_nodesCount;
/**
* At time of addition a function application can already normalize to something, so
@@ -404,7 +208,7 @@ private:
std::vector<EqualityNode> d_equalityNodes;
/** Number of asserted equalities we have so far */
- context::CDO<size_t> d_assertedEqualitiesCount;
+ context::CDO<DefaultSizeType> d_assertedEqualitiesCount;
/** Memory for the use-list nodes */
std::vector<UseListNode> d_useListNodes;
@@ -550,7 +354,7 @@ private:
/**
* Context dependent count of triggers
*/
- context::CDO<size_t> d_equalityTriggersCount;
+ context::CDO<DefaultSizeType> d_equalityTriggersCount;
/**
* Trigger lists per node. The begin id changes as we merge, but the end always points to
@@ -559,23 +363,15 @@ private:
std::vector<TriggerId> d_nodeTriggers;
/**
- * Map from ids to the id of the constant that is the representative.
+ * Map from ids to wheather they are constants (constants are always
+ * representatives of their class.
*/
- std::vector<EqualityNodeId> d_constantRepresentative;
+ std::vector<bool> d_isConstant;
/**
- * Size of the constant representatives list.
+ * Map from ids to wheather they are Boolean.
*/
- context::CDO<unsigned> d_constantRepresentativesSize;
-
- /** The list of representatives that became constant. */
- std::vector<EqualityNodeId> d_constantRepresentatives;
-
- /** List of all the constants. */
- std::vector<TNode> d_constants;
-
- /** Size of the constants list */
- context::CDO<unsigned> d_constantsSize;
+ std::vector<bool> d_isBoolean;
/**
* Adds the trigger with triggerId to the beginning of the trigger list of the node with id nodeId.
@@ -586,25 +382,11 @@ private:
Statistics d_stats;
/** Add a new function application node to the database, i.e APP t1 t2 */
- EqualityNodeId newApplicationNode(TNode original, EqualityNodeId t1, EqualityNodeId t2);
+ EqualityNodeId newApplicationNode(TNode original, EqualityNodeId t1, EqualityNodeId t2, bool isEquality);
/** Add a new node to the database */
EqualityNodeId newNode(TNode t);
- struct MergeCandidate {
- EqualityNodeId t1Id, t2Id;
- MergeReasonType type;
- TNode reason;
- MergeCandidate(EqualityNodeId x, EqualityNodeId y, MergeReasonType type, TNode reason):
- t1Id(x), t2Id(y), type(type), reason(reason) {}
-
- std::string toString(EqualityEngine& eqEngine) const {
- std::stringstream ss;
- ss << eqEngine.d_nodes[t1Id] << " = " << eqEngine.d_nodes[t2Id] << ", " << type;
- return ss.str();
- }
- };
-
/** Propagation queue */
std::queue<MergeCandidate> d_propagationQueue;
@@ -628,8 +410,13 @@ private:
/** The true node */
Node d_true;
+ /** True node id */
+ EqualityNodeId d_trueId;
+
/** The false node */
Node d_false;
+ /** False node id */
+ EqualityNodeId d_falseId;
/**
* Adds an equality of terms t1 and t2 to the database.
@@ -680,13 +467,13 @@ private:
char* d_triggerDatabase;
/** Allocated size of the trigger term database */
- size_t d_triggerDatabaseAllocatedSize ;
+ DefaultSizeType d_triggerDatabaseAllocatedSize ;
/** Reference for the trigger terms set */
- typedef size_t TriggerTermSetRef;
+ typedef DefaultSizeType TriggerTermSetRef;
/** Null reference */
- static const TriggerTermSetRef null_set_id = (size_t)(-1);
+ static const TriggerTermSetRef null_set_id = (TriggerTermSetRef)(-1);
/** Create new trigger term set based on the internally set information */
TriggerTermSetRef newTriggerTermSet();
@@ -704,7 +491,7 @@ private:
}
/** Used part of the trigger term database */
- context::CDO<size_t> d_triggerDatabaseSize;
+ context::CDO<DefaultSizeType> d_triggerDatabaseSize;
struct TriggerSetUpdate {
EqualityNodeId classId;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback