GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/conjecture_generator.h Lines: 43 50 86.0 %
Date: 2021-08-14 Branches: 22 36 61.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Mathias Preiner, Tim King
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 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.
11
 * ****************************************************************************
12
 *
13
 * conjecture generator class
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CONJECTURE_GENERATOR_H
19
#define CONJECTURE_GENERATOR_H
20
21
#include "context/cdhashmap.h"
22
#include "expr/node_trie.h"
23
#include "expr/term_canonize.h"
24
#include "theory/quantifiers/quant_module.h"
25
#include "theory/type_enumerator.h"
26
27
namespace cvc5 {
28
namespace theory {
29
namespace quantifiers {
30
31
//algorithm for computing candidate subgoals
32
33
class ConjectureGenerator;
34
35
// operator independent index of arguments for an EQC
36
29836
class OpArgIndex
37
{
38
public:
39
  std::map< TNode, OpArgIndex > d_child;
40
  std::vector< TNode > d_ops;
41
  std::vector< TNode > d_op_terms;
42
  void addTerm( std::vector< TNode >& terms, TNode n, unsigned index = 0 );
43
  Node getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args );
44
  void getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms );
45
};
46
47
324
class PatternTypIndex
48
{
49
public:
50
  std::vector< TNode > d_terms;
51
  std::map< TypeNode, std::map< unsigned, PatternTypIndex > > d_children;
52
44
  void clear() {
53
44
    d_terms.clear();
54
44
    d_children.clear();
55
44
  }
56
};
57
58
181948
class SubstitutionIndex
59
{
60
public:
61
  //current variable, or ground EQC if d_children.empty()
62
  TNode d_var;
63
  std::map< TNode, SubstitutionIndex > d_children;
64
  //add substitution
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 );
68
};
69
70
class TermGenEnv;
71
72
3660
class TermGenerator
73
{
74
 private:
75
  unsigned calculateGeneralizationDepth( TermGenEnv * s, std::map< TypeNode, std::vector< int > >& fvs );
76
77
 public:
78
3660
  TermGenerator()
79
3660
      : d_id(0),
80
        d_status(0),
81
        d_status_num(0),
82
        d_status_child_num(0),
83
        d_match_status(0),
84
        d_match_status_child_num(0),
85
3660
        d_match_mode(0)
86
  {
87
3660
  }
88
  TypeNode d_typ;
89
  unsigned d_id;
90
  //1 : consider as unique variable
91
  //2 : consider equal to another variable
92
  //5 : consider a function application
93
  unsigned d_status;
94
  int d_status_num;
95
  //for function applications: the number of children you have built
96
  int d_status_child_num;
97
  //children (pointers to TermGenerators)
98
  std::vector< unsigned > d_children;
99
100
  //match status
101
  int d_match_status;
102
  int d_match_status_child_num;
103
  //match mode bits
104
  //0 : different variables must have different matches
105
  //1 : variables must map to ground terms
106
  //2 : variables must map to non-ground terms
107
  unsigned d_match_mode;
108
  //children
109
  std::vector<std::map<TNode, TNodeTrie>::iterator> d_match_children;
110
  std::vector<std::map<TNode, TNodeTrie>::iterator> d_match_children_end;
111
112
  void reset( TermGenEnv * s, TypeNode tn );
113
  bool getNextTerm( TermGenEnv * s, unsigned depth );
114
  void resetMatching( TermGenEnv * s, TNode eqc, unsigned mode );
115
  bool getNextMatch( TermGenEnv * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs );
116
117
  unsigned getDepth( TermGenEnv * s );
118
  unsigned getGeneralizationDepth( TermGenEnv * s );
119
  Node getTerm( TermGenEnv * s );
120
121
  void debugPrint( TermGenEnv * s, const char * c, const char * cd );
122
};
123
124
125
20
class TermGenEnv
126
{
127
public:
128
  //collect signature information
129
  void collectSignatureInformation();
130
  //reset function
131
  void reset( unsigned gdepth, bool genRelevant, TypeNode tgen );
132
  //get next term
133
  bool getNextTerm();
134
  //reset matching
135
  void resetMatching( TNode eqc, unsigned mode );
136
  //get next match
137
  bool getNextMatch( TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs );
138
  //get term
139
  Node getTerm();
140
  //debug print
141
  void debugPrint( const char * c, const char * cd );
142
143
  //conjecture generation
144
  ConjectureGenerator * d_cg;
145
  //the current number of enumerated variables per type
146
  std::map< TypeNode, unsigned > d_var_id;
147
  //the limit of number of variables per type to enumerate
148
  std::map< TypeNode, unsigned > d_var_limit;
149
  //the functions we can currently generate
150
  std::map< TypeNode, std::vector< TNode > > d_typ_tg_funcs;
151
  // whether functions must add operators
152
  std::map< TNode, bool > d_tg_func_param;
153
  //the equivalence classes (if applicable) that match the currently generated term
154
  bool d_gen_relevant_terms;
155
  //relevant equivalence classes
156
  std::vector< TNode > d_relevant_eqc[2];
157
  //candidate equivalence classes
158
  std::vector< std::vector< TNode > > d_ccand_eqc[2];
159
  //the term generation objects
160
  unsigned d_tg_id;
161
  std::map< unsigned, TermGenerator > d_tg_alloc;
162
  unsigned d_tg_gdepth;
163
  int d_tg_gdepth_limit;
164
165
  //all functions
166
  std::vector< TNode > d_funcs;
167
  //function to kind map
168
  std::map< TNode, Kind > d_func_kind;
169
  //type of each argument of the function
170
  std::map< TNode, std::vector< TypeNode > > d_func_args;
171
172
  //access functions
173
  unsigned getNumTgVars( TypeNode tn );
174
  bool allowVar( TypeNode tn );
175
  void addVar( TypeNode tn );
176
  void removeVar( TypeNode tn );
177
  unsigned getNumTgFuncs( TypeNode tn );
178
  TNode getTgFunc( TypeNode tn, unsigned i );
179
  Node getFreeVar( TypeNode tn, unsigned i );
180
  bool considerCurrentTerm();
181
  bool considerCurrentTermCanon( unsigned tg_id );
182
  void changeContext( bool add );
183
  bool isRelevantFunc( Node f );
184
  bool isRelevantTerm( Node t );
185
  //carry
186
  TermDb * getTermDatabase();
187
  Node getGroundEqc( TNode r );
188
  bool isGroundEqc( TNode r );
189
  bool isGroundTerm( TNode n );
190
};
191
192
193
194
608
class TheoremIndex
195
{
196
private:
197
  void addTheorem( std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );
198
  void addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );
199
  void getEquivalentTerms( std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,
200
                           std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,
201
                           std::vector< Node >& terms );
202
  void getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,
203
                               std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,
204
                               std::vector< Node >& terms );
205
public:
206
  std::map< TypeNode, TNode > d_var;
207
  std::map< TNode, TheoremIndex > d_children;
208
  std::vector< Node > d_terms;
209
210
92
  void addTheorem( TNode lhs, TNode rhs ) {
211
184
    std::vector< TNode > v;
212
184
    std::vector< unsigned > a;
213
92
    addTheoremNode( lhs, v, a, rhs );
214
92
  }
215
1618
  void getEquivalentTerms( TNode n, std::vector< Node >& terms ) {
216
3236
    std::vector< TNode > nv;
217
3236
    std::vector< unsigned > na;
218
3236
    std::map< TNode, TNode > smap;
219
3236
    std::vector< TNode > vars;
220
3236
    std::vector< TNode > subs;
221
1618
    getEquivalentTermsNode( n, nv, na, smap, vars, subs, terms );
222
1618
  }
223
44
  void clear(){
224
44
    d_var.clear();
225
44
    d_children.clear();
226
44
    d_terms.clear();
227
44
  }
228
  void debugPrint( const char * c, unsigned ind = 0 );
229
};
230
231
232
233
class ConjectureGenerator : public QuantifiersModule
234
{
235
  friend class OpArgIndex;
236
  friend class PatGen;
237
  friend class PatternGenEqc;
238
  friend class PatternGen;
239
  friend class SubsEqcIndex;
240
  friend class TermGenerator;
241
  friend class TermGenEnv;
242
  typedef context::CDHashMap<Node, Node> NodeMap;
243
  typedef context::CDHashMap<Node, bool> BoolMap;
244
  // this class maintains a congruence closure for *universal* facts
245
 private:
246
  //notification class for equality engine
247
10
  class NotifyClass : public eq::EqualityEngineNotify {
248
    ConjectureGenerator& d_sg;
249
  public:
250
10
    NotifyClass(ConjectureGenerator& sg): d_sg(sg) {}
251
    bool eqNotifyTriggerPredicate(TNode predicate, bool value) override
252
    {
253
      return true;
254
    }
255
    bool eqNotifyTriggerTermEquality(TheoryId tag,
256
                                     TNode t1,
257
                                     TNode t2,
258
                                     bool value) override
259
    {
260
      return true;
261
    }
262
    void eqNotifyConstantTermMerge(TNode t1, TNode t2) override {}
263
1618
    void eqNotifyNewClass(TNode t) override { d_sg.eqNotifyNewClass(t); }
264
196
    void eqNotifyMerge(TNode t1, TNode t2) override
265
    {
266
196
      d_sg.eqNotifyMerge(t1, t2);
267
196
    }
268
    void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) override
269
    {
270
    }
271
  };/* class ConjectureGenerator::NotifyClass */
272
  /** The notify class */
273
  NotifyClass d_notify;
274
23
  class EqcInfo{
275
  public:
276
    EqcInfo( context::Context* c );
277
    //representative
278
    context::CDO< Node > d_rep;
279
  };
280
  /** get or make eqc info */
281
  EqcInfo* getOrMakeEqcInfo( TNode n, bool doMake = false );
282
  /** boolean terms */
283
  Node d_true;
284
  Node d_false;
285
  /** (universal) equaltity engine */
286
  eq::EqualityEngine d_uequalityEngine;
287
  /** pending adds */
288
  std::vector< Node > d_upendingAdds;
289
  /** relevant terms */
290
  std::map< Node, bool > d_urelevant_terms;
291
  /** information necessary for equivalence classes */
292
  std::map< Node, EqcInfo* > d_eqc_info;
293
  /** called when a new equivalance class is created */
294
  void eqNotifyNewClass(TNode t);
295
  /** called when two equivalance classes have merged */
296
  void eqNotifyMerge(TNode t1, TNode t2);
297
  /** are universal equal */
298
  bool areUniversalEqual( TNode n1, TNode n2 );
299
  /** are universal disequal */
300
  bool areUniversalDisequal( TNode n1, TNode n2 );
301
  /** get universal representative */
302
  Node getUniversalRepresentative(TNode n, bool add = false);
303
  /** set relevant */
304
  void setUniversalRelevant( TNode n );
305
  /** ordering for universal terms */
306
  bool isUniversalLessThan( TNode rt1, TNode rt2 );
307
308
  /** the nodes we have reported as canonical representative */
309
  std::vector< TNode > d_ue_canon;
310
  /** is reported canon */
311
  bool isReportedCanon( TNode n );
312
  /** mark that term has been reported as canonical rep */
313
  void markReportedCanon( TNode n );
314
315
private:  //information regarding the conjectures
316
  /** list of all conjectures */
317
  std::vector< Node > d_conjectures;
318
  /** list of all waiting conjectures */
319
  std::vector< Node > d_waiting_conjectures_lhs;
320
  std::vector< Node > d_waiting_conjectures_rhs;
321
  std::vector< int > d_waiting_conjectures_score;
322
  /** map of currently considered equality conjectures */
323
  std::map< Node, std::vector< Node > > d_waiting_conjectures;
324
  /** map of equality conjectures */
325
  std::map< Node, std::vector< Node > > d_eq_conjectures;
326
  /** currently existing conjectures in equality engine */
327
  BoolMap d_ee_conjectures;
328
  /** conjecture index */
329
  TheoremIndex d_thm_index;
330
private:  //free variable list
331
  // get canonical free variable #i of type tn
332
  Node getFreeVar( TypeNode tn, unsigned i );
333
private:  //information regarding the terms
334
  //relevant patterns (the LHS's)
335
  std::map< TypeNode, std::vector< Node > > d_rel_patterns;
336
  //total number of unique variables
337
  std::map< TNode, unsigned > d_rel_pattern_var_sum;
338
  //by types
339
  PatternTypIndex d_rel_pattern_typ_index;
340
  // substitution to ground EQC index
341
  std::map< TNode, SubstitutionIndex > d_rel_pattern_subs_index;
342
  //patterns (the RHS's)
343
  std::map< TypeNode, std::vector< Node > > d_patterns;
344
  //patterns to # variables per type
345
  std::map< TNode, std::map< TypeNode, unsigned > > d_pattern_var_id;
346
  // # duplicated variables
347
  std::map< TNode, unsigned > d_pattern_var_duplicate;
348
  // is normal pattern?  (variables allocated in canonical way left to right)
349
  std::map< TNode, int > d_pattern_is_normal;
350
  std::map< TNode, int > d_pattern_is_relevant;
351
  // patterns to a count of # operators (variables and functions)
352
  std::map< TNode, std::map< TNode, unsigned > > d_pattern_fun_id;
353
  // term size
354
  std::map< TNode, unsigned > d_pattern_fun_sum;
355
  // collect functions
356
  unsigned collectFunctions( TNode opat, TNode pat, std::map< TNode, unsigned >& funcs,
357
                             std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn );
358
  // add pattern
359
  void registerPattern( Node pat, TypeNode tpat );
360
private: //for debugging
361
  std::map< TNode, unsigned > d_em;
362
  unsigned d_conj_count;
363
public:
364
  //term generation environment
365
  TermGenEnv d_tge;
366
  //consider term canon
367
  bool considerTermCanon( Node ln, bool genRelevant );
368
public:  //for generalization
369
  //generalizations
370
192
  bool isGeneralization( TNode patg, TNode pat ) {
371
384
    std::map< TNode, TNode > subs;
372
384
    return isGeneralization( patg, pat, subs );
373
  }
374
  bool isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs );
375
  // get generalization depth
376
  int calculateGeneralizationDepth( TNode n, std::vector< TNode >& fv );
377
private:
378
  //predicate for type
379
  std::map< TypeNode, Node > d_typ_pred;
380
  //get predicate for type
381
  Node getPredicateForType( TypeNode tn );
382
  /** get enumerate uf term
383
   *
384
   * This function adds up to #num f-applications to terms, where f is
385
   * n.getOperator(). These applications are enumerated in a fair manner based
386
   * on an iterative deepening of the sum of indices of the arguments. For
387
   * example, if f : U x U -> U, an the term enumerator for U gives t1, t2, t3
388
   * ..., then we add f-applications to terms in this order:
389
   *   f( t1, t1 )
390
   *   f( t2, t1 )
391
   *   f( t1, t2 )
392
   *   f( t1, t3 )
393
   *   f( t2, t2 )
394
   *   f( t3, t1 )
395
   *   ...
396
   * This function may add fewer than #num terms to terms if the enumeration is
397
   * exhausted, or if an internal error occurs.
398
   */
399
  void getEnumerateUfTerm( Node n, unsigned num, std::vector< Node >& terms );
400
  //
401
  void getEnumeratePredUfTerm( Node n, unsigned num, std::vector< Node >& terms );
402
  // uf operators enumerated
403
  std::map< Node, bool > d_uf_enum;
404
public:  //for property enumeration
405
  //process this candidate conjecture
406
  void processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth );
407
  //whether it should be considered, negative : no, positive returns score
408
  int considerCandidateConjecture( TNode lhs, TNode rhs );
409
  //notified of a substitution
410
  bool notifySubstitution( TNode glhs, std::map< TNode, TNode >& subs, TNode rhs );
411
  //confirmation count
412
  unsigned d_subs_confirmCount;
413
  //individual witnesses (for range)
414
  std::vector< TNode > d_subs_confirmWitnessRange;
415
  //individual witnesses (for domain)
416
  std::map< TNode, std::vector< TNode > > d_subs_confirmWitnessDomain;
417
  //number of ground substitutions whose equality is unknown
418
  unsigned d_subs_unkCount;
419
private:  //information about ground equivalence classes
420
  TNode d_bool_eqc[2];
421
  std::map< TNode, Node > d_ground_eqc_map;
422
  std::vector< TNode > d_ground_terms;
423
  //operator independent term index
424
  std::map< TNode, OpArgIndex > d_op_arg_index;
425
  //is handled term
426
  bool isHandledTerm( TNode n );
427
  Node getGroundEqc( TNode r );
428
  bool isGroundEqc( TNode r );
429
  bool isGroundTerm( TNode n );
430
  //has enumerated UF
431
  bool hasEnumeratedUf( Node n );
432
  // count of full effort checks
433
  unsigned d_fullEffortCount;
434
  // has added lemma
435
  bool d_hasAddedLemma;
436
  //flush the waiting conjectures
437
  unsigned flushWaitingConjectures( unsigned& addedLemmas, int ldepth, int rdepth );
438
439
 public:
440
  ConjectureGenerator(QuantifiersState& qs,
441
                      QuantifiersInferenceManager& qim,
442
                      QuantifiersRegistry& qr,
443
                      TermRegistry& tr);
444
  ~ConjectureGenerator();
445
446
  /* needs check */
447
  bool needsCheck(Theory::Effort e) override;
448
  /* reset at a round */
449
  void reset_round(Theory::Effort e) override;
450
  /* Call during quantifier engine's check */
451
  void check(Theory::Effort e, QEffort quant_e) override;
452
  /** Identify this module (for debugging, dynamic configuration, etc..) */
453
555
  std::string identify() const override { return "ConjectureGenerator"; }
454
  // options
455
 private:
456
  bool optReqDistinctVarPatterns();
457
  bool optFilterUnknown();
458
  int optFilterScoreThreshold();
459
  unsigned optFullCheckFrequency();
460
  unsigned optFullCheckConjectures();
461
462
  bool optStatsOnly();
463
  /** term canonizer */
464
  expr::TermCanonize d_termCanon;
465
};
466
467
468
}
469
}
470
}  // namespace cvc5
471
472
#endif