Adding listeners to Options.
[cvc5.git] / src / theory / theory_engine.h
1 /********************* */
2 /*! \file theory_engine.h
3 ** \verbatim
4 ** Original author: Morgan Deters
5 ** Major contributors: Andrew Reynolds, Dejan Jovanovic
6 ** Minor contributors (to current version): Christopher L. Conway, Francois Bobot, Kshitij Bansal, Clark Barrett, Liana Hadarean, Tim King
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 The theory engine
13 **
14 ** The theory engine.
15 **/
16
17 #include "cvc4_private.h"
18
19 #ifndef __CVC4__THEORY_ENGINE_H
20 #define __CVC4__THEORY_ENGINE_H
21
22 #include <deque>
23 #include <set>
24 #include <vector>
25 #include <utility>
26
27 #include "base/cvc4_assert.h"
28 #include "context/cdhashset.h"
29 #include "expr/node.h"
30 #include "options/options.h"
31 #include "options/smt_options.h"
32 #include "prop/prop_engine.h"
33 #include "smt_util/command.h"
34 #include "smt_util/lemma_channels.h"
35 #include "theory/atom_requests.h"
36 #include "theory/bv/bv_to_bool.h"
37 #include "theory/interrupted.h"
38 #include "theory/quantifiers/quant_conflict_find.h"
39 #include "theory/rewriter.h"
40 #include "theory/shared_terms_database.h"
41 #include "theory/sort_inference.h"
42 #include "theory/substitutions.h"
43 #include "theory/term_registration_visitor.h"
44 #include "theory/theory.h"
45 #include "theory/uf/equality_engine.h"
46 #include "theory/valuation.h"
47 #include "util/statistics_registry.h"
48 #include "util/unsafe_interrupt_exception.h"
49
50 namespace CVC4 {
51
52 class ResourceManager;
53
54 /**
55 * A pair of a theory and a node. This is used to mark the flow of
56 * propagations between theories.
57 */
58 struct NodeTheoryPair {
59 Node node;
60 theory::TheoryId theory;
61 size_t timestamp;
62 NodeTheoryPair(TNode node, theory::TheoryId theory, size_t timestamp)
63 : node(node), theory(theory), timestamp(timestamp) {}
64 NodeTheoryPair()
65 : theory(theory::THEORY_LAST) {}
66 // Comparison doesn't take into account the timestamp
67 bool operator == (const NodeTheoryPair& pair) const {
68 return node == pair.node && theory == pair.theory;
69 }
70 };/* struct NodeTheoryPair */
71
72 struct NodeTheoryPairHashFunction {
73 NodeHashFunction hashFunction;
74 // Hash doesn't take into account the timestamp
75 size_t operator()(const NodeTheoryPair& pair) const {
76 return hashFunction(pair.node)*0x9e3779b9 + pair.theory;
77 }
78 };/* struct NodeTheoryPairHashFunction */
79
80
81 /* Forward declarations */
82 namespace theory {
83 class TheoryModel;
84 class TheoryEngineModelBuilder;
85 class ITEUtilities;
86
87 namespace eq {
88 class EqualityEngine;
89 }/* CVC4::theory::eq namespace */
90
91 namespace quantifiers {
92 class TermDb;
93 }
94
95 class EntailmentCheckParameters;
96 class EntailmentCheckSideEffects;
97 }/* CVC4::theory namespace */
98
99 class DecisionEngine;
100 class RemoveITE;
101 class UnconstrainedSimplifier;
102
103 /**
104 * This is essentially an abstraction for a collection of theories. A
105 * TheoryEngine provides services to a PropEngine, making various
106 * T-solvers look like a single unit to the propositional part of
107 * CVC4.
108 */
109 class TheoryEngine {
110
111 /** Shared terms database can use the internals notify the theories */
112 friend class SharedTermsDatabase;
113 friend class theory::quantifiers::TermDb;
114
115 /** Associated PropEngine engine */
116 prop::PropEngine* d_propEngine;
117
118 /** Access to decision engine */
119 DecisionEngine* d_decisionEngine;
120
121 /** Our context */
122 context::Context* d_context;
123
124 /** Our user context */
125 context::UserContext* d_userContext;
126
127 /**
128 * A table of from theory IDs to theory pointers. Never use this table
129 * directly, use theoryOf() instead.
130 */
131 theory::Theory* d_theoryTable[theory::THEORY_LAST];
132
133 /**
134 * A collection of theories that are "active" for the current run.
135 * This set is provided by the user (as a logic string, say, in SMT-LIBv2
136 * format input), or else by default it's all-inclusive. This is important
137 * because we can optimize for single-theory runs (no sharing), can reduce
138 * the cost of walking the DAG on registration, etc.
139 */
140 const LogicInfo& d_logicInfo;
141
142 /**
143 * The database of shared terms.
144 */
145 SharedTermsDatabase d_sharedTerms;
146
147 /**
148 * Master equality engine, to share with theories.
149 */
150 theory::eq::EqualityEngine* d_masterEqualityEngine;
151
152 /** notify class for master equality engine */
153 class NotifyClass : public theory::eq::EqualityEngineNotify {
154 TheoryEngine& d_te;
155 public:
156 NotifyClass(TheoryEngine& te): d_te(te) {}
157 bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; }
158 bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; }
159 bool eqNotifyTriggerTermEquality(theory::TheoryId tag, TNode t1, TNode t2, bool value) { return true; }
160 void eqNotifyConstantTermMerge(TNode t1, TNode t2) {}
161 void eqNotifyNewClass(TNode t) { d_te.eqNotifyNewClass(t); }
162 void eqNotifyPreMerge(TNode t1, TNode t2) { d_te.eqNotifyPreMerge(t1, t2); }
163 void eqNotifyPostMerge(TNode t1, TNode t2) { d_te.eqNotifyPostMerge(t1, t2); }
164 void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { d_te.eqNotifyDisequal(t1, t2, reason); }
165 };/* class TheoryEngine::NotifyClass */
166 NotifyClass d_masterEENotify;
167
168 /**
169 * notification methods
170 */
171 void eqNotifyNewClass(TNode t);
172 void eqNotifyPreMerge(TNode t1, TNode t2);
173 void eqNotifyPostMerge(TNode t1, TNode t2);
174 void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);
175
176 /**
177 * The quantifiers engine
178 */
179 theory::QuantifiersEngine* d_quantEngine;
180
181 /**
182 * Default model object
183 */
184 theory::TheoryModel* d_curr_model;
185 /**
186 * Model builder object
187 */
188 theory::TheoryEngineModelBuilder* d_curr_model_builder;
189
190 typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap;
191 typedef std::hash_map<TNode, Node, TNodeHashFunction> TNodeMap;
192
193 /**
194 * Cache for theory-preprocessing of assertions
195 */
196 NodeMap d_ppCache;
197
198 /**
199 * Used for "missed-t-propagations" dumping mode only. A set of all
200 * theory-propagable literals.
201 */
202 context::CDList<TNode> d_possiblePropagations;
203
204 /**
205 * Used for "missed-t-propagations" dumping mode only. A
206 * context-dependent set of those theory-propagable literals that
207 * have been propagated.
208 */
209 context::CDHashSet<Node, NodeHashFunction> d_hasPropagated;
210
211
212 /**
213 * Statistics for a particular theory.
214 */
215 class Statistics {
216
217 static std::string mkName(std::string prefix,
218 theory::TheoryId theory,
219 std::string suffix) {
220 std::stringstream ss;
221 ss << prefix << theory << suffix;
222 return ss.str();
223 }
224
225 public:
226
227 IntStat conflicts, propagations, lemmas, requirePhase, flipDecision, restartDemands;
228
229 Statistics(theory::TheoryId theory);
230 ~Statistics();
231 };/* class TheoryEngine::Statistics */
232
233
234 /**
235 * An output channel for Theory that passes messages
236 * back to a TheoryEngine.
237 */
238 class EngineOutputChannel : public theory::OutputChannel {
239
240 friend class TheoryEngine;
241
242 /**
243 * The theory engine we're communicating with.
244 */
245 TheoryEngine* d_engine;
246
247 /**
248 * The statistics of the theory interractions.
249 */
250 Statistics d_statistics;
251
252 /**
253 * The theory owning this chanell.
254 */
255 theory::TheoryId d_theory;
256
257 public:
258
259 EngineOutputChannel(TheoryEngine* engine, theory::TheoryId theory) :
260 d_engine(engine),
261 d_statistics(theory),
262 d_theory(theory)
263 {
264 }
265
266 void safePoint(uint64_t ammount) throw(theory::Interrupted, UnsafeInterruptException, AssertionException) {
267 spendResource(ammount);
268 if (d_engine->d_interrupted) {
269 throw theory::Interrupted();
270 }
271 }
272
273 void conflict(TNode conflictNode, Proof* pf = NULL) throw(AssertionException, UnsafeInterruptException) {
274 Trace("theory::conflict") << "EngineOutputChannel<" << d_theory << ">::conflict(" << conflictNode << ")" << std::endl;
275 Assert(pf == NULL); // theory shouldn't be producing proofs yet
276 ++ d_statistics.conflicts;
277 d_engine->d_outputChannelUsed = true;
278 d_engine->conflict(conflictNode, d_theory);
279 }
280
281 bool propagate(TNode literal) throw(AssertionException, UnsafeInterruptException) {
282 Trace("theory::propagate") << "EngineOutputChannel<" << d_theory << ">::propagate(" << literal << ")" << std::endl;
283 ++ d_statistics.propagations;
284 d_engine->d_outputChannelUsed = true;
285 return d_engine->propagate(literal, d_theory);
286 }
287
288 theory::LemmaStatus lemma(TNode lemma,
289 ProofRule rule,
290 bool removable = false,
291 bool preprocess = false,
292 bool sendAtoms = false)
293 throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
294 Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
295 ++ d_statistics.lemmas;
296 d_engine->d_outputChannelUsed = true;
297 return d_engine->lemma(lemma, rule, false, removable, preprocess, sendAtoms ? d_theory: theory::THEORY_LAST);
298 }
299
300 theory::LemmaStatus splitLemma(TNode lemma, bool removable = false) throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
301 Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
302 ++ d_statistics.lemmas;
303 d_engine->d_outputChannelUsed = true;
304 return d_engine->lemma(lemma, RULE_SPLIT, false, removable, false, d_theory);
305 }
306
307 void demandRestart() throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
308 NodeManager* curr = NodeManager::currentNM();
309 Node restartVar = curr->mkSkolem("restartVar",
310 curr->booleanType(),
311 "A boolean variable asserted to be true to force a restart");
312 Trace("theory::restart") << "EngineOutputChannel<" << d_theory << ">::restart(" << restartVar << ")" << std::endl;
313 ++ d_statistics.restartDemands;
314 lemma(restartVar, RULE_INVALID, true);
315 }
316
317 void requirePhase(TNode n, bool phase)
318 throw(theory::Interrupted, AssertionException, UnsafeInterruptException) {
319 Debug("theory") << "EngineOutputChannel::requirePhase("
320 << n << ", " << phase << ")" << std::endl;
321 ++ d_statistics.requirePhase;
322 d_engine->d_propEngine->requirePhase(n, phase);
323 }
324
325 bool flipDecision()
326 throw(theory::Interrupted, AssertionException, UnsafeInterruptException) {
327 Debug("theory") << "EngineOutputChannel::flipDecision()" << std::endl;
328 ++ d_statistics.flipDecision;
329 return d_engine->d_propEngine->flipDecision();
330 }
331
332 void setIncomplete() throw(AssertionException, UnsafeInterruptException) {
333 Trace("theory") << "TheoryEngine::setIncomplete()" << std::endl;
334 d_engine->setIncomplete(d_theory);
335 }
336
337 void spendResource(unsigned ammount) throw(UnsafeInterruptException) {
338 d_engine->spendResource(ammount);
339 }
340
341 void handleUserAttribute( const char* attr, theory::Theory* t ){
342 d_engine->handleUserAttribute( attr, t );
343 }
344 };/* class TheoryEngine::EngineOutputChannel */
345
346 /**
347 * Output channels for individual theories.
348 */
349 EngineOutputChannel* d_theoryOut[theory::THEORY_LAST];
350
351 /**
352 * Are we in conflict.
353 */
354 context::CDO<bool> d_inConflict;
355
356 /**
357 * Called by the theories to notify of a conflict.
358 */
359 void conflict(TNode conflict, theory::TheoryId theoryId);
360
361 /**
362 * Debugging flag to ensure that shutdown() is called before the
363 * destructor.
364 */
365 bool d_hasShutDown;
366
367 /**
368 * True if a theory has notified us of incompleteness (at this
369 * context level or below).
370 */
371 context::CDO<bool> d_incomplete;
372
373 /**
374 * Called by the theories to notify that the current branch is incomplete.
375 */
376 void setIncomplete(theory::TheoryId theory) {
377 d_incomplete = true;
378 }
379
380
381 /**
382 * Mapping of propagations from recievers to senders.
383 */
384 typedef context::CDHashMap<NodeTheoryPair, NodeTheoryPair, NodeTheoryPairHashFunction> PropagationMap;
385 PropagationMap d_propagationMap;
386
387 /**
388 * Timestamp of propagations
389 */
390 context::CDO<size_t> d_propagationMapTimestamp;
391
392 /**
393 * Literals that are propagated by the theory. Note that these are TNodes.
394 * The theory can only propagate nodes that have an assigned literal in the
395 * SAT solver and are hence referenced in the SAT solver.
396 */
397 context::CDList<TNode> d_propagatedLiterals;
398
399 /**
400 * The index of the next literal to be propagated by a theory.
401 */
402 context::CDO<unsigned> d_propagatedLiteralsIndex;
403
404 /**
405 * Called by the output channel to propagate literals and facts
406 * @return false if immediate conflict
407 */
408 bool propagate(TNode literal, theory::TheoryId theory);
409
410 /**
411 * Internal method to call the propagation routines and collect the
412 * propagated literals.
413 */
414 void propagate(theory::Theory::Effort effort);
415
416 /**
417 * Called by the output channel to request decisions "as soon as
418 * possible."
419 */
420 void propagateAsDecision(TNode literal, theory::TheoryId theory);
421
422 /**
423 * A variable to mark if we added any lemmas.
424 */
425 bool d_lemmasAdded;
426
427 /**
428 * A variable to mark if the OutputChannel was "used" by any theory
429 * since the start of the last check. If it has been, we require
430 * a FULL_EFFORT check before exiting and reporting SAT.
431 *
432 * See the documentation for the needCheck() function, below.
433 */
434 bool d_outputChannelUsed;
435
436 /** Atom requests from lemmas */
437 AtomRequests d_atomRequests;
438
439 /**
440 * Adds a new lemma, returning its status.
441 * @param node the lemma
442 * @param negated should the lemma be asserted negated
443 * @param removable can the lemma be remove (restrictions apply)
444 * @param needAtoms if not THEORY_LAST, then
445 */
446 theory::LemmaStatus lemma(TNode node,
447 ProofRule rule,
448 bool negated,
449 bool removable,
450 bool preprocess,
451 theory::TheoryId atomsTo);
452
453 /** Enusre that the given atoms are send to the given theory */
454 void ensureLemmaAtoms(const std::vector<TNode>& atoms, theory::TheoryId theory);
455
456 RemoveITE& d_iteRemover;
457
458 /** sort inference module */
459 SortInference d_sortInfer;
460
461 /** Time spent in theory combination */
462 TimerStat d_combineTheoriesTime;
463
464 Node d_true;
465 Node d_false;
466
467 /** Whether we were just interrupted (or not) */
468 bool d_interrupted;
469 ResourceManager* d_resourceManager;
470
471 /** Container for lemma input and output channels. */
472 LemmaChannels* d_channels;
473
474 public:
475
476 /** Constructs a theory engine */
477 TheoryEngine(context::Context* context, context::UserContext* userContext,
478 RemoveITE& iteRemover, const LogicInfo& logic,
479 LemmaChannels* channels);
480
481 /** Destroys a theory engine */
482 ~TheoryEngine();
483
484 void interrupt() throw(ModalException);
485 /**
486 * "Spend" a resource during a search or preprocessing.
487 */
488 void spendResource(unsigned ammount);
489
490 /**
491 * Adds a theory. Only one theory per TheoryId can be present, so if
492 * there is another theory it will be deleted.
493 */
494 template <class TheoryClass>
495 inline void addTheory(theory::TheoryId theoryId) {
496 Assert(d_theoryTable[theoryId] == NULL && d_theoryOut[theoryId] == NULL);
497 d_theoryOut[theoryId] = new EngineOutputChannel(this, theoryId);
498 d_theoryTable[theoryId] =
499 new TheoryClass(d_context, d_userContext, *d_theoryOut[theoryId],
500 theory::Valuation(this), d_logicInfo);
501 }
502
503 inline void setPropEngine(prop::PropEngine* propEngine) {
504 Assert(d_propEngine == NULL);
505 d_propEngine = propEngine;
506 }
507
508 inline void setDecisionEngine(DecisionEngine* decisionEngine) {
509 Assert(d_decisionEngine == NULL);
510 d_decisionEngine = decisionEngine;
511 }
512
513 /** Called when all initialization of options/logic is done */
514 void finishInit();
515
516 /**
517 * Get a pointer to the underlying propositional engine.
518 */
519 inline prop::PropEngine* getPropEngine() const {
520 return d_propEngine;
521 }
522
523 /**
524 * Get a pointer to the underlying sat context.
525 */
526 inline context::Context* getSatContext() const {
527 return d_context;
528 }
529
530 /**
531 * Get a pointer to the underlying user context.
532 */
533 inline context::Context* getUserContext() const {
534 return d_userContext;
535 }
536
537 /**
538 * Get a pointer to the underlying quantifiers engine.
539 */
540 theory::QuantifiersEngine* getQuantifiersEngine() const {
541 return d_quantEngine;
542 }
543
544 private:
545
546 /**
547 * Helper for preprocess
548 */
549 Node ppTheoryRewrite(TNode term);
550
551 /**
552 * Queue of nodes for pre-registration.
553 */
554 std::queue<TNode> d_preregisterQueue;
555
556 /**
557 * Boolean flag denoting we are in pre-registration.
558 */
559 bool d_inPreregister;
560
561 /**
562 * Did the theories get any new facts since the last time we called
563 * check()
564 */
565 context::CDO<bool> d_factsAsserted;
566
567 /**
568 * Map from equality atoms to theories that would like to be notified about them.
569 */
570
571
572 /**
573 * Assert the formula to the given theory.
574 * @param assertion the assertion to send (not necesserily normalized)
575 * @param original the assertion as it was sent in from the propagating theory
576 * @param toTheoryId the theory to assert to
577 * @param fromTheoryId the theory that sent it
578 */
579 void assertToTheory(TNode assertion, TNode originalAssertion, theory::TheoryId toTheoryId, theory::TheoryId fromTheoryId);
580
581 /**
582 * Marks a theory propagation from a theory to a theory where a
583 * theory could be the THEORY_SAT_SOLVER for literals coming from
584 * or being propagated to the SAT solver. If the receiving theory
585 * already recieved the literal, the method returns false, otherwise
586 * it returns true.
587 *
588 * @param assertion the normalized assertion being sent
589 * @param originalAssertion the actual assertion that was sent
590 * @param toTheoryId the theory that is on the receiving end
591 * @param fromTheoryId the theory that sent the assertino
592 * @return true if a new assertion, false if theory already got it
593 */
594 bool markPropagation(TNode assertion, TNode originalAssertions, theory::TheoryId toTheoryId, theory::TheoryId fromTheoryId);
595
596 /**
597 * Computes the explanation by travarsing the propagation graph and
598 * asking relevant theories to explain the propagations. Initially
599 * the explanation vector should contain only the element (node, theory)
600 * where the node is the one to be explained, and the theory is the
601 * theory that sent the literal.
602 */
603 void getExplanation(std::vector<NodeTheoryPair>& explanationVector);
604
605 public:
606
607 /**
608 * Signal the start of a new round of assertion preprocessing
609 */
610 void preprocessStart();
611
612 /**
613 * Runs theory specific preprocessing on the non-Boolean parts of
614 * the formula. This is only called on input assertions, after ITEs
615 * have been removed.
616 */
617 Node preprocess(TNode node);
618
619 /**
620 * Return whether or not we are incomplete (in the current context).
621 */
622 inline bool isIncomplete() const {
623 return d_incomplete;
624 }
625
626 /**
627 * Returns true if we need another round of checking. If this
628 * returns true, check(FULL_EFFORT) _must_ be called by the
629 * propositional layer before reporting SAT.
630 *
631 * This is especially necessary for incomplete theories that lazily
632 * output some lemmas on FULL_EFFORT check (e.g. quantifier reasoning
633 * outputing quantifier instantiations). In such a case, a lemma can
634 * be asserted that is simplified away (perhaps it's already true).
635 * However, we must maintain the invariant that, if a theory uses the
636 * OutputChannel, it implicitly requests that another check(FULL_EFFORT)
637 * be performed before exit, even if no new facts are on its fact queue,
638 * as it might decide to further instantiate some lemmas, precluding
639 * a SAT response.
640 */
641 inline bool needCheck() const {
642 return d_outputChannelUsed || d_lemmasAdded;
643 }
644
645 /**
646 * This is called at shutdown time by the SmtEngine, just before
647 * destruction. It is important because there are destruction
648 * ordering issues between PropEngine and Theory.
649 */
650 void shutdown();
651
652 /**
653 * Solve the given literal with a theory that owns it.
654 */
655 theory::Theory::PPAssertStatus solve(TNode literal,
656 theory::SubstitutionMap& substitutionOut);
657
658 /**
659 * Preregister a Theory atom with the responsible theory (or
660 * theories).
661 */
662 void preRegister(TNode preprocessed);
663
664 /**
665 * Assert the formula to the appropriate theory.
666 * @param node the assertion
667 */
668 void assertFact(TNode node);
669
670 /**
671 * Check all (currently-active) theories for conflicts.
672 * @param effort the effort level to use
673 */
674 void check(theory::Theory::Effort effort);
675
676 /**
677 * Run the combination framework.
678 */
679 void combineTheories();
680
681 /**
682 * Calls ppStaticLearn() on all theories, accumulating their
683 * combined contributions in the "learned" builder.
684 */
685 void ppStaticLearn(TNode in, NodeBuilder<>& learned);
686
687 /**
688 * Calls presolve() on all theories and returns true
689 * if one of the theories discovers a conflict.
690 */
691 bool presolve();
692
693 /**
694 * Calls postsolve() on all theories.
695 */
696 void postsolve();
697
698 /**
699 * Calls notifyRestart() on all active theories.
700 */
701 void notifyRestart();
702
703 void getPropagatedLiterals(std::vector<TNode>& literals) {
704 for (; d_propagatedLiteralsIndex < d_propagatedLiterals.size(); d_propagatedLiteralsIndex = d_propagatedLiteralsIndex + 1) {
705 Debug("getPropagatedLiterals") << "TheoryEngine::getPropagatedLiterals: propagating: " << d_propagatedLiterals[d_propagatedLiteralsIndex] << std::endl;
706 literals.push_back(d_propagatedLiterals[d_propagatedLiteralsIndex]);
707 }
708 }
709
710 Node getNextDecisionRequest();
711
712 bool properConflict(TNode conflict) const;
713 bool properPropagation(TNode lit) const;
714 bool properExplanation(TNode node, TNode expl) const;
715
716 /**
717 * Returns an explanation of the node propagated to the SAT solver.
718 */
719 Node getExplanation(TNode node);
720
721 /**
722 * collect model info
723 */
724 void collectModelInfo( theory::TheoryModel* m, bool fullModel );
725
726 /**
727 * Get the current model
728 */
729 theory::TheoryModel* getModel();
730
731 /**
732 * Get the model builder
733 */
734 theory::TheoryEngineModelBuilder* getModelBuilder() { return d_curr_model_builder; }
735
736 /**
737 * Get the theory associated to a given Node.
738 *
739 * @returns the theory, or NULL if the TNode is
740 * of built-in type.
741 */
742 inline theory::Theory* theoryOf(TNode node) const {
743 return d_theoryTable[theory::Theory::theoryOf(node)];
744 }
745
746 /**
747 * Get the theory associated to a the given theory id.
748 *
749 * @returns the theory
750 */
751 inline theory::Theory* theoryOf(theory::TheoryId theoryId) const {
752 return d_theoryTable[theoryId];
753 }
754
755 inline bool isTheoryEnabled(theory::TheoryId theoryId) const {
756 return d_logicInfo.isTheoryEnabled(theoryId);
757 }
758
759 /**
760 * Returns the equality status of the two terms, from the theory
761 * that owns the domain type. The types of a and b must be the same.
762 */
763 theory::EqualityStatus getEqualityStatus(TNode a, TNode b);
764
765 /**
766 * Returns the value that a theory that owns the type of var currently
767 * has (or null if none);
768 */
769 Node getModelValue(TNode var);
770
771 /**
772 * Takes a literal and returns an equivalent literal that is guaranteed to be a SAT literal
773 */
774 Node ensureLiteral(TNode n);
775
776 /**
777 * Print all instantiations made by the quantifiers module.
778 */
779 void printInstantiations( std::ostream& out );
780
781 /**
782 * Print solution for synthesis conjectures found by ce_guided_instantiation module
783 */
784 void printSynthSolution( std::ostream& out );
785
786 /**
787 * Forwards an entailment check according to the given theoryOfMode.
788 * See theory.h for documentation on entailmentCheck().
789 */
790 std::pair<bool, Node> entailmentCheck(theory::TheoryOfMode mode, TNode lit, const theory::EntailmentCheckParameters* params = NULL, theory::EntailmentCheckSideEffects* out = NULL);
791
792 private:
793
794 /** Default visitor for pre-registration */
795 PreRegisterVisitor d_preRegistrationVisitor;
796
797 /** Visitor for collecting shared terms */
798 SharedTermsVisitor d_sharedTermsVisitor;
799
800 /** Dump the assertions to the dump */
801 void dumpAssertions(const char* tag);
802
803 /**
804 * A collection of ite preprocessing passes.
805 */
806 theory::ITEUtilities* d_iteUtilities;
807
808
809 /** For preprocessing pass simplifying unconstrained expressions */
810 UnconstrainedSimplifier* d_unconstrainedSimp;
811
812 /** For preprocessing pass lifting bit-vectors of size 1 to booleans */
813 theory::bv::BvToBoolPreprocessor d_bvToBoolPreprocessor;
814 public:
815 void staticInitializeBVOptions(const std::vector<Node>& assertions);
816 void ppBvToBool(const std::vector<Node>& assertions, std::vector<Node>& new_assertions);
817 bool ppBvAbstraction(const std::vector<Node>& assertions, std::vector<Node>& new_assertions);
818 void mkAckermanizationAsssertions(std::vector<Node>& assertions);
819
820 Node ppSimpITE(TNode assertion);
821 /** Returns false if an assertion simplified to false. */
822 bool donePPSimpITE(std::vector<Node>& assertions);
823
824 void ppUnconstrainedSimp(std::vector<Node>& assertions);
825
826 SharedTermsDatabase* getSharedTermsDatabase() { return &d_sharedTerms; }
827
828 theory::eq::EqualityEngine* getMasterEqualityEngine() { return d_masterEqualityEngine; }
829
830 RemoveITE* getIteRemover() { return &d_iteRemover; }
831
832 SortInference* getSortInference() { return &d_sortInfer; }
833
834 /** Prints the assertions to the debug stream */
835 void printAssertions(const char* tag);
836
837 /** Theory alternative is in use. */
838 bool useTheoryAlternative(const std::string& name);
839
840 /** Enables using a theory alternative by name. */
841 void enableTheoryAlternative(const std::string& name);
842
843 private:
844 std::set< std::string > d_theoryAlternatives;
845
846 std::map< std::string, std::vector< theory::Theory* > > d_attr_handle;
847 public:
848
849 /**
850 * Set user attribute.
851 * This function is called when an attribute is set by a user. In SMT-LIBv2 this is done
852 * via the syntax (! n :attr)
853 */
854 void setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value);
855
856 /**
857 * Handle user attribute.
858 * Associates theory t with the attribute attr. Theory t will be
859 * notified whenever an attribute of name attr is set.
860 */
861 void handleUserAttribute(const char* attr, theory::Theory* t);
862
863 /**
864 * Check that the theory assertions are satisfied in the model.
865 * This function is called from the smt engine's checkModel routine.
866 */
867 void checkTheoryAssertionsWithModel();
868
869 private:
870 IntStat d_arithSubstitutionsAdded;
871
872 };/* class TheoryEngine */
873
874 }/* CVC4 namespace */
875
876 #endif /* __CVC4__THEORY_ENGINE_H */