GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/quant_conflict_find.h Lines: 18 18 100.0 %
Date: 2021-08-16 Branches: 19 36 52.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Tim King, Morgan Deters
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
 * Quantifiers conflict find class.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef QUANT_CONFLICT_FIND
19
#define QUANT_CONFLICT_FIND
20
21
#include <ostream>
22
#include <vector>
23
24
#include "context/cdhashmap.h"
25
#include "context/cdlist.h"
26
#include "expr/node_trie.h"
27
#include "theory/quantifiers/quant_module.h"
28
29
namespace cvc5 {
30
namespace theory {
31
namespace quantifiers {
32
33
class QuantConflictFind;
34
class QuantInfo;
35
36
//match generator
37
357814
class MatchGen {
38
  friend class QuantInfo;
39
private:
40
  //current children information
41
  int d_child_counter;
42
  bool d_use_children;
43
  //children of this object
44
  std::vector< int > d_children_order;
45
432273
  unsigned getNumChildren() { return d_children.size(); }
46
1667157
  MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }
47
  //MatchGen * getChild( int i ) { return &d_children[i]; }
48
  //current matching information
49
  std::vector<TNodeTrie*> d_qn;
50
  std::vector<std::map<TNode, TNodeTrie>::iterator> d_qni;
51
  bool doMatching( QuantConflictFind * p, QuantInfo * qi );
52
  //for matching : each index is either a variable or a ground term
53
  unsigned d_qni_size;
54
  std::map< int, int > d_qni_var_num;
55
  std::map< int, TNode > d_qni_gterm;
56
  std::map< int, int > d_qni_bound;
57
  std::vector< int > d_qni_bound_except;
58
  std::map< int, TNode > d_qni_bound_cons;
59
  std::map< int, int > d_qni_bound_cons_var;
60
  std::map< int, int >::iterator d_binding_it;
61
  //std::vector< int > d_independent;
62
  bool d_matched_basis;
63
  bool d_binding;
64
  //int getVarBindingVar();
65
  std::map< int, Node > d_ground_eval;
66
  //determine variable order
67
  void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );
68
  void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars, std::map< Node, bool >& visited, bool& hasNested );
69
public:
70
  //type of the match generator
71
  enum {
72
    typ_invalid,
73
    typ_ground,
74
    typ_pred,
75
    typ_eq,
76
    typ_formula,
77
    typ_var,
78
    typ_bool_var,
79
    typ_tconstraint,
80
    typ_tsym,
81
  };
82
  void debugPrintType( const char * c, short typ, bool isTrace = false );
83
public:
84
  MatchGen();
85
  MatchGen( QuantInfo * qi, Node n, bool isVar = false );
86
  bool d_tgt;
87
  bool d_tgt_orig;
88
  bool d_wasSet;
89
  Node d_n;
90
  std::vector< MatchGen > d_children;
91
  short d_type;
92
  bool d_type_not;
93
  /** reset round
94
   *
95
   * Called once at the beginning of each full/last-call effort, prior to
96
   * processing this match generator. This method returns false if the reset
97
   * failed, e.g. if a conflict was encountered during term indexing.
98
   */
99
  bool reset_round(QuantConflictFind* p);
100
  void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );
101
  bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );
102
442231
  bool isValid() { return d_type!=typ_invalid; }
103
  void setInvalid();
104
105
  // is this term treated as UF application?
106
  static bool isHandledBoolConnective( TNode n );
107
  static bool isHandledUfTerm( TNode n );
108
  static Node getMatchOperator( QuantConflictFind * p, Node n );
109
  //can this node be handled by the algorithm
110
  static bool isHandled( TNode n );
111
};
112
113
//info for quantifiers
114
class QuantInfo {
115
private:
116
  void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );
117
  void flatten( Node n, bool beneathQuant );
118
private: //for completing match
119
  std::vector< int > d_unassigned;
120
  std::vector< TypeNode > d_unassigned_tn;
121
  int d_unassigned_nvar;
122
  int d_una_index;
123
  std::vector< int > d_una_eqc_count;
124
  //optimization: track which arguments variables appear under UF terms in
125
  std::map< int, std::map< TNode, std::vector< unsigned > > > d_var_rel_dom;
126
  void getPropagateVars( QuantConflictFind * p, std::vector< TNode >& vars, TNode n, bool pol, std::map< TNode, bool >& visited );
127
  //optimization: number of variables set, to track when we can stop
128
  std::map< int, bool > d_vars_set;
129
  std::vector< Node > d_extra_var;
130
public:
131
  bool isBaseMatchComplete();
132
public:
133
  QuantInfo();
134
  ~QuantInfo();
135
  /** Get quantifiers inference manager */
136
  QuantifiersInferenceManager& getInferenceManager();
137
  std::vector< TNode > d_vars;
138
  std::vector< TypeNode > d_var_types;
139
  std::map< TNode, int > d_var_num;
140
  std::vector< int > d_tsym_vars;
141
  std::map< TNode, bool > d_inMatchConstraint;
142
7726814
  int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }
143
419524
  bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }
144
2252568
  int getNumVars() { return (int)d_vars.size(); }
145
406
  TNode getVar( int i ) { return d_vars[i]; }
146
147
  typedef std::map< int, MatchGen * > VarMgMap;
148
 private:
149
  /** The parent who owns this class */
150
  QuantConflictFind* d_parent;
151
  MatchGen * d_mg;
152
  VarMgMap d_var_mg;
153
 public:
154
4338818
  VarMgMap::const_iterator var_mg_find(int i) const { return d_var_mg.find(i); }
155
3821299
  VarMgMap::const_iterator var_mg_end() const { return d_var_mg.end(); }
156
1406992
  bool containsVarMg(int i) const { return var_mg_find(i) != var_mg_end(); }
157
158
222394
  bool matchGeneratorIsValid() const { return d_mg->isValid(); }
159
358449
  bool getNextMatch( QuantConflictFind * p ) {
160
358449
    return d_mg->getNextMatch(p, this);
161
  }
162
163
  Node d_q;
164
  bool reset_round( QuantConflictFind * p );
165
public:
166
  //initialize
167
  void initialize( QuantConflictFind * p, Node q, Node qn );
168
  //current constraints
169
  std::vector< TNode > d_match;
170
  std::vector< TNode > d_match_term;
171
  std::map< int, std::map< TNode, int > > d_curr_var_deq;
172
  std::map< Node, bool > d_tconstraints;
173
  int getCurrentRepVar( int v );
174
  TNode getCurrentValue( TNode n );
175
  TNode getCurrentExpValue( TNode n );
176
  bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );
177
  int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );
178
  int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );
179
  bool setMatch( QuantConflictFind * p, int v, TNode n, bool isGroundRep, bool isGround );
180
  void unsetMatch( QuantConflictFind * p, int v );
181
  bool isMatchSpurious( QuantConflictFind * p );
182
  bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );
183
  bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );
184
  bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );
185
  void revertMatch( QuantConflictFind * p, std::vector< int >& assigned );
186
  void debugPrintMatch( const char * c );
187
  bool isConstrainedVar( int v );
188
public:
189
  void getMatch( std::vector< Node >& terms );
190
};
191
192
9856
class QuantConflictFind : public QuantifiersModule
193
{
194
  friend class MatchGen;
195
  friend class QuantInfo;
196
  typedef context::CDHashMap<Node, bool> NodeBoolMap;
197
198
 private:
199
  context::CDO< bool > d_conflict;
200
  std::map< Kind, Node > d_zero;
201
  //for storing nodes created during t-constraint solving (prevents memory leaks)
202
  std::vector< Node > d_tempCache;
203
  //optimization: list of quantifiers that depend on ground function applications
204
  std::map< TNode, std::vector< Node > > d_func_rel_dom;
205
  std::map< TNode, bool > d_irr_func;
206
  std::map< Node, bool > d_irr_quant;
207
  void setIrrelevantFunction( TNode f );
208
private:
209
  std::map< Node, Node > d_op_node;
210
  std::map< Node, int > d_fid;
211
public:  //for ground terms
212
  Node d_true;
213
  Node d_false;
214
  TNode getZero( Kind k );
215
private:
216
  std::map< Node, QuantInfo > d_qinfo;
217
private:  //for equivalence classes
218
  // type -> list(eqc)
219
  std::map< TypeNode, std::vector< TNode > > d_eqcs;
220
221
 public:
222
  enum Effort : unsigned {
223
    EFFORT_CONFLICT,
224
    EFFORT_PROP_EQ,
225
    EFFORT_INVALID,
226
  };
227
  void setEffort(Effort e) { d_effort = e; }
228
229
1265033
  inline bool atConflictEffort() const {
230
1265033
    return d_effort == QuantConflictFind::EFFORT_CONFLICT;
231
  }
232
233
 private:
234
  Effort d_effort;
235
236
 public:
237
  bool areMatchEqual( TNode n1, TNode n2 );
238
  bool areMatchDisequal( TNode n1, TNode n2 );
239
240
 public:
241
  QuantConflictFind(QuantifiersState& qs,
242
                    QuantifiersInferenceManager& qim,
243
                    QuantifiersRegistry& qr,
244
                    TermRegistry& tr);
245
246
  /** register quantifier */
247
  void registerQuantifier(Node q) override;
248
249
 public:
250
  /** needs check */
251
  bool needsCheck(Theory::Effort level) override;
252
  /** reset round */
253
  void reset_round(Theory::Effort level) override;
254
  /** check
255
   *
256
   * This method attempts to construct a conflicting or propagating instance.
257
   * If such an instance exists, then it makes a call to
258
   * Instantiation::addInstantiation.
259
   */
260
  void check(Theory::Effort level, QEffort quant_e) override;
261
262
 private:
263
  /** check quantified formula
264
   *
265
   * This method is called by the above check method for each quantified
266
   * formula q. It attempts to find a conflicting or propagating instance for
267
   * q, depending on the effort level (d_effort).
268
   *
269
   * isConflict: this is set to true if we discovered a conflicting instance.
270
   * This flag may be set instead of d_conflict if --qcf-all-conflict is true,
271
   * in which we continuing adding all conflicts.
272
   * addedLemmas: tracks the total number of lemmas added, and is incremented by
273
   * this method when applicable.
274
   */
275
  void checkQuantifiedFormula(Node q, bool& isConflict, unsigned& addedLemmas);
276
277
 private:
278
  void debugPrint( const char * c );
279
  //for debugging
280
  std::vector< Node > d_quants;
281
  std::map< Node, int > d_quant_id;
282
  void debugPrintQuant( const char * c, Node q );
283
  void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );
284
public:
285
  /** statistics class */
286
  class Statistics {
287
  public:
288
    IntStat d_inst_rounds;
289
    IntStat d_entailment_checks;
290
    Statistics();
291
  };
292
  Statistics d_statistics;
293
  /** Identify this module */
294
152665
  std::string identify() const override { return "QcfEngine"; }
295
  /** is n a propagating instance?
296
   *
297
   * A propagating instance is any formula that consists of Boolean connectives,
298
   * equality, quantified formulas, and terms that exist in the current
299
   * context (those in the master equality engine).
300
   *
301
   * Notice the distinction that quantified formulas that do not appear in the
302
   * current context are considered to be legal in propagating instances. This
303
   * choice is significant for TPTP, where a net of ~200 benchmarks are gained
304
   * due to this decision.
305
   *
306
   * Propagating instances are the second most useful kind of instantiation
307
   * after conflicting instances and are used as a second effort in the
308
   * algorithm performed by this class.
309
   */
310
  bool isPropagatingInstance(Node n) const;
311
};
312
313
std::ostream& operator<<(std::ostream& os, const QuantConflictFind::Effort& e);
314
315
}  // namespace quantifiers
316
}  // namespace theory
317
}  // namespace cvc5
318
319
#endif