1 /********************* */
2 /*! \file conjecture_generator.h
4 ** Original author: Andrew Reynolds
5 ** Major contributors: none
6 ** Minor contributors (to current version): none
7 ** This file is part of the CVC4 project.
8 ** Copyright (c) 2009-2014 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** information.\endverbatim
12 ** \brief conjecture generator class
15 #include "cvc4_private.h"
17 #ifndef CONJECTURE_GENERATOR_H
18 #define CONJECTURE_GENERATOR_H
20 #include "context/cdhashmap.h"
21 #include "context/cdchunk_list.h"
22 #include "theory/quantifiers_engine.h"
23 #include "theory/type_enumerator.h"
27 namespace quantifiers
{
31 //algorithm for computing candidate subgoals
33 class ConjectureGenerator
;
35 // operator independent index of arguments for an EQC
39 std::map
< TNode
, OpArgIndex
> d_child
;
40 std::vector
< TNode
> d_ops
;
41 std::vector
< TNode
> d_op_terms
;
42 void addTerm( ConjectureGenerator
* s
, TNode n
, unsigned index
= 0 );
43 Node
getGroundTerm( ConjectureGenerator
* s
, std::vector
< TNode
>& args
);
44 void getGroundTerms( ConjectureGenerator
* s
, std::vector
< TNode
>& terms
);
50 std::vector
< TNode
> d_terms
;
51 std::map
< TypeNode
, std::map
< unsigned, PatternTypIndex
> > d_children
;
58 class SubstitutionIndex
61 //current variable, or ground EQC if d_children.empty()
63 std::map
< TNode
, SubstitutionIndex
> d_children
;
65 void addSubstitution( TNode eqc
, std::vector
< TNode
>& vars
, std::vector
< TNode
>& terms
, unsigned i
= 0 );
66 //notify substitutions
67 bool notifySubstitutions( ConjectureGenerator
* s
, std::map
< TNode
, TNode
>& subs
, TNode rhs
, unsigned numVars
, unsigned i
= 0 );
75 unsigned calculateGeneralizationDepth( TermGenEnv
* s
, std::map
< TypeNode
, std::vector
< int > >& fvs
);
80 //1 : consider as unique variable
81 //2 : consider equal to another variable
82 //5 : consider a function application
85 //for function applications: the number of children you have built
86 int d_status_child_num
;
87 //children (pointers to TermGenerators)
88 std::vector
< unsigned > d_children
;
92 int d_match_status_child_num
;
94 //0 : different variables must have different matches
95 //1 : variables must map to ground terms
96 //2 : variables must map to non-ground terms
97 unsigned d_match_mode
;
99 std::vector
< std::map
< TNode
, TermArgTrie
>::iterator
> d_match_children
;
100 std::vector
< std::map
< TNode
, TermArgTrie
>::iterator
> d_match_children_end
;
102 void reset( TermGenEnv
* s
, TypeNode tn
);
103 bool getNextTerm( TermGenEnv
* s
, unsigned depth
);
104 void resetMatching( TermGenEnv
* s
, TNode eqc
, unsigned mode
);
105 bool getNextMatch( TermGenEnv
* s
, TNode eqc
, std::map
< TypeNode
, std::map
< unsigned, TNode
> >& subs
, std::map
< TNode
, bool >& rev_subs
);
107 unsigned getDepth( TermGenEnv
* s
);
108 unsigned getGeneralizationDepth( TermGenEnv
* s
);
109 Node
getTerm( TermGenEnv
* s
);
111 void debugPrint( TermGenEnv
* s
, const char * c
, const char * cd
);
118 //collect signature information
119 void collectSignatureInformation();
121 void reset( unsigned gdepth
, bool genRelevant
, TypeNode tgen
);
125 void resetMatching( TNode eqc
, unsigned mode
);
127 bool getNextMatch( TNode eqc
, std::map
< TypeNode
, std::map
< unsigned, TNode
> >& subs
, std::map
< TNode
, bool >& rev_subs
);
131 void debugPrint( const char * c
, const char * cd
);
133 //conjecture generation
134 ConjectureGenerator
* d_cg
;
135 //the current number of enumerated variables per type
136 std::map
< TypeNode
, unsigned > d_var_id
;
137 //the limit of number of variables per type to enumerate
138 std::map
< TypeNode
, unsigned > d_var_limit
;
139 //the functions we can currently generate
140 std::map
< TypeNode
, std::vector
< TNode
> > d_typ_tg_funcs
;
141 // whether functions must add operators
142 std::map
< TNode
, bool > d_tg_func_param
;
143 //the equivalence classes (if applicable) that match the currently generated term
144 bool d_gen_relevant_terms
;
145 //relevant equivalence classes
146 std::vector
< TNode
> d_relevant_eqc
[2];
147 //candidate equivalence classes
148 std::vector
< std::vector
< TNode
> > d_ccand_eqc
[2];
149 //the term generation objects
151 std::map
< unsigned, TermGenerator
> d_tg_alloc
;
152 unsigned d_tg_gdepth
;
153 int d_tg_gdepth_limit
;
156 std::vector
< TNode
> d_funcs
;
157 //function to kind map
158 std::map
< TNode
, Kind
> d_func_kind
;
159 //type of each argument of the function
160 std::map
< TNode
, std::vector
< TypeNode
> > d_func_args
;
163 unsigned getNumTgVars( TypeNode tn
);
164 bool allowVar( TypeNode tn
);
165 void addVar( TypeNode tn
);
166 void removeVar( TypeNode tn
);
167 unsigned getNumTgFuncs( TypeNode tn
);
168 TNode
getTgFunc( TypeNode tn
, unsigned i
);
169 Node
getFreeVar( TypeNode tn
, unsigned i
);
170 bool considerCurrentTerm();
171 bool considerCurrentTermCanon( unsigned tg_id
);
172 void changeContext( bool add
);
173 bool isRelevantFunc( Node f
);
175 TermDb
* getTermDatabase();
176 Node
getGroundEqc( TNode r
);
177 bool isGroundEqc( TNode r
);
178 bool isGroundTerm( TNode n
);
186 void addTheorem( std::vector
< TNode
>& lhs_v
, std::vector
< unsigned >& lhs_arg
, TNode rhs
);
187 void addTheoremNode( TNode curr
, std::vector
< TNode
>& lhs_v
, std::vector
< unsigned >& lhs_arg
, TNode rhs
);
188 void getEquivalentTerms( std::vector
< TNode
>& n_v
, std::vector
< unsigned >& n_arg
,
189 std::map
< TNode
, TNode
>& smap
, std::vector
< TNode
>& vars
, std::vector
< TNode
>& subs
,
190 std::vector
< Node
>& terms
);
191 void getEquivalentTermsNode( Node curr
, std::vector
< TNode
>& n_v
, std::vector
< unsigned >& n_arg
,
192 std::map
< TNode
, TNode
>& smap
, std::vector
< TNode
>& vars
, std::vector
< TNode
>& subs
,
193 std::vector
< Node
>& terms
);
195 std::map
< TypeNode
, TNode
> d_var
;
196 std::map
< TNode
, TheoremIndex
> d_children
;
197 std::vector
< Node
> d_terms
;
199 void addTheorem( TNode lhs
, TNode rhs
) {
200 std::vector
< TNode
> v
;
201 std::vector
< unsigned > a
;
202 addTheoremNode( lhs
, v
, a
, rhs
);
204 void getEquivalentTerms( TNode n
, std::vector
< Node
>& terms
) {
205 std::vector
< TNode
> nv
;
206 std::vector
< unsigned > na
;
207 std::map
< TNode
, TNode
> smap
;
208 std::vector
< TNode
> vars
;
209 std::vector
< TNode
> subs
;
210 getEquivalentTermsNode( n
, nv
, na
, smap
, vars
, subs
, terms
);
217 void debugPrint( const char * c
, unsigned ind
= 0 );
222 class ConjectureGenerator
: public QuantifiersModule
224 friend class OpArgIndex
;
226 friend class PatternGenEqc
;
227 friend class PatternGen
;
228 friend class SubsEqcIndex
;
229 friend class TermGenerator
;
230 friend class TermGenEnv
;
231 typedef context::CDChunkList
<Node
> NodeList
;
232 typedef context::CDHashMap
< Node
, Node
, NodeHashFunction
> NodeMap
;
233 typedef context::CDHashMap
< Node
, bool, NodeHashFunction
> BoolMap
;
234 //this class maintains a congruence closure for *universal* facts
236 //notification class for equality engine
237 class NotifyClass
: public eq::EqualityEngineNotify
{
238 ConjectureGenerator
& d_sg
;
240 NotifyClass(ConjectureGenerator
& sg
): d_sg(sg
) {}
241 bool eqNotifyTriggerEquality(TNode equality
, bool value
) { return true; }
242 bool eqNotifyTriggerPredicate(TNode predicate
, bool value
) { return true; }
243 bool eqNotifyTriggerTermEquality(TheoryId tag
, TNode t1
, TNode t2
, bool value
) { return true; }
244 void eqNotifyConstantTermMerge(TNode t1
, TNode t2
) { }
245 void eqNotifyNewClass(TNode t
) { d_sg
.eqNotifyNewClass(t
); }
246 void eqNotifyPreMerge(TNode t1
, TNode t2
) { d_sg
.eqNotifyPreMerge(t1
, t2
); }
247 void eqNotifyPostMerge(TNode t1
, TNode t2
) { d_sg
.eqNotifyPostMerge(t1
, t2
); }
248 void eqNotifyDisequal(TNode t1
, TNode t2
, TNode reason
) {d_sg
.eqNotifyDisequal(t1
, t2
, reason
); }
249 };/* class ConjectureGenerator::NotifyClass */
250 /** The notify class */
251 NotifyClass d_notify
;
254 EqcInfo( context::Context
* c
);
256 context::CDO
< Node
> d_rep
;
258 /** get or make eqc info */
259 EqcInfo
* getOrMakeEqcInfo( TNode n
, bool doMake
= false );
260 /** (universal) equaltity engine */
261 eq::EqualityEngine d_uequalityEngine
;
263 std::vector
< Node
> d_upendingAdds
;
264 /** relevant terms */
265 std::map
< Node
, bool > d_urelevant_terms
;
266 /** information necessary for equivalence classes */
267 std::map
< Node
, EqcInfo
* > d_eqc_info
;
268 /** called when a new equivalance class is created */
269 void eqNotifyNewClass(TNode t
);
270 /** called when two equivalance classes will merge */
271 void eqNotifyPreMerge(TNode t1
, TNode t2
);
272 /** called when two equivalance classes have merged */
273 void eqNotifyPostMerge(TNode t1
, TNode t2
);
274 /** called when two equivalence classes are made disequal */
275 void eqNotifyDisequal(TNode t1
, TNode t2
, TNode reason
);
276 /** are universal equal */
277 bool areUniversalEqual( TNode n1
, TNode n2
);
278 /** are universal disequal */
279 bool areUniversalDisequal( TNode n1
, TNode n2
);
280 /** get universal representative */
281 TNode
getUniversalRepresentative( TNode n
, bool add
= false );
283 void setUniversalRelevant( TNode n
);
284 /** ordering for universal terms */
285 bool isUniversalLessThan( TNode rt1
, TNode rt2
);
287 /** the nodes we have reported as canonical representative */
288 std::vector
< TNode
> d_ue_canon
;
289 /** is reported canon */
290 bool isReportedCanon( TNode n
);
291 /** mark that term has been reported as canonical rep */
292 void markReportedCanon( TNode n
);
294 private: //information regarding the conjectures
295 /** list of all conjectures */
296 std::vector
< Node
> d_conjectures
;
297 /** list of all waiting conjectures */
298 std::vector
< Node
> d_waiting_conjectures_lhs
;
299 std::vector
< Node
> d_waiting_conjectures_rhs
;
300 std::vector
< int > d_waiting_conjectures_score
;
301 /** map of currently considered equality conjectures */
302 std::map
< Node
, std::vector
< Node
> > d_waiting_conjectures
;
303 /** map of equality conjectures */
304 std::map
< Node
, std::vector
< Node
> > d_eq_conjectures
;
305 /** currently existing conjectures in equality engine */
306 BoolMap d_ee_conjectures
;
307 /** conjecture index */
308 TheoremIndex d_thm_index
;
309 private: //free variable list
311 std::map
< TypeNode
, std::vector
< Node
> > d_free_var
;
312 //map from free variable to FV#
313 std::map
< TNode
, unsigned > d_free_var_num
;
314 // get canonical free variable #i of type tn
315 Node
getFreeVar( TypeNode tn
, unsigned i
);
316 // get canonical term, return null if it contains a term apart from handled signature
317 Node
getCanonicalTerm( TNode n
, std::map
< TypeNode
, unsigned >& var_count
, std::map
< TNode
, TNode
>& subs
);
318 private: //information regarding the terms
319 //relevant patterns (the LHS's)
320 std::map
< TypeNode
, std::vector
< Node
> > d_rel_patterns
;
321 //total number of unique variables
322 std::map
< TNode
, unsigned > d_rel_pattern_var_sum
;
324 PatternTypIndex d_rel_pattern_typ_index
;
325 // substitution to ground EQC index
326 std::map
< TNode
, SubstitutionIndex
> d_rel_pattern_subs_index
;
327 //patterns (the RHS's)
328 std::map
< TypeNode
, std::vector
< Node
> > d_patterns
;
329 //patterns to # variables per type
330 std::map
< TNode
, std::map
< TypeNode
, unsigned > > d_pattern_var_id
;
331 // # duplicated variables
332 std::map
< TNode
, unsigned > d_pattern_var_duplicate
;
333 // is normal pattern? (variables allocated in canonical way left to right)
334 std::map
< TNode
, int > d_pattern_is_normal
;
335 std::map
< TNode
, int > d_pattern_is_relevant
;
336 // patterns to a count of # operators (variables and functions)
337 std::map
< TNode
, std::map
< TNode
, unsigned > > d_pattern_fun_id
;
339 std::map
< TNode
, unsigned > d_pattern_fun_sum
;
341 unsigned collectFunctions( TNode opat
, TNode pat
, std::map
< TNode
, unsigned >& funcs
,
342 std::map
< TypeNode
, unsigned >& mnvn
, std::map
< TypeNode
, unsigned >& mxvn
);
344 void registerPattern( Node pat
, TypeNode tpat
);
345 private: //for debugging
346 std::map
< TNode
, unsigned > d_em
;
347 unsigned d_conj_count
;
349 //term generation environment
351 //consider term canon
352 bool considerTermCanon( Node ln
, bool genRelevant
);
353 public: //for generalization
355 bool isGeneralization( TNode patg
, TNode pat
) {
356 std::map
< TNode
, TNode
> subs
;
357 return isGeneralization( patg
, pat
, subs
);
359 bool isGeneralization( TNode patg
, TNode pat
, std::map
< TNode
, TNode
>& subs
);
360 // get generalization depth
361 int calculateGeneralizationDepth( TNode n
, std::vector
< TNode
>& fv
);
364 std::map
< TypeNode
, Node
> d_typ_pred
;
365 //get predicate for type
366 Node
getPredicateForType( TypeNode tn
);
368 void getEnumerateUfTerm( Node n
, unsigned num
, std::vector
< Node
>& terms
);
370 void getEnumeratePredUfTerm( Node n
, unsigned num
, std::vector
< Node
>& terms
);
371 // uf operators enumerated
372 std::map
< Node
, bool > d_uf_enum
;
373 public: //for property enumeration
374 //process this candidate conjecture
375 void processCandidateConjecture( TNode lhs
, TNode rhs
, unsigned lhs_depth
, unsigned rhs_depth
);
376 //whether it should be considered, negative : no, positive returns score
377 int considerCandidateConjecture( TNode lhs
, TNode rhs
);
378 //notified of a substitution
379 bool notifySubstitution( TNode glhs
, std::map
< TNode
, TNode
>& subs
, TNode rhs
);
381 unsigned d_subs_confirmCount
;
382 //individual witnesses (for range)
383 std::vector
< TNode
> d_subs_confirmWitnessRange
;
384 //individual witnesses (for domain)
385 std::map
< TNode
, std::vector
< TNode
> > d_subs_confirmWitnessDomain
;
386 //number of ground substitutions whose equality is unknown
387 unsigned d_subs_unkCount
;
388 private: //information about ground equivalence classes
390 std::map
< TNode
, Node
> d_ground_eqc_map
;
391 std::vector
< TNode
> d_ground_terms
;
392 //operator independent term index
393 std::map
< TNode
, OpArgIndex
> d_op_arg_index
;
395 bool isHandledTerm( TNode n
);
396 Node
getGroundEqc( TNode r
);
397 bool isGroundEqc( TNode r
);
398 bool isGroundTerm( TNode n
);
400 bool hasEnumeratedUf( Node n
);
401 // count of full effort checks
402 unsigned d_fullEffortCount
;
404 bool d_hasAddedLemma
;
405 //flush the waiting conjectures
406 unsigned flushWaitingConjectures( unsigned& addedLemmas
, int ldepth
, int rdepth
);
408 ConjectureGenerator( QuantifiersEngine
* qe
, context::Context
* c
);
410 bool needsCheck( Theory::Effort e
);
411 /* reset at a round */
412 void reset_round( Theory::Effort e
);
413 /* Call during quantifier engine's check */
414 void check( Theory::Effort e
, unsigned quant_e
);
415 /* Called for new quantifiers */
416 void registerQuantifier( Node q
);
417 void assertNode( Node n
);
418 /** Identify this module (for debugging, dynamic configuration, etc..) */
419 std::string
identify() const { return "ConjectureGenerator"; }
422 bool optReqDistinctVarPatterns();
423 bool optFilterUnknown();
424 int optFilterScoreThreshold();
425 unsigned optFullCheckFrequency();
426 unsigned optFullCheckConjectures();