1 /********************* */
4 ** Original author: mdeters
5 ** Major contributors: none
6 ** Minor contributors (to current version): none
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
9 ** Courant Institute of Mathematical Sciences
10 ** New York University
11 ** See the file COPYING in the top-level source directory for licensing
12 ** information.\endverbatim
14 ** \brief Path-compressing, backtrackable union-find using an undo
17 ** Path-compressing, backtrackable union-find using an undo stack
18 ** rather than storing items in a CDMap<>.
21 #include "cvc4_private.h"
23 #ifndef __CVC4__THEORY__UF__MORGAN__UNION_FIND_H
24 #define __CVC4__THEORY__UF__MORGAN__UNION_FIND_H
28 #include <ext/hash_map>
30 #include "expr/node.h"
31 #include "context/cdo.h"
37 }/* CVC4::context namespace */
43 // NodeType \in { Node, TNode }
44 template <class NodeType
, class NodeHash
>
45 class UnionFind
: context::ContextNotifyObj
{
46 /** Our underlying map type. */
47 typedef __gnu_cxx::hash_map
<NodeType
, NodeType
, NodeHash
> MapType
;
50 * Our map of Nodes to their canonical representatives.
51 * If a Node is not present in the map, it is its own
56 /** Our undo stack for changes made to d_map. */
57 std::vector
<std::pair
<TNode
, TNode
> > d_trace
;
59 /** Our current offset in the d_trace stack (context-dependent). */
60 context::CDO
<size_t> d_offset
;
63 UnionFind(context::Context
* ctxt
) :
64 context::ContextNotifyObj(ctxt
),
68 ~UnionFind() throw() { }
71 * Return a Node's union-find representative, doing path compression.
73 inline TNode
find(TNode n
);
76 * Return a Node's union-find representative, NOT doing path compression.
77 * This is useful for Assert() statements, debug checking, and similar
78 * things that you do NOT want to mutate the structure.
80 inline TNode
debugFind(TNode n
) const;
83 * Set the canonical representative of n to newParent. They should BOTH
84 * be their own canonical representatives on entry to this funciton.
86 inline void setCanon(TNode n
, TNode newParent
);
89 * Called by the Context when a pop occurs. Cancels everything to the
90 * current context level. Overrides ContextNotifyObj::notify().
94 };/* class UnionFind<> */
96 template <class NodeType
, class NodeHash
>
97 inline TNode UnionFind
<NodeType
, NodeHash
>::debugFind(TNode n
) const {
98 typename
MapType::const_iterator i
= d_map
.find(n
);
99 if(i
== d_map
.end()) {
102 return debugFind((*i
).second
);
106 template <class NodeType
, class NodeHash
>
107 inline TNode UnionFind
<NodeType
, NodeHash
>::find(TNode n
) {
108 Trace("ufuf") << "UFUF find of " << n
<< std::endl
;
109 typename
MapType::iterator i
= d_map
.find(n
);
110 if(i
== d_map
.end()) {
111 Trace("ufuf") << "UFUF it is rep" << std::endl
;
114 Trace("ufuf") << "UFUF not rep: par is " << (*i
).second
<< std::endl
;
115 std::pair
<TNode
, TNode
> pr
= *i
;
116 // our iterator is invalidated by the recursive call to find(),
117 // since it mutates the map
118 TNode p
= find(pr
.second
);
122 d_trace
.push_back(std::make_pair(n
, pr
.second
));
123 d_offset
= d_trace
.size();
124 Trace("ufuf") << "UFUF setting canon of " << n
<< " : " << p
<< " @ " << d_trace
.size() << std::endl
;
131 template <class NodeType
, class NodeHash
>
132 inline void UnionFind
<NodeType
, NodeHash
>::setCanon(TNode n
, TNode newParent
) {
133 Assert(d_map
.find(n
) == d_map
.end());
134 Assert(d_map
.find(newParent
) == d_map
.end());
136 Trace("ufuf") << "UFUF setting canon of " << n
<< " : " << newParent
<< " @ " << d_trace
.size() << std::endl
;
137 d_map
[n
] = newParent
;
138 d_trace
.push_back(std::make_pair(n
, TNode::null()));
139 d_offset
= d_trace
.size();
143 }/* CVC4::theory::uf::morgan namespace */
144 }/* CVC4::theory::uf namespace */
145 }/* CVC4::theory namespace */
146 }/* CVC4 namespace */
148 #endif /*__CVC4__THEORY__UF__MORGAN__UNION_FIND_H */