1 /********************* */
2 /*! \file substitutions.h
4 ** Top contributors (to current version):
5 ** Morgan Deters, Dejan Jovanovic, Clark Barrett
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
8 ** in the top-level source directory and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
12 ** \brief A substitution mapping for theory simplification
14 ** A substitution mapping for theory simplification.
17 #include "cvc4_private.h"
19 #ifndef CVC4__THEORY__SUBSTITUTIONS_H
20 #define CVC4__THEORY__SUBSTITUTIONS_H
22 //#include <algorithm>
25 #include <unordered_map>
27 #include "expr/node.h"
28 #include "context/context.h"
29 #include "context/cdo.h"
30 #include "context/cdhashmap.h"
31 #include "util/hash.h"
37 * The type for the Substitutions mapping output by
38 * Theory::simplify(), TheoryEngine::simplify(), and
39 * Valuation::simplify(). This is in its own header to
40 * avoid circular dependences between those three.
42 * This map is context-dependent.
44 class SubstitutionMap
{
48 typedef context::CDHashMap
<Node
, Node
, NodeHashFunction
> NodeMap
;
50 typedef NodeMap::iterator iterator
;
51 typedef NodeMap::const_iterator const_iterator
;
55 typedef std::unordered_map
<Node
, Node
, NodeHashFunction
> NodeCache
;
57 /** The variables, in order of addition */
58 NodeMap d_substitutions
;
60 /** Cache of the already performed substitutions */
61 NodeCache d_substitutionCache
;
63 /** Whether or not to substitute under quantifiers */
64 bool d_substituteUnderQuantifiers
;
66 /** Has the cache been invalidated? */
67 bool d_cacheInvalidated
;
69 /** Internal method that performs substitution */
70 Node
internalSubstitute(TNode t
, NodeCache
& cache
);
72 /** Helper class to invalidate cache on user pop */
73 class CacheInvalidator
: public context::ContextNotifyObj
{
74 bool& d_cacheInvalidated
;
76 void contextNotifyPop() override
{ d_cacheInvalidated
= true; }
79 CacheInvalidator(context::Context
* context
, bool& cacheInvalidated
) :
80 context::ContextNotifyObj(context
),
81 d_cacheInvalidated(cacheInvalidated
) {
84 };/* class SubstitutionMap::CacheInvalidator */
87 * This object is notified on user pop and marks the SubstitutionMap's
88 * cache as invalidated.
90 CacheInvalidator d_cacheInvalidator
;
93 SubstitutionMap(context::Context
* context
,
94 bool substituteUnderQuantifiers
= true)
95 : d_substitutions(context
),
96 d_substitutionCache(),
97 d_substituteUnderQuantifiers(substituteUnderQuantifiers
),
98 d_cacheInvalidated(false),
99 d_cacheInvalidator(context
, d_cacheInvalidated
)
104 * Adds a substitution from x to t.
106 void addSubstitution(TNode x
, TNode t
, bool invalidateCache
= true);
109 * Merge subMap into current set of substitutions
111 void addSubstitutions(SubstitutionMap
& subMap
, bool invalidateCache
= true);
114 * Returns true iff x is in the substitution map
116 bool hasSubstitution(TNode x
) const {
117 return d_substitutions
.find(x
) != d_substitutions
.end();
121 * Returns the substitution mapping that was given for x via
122 * addSubstitution(). Note that the returned value might itself
123 * be in the map; for the actual substitution that would be
124 * performed for x, use .apply(x). This getSubstitution() function
125 * is mainly intended for constructing assertions about what has
126 * already been put in the map.
128 TNode
getSubstitution(TNode x
) const {
129 AssertArgument(hasSubstitution(x
), x
, "element not in this substitution map");
130 return (*d_substitutions
.find(x
)).second
;
134 * Apply the substitutions to the node.
139 * Apply the substitutions to the node.
141 Node
apply(TNode t
) const {
142 return const_cast<SubstitutionMap
*>(this)->apply(t
);
146 return d_substitutions
.begin();
150 return d_substitutions
.end();
153 const_iterator
begin() const {
154 return d_substitutions
.begin();
157 const_iterator
end() const {
158 return d_substitutions
.end();
162 return d_substitutions
.empty();
166 * Print to the output stream
168 void print(std::ostream
& out
) const;
169 void debugPrint() const;
171 };/* class SubstitutionMap */
173 inline std::ostream
& operator << (std::ostream
& out
, const SubstitutionMap
& subst
) {
178 }/* CVC4::theory namespace */
180 std::ostream
& operator<<(std::ostream
& out
, const theory::SubstitutionMap::iterator
& i
);
182 }/* CVC4 namespace */
184 #endif /* CVC4__THEORY__SUBSTITUTIONS_H */