1 /********************* */
4 ** Top contributors (to current version):
5 ** Dejan Jovanovic, Morgan Deters, Tim King
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2016 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 This is the interface to TheoryUF implementations
14 ** This is the interface to TheoryUF implementations. All
15 ** implementations of TheoryUF should inherit from this class.
18 #include "cvc4_private.h"
20 #ifndef __CVC4__THEORY__UF__THEORY_UF_H
21 #define __CVC4__THEORY__UF__THEORY_UF_H
23 #include "expr/node.h"
24 //#include "expr/attribute.h"
26 #include "theory/theory.h"
27 #include "theory/uf/equality_engine.h"
28 #include "theory/uf/symmetry_breaker.h"
30 #include "context/cdo.h"
31 #include "context/cdhashset.h"
36 namespace quantifiers
{
43 class StrongSolverTheoryUF
;
45 class TheoryUF
: public Theory
{
47 friend class StrongSolverTheoryUF
;
51 class NotifyClass
: public eq::EqualityEngineNotify
{
54 NotifyClass(TheoryUF
& uf
): d_uf(uf
) {}
56 bool eqNotifyTriggerEquality(TNode equality
, bool value
) {
57 Debug("uf") << "NotifyClass::eqNotifyTriggerEquality(" << equality
<< ", " << (value
? "true" : "false" )<< ")" << std::endl
;
59 return d_uf
.propagate(equality
);
61 // We use only literal triggers so taking not is safe
62 return d_uf
.propagate(equality
.notNode());
66 bool eqNotifyTriggerPredicate(TNode predicate
, bool value
) {
67 Debug("uf") << "NotifyClass::eqNotifyTriggerPredicate(" << predicate
<< ", " << (value
? "true" : "false") << ")" << std::endl
;
69 return d_uf
.propagate(predicate
);
71 return d_uf
.propagate(predicate
.notNode());
75 bool eqNotifyTriggerTermEquality(TheoryId tag
, TNode t1
, TNode t2
, bool value
) {
76 Debug("uf") << "NotifyClass::eqNotifyTriggerTermMerge(" << tag
<< ", " << t1
<< ", " << t2
<< ")" << std::endl
;
78 return d_uf
.propagate(t1
.eqNode(t2
));
80 return d_uf
.propagate(t1
.eqNode(t2
).notNode());
84 void eqNotifyConstantTermMerge(TNode t1
, TNode t2
) {
85 Debug("uf-notify") << "NotifyClass::eqNotifyConstantTermMerge(" << t1
<< ", " << t2
<< ")" << std::endl
;
86 d_uf
.conflict(t1
, t2
);
89 void eqNotifyNewClass(TNode t
) {
90 Debug("uf-notify") << "NotifyClass::eqNotifyNewClass(" << t
<< ")" << std::endl
;
91 d_uf
.eqNotifyNewClass(t
);
94 void eqNotifyPreMerge(TNode t1
, TNode t2
) {
95 Debug("uf-notify") << "NotifyClass::eqNotifyPreMerge(" << t1
<< ", " << t2
<< ")" << std::endl
;
96 d_uf
.eqNotifyPreMerge(t1
, t2
);
99 void eqNotifyPostMerge(TNode t1
, TNode t2
) {
100 Debug("uf-notify") << "NotifyClass::eqNotifyPostMerge(" << t1
<< ", " << t2
<< ")" << std::endl
;
101 d_uf
.eqNotifyPostMerge(t1
, t2
);
104 void eqNotifyDisequal(TNode t1
, TNode t2
, TNode reason
) {
105 Debug("uf-notify") << "NotifyClass::eqNotifyDisequal(" << t1
<< ", " << t2
<< ", " << reason
<< ")" << std::endl
;
106 d_uf
.eqNotifyDisequal(t1
, t2
, reason
);
109 };/* class TheoryUF::NotifyClass */
113 /** The notify class */
114 NotifyClass d_notify
;
116 /** The associated theory strong solver (or NULL if none) */
117 StrongSolverTheoryUF
* d_thss
;
119 /** Equaltity engine */
120 eq::EqualityEngine d_equalityEngine
;
122 /** Are we in conflict */
123 context::CDO
<bool> d_conflict
;
125 /** The conflict node */
129 * Should be called to propagate the literal. We use a node here
130 * since some of the propagated literals are not kept anywhere.
132 bool propagate(TNode literal
);
135 * Explain why this literal is true by adding assumptions
136 * with proof (if "pf" is non-NULL).
138 void explain(TNode literal
, std::vector
<TNode
>& assumptions
, eq::EqProof
* pf
);
141 * Explain a literal, with proof (if "pf" is non-NULL).
143 Node
explain(TNode literal
, eq::EqProof
* pf
);
145 /** Literals to propagate */
146 context::CDList
<Node
> d_literalsToPropagate
;
148 /** Index of the next literal to propagate */
149 context::CDO
<unsigned> d_literalsToPropagateIndex
;
151 /** All the function terms that the theory has seen */
152 context::CDList
<TNode
> d_functionsTerms
;
154 /** Symmetry analyzer */
155 SymmetryBreaker d_symb
;
157 /** Conflict when merging two constants */
158 void conflict(TNode a
, TNode b
);
160 /** called when a new equivalance class is created */
161 void eqNotifyNewClass(TNode t
);
163 /** called when two equivalance classes will merge */
164 void eqNotifyPreMerge(TNode t1
, TNode t2
);
166 /** called when two equivalance classes have merged */
167 void eqNotifyPostMerge(TNode t1
, TNode t2
);
169 /** called when two equivalence classes are made disequal */
170 void eqNotifyDisequal(TNode t1
, TNode t2
, TNode reason
);
174 /** Constructs a new instance of TheoryUF w.r.t. the provided context.*/
175 TheoryUF(context::Context
* c
, context::UserContext
* u
, OutputChannel
& out
,
176 Valuation valuation
, const LogicInfo
& logicInfo
,
177 std::string instanceName
= "");
181 void setMasterEqualityEngine(eq::EqualityEngine
* eq
);
185 void preRegisterTerm(TNode term
);
186 Node
explain(TNode n
);
188 void collectModelInfo( TheoryModel
* m
, bool fullModel
);
190 void ppStaticLearn(TNode in
, NodeBuilder
<>& learned
);
193 void addSharedTerm(TNode n
);
194 void computeCareGraph();
196 void propagate(Effort effort
);
197 Node
getNextDecisionRequest( unsigned& priority
);
199 EqualityStatus
getEqualityStatus(TNode a
, TNode b
);
201 std::string
identify() const {
205 eq::EqualityEngine
* getEqualityEngine() {
206 return &d_equalityEngine
;
209 StrongSolverTheoryUF
* getStrongSolver() {
213 void addCarePairs( quantifiers::TermArgTrie
* t1
, quantifiers::TermArgTrie
* t2
, unsigned arity
, unsigned depth
);
214 };/* class TheoryUF */
216 }/* CVC4::theory::uf namespace */
217 }/* CVC4::theory namespace */
218 }/* CVC4 namespace */
220 #endif /* __CVC4__THEORY__UF__THEORY_UF_H */