Mostly resolves bug #561 memory leaks, and more.
[cvc5.git] / src / theory / quantifiers / quant_conflict_find.h
1 /********************* */
2 /*! \file quant_conflict_find.h
3 ** \verbatim
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-2013 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** information.\endverbatim
11 **
12 ** \brief quantifiers conflict find class
13 **/
14
15 #include "cvc4_private.h"
16
17 #ifndef QUANT_CONFLICT_FIND
18 #define QUANT_CONFLICT_FIND
19
20 #include "context/cdhashmap.h"
21 #include "context/cdchunk_list.h"
22 #include "theory/quantifiers_engine.h"
23
24 namespace CVC4 {
25 namespace theory {
26 namespace quantifiers {
27
28 class QcfNode;
29
30 class QuantConflictFind;
31
32 class QcfNodeIndex {
33 public:
34 std::map< TNode, QcfNodeIndex > d_children;
35 void clear() { d_children.clear(); }
36 void debugPrint( const char * c, int t );
37 Node existsTerm( TNode n, std::vector< TNode >& reps, int index = 0 );
38 Node addTerm( TNode n, std::vector< TNode >& reps, int index = 0 );
39 };
40
41 class QuantInfo;
42
43 //match generator
44 class MatchGen {
45 friend class QuantInfo;
46 private:
47 //current children information
48 int d_child_counter;
49 //children of this object
50 std::vector< int > d_children_order;
51 unsigned getNumChildren() { return d_children.size(); }
52 MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }
53 //MatchGen * getChild( int i ) { return &d_children[i]; }
54 //current matching information
55 std::vector< QcfNodeIndex * > d_qn;
56 std::vector< std::map< TNode, QcfNodeIndex >::iterator > d_qni;
57 bool doMatching( QuantConflictFind * p, QuantInfo * qi );
58 //for matching : each index is either a variable or a ground term
59 unsigned d_qni_size;
60 std::map< int, int > d_qni_var_num;
61 std::map< int, TNode > d_qni_gterm;
62 std::map< int, TNode > d_qni_gterm_rep;
63 std::map< int, int > d_qni_bound;
64 std::vector< int > d_qni_bound_except;
65 std::map< int, TNode > d_qni_bound_cons;
66 std::map< int, int > d_qni_bound_cons_var;
67 std::map< int, int >::iterator d_binding_it;
68 //std::vector< int > d_independent;
69 bool d_matched_basis;
70 bool d_binding;
71 //int getVarBindingVar();
72 std::map< int, Node > d_ground_eval;
73 //determine variable order
74 void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );
75 void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars );
76 public:
77 //type of the match generator
78 enum {
79 typ_invalid,
80 typ_ground,
81 typ_pred,
82 typ_eq,
83 typ_formula,
84 typ_var,
85 typ_ite_var,
86 typ_bool_var,
87 };
88 void debugPrintType( const char * c, short typ, bool isTrace = false );
89 public:
90 MatchGen() : d_type( typ_invalid ){}
91 MatchGen( QuantInfo * qi, Node n, bool isVar = false, bool beneathQuant = false );
92 bool d_tgt;
93 bool d_tgt_orig;
94 bool d_wasSet;
95 Node d_n;
96 std::vector< MatchGen > d_children;
97 short d_type;
98 bool d_type_not;
99 void reset_round( QuantConflictFind * p );
100 void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );
101 bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );
102 bool getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp );
103 Node getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp );
104 bool isValid() { return d_type!=typ_invalid; }
105 void setInvalid();
106
107 // is this term treated as UF application?
108 static bool isHandledBoolConnective( TNode n );
109 static bool isHandledUfTerm( TNode n );
110 static Node getOperator( QuantConflictFind * p, Node n );
111 //can this node be handled by the algorithm
112 static bool isHandled( TNode n );
113 };
114
115 //info for quantifiers
116 class QuantInfo {
117 private:
118 void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );
119 void flatten( Node n, bool beneathQuant );
120 private: //for completing match
121 std::vector< int > d_unassigned;
122 std::vector< TypeNode > d_unassigned_tn;
123 int d_unassigned_nvar;
124 int d_una_index;
125 std::vector< int > d_una_eqc_count;
126 public:
127 QuantInfo() : d_mg( NULL ) {}
128 ~QuantInfo() { delete d_mg; }
129 std::vector< TNode > d_vars;
130 std::map< TNode, int > d_var_num;
131 std::map< TNode, bool > d_nbeneathQuant;
132 std::map< int, std::vector< Node > > d_var_constraint[2];
133 int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }
134 bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }
135 int getNumVars() { return (int)d_vars.size(); }
136 TNode getVar( int i ) { return d_vars[i]; }
137
138 MatchGen * d_mg;
139 Node d_q;
140 std::map< int, MatchGen * > d_var_mg;
141 void reset_round( QuantConflictFind * p );
142 public:
143 //initialize
144 void initialize( Node q, Node qn );
145 //current constraints
146 std::vector< TNode > d_match;
147 std::vector< TNode > d_match_term;
148 std::map< int, std::map< TNode, int > > d_curr_var_deq;
149 int getCurrentRepVar( int v );
150 TNode getCurrentValue( TNode n );
151 TNode getCurrentExpValue( TNode n );
152 bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );
153 int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );
154 int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );
155 bool setMatch( QuantConflictFind * p, int v, TNode n );
156 bool isMatchSpurious( QuantConflictFind * p );
157 bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );
158 void revertMatch( std::vector< int >& assigned );
159 void debugPrintMatch( const char * c );
160 bool isConstrainedVar( int v );
161 public:
162 void getMatch( std::vector< Node >& terms );
163 };
164
165 class QuantConflictFind : public QuantifiersModule
166 {
167 friend class QcfNodeIndex;
168 friend class MatchGen;
169 friend class QuantInfo;
170 typedef context::CDChunkList<Node> NodeList;
171 typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;
172 private:
173 context::Context* d_c;
174 context::CDO< bool > d_conflict;
175 bool d_performCheck;
176 std::vector< Node > d_quant_order;
177 private:
178 std::map< Node, Node > d_op_node;
179 int d_fid_count;
180 std::map< Node, int > d_fid;
181 Node mkEqNode( Node a, Node b );
182 public: //for ground terms
183 Node d_true;
184 Node d_false;
185 private:
186 Node evaluateTerm( Node n );
187 int evaluate( Node n, bool pref = false, bool hasPref = false );
188 private:
189 //currently asserted quantifiers
190 NodeList d_qassert;
191 std::map< Node, QuantInfo > d_qinfo;
192 private: //for equivalence classes
193 eq::EqualityEngine * getEqualityEngine();
194 bool areDisequal( Node n1, Node n2 );
195 bool areEqual( Node n1, Node n2 );
196 Node getRepresentative( Node n );
197
198 /*
199 class EqcInfo {
200 public:
201 EqcInfo( context::Context* c ) : d_diseq( c ) {}
202 NodeBoolMap d_diseq;
203 bool isDisequal( Node n ) { return d_diseq.find( n )!=d_diseq.end() && d_diseq[n]; }
204 void setDisequal( Node n, bool val = true ) { d_diseq[n] = val; }
205 //NodeBoolMap& getRelEqr( int index ) { return index==0 ? d_rel_eqr_e : d_rel_eqr_d; }
206 };
207 std::map< Node, EqcInfo * > d_eqc_info;
208 EqcInfo * getEqcInfo( Node n, bool doCreate = true );
209 */
210 // operator -> index(terms)
211 std::map< TNode, QcfNodeIndex > d_uf_terms;
212 // operator -> index(eqc -> terms)
213 std::map< TNode, QcfNodeIndex > d_eqc_uf_terms;
214 //get qcf node index
215 QcfNodeIndex * getQcfNodeIndex( Node eqc, Node f );
216 QcfNodeIndex * getQcfNodeIndex( Node f );
217 // type -> list(eqc)
218 std::map< TypeNode, std::vector< TNode > > d_eqcs;
219 std::map< TypeNode, Node > d_model_basis;
220 //mapping from UF terms to representatives of their arguments
221 std::map< TNode, std::vector< TNode > > d_arg_reps;
222 //compute arg reps
223 void computeArgReps( TNode n );
224 //compute
225 void computeUfTerms( TNode f );
226 public:
227 enum {
228 effort_conflict,
229 effort_prop_eq,
230 effort_mc,
231 };
232 short d_effort;
233 void setEffort( int e ) { d_effort = e; }
234 static short getMaxQcfEffort();
235 bool areMatchEqual( TNode n1, TNode n2 );
236 bool areMatchDisequal( TNode n1, TNode n2 );
237 public:
238 QuantConflictFind( QuantifiersEngine * qe, context::Context* c );
239 /** register quantifier */
240 void registerQuantifier( Node q );
241 public:
242 /** assert quantifier */
243 void assertNode( Node q );
244 /** new node */
245 void newEqClass( Node n );
246 /** merge */
247 void merge( Node a, Node b );
248 /** assert disequal */
249 void assertDisequal( Node a, Node b );
250 /** reset round */
251 void reset_round( Theory::Effort level );
252 /** check */
253 void check( Theory::Effort level );
254 /** needs check */
255 bool needsCheck( Theory::Effort level );
256 private:
257 bool d_needs_computeRelEqr;
258 public:
259 void computeRelevantEqr();
260 private:
261 void debugPrint( const char * c );
262 //for debugging
263 std::vector< Node > d_quants;
264 std::map< Node, int > d_quant_id;
265 void debugPrintQuant( const char * c, Node q );
266 void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );
267 public:
268 /** statistics class */
269 class Statistics {
270 public:
271 IntStat d_inst_rounds;
272 IntStat d_conflict_inst;
273 IntStat d_prop_inst;
274 Statistics();
275 ~Statistics();
276 };
277 Statistics d_statistics;
278 /** Identify this module */
279 std::string identify() const { return "QcfEngine"; }
280 };
281
282 }
283 }
284 }
285
286 #endif