Merge branch '1.3.x'
[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 std::vector< TNode > d_vars;
129 std::map< TNode, int > d_var_num;
130 std::map< TNode, bool > d_nbeneathQuant;
131 std::map< int, std::vector< Node > > d_var_constraint[2];
132 int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }
133 bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }
134 int getNumVars() { return (int)d_vars.size(); }
135 TNode getVar( int i ) { return d_vars[i]; }
136
137 MatchGen * d_mg;
138 Node d_q;
139 std::map< int, MatchGen * > d_var_mg;
140 void reset_round( QuantConflictFind * p );
141 public:
142 //initialize
143 void initialize( Node q, Node qn );
144 //current constraints
145 std::vector< TNode > d_match;
146 std::vector< TNode > d_match_term;
147 std::map< int, std::map< TNode, int > > d_curr_var_deq;
148 int getCurrentRepVar( int v );
149 TNode getCurrentValue( TNode n );
150 TNode getCurrentExpValue( TNode n );
151 bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );
152 int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );
153 int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );
154 bool setMatch( QuantConflictFind * p, int v, TNode n );
155 bool isMatchSpurious( QuantConflictFind * p );
156 bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );
157 void revertMatch( std::vector< int >& assigned );
158 void debugPrintMatch( const char * c );
159 bool isConstrainedVar( int v );
160 public:
161 void getMatch( std::vector< Node >& terms );
162 };
163
164 class QuantConflictFind : public QuantifiersModule
165 {
166 friend class QcfNodeIndex;
167 friend class MatchGen;
168 friend class QuantInfo;
169 typedef context::CDChunkList<Node> NodeList;
170 typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;
171 private:
172 context::Context* d_c;
173 context::CDO< bool > d_conflict;
174 bool d_performCheck;
175 std::vector< Node > d_quant_order;
176 private:
177 std::map< Node, Node > d_op_node;
178 int d_fid_count;
179 std::map< Node, int > d_fid;
180 Node mkEqNode( Node a, Node b );
181 public: //for ground terms
182 Node d_true;
183 Node d_false;
184 private:
185 Node evaluateTerm( Node n );
186 int evaluate( Node n, bool pref = false, bool hasPref = false );
187 private:
188 //currently asserted quantifiers
189 NodeList d_qassert;
190 std::map< Node, QuantInfo > d_qinfo;
191 private: //for equivalence classes
192 eq::EqualityEngine * getEqualityEngine();
193 bool areDisequal( Node n1, Node n2 );
194 bool areEqual( Node n1, Node n2 );
195 Node getRepresentative( Node n );
196
197 /*
198 class EqcInfo {
199 public:
200 EqcInfo( context::Context* c ) : d_diseq( c ) {}
201 NodeBoolMap d_diseq;
202 bool isDisequal( Node n ) { return d_diseq.find( n )!=d_diseq.end() && d_diseq[n]; }
203 void setDisequal( Node n, bool val = true ) { d_diseq[n] = val; }
204 //NodeBoolMap& getRelEqr( int index ) { return index==0 ? d_rel_eqr_e : d_rel_eqr_d; }
205 };
206 std::map< Node, EqcInfo * > d_eqc_info;
207 EqcInfo * getEqcInfo( Node n, bool doCreate = true );
208 */
209 // operator -> index(terms)
210 std::map< TNode, QcfNodeIndex > d_uf_terms;
211 // operator -> index(eqc -> terms)
212 std::map< TNode, QcfNodeIndex > d_eqc_uf_terms;
213 //get qcf node index
214 QcfNodeIndex * getQcfNodeIndex( Node eqc, Node f );
215 QcfNodeIndex * getQcfNodeIndex( Node f );
216 // type -> list(eqc)
217 std::map< TypeNode, std::vector< TNode > > d_eqcs;
218 std::map< TypeNode, Node > d_model_basis;
219 //mapping from UF terms to representatives of their arguments
220 std::map< TNode, std::vector< TNode > > d_arg_reps;
221 //compute arg reps
222 void computeArgReps( TNode n );
223 //compute
224 void computeUfTerms( TNode f );
225 public:
226 enum {
227 effort_conflict,
228 effort_prop_eq,
229 effort_mc,
230 };
231 short d_effort;
232 void setEffort( int e ) { d_effort = e; }
233 static short getMaxQcfEffort();
234 bool areMatchEqual( TNode n1, TNode n2 );
235 bool areMatchDisequal( TNode n1, TNode n2 );
236 public:
237 QuantConflictFind( QuantifiersEngine * qe, context::Context* c );
238 /** register quantifier */
239 void registerQuantifier( Node q );
240 public:
241 /** assert quantifier */
242 void assertNode( Node q );
243 /** new node */
244 void newEqClass( Node n );
245 /** merge */
246 void merge( Node a, Node b );
247 /** assert disequal */
248 void assertDisequal( Node a, Node b );
249 /** reset round */
250 void reset_round( Theory::Effort level );
251 /** check */
252 void check( Theory::Effort level );
253 /** needs check */
254 bool needsCheck( Theory::Effort level );
255 private:
256 bool d_needs_computeRelEqr;
257 public:
258 void computeRelevantEqr();
259 private:
260 void debugPrint( const char * c );
261 //for debugging
262 std::vector< Node > d_quants;
263 std::map< Node, int > d_quant_id;
264 void debugPrintQuant( const char * c, Node q );
265 void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );
266 public:
267 /** statistics class */
268 class Statistics {
269 public:
270 IntStat d_inst_rounds;
271 IntStat d_conflict_inst;
272 IntStat d_prop_inst;
273 Statistics();
274 ~Statistics();
275 };
276 Statistics d_statistics;
277 };
278
279 }
280 }
281 }
282
283 #endif