1 /********************* */
2 /*! \file theory_datatypes.h
4 ** Top contributors (to current version):
5 ** Andrew Reynolds, 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 Theory of datatypes.
14 ** Theory of datatypes.
17 #include "cvc4_private.h"
19 #ifndef __CVC4__THEORY__DATATYPES__THEORY_DATATYPES_H
20 #define __CVC4__THEORY__DATATYPES__THEORY_DATATYPES_H
22 #include <ext/hash_set>
26 #include "context/cdchunk_list.h"
27 #include "expr/datatype.h"
28 #include "theory/datatypes/datatypes_sygus.h"
29 #include "theory/theory.h"
30 #include "theory/uf/equality_engine.h"
31 #include "util/hash.h"
36 namespace quantifiers
{
42 class TheoryDatatypes
: public Theory
{
44 typedef context::CDChunkList
<Node
> NodeList
;
45 typedef context::CDHashMap
< Node
, int, NodeHashFunction
> NodeIntMap
;
46 typedef context::CDHashMap
< Node
, bool, NodeHashFunction
> BoolMap
;
47 typedef context::CDHashMap
< Node
, Node
, NodeHashFunction
> NodeMap
;
49 /** transitive closure to record equivalence/subterm relation. */
50 //TransitiveClosureNode d_cycle_check;
52 context::CDO
< bool > d_hasSeenCycle
;
58 Node
mkAnd( std::vector
< TNode
>& assumptions
);
60 //notification class for equality engine
61 class NotifyClass
: public eq::EqualityEngineNotify
{
62 TheoryDatatypes
& d_dt
;
64 NotifyClass(TheoryDatatypes
& dt
): d_dt(dt
) {}
65 bool eqNotifyTriggerEquality(TNode equality
, bool value
) {
66 Debug("dt") << "NotifyClass::eqNotifyTriggerEquality(" << equality
<< ", " << (value
? "true" : "false" )<< ")" << std::endl
;
68 return d_dt
.propagate(equality
);
70 // We use only literal triggers so taking not is safe
71 return d_dt
.propagate(equality
.notNode());
74 bool eqNotifyTriggerPredicate(TNode predicate
, bool value
) {
75 Debug("dt") << "NotifyClass::eqNotifyTriggerPredicate(" << predicate
<< ", " << (value
? "true" : "false") << ")" << std::endl
;
77 return d_dt
.propagate(predicate
);
79 return d_dt
.propagate(predicate
.notNode());
82 bool eqNotifyTriggerTermEquality(TheoryId tag
, TNode t1
, TNode t2
, bool value
) {
83 Debug("dt") << "NotifyClass::eqNotifyTriggerTermMerge(" << tag
<< ", " << t1
<< ", " << t2
<< ")" << std::endl
;
85 return d_dt
.propagate(t1
.eqNode(t2
));
87 return d_dt
.propagate(t1
.eqNode(t2
).notNode());
90 void eqNotifyConstantTermMerge(TNode t1
, TNode t2
) {
91 Debug("dt") << "NotifyClass::eqNotifyConstantTermMerge(" << t1
<< ", " << t2
<< ")" << std::endl
;
92 d_dt
.conflict(t1
, t2
);
94 void eqNotifyNewClass(TNode t
) {
95 Debug("dt") << "NotifyClass::eqNotifyNewClass(" << t
<< ")" << std::endl
;
96 d_dt
.eqNotifyNewClass(t
);
98 void eqNotifyPreMerge(TNode t1
, TNode t2
) {
99 Debug("dt") << "NotifyClass::eqNotifyPreMerge(" << t1
<< ", " << t2
<< ")" << std::endl
;
100 d_dt
.eqNotifyPreMerge(t1
, t2
);
102 void eqNotifyPostMerge(TNode t1
, TNode t2
) {
103 Debug("dt") << "NotifyClass::eqNotifyPostMerge(" << t1
<< ", " << t2
<< ")" << std::endl
;
104 d_dt
.eqNotifyPostMerge(t1
, t2
);
106 void eqNotifyDisequal(TNode t1
, TNode t2
, TNode reason
) {
107 Debug("dt") << "NotifyClass::eqNotifyDisequal(" << t1
<< ", " << t2
<< ", " << reason
<< ")" << std::endl
;
108 d_dt
.eqNotifyDisequal(t1
, t2
, reason
);
110 };/* class TheoryDatatypes::NotifyClass */
112 /** equivalence class info
113 * d_inst is whether the instantiate rule has been applied,
114 * d_constructor is a node of kind APPLY_CONSTRUCTOR (if any) in this equivalence class,
115 * d_selectors is whether a selector has been applied to this equivalence class.
120 EqcInfo( context::Context
* c
);
122 //whether we have instantiatied this eqc
123 context::CDO
< bool > d_inst
;
124 //constructor equal to this eqc
125 context::CDO
< Node
> d_constructor
;
126 //all selectors whose argument is this eqc
127 context::CDO
< bool > d_selectors
;
129 /** does eqc of n have a label (do we know its constructor)? */
130 bool hasLabel( EqcInfo
* eqc
, Node n
);
131 /** get the label associated to n */
132 Node
getLabel( Node n
);
133 /** get the index of the label associated to n */
134 int getLabelIndex( EqcInfo
* eqc
, Node n
);
135 /** does eqc of n have any testers? */
136 bool hasTester( Node n
);
137 /** get the possible constructors for n */
138 void getPossibleCons( EqcInfo
* eqc
, Node n
, std::vector
< bool >& cons
);
139 void getSelectorsForCons( Node r
, std::map
< int, bool >& sels
);
140 /** mkExpDefSkolem */
141 void mkExpDefSkolem( Node sel
, TypeNode dt
, TypeNode rt
);
142 /** skolems for terms */
144 Node
getTermSkolemFor( Node n
);
146 /** The notify class */
147 NotifyClass d_notify
;
148 /** Equaltity engine */
149 eq::EqualityEngine d_equalityEngine
;
150 /** information necessary for equivalence classes */
151 std::map
< Node
, EqcInfo
* > d_eqc_info
;
152 /** map from nodes to their instantiated equivalent for each constructor type */
153 std::map
< Node
, std::map
< int, Node
> > d_inst_map
;
154 /** which instantiation lemmas we have sent */
155 //std::map< Node, std::vector< Node > > d_inst_lemmas;
156 /** labels for each equivalence class
157 * for each eqc n, d_labels[n] is testers that hold for this equivalence class, either:
158 * a list of equations of the form
159 * NOT is_[constructor_1]( t )...NOT is_[constructor_n]( t ), each of which are unique testers
160 * and n is less than the number of possible constructors for t minus one,
161 * or a list of equations of the form
162 * NOT is_[constructor_1]( t )...NOT is_[constructor_n]( t ) followed by
163 * is_[constructor_(n+1)]( t ), each of which is a unique tester.
166 std::map
< Node
, std::vector
< Node
> > d_labels_data
;
167 /** selector apps for eqch equivalence class */
168 NodeIntMap d_selector_apps
;
169 std::map
< Node
, std::vector
< Node
> > d_selector_apps_data
;
170 /** constructor terms */
172 /** Are we in conflict */
173 context::CDO
<bool> d_conflict
;
177 /** The conflict node */
179 /** cache for which terms we have called collectTerms(...) on */
180 BoolMap d_collectTermsCache
;
181 /** pending assertions/merges */
182 std::vector
< Node
> d_pending_lem
;
183 std::vector
< Node
> d_pending
;
184 std::map
< Node
, Node
> d_pending_exp
;
185 std::vector
< Node
> d_pending_merge
;
186 /** All the function terms that the theory has seen */
187 context::CDList
<TNode
> d_functionTerms
;
188 /** counter for forcing assignments (ensures fairness) */
189 unsigned d_dtfCounter
;
190 /** expand definition skolem functions */
191 std::map
< TypeNode
, std::map
< Node
, Node
> > d_exp_def_skolem
;
192 /** sygus utilities */
193 SygusSplit
* d_sygus_split
;
194 SygusSymBreak
* d_sygus_sym_break
;
197 /** singleton lemmas (for degenerate co-datatype case) */
198 std::map
< TypeNode
, Node
> d_singleton_lemma
[2];
199 /** Cache for singleton equalities processed */
200 BoolMap d_singleton_eq
;
201 /** list of all lemmas produced */
202 BoolMap d_lemmas_produced_c
;
205 void assertFact( Node fact
, Node exp
);
207 /** flush pending facts */
208 void flushPendingFacts();
210 /** do pending merged */
211 void doPendingMerges();
213 bool doSendLemma( Node lem
);
214 /** get or make eqc info */
215 EqcInfo
* getOrMakeEqcInfo( TNode n
, bool doMake
= false );
218 bool hasEqcInfo( TNode n
) { return d_labels
.find( n
)!=d_labels
.end(); }
220 /** get eqc constructor */
221 TNode
getEqcConstructor( TNode r
);
224 void addCarePairs( quantifiers::TermArgTrie
* t1
, quantifiers::TermArgTrie
* t2
, unsigned arity
, unsigned depth
, unsigned& n_pairs
);
225 /** compute care graph */
226 void computeCareGraph();
229 TheoryDatatypes(context::Context
* c
, context::UserContext
* u
,
230 OutputChannel
& out
, Valuation valuation
,
231 const LogicInfo
& logicInfo
);
234 void setMasterEqualityEngine(eq::EqualityEngine
* eq
);
237 void propagate(Effort effort
);
239 bool propagate(TNode literal
);
241 void addAssumptions( std::vector
<TNode
>& assumptions
, std::vector
<TNode
>& tassumptions
);
242 void explainEquality( TNode a
, TNode b
, bool polarity
, std::vector
<TNode
>& assumptions
);
243 void explainPredicate( TNode p
, bool polarity
, std::vector
<TNode
>& assumptions
);
244 void explain( TNode literal
, std::vector
<TNode
>& assumptions
);
245 Node
explain( TNode literal
);
246 Node
explain( std::vector
< Node
>& lits
);
247 /** Conflict when merging two constants */
248 void conflict(TNode a
, TNode b
);
249 /** called when a new equivalance class is created */
250 void eqNotifyNewClass(TNode t
);
251 /** called when two equivalance classes will merge */
252 void eqNotifyPreMerge(TNode t1
, TNode t2
);
253 /** called when two equivalance classes have merged */
254 void eqNotifyPostMerge(TNode t1
, TNode t2
);
255 /** called when two equivalence classes are made disequal */
256 void eqNotifyDisequal(TNode t1
, TNode t2
, TNode reason
);
258 void check(Effort e
);
259 void preRegisterTerm(TNode n
);
261 Node
expandDefinition(LogicRequest
&logicRequest
, Node n
);
262 Node
ppRewrite(TNode n
);
264 void addSharedTerm(TNode t
);
265 EqualityStatus
getEqualityStatus(TNode a
, TNode b
);
266 void collectModelInfo( TheoryModel
* m
, bool fullModel
);
268 std::string
identify() const { return std::string("TheoryDatatypes"); }
269 /** equality engine */
270 eq::EqualityEngine
* getEqualityEngine() { return &d_equalityEngine
; }
271 bool getCurrentSubstitution( int effort
, std::vector
< Node
>& vars
, std::vector
< Node
>& subs
, std::map
< Node
, std::vector
< Node
> >& exp
);
273 void printModelDebug( const char* c
);
274 /** entailment check */
275 virtual std::pair
<bool, Node
> entailmentCheck(TNode lit
, const EntailmentCheckParameters
* params
= NULL
, EntailmentCheckSideEffects
* out
= NULL
);
277 /** add tester to equivalence class info */
278 void addTester( int ttindex
, Node t
, EqcInfo
* eqc
, Node n
, Node t_arg
);
279 /** add selector to equivalence class info */
280 void addSelector( Node s
, EqcInfo
* eqc
, Node n
, bool assertFacts
= true );
281 /** add constructor */
282 void addConstructor( Node c
, EqcInfo
* eqc
, Node n
);
283 /** merge the equivalence class info of t1 and t2 */
284 void merge( Node t1
, Node t2
);
285 /** collapse selector, s is of the form sel( n ) where n = c */
286 void collapseSelector( Node s
, Node c
);
287 /** for checking if cycles exist */
289 Node
searchForCycle( TNode n
, TNode on
,
290 std::map
< TNode
, bool >& visited
,
291 std::vector
< TNode
>& explanation
, bool firstTime
= true );
292 /** for checking whether two codatatype terms must be equal */
293 void separateBisimilar( std::vector
< Node
>& part
, std::vector
< std::vector
< Node
> >& part_out
,
294 std::vector
< TNode
>& exp
,
295 std::map
< Node
, Node
>& cn
,
296 std::map
< Node
, std::map
< Node
, int > >& dni
, int dniLvl
, bool mkExp
);
298 Node
getCodatatypesValue( Node n
, std::map
< Node
, Node
>& eqc_cons
, std::map
< Node
, int >& vmap
, int depth
);
299 /** get singleton lemma */
300 Node
getSingletonLemma( TypeNode tn
, bool pol
);
302 void collectTerms( Node n
);
303 /** get instantiate cons */
304 Node
getInstantiateCons( Node n
, const Datatype
& dt
, int index
);
305 /** process new term that was created internally */
306 void processNewTerm( Node n
);
307 /** check instantiate */
308 void instantiate( EqcInfo
* eqc
, Node n
);
309 /** must communicate fact */
310 bool mustCommunicateFact( Node n
, Node exp
);
311 /** check clash mod eq */
312 bool checkClashModEq( TNode n1
, TNode n2
, std::vector
< Node
>& exp
, std::vector
< std::pair
< TNode
, TNode
> >& deq_cand
);
313 /** get relevant terms */
314 void getRelevantTerms( std::set
<Node
>& termSet
);
317 bool hasTerm( TNode a
);
318 bool areEqual( TNode a
, TNode b
);
319 bool areDisequal( TNode a
, TNode b
);
320 TNode
getRepresentative( TNode a
);
321 };/* class TheoryDatatypes */
323 }/* CVC4::theory::datatypes namespace */
324 }/* CVC4::theory namespace */
325 }/* CVC4 namespace */
327 #endif /* __CVC4__THEORY__DATATYPES__THEORY_DATATYPES_H */