summaryrefslogtreecommitdiff
path: root/src/theory/theory_engine.h
blob: 886aa68635bd9ce3ed51fc7530d4974a8863e2e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
/*********************                                                        */
/*! \file theory_engine.h
 ** \verbatim
 ** Original author: Morgan Deters
 ** Major contributors: Andrew Reynolds, Dejan Jovanovic
 ** Minor contributors (to current version): Christopher L. Conway, Francois Bobot, Kshitij Bansal, Clark Barrett, Liana Hadarean, Tim King
 ** This file is part of the CVC4 project.
 ** Copyright (c) 2009-2014  New York University and The University of Iowa
 ** See the file COPYING in the top-level source directory for licensing
 ** information.\endverbatim
 **
 ** \brief The theory engine
 **
 ** The theory engine.
 **/

#include "cvc4_private.h"

#ifndef __CVC4__THEORY_ENGINE_H
#define __CVC4__THEORY_ENGINE_H

#include <deque>
#include <set>
#include <vector>
#include <utility>

#include "base/cvc4_assert.h"
#include "context/cdhashset.h"
#include "expr/node.h"
#include "options/options.h"
#include "options/smt_options.h"
#include "prop/prop_engine.h"
#include "smt/command.h"
#include "smt_util/lemma_channels.h"
#include "theory/atom_requests.h"
#include "theory/bv/bv_to_bool.h"
#include "theory/interrupted.h"
#include "theory/quantifiers/quant_conflict_find.h"
#include "theory/rewriter.h"
#include "theory/shared_terms_database.h"
#include "theory/sort_inference.h"
#include "theory/substitutions.h"
#include "theory/term_registration_visitor.h"
#include "theory/theory.h"
#include "theory/uf/equality_engine.h"
#include "theory/valuation.h"
#include "util/statistics_registry.h"
#include "util/unsafe_interrupt_exception.h"

namespace CVC4 {

class ResourceManager;

/**
 * A pair of a theory and a node. This is used to mark the flow of
 * propagations between theories.
 */
struct NodeTheoryPair {
  Node node;
  theory::TheoryId theory;
  size_t timestamp;
  NodeTheoryPair(TNode node, theory::TheoryId theory, size_t timestamp)
  : node(node), theory(theory), timestamp(timestamp) {}
  NodeTheoryPair()
  : theory(theory::THEORY_LAST) {}
  // Comparison doesn't take into account the timestamp
  bool operator == (const NodeTheoryPair& pair) const {
    return node == pair.node && theory == pair.theory;
  }
};/* struct NodeTheoryPair */

struct NodeTheoryPairHashFunction {
  NodeHashFunction hashFunction;
  // Hash doesn't take into account the timestamp
  size_t operator()(const NodeTheoryPair& pair) const {
    return hashFunction(pair.node)*0x9e3779b9 + pair.theory;
  }
};/* struct NodeTheoryPairHashFunction */


/* Forward declarations */
namespace theory {
  class TheoryModel;
  class TheoryEngineModelBuilder;
  class ITEUtilities;

  namespace eq {
    class EqualityEngine;
  }/* CVC4::theory::eq namespace */

  namespace quantifiers {
    class TermDb;
  }

  class EntailmentCheckParameters;
  class EntailmentCheckSideEffects;
}/* CVC4::theory namespace */

class DecisionEngine;
class RemoveITE;
class UnconstrainedSimplifier;

/**
 * This is essentially an abstraction for a collection of theories.  A
 * TheoryEngine provides services to a PropEngine, making various
 * T-solvers look like a single unit to the propositional part of
 * CVC4.
 */
class TheoryEngine {

  /** Shared terms database can use the internals notify the theories */
  friend class SharedTermsDatabase;
  friend class theory::quantifiers::TermDb;

  /** Associated PropEngine engine */
  prop::PropEngine* d_propEngine;

  /** Access to decision engine */
  DecisionEngine* d_decisionEngine;

  /** Our context */
  context::Context* d_context;

  /** Our user context */
  context::UserContext* d_userContext;

  /**
   * A table of from theory IDs to theory pointers. Never use this table
   * directly, use theoryOf() instead.
   */
  theory::Theory* d_theoryTable[theory::THEORY_LAST];

  /**
   * A collection of theories that are "active" for the current run.
   * This set is provided by the user (as a logic string, say, in SMT-LIBv2
   * format input), or else by default it's all-inclusive.  This is important
   * because we can optimize for single-theory runs (no sharing), can reduce
   * the cost of walking the DAG on registration, etc.
   */
  const LogicInfo& d_logicInfo;

  /**
   * The database of shared terms.
   */
  SharedTermsDatabase d_sharedTerms;

  /**
   * Master equality engine, to share with theories.
   */
  theory::eq::EqualityEngine* d_masterEqualityEngine;

  /** notify class for master equality engine */
  class NotifyClass : public theory::eq::EqualityEngineNotify {
    TheoryEngine& d_te;
  public:
    NotifyClass(TheoryEngine& te): d_te(te) {}
    bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; }
    bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; }
    bool eqNotifyTriggerTermEquality(theory::TheoryId tag, TNode t1, TNode t2, bool value) { return true; }
    void eqNotifyConstantTermMerge(TNode t1, TNode t2) {}
    void eqNotifyNewClass(TNode t) { d_te.eqNotifyNewClass(t); }
    void eqNotifyPreMerge(TNode t1, TNode t2) { d_te.eqNotifyPreMerge(t1, t2); }
    void eqNotifyPostMerge(TNode t1, TNode t2) { d_te.eqNotifyPostMerge(t1, t2); }
    void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) { d_te.eqNotifyDisequal(t1, t2, reason); }
  };/* class TheoryEngine::NotifyClass */
  NotifyClass d_masterEENotify;

  /**
   * notification methods
   */
  void eqNotifyNewClass(TNode t);
  void eqNotifyPreMerge(TNode t1, TNode t2);
  void eqNotifyPostMerge(TNode t1, TNode t2);
  void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);

  /**
   * The quantifiers engine
   */
  theory::QuantifiersEngine* d_quantEngine;

  /**
   * Default model object
   */
  theory::TheoryModel* d_curr_model;
  /**
   * Model builder object
   */
  theory::TheoryEngineModelBuilder* d_curr_model_builder;

  typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap;
  typedef std::hash_map<TNode, Node, TNodeHashFunction> TNodeMap;

  /**
  * Cache for theory-preprocessing of assertions
   */
  NodeMap d_ppCache;

  /**
   * Used for "missed-t-propagations" dumping mode only.  A set of all
   * theory-propagable literals.
   */
  context::CDList<TNode> d_possiblePropagations;

  /**
   * Used for "missed-t-propagations" dumping mode only.  A
   * context-dependent set of those theory-propagable literals that
   * have been propagated.
   */
  context::CDHashSet<Node, NodeHashFunction> d_hasPropagated;


  /**
   * Statistics for a particular theory.
   */
  class Statistics {

    static std::string mkName(std::string prefix,
                              theory::TheoryId theory,
                              std::string suffix) {
      std::stringstream ss;
      ss << prefix << theory << suffix;
      return ss.str();
    }

  public:

    IntStat conflicts, propagations, lemmas, requirePhase, flipDecision, restartDemands;

    Statistics(theory::TheoryId theory);
    ~Statistics();
  };/* class TheoryEngine::Statistics */


  /**
   * An output channel for Theory that passes messages
   * back to a TheoryEngine.
   */
  class EngineOutputChannel : public theory::OutputChannel {

    friend class TheoryEngine;

    /**
     * The theory engine we're communicating with.
     */
    TheoryEngine* d_engine;

    /**
     * The statistics of the theory interractions.
     */
    Statistics d_statistics;

    /**
     * The theory owning this chanell.
     */
    theory::TheoryId d_theory;

  public:

    EngineOutputChannel(TheoryEngine* engine, theory::TheoryId theory) :
      d_engine(engine),
      d_statistics(theory),
      d_theory(theory)
    {
    }

      void safePoint(uint64_t ammount) throw(theory::Interrupted, UnsafeInterruptException, AssertionException) {
      spendResource(ammount);
      if (d_engine->d_interrupted) {
        throw theory::Interrupted();
      }
    }

    void conflict(TNode conflictNode, Proof* pf = NULL) throw(AssertionException, UnsafeInterruptException) {
      Trace("theory::conflict") << "EngineOutputChannel<" << d_theory << ">::conflict(" << conflictNode << ")" << std::endl;
      Assert(pf == NULL); // theory shouldn't be producing proofs yet
      ++ d_statistics.conflicts;
      d_engine->d_outputChannelUsed = true;
      d_engine->conflict(conflictNode, d_theory);
    }

    bool propagate(TNode literal) throw(AssertionException, UnsafeInterruptException) {
      Trace("theory::propagate") << "EngineOutputChannel<" << d_theory << ">::propagate(" << literal << ")" << std::endl;
      ++ d_statistics.propagations;
      d_engine->d_outputChannelUsed = true;
      return d_engine->propagate(literal, d_theory);
    }

    theory::LemmaStatus lemma(TNode lemma,
                              ProofRule rule,
                              bool removable = false,
                              bool preprocess = false,
                              bool sendAtoms = false)
      throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
      Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
      ++ d_statistics.lemmas;
      d_engine->d_outputChannelUsed = true;
      return d_engine->lemma(lemma, rule, false, removable, preprocess, sendAtoms ? d_theory: theory::THEORY_LAST);
    }

    theory::LemmaStatus splitLemma(TNode lemma, bool removable = false) throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
      Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
      ++ d_statistics.lemmas;
      d_engine->d_outputChannelUsed = true;
      return d_engine->lemma(lemma, RULE_SPLIT, false, removable, false, d_theory);
    }

    void demandRestart() throw(TypeCheckingExceptionPrivate, AssertionException, UnsafeInterruptException) {
      NodeManager* curr = NodeManager::currentNM();
      Node restartVar =  curr->mkSkolem("restartVar",
                                        curr->booleanType(),
                                        "A boolean variable asserted to be true to force a restart");
      Trace("theory::restart") << "EngineOutputChannel<" << d_theory << ">::restart(" << restartVar << ")" << std::endl;
      ++ d_statistics.restartDemands;
      lemma(restartVar, RULE_INVALID, true);
    }

    void requirePhase(TNode n, bool phase)
      throw(theory::Interrupted, AssertionException, UnsafeInterruptException) {
      Debug("theory") << "EngineOutputChannel::requirePhase("
                      << n << ", " << phase << ")" << std::endl;
      ++ d_statistics.requirePhase;
      d_engine->d_propEngine->requirePhase(n, phase);
    }

    bool flipDecision()
      throw(theory::Interrupted, AssertionException, UnsafeInterruptException) {
      Debug("theory") << "EngineOutputChannel::flipDecision()" << std::endl;
      ++ d_statistics.flipDecision;
      return d_engine->d_propEngine->flipDecision();
    }

    void setIncomplete() throw(AssertionException, UnsafeInterruptException) {
      Trace("theory") << "TheoryEngine::setIncomplete()" << std::endl;
      d_engine->setIncomplete(d_theory);
    }

    void spendResource(unsigned ammount) throw(UnsafeInterruptException) {
      d_engine->spendResource(ammount);
    }

    void handleUserAttribute( const char* attr, theory::Theory* t ){
      d_engine->handleUserAttribute( attr, t );
    }
  };/* class TheoryEngine::EngineOutputChannel */

  /**
   * Output channels for individual theories.
   */
  EngineOutputChannel* d_theoryOut[theory::THEORY_LAST];

  /**
   * Are we in conflict.
   */
  context::CDO<bool> d_inConflict;

  /**
   * Called by the theories to notify of a conflict.
   */
  void conflict(TNode conflict, theory::TheoryId theoryId);

  /**
   * Debugging flag to ensure that shutdown() is called before the
   * destructor.
   */
  bool d_hasShutDown;

  /**
   * True if a theory has notified us of incompleteness (at this
   * context level or below).
   */
  context::CDO<bool> d_incomplete;

  /**
   * Called by the theories to notify that the current branch is incomplete.
   */
  void setIncomplete(theory::TheoryId theory) {
    d_incomplete = true;
  }


  /**
   * Mapping of propagations from recievers to senders.
   */
  typedef context::CDHashMap<NodeTheoryPair, NodeTheoryPair, NodeTheoryPairHashFunction> PropagationMap;
  PropagationMap d_propagationMap;

  /**
   * Timestamp of propagations
   */
  context::CDO<size_t> d_propagationMapTimestamp;

  /**
   * Literals that are propagated by the theory. Note that these are TNodes.
   * The theory can only propagate nodes that have an assigned literal in the
   * SAT solver and are hence referenced in the SAT solver.
   */
  context::CDList<TNode> d_propagatedLiterals;

  /**
   * The index of the next literal to be propagated by a theory.
   */
  context::CDO<unsigned> d_propagatedLiteralsIndex;

  /**
   * Called by the output channel to propagate literals and facts
   * @return false if immediate conflict
   */
  bool propagate(TNode literal, theory::TheoryId theory);

  /**
   * Internal method to call the propagation routines and collect the
   * propagated literals.
   */
  void propagate(theory::Theory::Effort effort);

  /**
   * Called by the output channel to request decisions "as soon as
   * possible."
   */
  void propagateAsDecision(TNode literal, theory::TheoryId theory);

  /**
   * A variable to mark if we added any lemmas.
   */
  bool d_lemmasAdded;

  /**
   * A variable to mark if the OutputChannel was "used" by any theory
   * since the start of the last check.  If it has been, we require
   * a FULL_EFFORT check before exiting and reporting SAT.
   *
   * See the documentation for the needCheck() function, below.
   */
  bool d_outputChannelUsed;

  /** Atom requests from lemmas */
  AtomRequests d_atomRequests;

  /**
   * Adds a new lemma, returning its status.
   * @param node the lemma
   * @param negated should the lemma be asserted negated
   * @param removable can the lemma be remove (restrictions apply)
   * @param needAtoms if not THEORY_LAST, then
   */
  theory::LemmaStatus lemma(TNode node,
                            ProofRule rule,
                            bool negated,
                            bool removable,
                            bool preprocess,
                            theory::TheoryId atomsTo);

  /** Enusre that the given atoms are send to the given theory */
  void ensureLemmaAtoms(const std::vector<TNode>& atoms, theory::TheoryId theory);

  RemoveITE& d_iteRemover;

  /** sort inference module */
  SortInference d_sortInfer;

  /** Time spent in theory combination */
  TimerStat d_combineTheoriesTime;

  Node d_true;
  Node d_false;

  /** Whether we were just interrupted (or not) */
  bool d_interrupted;
  ResourceManager* d_resourceManager;

  /** Container for lemma input and output channels. */
  LemmaChannels* d_channels;

public:

  /** Constructs a theory engine */
  TheoryEngine(context::Context* context, context::UserContext* userContext,
               RemoveITE& iteRemover, const LogicInfo& logic,
               LemmaChannels* channels);

  /** Destroys a theory engine */
  ~TheoryEngine();

  void interrupt() throw(ModalException);
  /**
   * "Spend" a resource during a search or preprocessing.
   */
  void spendResource(unsigned ammount);

  /**
   * Adds a theory. Only one theory per TheoryId can be present, so if
   * there is another theory it will be deleted.
   */
  template <class TheoryClass>
  inline void addTheory(theory::TheoryId theoryId) {
    Assert(d_theoryTable[theoryId] == NULL && d_theoryOut[theoryId] == NULL);
    d_theoryOut[theoryId] = new EngineOutputChannel(this, theoryId);
    d_theoryTable[theoryId] =
        new TheoryClass(d_context, d_userContext, *d_theoryOut[theoryId],
                        theory::Valuation(this), d_logicInfo);
  }

  inline void setPropEngine(prop::PropEngine* propEngine) {
    Assert(d_propEngine == NULL);
    d_propEngine = propEngine;
  }

  inline void setDecisionEngine(DecisionEngine* decisionEngine) {
    Assert(d_decisionEngine == NULL);
    d_decisionEngine = decisionEngine;
  }

  /** Called when all initialization of options/logic is done */
  void finishInit();

  /**
   * Get a pointer to the underlying propositional engine.
   */
  inline prop::PropEngine* getPropEngine() const {
    return d_propEngine;
  }

  /**
   * Get a pointer to the underlying sat context.
   */
  inline context::Context* getSatContext() const {
    return d_context;
  }

  /**
   * Get a pointer to the underlying user context.
   */
  inline context::Context* getUserContext() const {
    return d_userContext;
  }

  /**
   * Get a pointer to the underlying quantifiers engine.
   */
  theory::QuantifiersEngine* getQuantifiersEngine() const {
    return d_quantEngine;
  }

private:

  /**
   * Helper for preprocess
   */
  Node ppTheoryRewrite(TNode term);

  /**
   * Queue of nodes for pre-registration.
   */
  std::queue<TNode> d_preregisterQueue;

  /**
   * Boolean flag denoting we are in pre-registration.
   */
  bool d_inPreregister;

  /**
   * Did the theories get any new facts since the last time we called
   * check()
   */
  context::CDO<bool> d_factsAsserted;

  /**
   * Map from equality atoms to theories that would like to be notified about them.
   */


  /**
   * Assert the formula to the given theory.
   * @param assertion the assertion to send (not necesserily normalized)
   * @param original the assertion as it was sent in from the propagating theory
   * @param toTheoryId the theory to assert to
   * @param fromTheoryId the theory that sent it
   */
  void assertToTheory(TNode assertion, TNode originalAssertion, theory::TheoryId toTheoryId, theory::TheoryId fromTheoryId);

  /**
   * Marks a theory propagation from a theory to a theory where a
   * theory could be the THEORY_SAT_SOLVER for literals coming from
   * or being propagated to the SAT solver. If the receiving theory
   * already recieved the literal, the method returns false, otherwise
   * it returns true.
   *
   * @param assertion the normalized assertion being sent
   * @param originalAssertion the actual assertion that was sent
   * @param toTheoryId the theory that is on the receiving end
   * @param fromTheoryId the theory that sent the assertino
   * @return true if a new assertion, false if theory already got it
   */
  bool markPropagation(TNode assertion, TNode originalAssertions, theory::TheoryId toTheoryId, theory::TheoryId fromTheoryId);

  /**
   * Computes the explanation by travarsing the propagation graph and
   * asking relevant theories to explain the propagations. Initially
   * the explanation vector should contain only the element (node, theory)
   * where the node is the one to be explained, and the theory is the
   * theory that sent the literal.
   */
  void getExplanation(std::vector<NodeTheoryPair>& explanationVector);

public:

  /**
   * Signal the start of a new round of assertion preprocessing
   */
  void preprocessStart();

  /**
   * Runs theory specific preprocessing on the non-Boolean parts of
   * the formula.  This is only called on input assertions, after ITEs
   * have been removed.
   */
  Node preprocess(TNode node);

  /**
   * Return whether or not we are incomplete (in the current context).
   */
  inline bool isIncomplete() const {
    return d_incomplete;
  }

  /**
   * Returns true if we need another round of checking.  If this
   * returns true, check(FULL_EFFORT) _must_ be called by the
   * propositional layer before reporting SAT.
   *
   * This is especially necessary for incomplete theories that lazily
   * output some lemmas on FULL_EFFORT check (e.g. quantifier reasoning
   * outputing quantifier instantiations).  In such a case, a lemma can
   * be asserted that is simplified away (perhaps it's already true).
   * However, we must maintain the invariant that, if a theory uses the
   * OutputChannel, it implicitly requests that another check(FULL_EFFORT)
   * be performed before exit, even if no new facts are on its fact queue,
   * as it might decide to further instantiate some lemmas, precluding
   * a SAT response.
   */
  inline bool needCheck() const {
    return d_outputChannelUsed || d_lemmasAdded;
  }

  /**
   * This is called at shutdown time by the SmtEngine, just before
   * destruction.  It is important because there are destruction
   * ordering issues between PropEngine and Theory.
   */
  void shutdown();

  /**
   * Solve the given literal with a theory that owns it.
   */
  theory::Theory::PPAssertStatus solve(TNode literal,
                                    theory::SubstitutionMap& substitutionOut);

  /**
   * Preregister a Theory atom with the responsible theory (or
   * theories).
   */
  void preRegister(TNode preprocessed);

  /**
   * Assert the formula to the appropriate theory.
   * @param node the assertion
   */
  void assertFact(TNode node);

  /**
   * Check all (currently-active) theories for conflicts.
   * @param effort the effort level to use
   */
  void check(theory::Theory::Effort effort);

  /**
   * Run the combination framework.
   */
  void combineTheories();

  /**
   * Calls ppStaticLearn() on all theories, accumulating their
   * combined contributions in the "learned" builder.
   */
  void ppStaticLearn(TNode in, NodeBuilder<>& learned);

  /**
   * Calls presolve() on all theories and returns true
   * if one of the theories discovers a conflict.
   */
  bool presolve();

   /**
   * Calls postsolve() on all theories.
   */
  void postsolve();

  /**
   * Calls notifyRestart() on all active theories.
   */
  void notifyRestart();

  void getPropagatedLiterals(std::vector<TNode>& literals) {
    for (; d_propagatedLiteralsIndex < d_propagatedLiterals.size(); d_propagatedLiteralsIndex = d_propagatedLiteralsIndex + 1) {
      Debug("getPropagatedLiterals") << "TheoryEngine::getPropagatedLiterals: propagating: " << d_propagatedLiterals[d_propagatedLiteralsIndex] << std::endl;
      literals.push_back(d_propagatedLiterals[d_propagatedLiteralsIndex]);
    }
  }

  Node getNextDecisionRequest();

  bool properConflict(TNode conflict) const;
  bool properPropagation(TNode lit) const;
  bool properExplanation(TNode node, TNode expl) const;

  /**
   * Returns an explanation of the node propagated to the SAT solver.
   */
  Node getExplanation(TNode node);

  /**
   * collect model info
   */
  void collectModelInfo( theory::TheoryModel* m, bool fullModel );

  /**
   * Get the current model
   */
  theory::TheoryModel* getModel();

  /**
   * Get the model builder
   */
  theory::TheoryEngineModelBuilder* getModelBuilder() { return d_curr_model_builder; }

  /**
   * Get the theory associated to a given Node.
   *
   * @returns the theory, or NULL if the TNode is
   * of built-in type.
   */
  inline theory::Theory* theoryOf(TNode node) const {
    return d_theoryTable[theory::Theory::theoryOf(node)];
  }

  /**
   * Get the theory associated to a the given theory id.
   *
   * @returns the theory
   */
  inline theory::Theory* theoryOf(theory::TheoryId theoryId) const {
    return d_theoryTable[theoryId];
  }

  inline bool isTheoryEnabled(theory::TheoryId theoryId) const {
    return d_logicInfo.isTheoryEnabled(theoryId);
  }

  /**
   * Returns the equality status of the two terms, from the theory
   * that owns the domain type.  The types of a and b must be the same.
   */
  theory::EqualityStatus getEqualityStatus(TNode a, TNode b);

  /**
   * Returns the value that a theory that owns the type of var currently
   * has (or null if none);
   */
  Node getModelValue(TNode var);

  /**
   * Takes a literal and returns an equivalent literal that is guaranteed to be a SAT literal
   */
  Node ensureLiteral(TNode n);

  /**
   * Print all instantiations made by the quantifiers module.
   */
  void printInstantiations( std::ostream& out );

  /**
   * Print solution for synthesis conjectures found by ce_guided_instantiation module
   */
  void printSynthSolution( std::ostream& out );

  /**
   * Forwards an entailment check according to the given theoryOfMode.
   * See theory.h for documentation on entailmentCheck().
   */
  std::pair<bool, Node> entailmentCheck(theory::TheoryOfMode mode, TNode lit, const theory::EntailmentCheckParameters* params = NULL, theory::EntailmentCheckSideEffects* out = NULL);

private:

  /** Default visitor for pre-registration */
  PreRegisterVisitor d_preRegistrationVisitor;

  /** Visitor for collecting shared terms */
  SharedTermsVisitor d_sharedTermsVisitor;

  /** Dump the assertions to the dump */
  void dumpAssertions(const char* tag);

  /**
   * A collection of ite preprocessing passes.
   */
  theory::ITEUtilities* d_iteUtilities;


  /** For preprocessing pass simplifying unconstrained expressions */
  UnconstrainedSimplifier* d_unconstrainedSimp;

  /** For preprocessing pass lifting bit-vectors of size 1 to booleans */
  theory::bv::BvToBoolPreprocessor d_bvToBoolPreprocessor;
public:
  void staticInitializeBVOptions(const std::vector<Node>& assertions);
  void ppBvToBool(const std::vector<Node>& assertions, std::vector<Node>& new_assertions);
  bool ppBvAbstraction(const std::vector<Node>& assertions, std::vector<Node>& new_assertions);
  void mkAckermanizationAsssertions(std::vector<Node>& assertions);

  Node ppSimpITE(TNode assertion);
  /** Returns false if an assertion simplified to false. */
  bool donePPSimpITE(std::vector<Node>& assertions);

  void ppUnconstrainedSimp(std::vector<Node>& assertions);

  SharedTermsDatabase* getSharedTermsDatabase() { return &d_sharedTerms; }

  theory::eq::EqualityEngine* getMasterEqualityEngine() { return d_masterEqualityEngine; }

  RemoveITE* getIteRemover() { return &d_iteRemover; }

  SortInference* getSortInference() { return &d_sortInfer; }

  /** Prints the assertions to the debug stream */
  void printAssertions(const char* tag);

  /** Theory alternative is in use. */
  bool useTheoryAlternative(const std::string& name);

  /** Enables using a theory alternative by name. */
  void enableTheoryAlternative(const std::string& name);

private:
  std::set< std::string > d_theoryAlternatives;

  std::map< std::string, std::vector< theory::Theory* > > d_attr_handle;
public:

  /**
   * Set user attribute.
   * This function is called when an attribute is set by a user.  In SMT-LIBv2 this is done
   * via the syntax (! n :attr)
   */
  void setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value);

  /**
   * Handle user attribute.
   * Associates theory t with the attribute attr.  Theory t will be
   * notified whenever an attribute of name attr is set.
   */
  void handleUserAttribute(const char* attr, theory::Theory* t);

  /**
   * Check that the theory assertions are satisfied in the model.
   * This function is called from the smt engine's checkModel routine.
   */
  void checkTheoryAssertionsWithModel();

private:
  IntStat d_arithSubstitutionsAdded;

};/* class TheoryEngine */

}/* CVC4 namespace */

#endif /* __CVC4__THEORY_ENGINE_H */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback