Merge pull request #72 from kbansal/decision-requirephase
[cvc5.git] / src / theory / bv / bv_subtheory_core.cpp
1 /********************* */
2 /*! \file bv_subtheory_core.cpp
3 ** \verbatim
4 ** Original author: Liana Hadarean
5 ** Major contributors: Andrew Reynolds
6 ** Minor contributors (to current version): Morgan Deters
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
11 **
12 ** \brief Algebraic solver.
13 **
14 ** Algebraic solver.
15 **/
16
17 #include "theory/bv/bv_subtheory_core.h"
18
19 #include "theory/bv/theory_bv.h"
20 #include "theory/bv/theory_bv_utils.h"
21 #include "theory/bv/slicer.h"
22 #include "theory/theory_model.h"
23 #include "theory/bv/options.h"
24
25 using namespace std;
26 using namespace CVC4;
27 using namespace CVC4::context;
28 using namespace CVC4::theory;
29 using namespace CVC4::theory::bv;
30 using namespace CVC4::theory::bv::utils;
31
32 CoreSolver::CoreSolver(context::Context* c, TheoryBV* bv)
33 : SubtheorySolver(c, bv),
34 d_notify(*this),
35 d_equalityEngine(d_notify, c, "theory::bv::TheoryBV", true),
36 d_slicer(new Slicer()),
37 d_isComplete(c, true),
38 d_useSlicer(false),
39 d_preregisterCalled(false),
40 d_checkCalled(false),
41 d_reasons(c)
42 {
43 // The kinds we are treating as function application in congruence
44 d_equalityEngine.addFunctionKind(kind::BITVECTOR_CONCAT, true);
45 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_AND);
46 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_OR);
47 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_XOR);
48 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_NOT);
49 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_NAND);
50 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_NOR);
51 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_XNOR);
52 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_COMP);
53 d_equalityEngine.addFunctionKind(kind::BITVECTOR_MULT, true);
54 d_equalityEngine.addFunctionKind(kind::BITVECTOR_PLUS, true);
55 d_equalityEngine.addFunctionKind(kind::BITVECTOR_EXTRACT, true);
56 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SUB);
57 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_NEG);
58 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_UDIV);
59 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_UREM);
60 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SDIV);
61 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SREM);
62 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SMOD);
63 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SHL);
64 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_LSHR);
65 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_ASHR);
66 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_ULT);
67 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_ULE);
68 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_UGT);
69 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_UGE);
70 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SLT);
71 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SLE);
72 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SGT);
73 // d_equalityEngine.addFunctionKind(kind::BITVECTOR_SGE);
74 }
75
76 CoreSolver::~CoreSolver() {
77 delete d_slicer;
78 }
79 void CoreSolver::setMasterEqualityEngine(eq::EqualityEngine* eq) {
80 d_equalityEngine.setMasterEqualityEngine(eq);
81 }
82
83 void CoreSolver::enableSlicer() {
84 AlwaysAssert (!d_preregisterCalled);
85 d_useSlicer = true;
86 d_statistics.d_slicerEnabled.setData(true);
87 }
88
89 void CoreSolver::preRegister(TNode node) {
90 d_preregisterCalled = true;
91 if (node.getKind() == kind::EQUAL) {
92 d_equalityEngine.addTriggerEquality(node);
93 if (d_useSlicer) {
94 d_slicer->processEquality(node);
95 AlwaysAssert(!d_checkCalled);
96 }
97 } else {
98 d_equalityEngine.addTerm(node);
99 }
100 }
101
102
103 void CoreSolver::explain(TNode literal, std::vector<TNode>& assumptions) {
104 bool polarity = literal.getKind() != kind::NOT;
105 TNode atom = polarity ? literal : literal[0];
106 if (atom.getKind() == kind::EQUAL) {
107 d_equalityEngine.explainEquality(atom[0], atom[1], polarity, assumptions);
108 } else {
109 d_equalityEngine.explainPredicate(atom, polarity, assumptions);
110 }
111 }
112
113 Node CoreSolver::getBaseDecomposition(TNode a) {
114 std::vector<Node> a_decomp;
115 d_slicer->getBaseDecomposition(a, a_decomp);
116 Node new_a = utils::mkConcat(a_decomp);
117 Debug("bv-slicer") << "CoreSolver::getBaseDecomposition " << a <<" => " << new_a << "\n";
118 return new_a;
119 }
120
121 bool CoreSolver::decomposeFact(TNode fact) {
122 Debug("bv-slicer") << "CoreSolver::decomposeFact fact=" << fact << endl;
123 // FIXME: are this the right things to assert?
124 // assert decompositions since the equality engine does not know the semantics of
125 // concat:
126 // a == a_1 concat ... concat a_k
127 // b == b_1 concat ... concat b_k
128 TNode eq = fact.getKind() == kind::NOT? fact[0] : fact;
129
130 TNode a = eq[0];
131 TNode b = eq[1];
132 Node new_a = getBaseDecomposition(a);
133 Node new_b = getBaseDecomposition(b);
134
135 Assert (utils::getSize(new_a) == utils::getSize(new_b) &&
136 utils::getSize(new_a) == utils::getSize(a));
137
138 NodeManager* nm = NodeManager::currentNM();
139 Node a_eq_new_a = nm->mkNode(kind::EQUAL, a, new_a);
140 Node b_eq_new_b = nm->mkNode(kind::EQUAL, b, new_b);
141
142 bool ok = true;
143 ok = assertFactToEqualityEngine(a_eq_new_a, utils::mkTrue());
144 if (!ok) return false;
145 ok = assertFactToEqualityEngine(b_eq_new_b, utils::mkTrue());
146 if (!ok) return false;
147 ok = assertFactToEqualityEngine(fact, fact);
148 if (!ok) return false;
149
150 if (fact.getKind() == kind::EQUAL) {
151 // assert the individual equalities as well
152 // a_i == b_i
153 if (new_a.getKind() == kind::BITVECTOR_CONCAT &&
154 new_b.getKind() == kind::BITVECTOR_CONCAT) {
155
156 Assert (new_a.getNumChildren() == new_b.getNumChildren());
157 for (unsigned i = 0; i < new_a.getNumChildren(); ++i) {
158 Node eq_i = nm->mkNode(kind::EQUAL, new_a[i], new_b[i]);
159 ok = assertFactToEqualityEngine(eq_i, fact);
160 if (!ok) return false;
161 }
162 }
163 }
164 return true;
165 }
166
167 bool CoreSolver::check(Theory::Effort e) {
168 Trace("bitvector::core") << "CoreSolver::check \n";
169
170 d_bv->spendResource();
171
172 d_checkCalled = true;
173 Assert (!d_bv->inConflict());
174 ++(d_statistics.d_numCallstoCheck);
175 bool ok = true;
176 std::vector<Node> core_eqs;
177 TNodeBoolMap seen;
178 // slicer does not deal with cardinality constraints yet
179 if (d_useSlicer) {
180 d_isComplete = false;
181 }
182 while (! done()) {
183 TNode fact = get();
184 if (d_isComplete && !isCompleteForTerm(fact, seen)) {
185 d_isComplete = false;
186 }
187
188 // only reason about equalities
189 if (fact.getKind() == kind::EQUAL || (fact.getKind() == kind::NOT && fact[0].getKind() == kind::EQUAL)) {
190 if (d_useSlicer) {
191 ok = decomposeFact(fact);
192 } else {
193 ok = assertFactToEqualityEngine(fact, fact);
194 }
195 } else {
196 ok = assertFactToEqualityEngine(fact, fact);
197 }
198 if (!ok)
199 return false;
200 }
201
202 if (Theory::fullEffort(e) && isComplete()) {
203 buildModel();
204 }
205
206 return true;
207 }
208
209 void CoreSolver::buildModel() {
210 Debug("bv-core") << "CoreSolver::buildModel() \n";
211 d_modelValues.clear();
212 TNodeSet constants;
213 TNodeSet constants_in_eq_engine;
214 // collect constants in equality engine
215 eq::EqClassesIterator eqcs_i = eq::EqClassesIterator(&d_equalityEngine);
216 while (!eqcs_i.isFinished()) {
217 TNode repr = *eqcs_i;
218 if (repr.getKind() == kind::CONST_BITVECTOR) {
219 // must check if it's just the constant
220 eq::EqClassIterator it(repr, &d_equalityEngine);
221 if (!(++it).isFinished() || true) {
222 constants.insert(repr);
223 constants_in_eq_engine.insert(repr);
224 }
225 }
226 ++eqcs_i;
227 }
228
229 // build repr to value map
230
231 eqcs_i = eq::EqClassesIterator(&d_equalityEngine);
232 while (!eqcs_i.isFinished()) {
233 TNode repr = *eqcs_i;
234 ++eqcs_i;
235
236 if (repr.getKind() != kind::VARIABLE &&
237 repr.getKind() != kind::SKOLEM &&
238 repr.getKind() != kind::CONST_BITVECTOR &&
239 !d_bv->isSharedTerm(repr)) {
240 continue;
241 }
242
243 TypeNode type = repr.getType();
244 if (type.isBitVector() && repr.getKind()!= kind::CONST_BITVECTOR) {
245 Debug("bv-core-model") << " processing " << repr <<"\n";
246 // we need to assign a value for it
247 TypeEnumerator te(type);
248 Node val;
249 do {
250 val = *te;
251 ++te;
252 // Debug("bv-core-model") << " trying value " << val << "\n";
253 // Debug("bv-core-model") << " is in set? " << constants.count(val) << "\n";
254 // Debug("bv-core-model") << " enumerator done? " << te.isFinished() << "\n";
255 } while (constants.count(val) != 0 && !(te.isFinished()));
256
257 if (te.isFinished() && constants.count(val) != 0) {
258 // if we cannot enumerate anymore values we just return the lemma stating that
259 // at least two of the representatives are equal.
260 std::vector<TNode> representatives;
261 representatives.push_back(repr);
262
263 for (TNodeSet::const_iterator it = constants_in_eq_engine.begin();
264 it != constants_in_eq_engine.end(); ++it) {
265 TNode constant = *it;
266 if (utils::getSize(constant) == utils::getSize(repr)) {
267 representatives.push_back(constant);
268 }
269 }
270 for (ModelValue::const_iterator it = d_modelValues.begin(); it != d_modelValues.end(); ++it) {
271 representatives.push_back(it->first);
272 }
273 std::vector<Node> equalities;
274 for (unsigned i = 0; i < representatives.size(); ++i) {
275 for (unsigned j = i + 1; j < representatives.size(); ++j) {
276 TNode a = representatives[i];
277 TNode b = representatives[j];
278 if (utils::getSize(a) == utils::getSize(b)) {
279 equalities.push_back(utils::mkNode(kind::EQUAL, a, b));
280 }
281 }
282 }
283 Node lemma = utils::mkOr(equalities);
284 d_bv->lemma(lemma);
285 Debug("bv-core") << " lemma: " << lemma << "\n";
286 return;
287 }
288 Debug("bv-core-model") << " " << repr << " => " << val <<"\n" ;
289 constants.insert(val);
290 d_modelValues[repr] = val;
291 }
292 }
293 }
294
295 bool CoreSolver::assertFactToEqualityEngine(TNode fact, TNode reason) {
296 // Notify the equality engine
297 if (!d_bv->inConflict() && (!d_bv->wasPropagatedBySubtheory(fact) || d_bv->getPropagatingSubtheory(fact) != SUB_CORE)) {
298 Debug("bv-slicer-eq") << "CoreSolver::assertFactToEqualityEngine fact=" << fact << endl;
299 // Debug("bv-slicer-eq") << " reason=" << reason << endl;
300 bool negated = fact.getKind() == kind::NOT;
301 TNode predicate = negated ? fact[0] : fact;
302 if (predicate.getKind() == kind::EQUAL) {
303 if (negated) {
304 // dis-equality
305 d_equalityEngine.assertEquality(predicate, false, reason);
306 } else {
307 // equality
308 d_equalityEngine.assertEquality(predicate, true, reason);
309 }
310 } else {
311 // Adding predicate if the congruence over it is turned on
312 if (d_equalityEngine.isFunctionKind(predicate.getKind())) {
313 d_equalityEngine.assertPredicate(predicate, !negated, reason);
314 }
315 }
316 }
317
318 // checking for a conflict
319 if (d_bv->inConflict()) {
320 return false;
321 }
322 return true;
323 }
324
325 bool CoreSolver::NotifyClass::eqNotifyTriggerEquality(TNode equality, bool value) {
326 Debug("bitvector::core") << "NotifyClass::eqNotifyTriggerEquality(" << equality << ", " << (value ? "true" : "false" )<< ")" << std::endl;
327 if (value) {
328 return d_solver.storePropagation(equality);
329 } else {
330 return d_solver.storePropagation(equality.notNode());
331 }
332 }
333
334 bool CoreSolver::NotifyClass::eqNotifyTriggerPredicate(TNode predicate, bool value) {
335 Debug("bitvector::core") << "NotifyClass::eqNotifyTriggerPredicate(" << predicate << ", " << (value ? "true" : "false" ) << ")" << std::endl;
336 if (value) {
337 return d_solver.storePropagation(predicate);
338 } else {
339 return d_solver.storePropagation(predicate.notNode());
340 }
341 }
342
343 bool CoreSolver::NotifyClass::eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) {
344 Debug("bitvector::core") << "NotifyClass::eqNotifyTriggerTermMerge(" << t1 << ", " << t2 << ")" << std::endl;
345 if (value) {
346 return d_solver.storePropagation(t1.eqNode(t2));
347 } else {
348 return d_solver.storePropagation(t1.eqNode(t2).notNode());
349 }
350 }
351
352 void CoreSolver::NotifyClass::eqNotifyConstantTermMerge(TNode t1, TNode t2) {
353 d_solver.conflict(t1, t2);
354 }
355
356 bool CoreSolver::storePropagation(TNode literal) {
357 return d_bv->storePropagation(literal, SUB_CORE);
358 }
359
360 void CoreSolver::conflict(TNode a, TNode b) {
361 std::vector<TNode> assumptions;
362 d_equalityEngine.explainEquality(a, b, true, assumptions);
363 Node conflict = flattenAnd(assumptions);
364 d_bv->setConflict(conflict);
365 }
366
367 bool CoreSolver::isCompleteForTerm(TNode term, TNodeBoolMap& seen) {
368 if (d_useSlicer)
369 return utils::isCoreTerm(term, seen);
370
371 return utils::isEqualityTerm(term, seen);
372 }
373
374 void CoreSolver::collectModelInfo(TheoryModel* m, bool fullModel) {
375 if (d_useSlicer) {
376 Unreachable();
377 }
378 if (Debug.isOn("bitvector-model")) {
379 context::CDQueue<Node>::const_iterator it = d_assertionQueue.begin();
380 for (; it!= d_assertionQueue.end(); ++it) {
381 Debug("bitvector-model") << "CoreSolver::collectModelInfo (assert "
382 << *it << ")\n";
383 }
384 }
385 set<Node> termSet;
386 d_bv->computeRelevantTerms(termSet);
387 m->assertEqualityEngine(&d_equalityEngine, &termSet);
388 if (isComplete()) {
389 Debug("bitvector-model") << "CoreSolver::collectModelInfo complete.";
390 for (ModelValue::const_iterator it = d_modelValues.begin(); it != d_modelValues.end(); ++it) {
391 Node a = it->first;
392 Node b = it->second;
393 Debug("bitvector-model") << "CoreSolver::collectModelInfo modelValues "
394 << a << " => " << b <<")\n";
395 m->assertEquality(a, b, true);
396 }
397 }
398 }
399
400 Node CoreSolver::getModelValue(TNode var) {
401 // we don't need to evaluate bv expressions and only look at variable values
402 // because this only gets called when the core theory is complete (i.e. no other bv
403 // function symbols are currently asserted)
404 Assert (d_slicer->isCoreTerm(var));
405
406 Debug("bitvector-model") << "CoreSolver::getModelValue (" << var <<")";
407 Assert (isComplete());
408 TNode repr = d_equalityEngine.getRepresentative(var);
409 Node result = Node();
410 if (repr.getKind() == kind::CONST_BITVECTOR) {
411 result = repr;
412 } else if (d_modelValues.find(repr) == d_modelValues.end()) {
413 // it may be a shared term that never gets asserted
414 // result is just Null
415 Assert(d_bv->isSharedTerm(var));
416 } else {
417 result = d_modelValues[repr];
418 }
419 Debug("bitvector-model") << " => " << result <<"\n";
420 return result;
421 }
422
423 CoreSolver::Statistics::Statistics()
424 : d_numCallstoCheck("theory::bv::CoreSolver::NumCallsToCheck", 0)
425 , d_slicerEnabled("theory::bv::CoreSolver::SlicerEnabled", false)
426 {
427 StatisticsRegistry::registerStat(&d_numCallstoCheck);
428 StatisticsRegistry::registerStat(&d_slicerEnabled);
429 }
430 CoreSolver::Statistics::~Statistics() {
431 StatisticsRegistry::unregisterStat(&d_numCallstoCheck);
432 StatisticsRegistry::unregisterStat(&d_slicerEnabled);
433 }