Make collect model info return a Bool (#1421)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Fri, 8 Dec 2017 16:14:31 +0000 (10:14 -0600)
committerGitHub <noreply@github.com>
Fri, 8 Dec 2017 16:14:31 +0000 (10:14 -0600)
48 files changed:
src/theory/arith/theory_arith.cpp
src/theory/arith/theory_arith.h
src/theory/arith/theory_arith_private.cpp
src/theory/arith/theory_arith_private.h
src/theory/arrays/theory_arrays.cpp
src/theory/arrays/theory_arrays.h
src/theory/bv/bitblaster_template.h
src/theory/bv/bv_eager_solver.cpp
src/theory/bv/bv_eager_solver.h
src/theory/bv/bv_quick_check.cpp
src/theory/bv/bv_quick_check.h
src/theory/bv/bv_subtheory.h
src/theory/bv/bv_subtheory_algebraic.cpp
src/theory/bv/bv_subtheory_algebraic.h
src/theory/bv/bv_subtheory_bitblast.cpp
src/theory/bv/bv_subtheory_bitblast.h
src/theory/bv/bv_subtheory_core.cpp
src/theory/bv/bv_subtheory_core.h
src/theory/bv/bv_subtheory_inequality.cpp
src/theory/bv/bv_subtheory_inequality.h
src/theory/bv/eager_bitblaster.cpp
src/theory/bv/lazy_bitblaster.cpp
src/theory/bv/theory_bv.cpp
src/theory/bv/theory_bv.h
src/theory/datatypes/theory_datatypes.cpp
src/theory/datatypes/theory_datatypes.h
src/theory/fp/theory_fp.cpp
src/theory/fp/theory_fp.h
src/theory/quantifiers/theory_quantifiers.cpp
src/theory/quantifiers/theory_quantifiers.h
src/theory/quantifiers_engine.cpp
src/theory/sep/theory_sep.cpp
src/theory/sep/theory_sep.h
src/theory/sets/theory_sets.cpp
src/theory/sets/theory_sets.h
src/theory/sets/theory_sets_private.cpp
src/theory/sets/theory_sets_private.h
src/theory/strings/theory_strings.cpp
src/theory/strings/theory_strings.h
src/theory/theory.h
src/theory/theory_engine.cpp
src/theory/theory_engine.h
src/theory/theory_model.cpp
src/theory/theory_model.h
src/theory/theory_model_builder.cpp
src/theory/theory_model_builder.h
src/theory/uf/theory_uf.cpp
src/theory/uf/theory_uf.h

index 985799e88999690786dbaf980f49ca0fcc55c1a9..e354305d7244a7646406452ae44ba94bef9f8fe9 100644 (file)
@@ -106,9 +106,9 @@ bool TheoryArith::isExtfReduced( int effort, Node n, Node on, std::vector< Node
 void TheoryArith::propagate(Effort e) {
   d_internal->propagate(e);
 }
-
-void TheoryArith::collectModelInfo( TheoryModel* m ){
-  d_internal->collectModelInfo(m);
+bool TheoryArith::collectModelInfo(TheoryModel* m)
+{
+  return d_internal->collectModelInfo(m);
 }
 
 void TheoryArith::notifyRestart(){
index e1226279ab6d7532f41389da52e42df024b362e1..1c10bde0df2cd9b6ad6e28e2af994ff03f857f86 100644 (file)
@@ -61,7 +61,7 @@ public:
   bool getCurrentSubstitution( int effort, std::vector< Node >& vars, std::vector< Node >& subs, std::map< Node, std::vector< Node > >& exp );
   bool isExtfReduced( int effort, Node n, Node on, std::vector< Node >& exp );
 
-  void collectModelInfo( TheoryModel* m );
+  bool collectModelInfo(TheoryModel* m) override;
 
   void shutdown(){ }
 
index c9a2205664b8f16c45d5ea63b65a7983f89ff475..8313abd68eefd5ccb42617761f2b1a765b60d63a 100644 (file)
@@ -4252,7 +4252,8 @@ Rational TheoryArithPrivate::deltaValueForTotalOrder() const{
   return belowMin;
 }
 
-void TheoryArithPrivate::collectModelInfo( TheoryModel* m ){
+bool TheoryArithPrivate::collectModelInfo(TheoryModel* m)
+{
   AlwaysAssert(d_qflraStatus ==  Result::SAT);
   //AlwaysAssert(!d_nlIncomplete, "Arithmetic solver cannot currently produce models for input with nonlinear arithmetic constraints");
 
@@ -4288,7 +4289,10 @@ void TheoryArithPrivate::collectModelInfo( TheoryModel* m ){
         Node qNode = mkRationalNode(qmodel);
         Debug("arith::collectModelInfo") << "m->assertEquality(" << term << ", " << qmodel << ", true)" << endl;
 
-        m->assertEquality(term, qNode, true);
+        if (!m->assertEquality(term, qNode, true))
+        {
+          return false;
+        }
       }else{
         Debug("arith::collectModelInfo") << "Skipping m->assertEquality(" << term << ", true)" << endl;
 
@@ -4301,6 +4305,7 @@ void TheoryArithPrivate::collectModelInfo( TheoryModel* m ){
   // m->assertEqualityEngine(&ee);
 
   Debug("arith::collectModelInfo") << "collectModelInfo() end " << endl;
+  return true;
 }
 
 bool TheoryArithPrivate::safeToReset() const {
index b2471c5e81462f3a57800571a4e9ef7b1f9e7fd6..08b884a036699f8aed3aff425e85b1782556c960 100644 (file)
@@ -444,7 +444,7 @@ public:
 
   Rational deltaValueForTotalOrder() const;
 
-  void collectModelInfo( TheoryModel* m );
+  bool collectModelInfo(TheoryModel* m);
 
   void shutdown(){ }
 
index af417f7401725f9ba4973d873c209b65635de09f..508c9d8ff084fd895e49f97eb9ac050e2773898c 100644 (file)
@@ -1038,8 +1038,7 @@ void TheoryArrays::computeCareGraph()
 // MODEL GENERATION
 /////////////////////////////////////////////////////////////////////////////
 
-
-void TheoryArrays::collectModelInfo( TheoryModel* m )
+bool TheoryArrays::collectModelInfo(TheoryModel* m)
 {
   set<Node> termSet;
 
@@ -1140,7 +1139,10 @@ void TheoryArrays::collectModelInfo( TheoryModel* m )
   } while (changed);
 
   // Send the equality engine information to the model
-  m->assertEqualityEngine(&d_equalityEngine, &termSet);
+  if (!m->assertEqualityEngine(&d_equalityEngine, &termSet))
+  {
+    return false;
+  }
 
   // Build a list of all the relevant reads, indexed by the store representative
   std::map<Node, std::vector<Node> > selects;
@@ -1215,11 +1217,15 @@ void TheoryArrays::collectModelInfo( TheoryModel* m )
     for (unsigned j = 0; j < reads.size(); ++j) {
       rep = nm->mkNode(kind::STORE, rep, reads[j][1], reads[j]);
     }
-    m->assertEquality(n, rep, true);
+    if (!m->assertEquality(n, rep, true))
+    {
+      return false;
+    }
     if (!n.isConst()) {
-      m->assertRepresentative(rep);
+      m->assertSkeleton(rep);
     }
   }
+  return true;
 }
 
 /////////////////////////////////////////////////////////////////////////////
index 08d1618c2d1a69d178a68296421f86d2eb1a533c..24c286e9256417070a3129e88cdbc465d5d36703 100644 (file)
@@ -248,12 +248,11 @@ class TheoryArrays : public Theory {
   private:
 
   public:
+   bool collectModelInfo(TheoryModel* m) override;
 
-  void collectModelInfo(TheoryModel* m);
-
-  /////////////////////////////////////////////////////////////////////////////
-  // NOTIFICATIONS
-  /////////////////////////////////////////////////////////////////////////////
+   /////////////////////////////////////////////////////////////////////////////
+   // NOTIFICATIONS
+   /////////////////////////////////////////////////////////////////////////////
 
   private:
   public:
index 565c454e3f91d354b496460b0340bb21006991b1..0e761422173a2205e0eb1619680f4089a8185f3c 100644 (file)
@@ -207,7 +207,7 @@ public:
    * @param fullModel whether to create a "full model," i.e., add
    * constants to equivalence classes that don't already have them
    */
-  void collectModelInfo(TheoryModel* m, bool fullModel);
+  bool collectModelInfo(TheoryModel* m, bool fullModel);
   void setProofLog( BitVectorProof * bvp );
 
   typedef TNodeSet::const_iterator vars_iterator;
@@ -292,7 +292,7 @@ public:
 
   bool assertToSat(TNode node, bool propagate = true);
   bool solve();
-  void collectModelInfo(TheoryModel* m, bool fullModel);
+  bool collectModelInfo(TheoryModel* m, bool fullModel);
   void setProofLog( BitVectorProof * bvp );
 };
 
index 50070b29a8f8e3d36198df6f6034a0ad38efbc3a..01282880c7681972fd533a46fc9862873e170335 100644 (file)
@@ -123,9 +123,10 @@ bool EagerBitblastSolver::hasAssertions(const std::vector<TNode>& formulas) {
   return true;
 }
 
-void EagerBitblastSolver::collectModelInfo(TheoryModel* m, bool fullModel) {
+bool EagerBitblastSolver::collectModelInfo(TheoryModel* m, bool fullModel)
+{
   AlwaysAssert(!d_useAig && d_bitblaster);
-  d_bitblaster->collectModelInfo(m, fullModel);
+  return d_bitblaster->collectModelInfo(m, fullModel);
 }
 
 void EagerBitblastSolver::setProofLog(BitVectorProof* bvp) { d_bvp = bvp; }
index d259d49e6f675153c33df6a2eeb1b82f9cde80f3..856de530dc60989f18c9f24f55cb6a1efd45f077 100644 (file)
@@ -47,7 +47,7 @@ class EagerBitblastSolver {
   void turnOffAig();
   bool isInitialized();
   void initialize();
-  void collectModelInfo(theory::TheoryModel* m, bool fullModel);
+  bool collectModelInfo(theory::TheoryModel* m, bool fullModel);
   void setProofLog(BitVectorProof* bvp);
 
  private:
index b347ddccf6cc8d936cb8d8bbc22f8bffa12d4f0e..a3442e4c61329a2eb5fddecd6a6f42da638aec5a 100644 (file)
@@ -136,8 +136,9 @@ void BVQuickCheck::popToZero() {
   }
 }
 
-void BVQuickCheck::collectModelInfo(theory::TheoryModel* model, bool fullModel) {
-  d_bitblaster->collectModelInfo(model, fullModel);
+bool BVQuickCheck::collectModelInfo(theory::TheoryModel* model, bool fullModel)
+{
+  return d_bitblaster->collectModelInfo(model, fullModel);
 }
 
 BVQuickCheck::~BVQuickCheck() {
index c5fe63ad6110258c2006e7a601e53f39a1759e2e..d163bf7f96d2b4a3e2197b5d1ea464703255f23d 100644 (file)
@@ -97,7 +97,7 @@ public:
    * @return 
    */
   uint64_t computeAtomWeight(TNode atom, NodeSet& seen);
-  void collectModelInfo(theory::TheoryModel* model, bool fullModel); 
+  bool collectModelInfo(theory::TheoryModel* model, bool fullModel);
 
   typedef std::unordered_set<TNode, TNodeHashFunction>::const_iterator vars_iterator;
   vars_iterator beginVars(); 
index 454f89b6c59c36d95b32c4048d15e0fc0cf10315..63dd5340769de230f388e703f63336eeca3f0aa6 100644 (file)
@@ -75,7 +75,7 @@ class SubtheorySolver {
   virtual void explain(TNode literal, std::vector<TNode>& assumptions) = 0;
   virtual void preRegister(TNode node) {}
   virtual void propagate(Theory::Effort e) {}
-  virtual void collectModelInfo(TheoryModel* m, bool fullModel) = 0;
+  virtual bool collectModelInfo(TheoryModel* m, bool fullModel) = 0;
   virtual Node getModelValue(TNode var) = 0;
   virtual bool isComplete() = 0;
   virtual EqualityStatus getEqualityStatus(TNode a, TNode b) = 0;
index c5313b9e790dbadb6c753de34fae803708cc13ee..a6e3153cb7117bce65fbca69edc3bb9f3cbb449b 100644 (file)
@@ -676,7 +676,8 @@ void AlgebraicSolver::assertFact(TNode fact) {
 EqualityStatus AlgebraicSolver::getEqualityStatus(TNode a, TNode b) {
   return EQUALITY_UNKNOWN;
 }
-void AlgebraicSolver::collectModelInfo(TheoryModel* model, bool fullModel) {
+bool AlgebraicSolver::collectModelInfo(TheoryModel* model, bool fullModel)
+{
   Debug("bitvector-model") << "AlgebraicSolver::collectModelInfo\n";
   AlwaysAssert (!d_quickSolver->inConflict());
   set<Node> termSet;
@@ -729,9 +730,12 @@ void AlgebraicSolver::collectModelInfo(TheoryModel* model, bool fullModel) {
     Debug("bitvector-model") << "AlgebraicSolver:   " << variables[i] << " => " << subst << "\n";
     // Doesn't have to be constant as it may be irrelevant
     Assert (subst.getKind() == kind::CONST_BITVECTOR);
-    model->assertEquality(variables[i], subst, true);
+    if (!model->assertEquality(variables[i], subst, true))
+    {
+      return false;
+    }
   }
-
+  return true;
  }
 
 Node AlgebraicSolver::getModelValue(TNode node) {
index 4b4103e4430f6b7782f11a0a6baa5241d4c5d526..0534c0f17ba7ff62175bbdfdf81659a6d8e9e2f1 100644 (file)
@@ -227,8 +227,8 @@ public:
   void  preRegister(TNode node) {}
   bool  check(Theory::Effort e);
   void  explain(TNode literal, std::vector<TNode>& assumptions) {Unreachable("AlgebraicSolver does not propagate.\n");}
-  EqualityStatus getEqualityStatus(TNode a, TNode b); 
-  void collectModelInfo(TheoryModel* m, bool fullModel); 
+  EqualityStatus getEqualityStatus(TNode a, TNode b);
+  bool collectModelInfo(TheoryModel* m, bool fullModel);
   Node getModelValue(TNode node); 
   bool isComplete();
   virtual void assertFact(TNode fact);
index 77e596d1f1c84a76f824ebc82cc34eb6e87cd24c..b9467c1687ee43a8560af3215e0625a5bdecb536 100644 (file)
@@ -234,7 +234,8 @@ EqualityStatus BitblastSolver::getEqualityStatus(TNode a, TNode b) {
   return d_bitblaster->getEqualityStatus(a, b);
 }
 
-void BitblastSolver::collectModelInfo(TheoryModel* m, bool fullModel) {
+bool BitblastSolver::collectModelInfo(TheoryModel* m, bool fullModel)
+{
   return d_bitblaster->collectModelInfo(m, fullModel);
 }
 
index 4bbe4327ef0d4ca8deba4f5d3df2396cd96ea102..5927feddcf13481b98ae3728a7e9e021576d4489 100644 (file)
@@ -69,7 +69,7 @@ public:
   bool  check(Theory::Effort e);
   void  explain(TNode literal, std::vector<TNode>& assumptions);
   EqualityStatus getEqualityStatus(TNode a, TNode b);
-  void collectModelInfo(TheoryModel* m, bool fullModel);
+  bool collectModelInfo(TheoryModel* m, bool fullModel);
   Node getModelValue(TNode node);
   bool isComplete() { return true; }
   void bitblastQueue();
index 54f454dca6ee2836e92024f373787afef5e14804..8ef2b471f390f059fceb0a6ce4afb1f05c8d54db 100644 (file)
@@ -396,7 +396,8 @@ bool CoreSolver::isCompleteForTerm(TNode term, TNodeBoolMap& seen) {
   return utils::isEqualityTerm(term, seen); 
 }
 
-void CoreSolver::collectModelInfo(TheoryModel* m, bool fullModel) {
+bool CoreSolver::collectModelInfo(TheoryModel* m, bool fullModel)
+{
   if (d_useSlicer) {
     Unreachable(); 
   }
@@ -409,17 +410,24 @@ void CoreSolver::collectModelInfo(TheoryModel* m, bool fullModel) {
   }
   set<Node> termSet;
   d_bv->computeRelevantTerms(termSet);
-  m->assertEqualityEngine(&d_equalityEngine, &termSet);
+  if (!m->assertEqualityEngine(&d_equalityEngine, &termSet))
+  {
+    return false;
+  }
   if (isComplete()) {
     Debug("bitvector-model") << "CoreSolver::collectModelInfo complete.";
     for (ModelValue::const_iterator it = d_modelValues.begin(); it != d_modelValues.end(); ++it) {
       Node a = it->first;
       Node b = it->second;
       Debug("bitvector-model") << "CoreSolver::collectModelInfo modelValues "
-                               << a << " => " << b <<")\n"; 
-      m->assertEquality(a, b, true);
+                               << a << " => " << b <<")\n";
+      if (!m->assertEquality(a, b, true))
+      {
+        return false;
+      }
     }
   }
+  return true;
 }
 
 Node CoreSolver::getModelValue(TNode var) {
index b416e019dee9c6717a7c79172743f056377e37fa..6cc6253fffa499a31fecc59797f6b443087a8500 100644 (file)
@@ -105,7 +105,7 @@ public:
   void  preRegister(TNode node);
   bool  check(Theory::Effort e);
   void  explain(TNode literal, std::vector<TNode>& assumptions);
-  void  collectModelInfo(TheoryModel* m, bool fullModel);
+  bool collectModelInfo(TheoryModel* m, bool fullModel);
   Node  getModelValue(TNode var);
   void  addSharedTerm(TNode t) {
     d_equalityEngine.addTriggerTerm(t, THEORY_BV);
index d662f056b4ffb538ed7eb0fde53e5be6b2cf0477..d828cc892480c4ee79ad4fba1e3098c9503a9d40 100644 (file)
@@ -182,15 +182,19 @@ void InequalitySolver::explain(TNode literal, std::vector<TNode>& assumptions) {
 void InequalitySolver::propagate(Theory::Effort e) {
   Assert (false);
 }
-
-void InequalitySolver::collectModelInfo(TheoryModel* m, bool fullModel) {
+bool InequalitySolver::collectModelInfo(TheoryModel* m, bool fullModel)
+{
   Debug("bitvector-model") << "InequalitySolver::collectModelInfo \n";
   std::vector<Node> model;
   d_inequalityGraph.getAllValuesInModel(model);
   for (unsigned i = 0; i < model.size(); ++i) {
     Assert (model[i].getKind() == kind::EQUAL);
-    m->assertEquality(model[i][0], model[i][1], true);
+    if (!m->assertEquality(model[i][0], model[i][1], true))
+    {
+      return false;
+    }
   }
+  return true;
 }
 
 Node InequalitySolver::getModelValue(TNode var) {
index 1123d15ae19debc1047b1f566be51623dc6e8673..be04921259dba588896e01141161bfafd9f3c961 100644 (file)
@@ -69,7 +69,7 @@ public:
   void propagate(Theory::Effort e);
   void explain(TNode literal, std::vector<TNode>& assumptions);
   bool isComplete() { return d_isComplete; }
-  void collectModelInfo(TheoryModel* m, bool fullModel);
+  bool collectModelInfo(TheoryModel* m, bool fullModel);
   Node getModelValue(TNode var);
   EqualityStatus getEqualityStatus(TNode a, TNode b);
   void assertFact(TNode fact);
index 29f6e7800d2e71802599c17c5ccb4e4ec9e60526..e2bfec893c9b9b8660921983c84746d351aa998d 100644 (file)
@@ -219,7 +219,8 @@ Node EagerBitblaster::getModelFromSatSolver(TNode a, bool fullModel) {
   return utils::mkConst(BitVector(bits.size(), value));
 }
 
-void EagerBitblaster::collectModelInfo(TheoryModel* m, bool fullModel) {
+bool EagerBitblaster::collectModelInfo(TheoryModel* m, bool fullModel)
+{
   TNodeSet::iterator it = d_variables.begin();
   for (; it != d_variables.end(); ++it) {
     TNode var = *it;
@@ -234,10 +235,14 @@ void EagerBitblaster::collectModelInfo(TheoryModel* m, bool fullModel) {
         Debug("bitvector-model")
             << "EagerBitblaster::collectModelInfo (assert (= " << var << " "
             << const_value << "))\n";
-        m->assertEquality(var, const_value, true);
+        if (!m->assertEquality(var, const_value, true))
+        {
+          return false;
+        }
       }
     }
   }
+  return true;
 }
 
 void EagerBitblaster::setProofLog(BitVectorProof* bvp) {
index 32aff1fb04eff09e89b1664c153c16fd343b69ef..7976097e135a02c25ceab670ab974390f8872839 100644 (file)
@@ -484,7 +484,8 @@ Node TLazyBitblaster::getModelFromSatSolver(TNode a, bool fullModel) {
   return utils::mkConst(BitVector(bits.size(), value));
 }
 
-void TLazyBitblaster::collectModelInfo(TheoryModel* m, bool fullModel) {
+bool TLazyBitblaster::collectModelInfo(TheoryModel* m, bool fullModel)
+{
   std::set<Node> termSet;
   d_bv->computeRelevantTerms(termSet);
 
@@ -504,9 +505,13 @@ void TLazyBitblaster::collectModelInfo(TheoryModel* m, bool fullModel) {
       Debug("bitvector-model") << "TLazyBitblaster::collectModelInfo (assert (= "
                                << var << " "
                                << const_value << "))\n";
-        m->assertEquality(var, const_value, true);
+      if (!m->assertEquality(var, const_value, true))
+      {
+        return false;
+      }
     }
   }
+  return true;
 }
 
 void TLazyBitblaster::setProofLog( BitVectorProof * bvp ){
index e03cecdd929883e3889435444a494d886c0659f5..cb214217c953efdf168cfcda3d86d3318d8a0da0 100644 (file)
@@ -576,18 +576,21 @@ bool TheoryBV::doExtfReductions( std::vector< Node >& terms ) {
 bool TheoryBV::needsCheckLastEffort() {
   return d_needsLastCallCheck;
 }
-
-void TheoryBV::collectModelInfo( TheoryModel* m ){
+bool TheoryBV::collectModelInfo(TheoryModel* m)
+{
   Assert(!inConflict());
   if (options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER) {
-    d_eagerSolver->collectModelInfo(m, true);
+    if (!d_eagerSolver->collectModelInfo(m, true))
+    {
+      return false;
+    }
   }
   for (unsigned i = 0; i < d_subtheories.size(); ++i) {
     if (d_subtheories[i]->isComplete()) {
-      d_subtheories[i]->collectModelInfo(m, true);
-      return;
+      return d_subtheories[i]->collectModelInfo(m, true);
     }
   }
+  return true;
 }
 
 Node TheoryBV::getModelValue(TNode var) {
index c21938aa78c457928aaccf654906e20a140063a9..a425cbdc887fc37bc0890a0a6680610d85d75e44 100644 (file)
@@ -80,7 +80,7 @@ public:
 
   Node explain(TNode n);
 
-  void collectModelInfo( TheoryModel* m );
+  bool collectModelInfo(TheoryModel* m) override;
 
   std::string identify() const { return std::string("TheoryBV"); }
 
index 674e0d6b37804cc4d125456496153276707dbf73..c17c022a1342ea15efbb912c8f87679f3795bbf4 100644 (file)
@@ -1490,7 +1490,8 @@ void TheoryDatatypes::computeCareGraph(){
   Trace("dt-cg-summary") << "...done, # pairs = " << n_pairs << std::endl;
 }
 
-void TheoryDatatypes::collectModelInfo( TheoryModel* m ){
+bool TheoryDatatypes::collectModelInfo(TheoryModel* m)
+{
   Trace("dt-cmi") << "Datatypes : Collect model info " << d_equalityEngine.consistent() << std::endl;
   Trace("dt-model") << std::endl;
   printModelDebug( "dt-model" );
@@ -1502,7 +1503,10 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m ){
   getRelevantTerms(termSet);
 
   //combine the equality engine
-  m->assertEqualityEngine( &d_equalityEngine, &termSet );
+  if (!m->assertEqualityEngine(&d_equalityEngine, &termSet))
+  {
+    return false;
+  }
 
   //get all constructors
   eq::EqClassesIterator eqccs_i = eq::EqClassesIterator( &d_equalityEngine );
@@ -1579,7 +1583,10 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m ){
     }
     if( !neqc.isNull() ){
       Trace("dt-cmi") << "Assign : " << neqc << std::endl;
-      m->assertEquality( eqc, neqc, true );
+      if (!m->assertEquality(eqc, neqc, true))
+      {
+        return false;
+      }
       eqc_cons[ eqc ] = neqc;
     }
     if( addCons ){
@@ -1598,14 +1605,18 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m ){
         std::map< Node, int > vmap;
         Node v = getCodatatypesValue( it->first, eqc_cons, vmap, 0 );
         Trace("dt-cmi") << "  EQC(" << it->first << "), constructor is " << it->second << ", value is " << v << ", const = " << v.isConst() << std::endl;
-        m->assertEquality( eqc, v, true );
-        m->assertRepresentative( v );
+        if (!m->assertEquality(eqc, v, true))
+        {
+          return false;
+        }
+        m->assertSkeleton(v);
       }
     }else{
       Trace("dt-cmi") << "Datatypes : assert representative " << it->second << " for " << it->first << std::endl;
-      m->assertRepresentative( it->second );
+      m->assertSkeleton(it->second);
     }
   }
+  return true;
 }
 
 
index 3c0a7c7cfbb85ae2fad3d1399990174fcaebf635..b3d88bb1c444f59847082d33287b71065f7cab0f 100644 (file)
@@ -264,7 +264,7 @@ public:
   void presolve();
   void addSharedTerm(TNode t);
   EqualityStatus getEqualityStatus(TNode a, TNode b);
-  void collectModelInfo( TheoryModel* m );
+  bool collectModelInfo(TheoryModel* m) override;
   void shutdown() { }
   std::string identify() const { return std::string("TheoryDatatypes"); }
   /** equality engine */
index 276edfc0af29c8a47ad588bd43a74a20cb95e338..5be4a46010355bed6cb7eb521fd99093acbdf976 100644 (file)
@@ -578,7 +578,8 @@ Node TheoryFp::getModelValue(TNode var) {
   return d_conv.getValue(d_valuation, var);
 }
 
-void TheoryFp::collectModelInfo(TheoryModel *m) {
+bool TheoryFp::collectModelInfo(TheoryModel *m)
+{
   std::set<Node> relevantTerms;
 
   Trace("fp-collectModelInfo")
@@ -632,10 +633,13 @@ void TheoryFp::collectModelInfo(TheoryModel *m) {
         << "TheoryFp::collectModelInfo(): relevantVariable " << node
         << std::endl;
 
-    m->assertEquality(node, d_conv.getValue(d_valuation, node), true);
+    if (!m->assertEquality(node, d_conv.getValue(d_valuation, node), true))
+    {
+      return false;
+    }
   }
 
-  return;
+  return true;
 }
 
 bool TheoryFp::NotifyClass::eqNotifyTriggerEquality(TNode equality,
index 5205f5e2353cbcd107ea7a44cd25bcb123de09a1..614cbff46678d07294a85dec224d4c2f70a51313 100644 (file)
@@ -46,7 +46,7 @@ class TheoryFp : public Theory {
   void check(Effort);
 
   Node getModelValue(TNode var);
-  void collectModelInfo(TheoryModel* m);
+  bool collectModelInfo(TheoryModel* m) override;
 
   std::string identify() const { return "THEORY_FP"; }
 
index 66e05b1cde61972eaa0eaa79ee93970176005a91..a278274c378fb6c6d5447da6ac1de65da529e513 100644 (file)
@@ -120,16 +120,24 @@ void TheoryQuantifiers::computeCareGraph() {
   //do nothing
 }
 
-void TheoryQuantifiers::collectModelInfo(TheoryModel* m) {
+bool TheoryQuantifiers::collectModelInfo(TheoryModel* m)
+{
   for(assertions_iterator i = facts_begin(); i != facts_end(); ++i) {
     if((*i).assertion.getKind() == kind::NOT) {
       Debug("quantifiers::collectModelInfo") << "got quant FALSE: " << (*i).assertion[0] << endl;
-      m->assertPredicate((*i).assertion[0], false);
+      if (!m->assertPredicate((*i).assertion[0], false))
+      {
+        return false;
+      }
     } else {
       Debug("quantifiers::collectModelInfo") << "got quant TRUE : " << *i << endl;
-      m->assertPredicate(*i, true);
+      if (!m->assertPredicate(*i, true))
+      {
+        return false;
+      }
     }
   }
+  return true;
 }
 
 void TheoryQuantifiers::check(Effort e) {
index 9c621dbd6838b4faf28103063a75ed5b2e77c179..295a3946470931203c33e0724938f52dd03d443f 100644 (file)
@@ -56,7 +56,7 @@ public:
   void check(Effort e);
   Node getNextDecisionRequest( unsigned& priority );
   Node getValue(TNode n);
-  void collectModelInfo( TheoryModel* m );
+  bool collectModelInfo(TheoryModel* m) override;
   void shutdown() { }
   std::string identify() const { return std::string("TheoryQuantifiers"); }
   void setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value);
index 59a85de1f7e9c3b4a636f3ab6e1405a505d19cd4..34dde7fc8dc09e41cae2abcfcd0cec918e6bc16a 100644 (file)
@@ -562,14 +562,22 @@ void QuantifiersEngine::check( Theory::Effort e ){
           static_cast<QuantifiersModule::QEffort>(qef);
       d_curr_effort_level = quant_e;
       //build the model if any module requested it
-      if( needsModelE==quant_e && !d_model->isBuilt() ){
-        // theory engine's model builder is quantifier engine's builder if it has one
-        Assert( !d_builder || d_builder==d_te->getModelBuilder() );
-        Trace("quant-engine-debug") << "Build model..." << std::endl;
-        if( !d_te->getModelBuilder()->buildModel( d_model ) ){
-          //we are done if model building was unsuccessful
-          Trace("quant-engine-debug") << "...added lemmas." << std::endl;
-          flushLemmas();
+      if (needsModelE == quant_e)
+      {
+        if (!d_model->isBuilt())
+        {
+          // theory engine's model builder is quantifier engine's builder if it
+          // has one
+          Assert(!d_builder || d_builder == d_te->getModelBuilder());
+          Trace("quant-engine-debug") << "Build model..." << std::endl;
+          if (!d_te->getModelBuilder()->buildModel(d_model))
+          {
+            flushLemmas();
+          }
+        }
+        if (!d_model->isBuiltSuccess())
+        {
+          break;
         }
       }
       if( !d_hasAddedLemma ){
@@ -690,16 +698,6 @@ void QuantifiersEngine::check( Theory::Effort e ){
 
   //SAT case
   if( e==Theory::EFFORT_LAST_CALL && !d_hasAddedLemma ){
-    if( options::produceModels() ){
-      if( d_model->isBuilt() ){
-        Trace("quant-engine-debug") << "Already built model using model builder, finish..." << std::endl;
-      }else{
-        //use default model builder when no module built the model
-        Trace("quant-engine-debug") << "Build the default model..." << std::endl;
-        d_te->getModelBuilder()->buildModel( d_model );
-        Trace("quant-engine-debug") << "Done building the model." << std::endl;
-      }
-    }
     if( setIncomplete ){
       Trace("quant-engine") << "Set incomplete flag." << std::endl;
       getOutputChannel().setIncomplete();
index 71cde2841a0a0aa63e313c59ad05fe392966e48f..0107b80c8c3680920c6c03c3486a2035dd10142d 100644 (file)
@@ -200,15 +200,15 @@ void TheorySep::computeCareGraph() {
 // MODEL GENERATION
 /////////////////////////////////////////////////////////////////////////////
 
-
-void TheorySep::collectModelInfo( TheoryModel* m ){
+bool TheorySep::collectModelInfo(TheoryModel* m)
+{
   set<Node> termSet;
 
   // Compute terms appearing in assertions and shared terms
   computeRelevantTerms(termSet);
 
   // Send the equality engine information to the model
-  m->assertEqualityEngine( &d_equalityEngine, &termSet );
+  return m->assertEqualityEngine(&d_equalityEngine, &termSet);
 }
 
 void TheorySep::postProcessModel( TheoryModel* m ){
index 591a495d08068f0a8486091dae3db22e7e7d822d..65f0766318d8f5f0f100d24384d02d210dfb2046 100644 (file)
@@ -109,13 +109,12 @@ class TheorySep : public Theory {
   /////////////////////////////////////////////////////////////////////////////
 
   public:
+   bool collectModelInfo(TheoryModel* m) override;
+   void postProcessModel(TheoryModel* m);
 
-  void collectModelInfo(TheoryModel* m);
-  void postProcessModel(TheoryModel* m);
-
-  /////////////////////////////////////////////////////////////////////////////
-  // NOTIFICATIONS
-  /////////////////////////////////////////////////////////////////////////////
+   /////////////////////////////////////////////////////////////////////////////
+   // NOTIFICATIONS
+   /////////////////////////////////////////////////////////////////////////////
 
   private:
   public:
index 263d619342f41e1aaa2a5886290c9d5c7ae28556..9fcf3c089f71da721fef37ca330628e5d61f6c1a 100644 (file)
@@ -50,8 +50,9 @@ bool TheorySets::needsCheckLastEffort() {
   return d_internal->needsCheckLastEffort();
 }
 
-void TheorySets::collectModelInfo(TheoryModel* m) {
-  d_internal->collectModelInfo(m);
+bool TheorySets::collectModelInfo(TheoryModel* m)
+{
+  return d_internal->collectModelInfo(m);
 }
 
 void TheorySets::computeCareGraph() {
index 3ecd404bbb0062dcec32bc668afc99476453407b..1f0fbdd1fff00ff0784622e04d6750c58ea717ca 100644 (file)
@@ -52,7 +52,7 @@ public:
   
   bool needsCheckLastEffort();
 
-  void collectModelInfo(TheoryModel* m);
+  bool collectModelInfo(TheoryModel* m) override;
 
   void computeCareGraph();
 
index 3013711eba68522998760db4290baf4e2eb50b74..6bafbb0de0cee0dabf391ea01b2c63d2e65dc67b 100644 (file)
@@ -1911,16 +1911,19 @@ EqualityStatus TheorySetsPrivate::getEqualityStatus(TNode a, TNode b) {
 /******************** Model generation ********************/
 /******************** Model generation ********************/
 
-
-void TheorySetsPrivate::collectModelInfo(TheoryModel* m) {
+bool TheorySetsPrivate::collectModelInfo(TheoryModel* m)
+{
   Trace("sets-model") << "Set collect model info" << std::endl;
   set<Node> termSet;
   // Compute terms appearing in assertions and shared terms
   d_external.computeRelevantTerms(termSet);
   
   // Assert equalities and disequalities to the model
-  m->assertEqualityEngine(&d_equalityEngine,&termSet);
-  
+  if (!m->assertEqualityEngine(&d_equalityEngine, &termSet))
+  {
+    return false;
+  }
+
   std::map< Node, Node > mvals;
   for( int i=(int)(d_set_eqc.size()-1); i>=0; i-- ){
     Node eqc = d_set_eqc[i];
@@ -1970,10 +1973,14 @@ void TheorySetsPrivate::collectModelInfo(TheoryModel* m) {
       rep = Rewriter::rewrite( rep );
       Trace("sets-model") << "* Assign representative of " << eqc << " to " << rep << std::endl;
       mvals[eqc] = rep;
-      m->assertEquality( eqc, rep, true );
-      m->assertRepresentative( rep );
+      if (!m->assertEquality(eqc, rep, true))
+      {
+        return false;
+      }
+      m->assertSkeleton(rep);
     }
   }
+  return true;
 }
 
 /********************** Helper functions ***************************/
index 175e82bb8a8a9792a81d660cab9273b104c7af8f..bd63ff43d258c0ca4b435c98f64493277510cabe 100644 (file)
@@ -178,7 +178,7 @@ public:
   
   bool needsCheckLastEffort();
 
-  void collectModelInfo(TheoryModel* m);
+  bool collectModelInfo(TheoryModel* m);
 
   void computeCareGraph();
 
index 9b259bf971289155748abff0bd7c862a3e1bb9b9..e6b8807e9955f2350f6a64ae7ca793616cc32a66 100644 (file)
@@ -447,8 +447,8 @@ void TheoryStrings::presolve() {
 // MODEL GENERATION
 /////////////////////////////////////////////////////////////////////////////
 
-
-void TheoryStrings::collectModelInfo( TheoryModel* m ) {
+bool TheoryStrings::collectModelInfo(TheoryModel* m)
+{
   Trace("strings-model") << "TheoryStrings : Collect model info" << std::endl;
   Trace("strings-model") << "TheoryStrings : assertEqualityEngine." << std::endl;
   
@@ -458,9 +458,12 @@ void TheoryStrings::collectModelInfo( TheoryModel* m ) {
   // Compute terms appearing in assertions and shared terms
   //computeRelevantTerms(termSet);
   //m->assertEqualityEngine( &d_equalityEngine, &termSet );
-  
-  m->assertEqualityEngine( &d_equalityEngine );
-  
+
+  if (!m->assertEqualityEngine(&d_equalityEngine))
+  {
+    return false;
+  }
+
   // Generate model
   std::vector< Node > nodes;
   getEquivalenceClasses( nodes );
@@ -554,7 +557,10 @@ void TheoryStrings::collectModelInfo( TheoryModel* m ) {
         ++sel;
         Trace("strings-model") << "*** Assigned constant " << c << " for " << pure_eq[j] << std::endl;
         processed[pure_eq[j]] = c;
-        m->assertEquality( pure_eq[j], c, true );
+        if (!m->assertEquality(pure_eq[j], c, true))
+        {
+          return false;
+        }
       }
     }
   }
@@ -583,11 +589,15 @@ void TheoryStrings::collectModelInfo( TheoryModel* m ) {
       Assert( cc.getKind()==kind::CONST_STRING );
       Trace("strings-model") << "*** Determined constant " << cc << " for " << nodes[i] << std::endl;
       processed[nodes[i]] = cc;
-      m->assertEquality( nodes[i], cc, true );
+      if (!m->assertEquality(nodes[i], cc, true))
+      {
+        return false;
+      }
     }
   }
   //Trace("strings-model") << "String Model : Assigned." << std::endl;
   Trace("strings-model") << "String Model : Finished." << std::endl;
+  return true;
 }
 
 /////////////////////////////////////////////////////////////////////////////
index 39ab70e2fd38f2d1dd5abfebdcc0c4d5ad37477a..70706bbd441ec31c50c578bae70cd5e1964d8957 100644 (file)
@@ -214,11 +214,11 @@ private:
   // MODEL GENERATION
   /////////////////////////////////////////////////////////////////////////////
 public:
 void collectModelInfo(TheoryModel* m);
bool collectModelInfo(TheoryModel* m) override;
 
 /////////////////////////////////////////////////////////////////////////////
 // NOTIFICATIONS
 /////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////
+ // NOTIFICATIONS
+ /////////////////////////////////////////////////////////////////////////////
 public:
   void presolve();
   void shutdown() { }
index 0f820ac8e81696dbcf802921371fbcb5befde394..204c514a977bca55ba49b87ec952e1c20a3b57ff 100644 (file)
@@ -512,9 +512,11 @@ public:
    * Get all relevant information in this theory regarding the current
    * model.  This should be called after a call to check( FULL_EFFORT )
    * for all theories with no conflicts and no lemmas added.
+   *
+   * This method returns true if and only if the equality engine of m is
+   * consistent as a result of this call.
    */
-  virtual void collectModelInfo( TheoryModel* m ){ }
-
+  virtual bool collectModelInfo(TheoryModel* m) { return true; }
   /** if theories want to do something with model after building, do it here */
   virtual void postProcessModel( TheoryModel* m ){ }
   /**
index 944185b31f1bba5fab11d0d9c579b5eb10b2d238..4e2062c439991fba03b5049722933fca7e3a1d33 100644 (file)
@@ -605,8 +605,6 @@ void TheoryEngine::check(Theory::Effort effort) {
             if( theory->needsCheckLastEffort() ){
               if( !d_curr_model->isBuilt() ){
                 if( !d_curr_model_builder->buildModel(d_curr_model) ){
-                  //model building should fail only if the model builder adds lemmas
-                  Assert( needCheck() );
                   break;
                 }
               }
@@ -617,10 +615,14 @@ void TheoryEngine::check(Theory::Effort effort) {
       }
       if( ! d_inConflict && ! needCheck() ){
         if(d_logicInfo.isQuantified()) {
-          // quantifiers engine must pass effort last call check
+          // quantifiers engine must check at last call effort
           d_quantEngine->check(Theory::EFFORT_LAST_CALL);
-          // if returning incomplete or SAT, we have ensured that d_curr_model has been built
-        } else if(options::produceModels() && !d_curr_model->isBuilt()) {
+        }
+      }
+      if (!d_inConflict && !needCheck())
+      {
+        if (options::produceModels() && !d_curr_model->isBuilt())
+        {
           // must build model at this point
           d_curr_model_builder->buildModel(d_curr_model);
         }
@@ -631,14 +633,21 @@ void TheoryEngine::check(Theory::Effort effort) {
     Debug("theory") << ", need check = " << (needCheck() ? "YES" : "NO") << endl;
 
     if( Theory::fullEffort(effort) && !d_inConflict && !needCheck()) {
-      //we will answer SAT
+      // case where we are about to answer SAT
       if( d_masterEqualityEngine != NULL ){
         AlwaysAssert(d_masterEqualityEngine->consistent());
       }
-      if( options::produceModels() ){
-        d_curr_model_builder->debugCheckModel(d_curr_model);  
-        // Do post-processing of model from the theories (used for THEORY_SEP to construct heap model)
-        postProcessModel(d_curr_model);
+      if (d_curr_model->isBuilt())
+      {
+        // model construction should always succeed unless lemmas were added
+        AlwaysAssert(d_curr_model->isBuiltSuccess());
+        if (options::produceModels())
+        {
+          d_curr_model_builder->debugCheckModel(d_curr_model);
+          // Do post-processing of model from the theories (used for THEORY_SEP
+          // to construct heap model)
+          postProcessModel(d_curr_model);
+        }
       }
     }
   } catch(const theory::Interrupted&) {
@@ -846,7 +855,8 @@ bool TheoryEngine::properExplanation(TNode node, TNode expl) const {
   return true;
 }
 
-void TheoryEngine::collectModelInfo( theory::TheoryModel* m ){
+bool TheoryEngine::collectModelInfo(theory::TheoryModel* m)
+{
   //have shared term engine collectModelInfo
   //  d_sharedTerms.collectModelInfo( m );
   // Consult each active theory to get all relevant information
@@ -854,7 +864,10 @@ void TheoryEngine::collectModelInfo( theory::TheoryModel* m ){
   for(TheoryId theoryId = theory::THEORY_FIRST; theoryId < theory::THEORY_LAST; ++theoryId) {
     if(d_logicInfo.isTheoryEnabled(theoryId)) {
       Trace("model-builder") << "  CollectModelInfo on theory: " << theoryId << endl;
-      d_theoryTable[theoryId]->collectModelInfo( m );
+      if (!d_theoryTable[theoryId]->collectModelInfo(m))
+      {
+        return false;
+      }
     }
   }
   // Get the Boolean variables
@@ -870,8 +883,12 @@ void TheoryEngine::collectModelInfo( theory::TheoryModel* m ){
       value = false;
     }
     Trace("model-builder-assertions") << "(assert" << (value ? " " : " (not ") << var << (value ? ");" : "));") << endl;
-    m->assertPredicate(var, value);
+    if (!m->assertPredicate(var, value))
+    {
+      return false;
+    }
   }
+  return true;
 }
 
 void TheoryEngine::postProcessModel( theory::TheoryModel* m ){
index 179530240d0f13f7975566cbdd6bbc33bac7247b..f380e86aab29bb579526cd353d7987ebfc91332e 100644 (file)
@@ -707,7 +707,7 @@ public:
   /**
    * collect model info
    */
-  void collectModelInfo( theory::TheoryModel* m );
+  bool collectModelInfo(theory::TheoryModel* m);
   /** post process model */
   void postProcessModel( theory::TheoryModel* m );
 
index 02dd92ad7273919b78d0be8697cf5b8be39542a2..5555e29e255095dda84ffb9acc4ff6dd6b1de88b 100644 (file)
@@ -25,8 +25,13 @@ using namespace CVC4::context;
 namespace CVC4 {
 namespace theory {
 
-TheoryModel::TheoryModel(context::Context* c, std::string name, bool enableFuncModels) :
-  d_substitutions(c, false), d_modelBuilt(false), d_enableFuncModels(enableFuncModels)
+TheoryModel::TheoryModel(context::Context* c,
+                         std::string name,
+                         bool enableFuncModels)
+    : d_substitutions(c, false),
+      d_modelBuilt(false),
+      d_modelBuiltSuccess(false),
+      d_enableFuncModels(enableFuncModels)
 {
   d_true = NodeManager::currentNM()->mkConst( true );
   d_false = NodeManager::currentNM()->mkConst( false );
@@ -53,6 +58,7 @@ TheoryModel::~TheoryModel() throw() {
 
 void TheoryModel::reset(){
   d_modelBuilt = false;
+  d_modelBuiltSuccess = false;
   d_modelCache.clear();
   d_comment_str.clear();
   d_sep_heap = Node::null();
@@ -333,20 +339,24 @@ void TheoryModel::addTermInternal(TNode n)
 }
 
 /** assert equality */
-void TheoryModel::assertEquality(TNode a, TNode b, bool polarity ){
+bool TheoryModel::assertEquality(TNode a, TNode b, bool polarity)
+{
+  Assert(d_equalityEngine->consistent());
   if (a == b && polarity) {
-    return;
+    return true;
   }
   Trace("model-builder-assertions") << "(assert " << (polarity ? "(= " : "(not (= ") << a << " " << b << (polarity ? "));" : ")));") << endl;
   d_equalityEngine->assertEquality( a.eqNode(b), polarity, Node::null() );
-  Assert(d_equalityEngine->consistent());
+  return d_equalityEngine->consistent();
 }
 
 /** assert predicate */
-void TheoryModel::assertPredicate(TNode a, bool polarity ){
+bool TheoryModel::assertPredicate(TNode a, bool polarity)
+{
+  Assert(d_equalityEngine->consistent());
   if ((a == d_true && polarity) ||
       (a == d_false && (!polarity))) {
-    return;
+    return true;
   }
   if (a.getKind() == EQUAL) {
     Trace("model-builder-assertions") << "(assert " << (polarity ? " " : "(not ") << a << (polarity ? ");" : "));") << endl;
@@ -354,13 +364,15 @@ void TheoryModel::assertPredicate(TNode a, bool polarity ){
   } else {
     Trace("model-builder-assertions") << "(assert " << (polarity ? "" : "(not ") << a << (polarity ? ");" : "));") << endl;
     d_equalityEngine->assertPredicate( a, polarity, Node::null() );
-    Assert(d_equalityEngine->consistent());
   }
+  return d_equalityEngine->consistent();
 }
 
 /** assert equality engine */
-void TheoryModel::assertEqualityEngine(const eq::EqualityEngine* ee, set<Node>* termSet)
+bool TheoryModel::assertEqualityEngine(const eq::EqualityEngine* ee,
+                                       set<Node>* termSet)
 {
+  Assert(d_equalityEngine->consistent());
   eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );
   for (; !eqcs_i.isFinished(); ++eqcs_i) {
     Node eqc = (*eqcs_i);
@@ -384,11 +396,12 @@ void TheoryModel::assertEqualityEngine(const eq::EqualityEngine* ee, set<Node>*
         continue;
       }
       if (predicate) {
-        if (predTrue) {
-          assertPredicate(*eqc_i, true);
-        }
-        else if (predFalse) {
-          assertPredicate(*eqc_i, false);
+        if (predTrue || predFalse)
+        {
+          if (!assertPredicate(*eqc_i, predTrue))
+          {
+            return false;
+          }
         }
         else {
           if (first) {
@@ -398,7 +411,10 @@ void TheoryModel::assertEqualityEngine(const eq::EqualityEngine* ee, set<Node>*
           else {
             Trace("model-builder-assertions") << "(assert (= " << *eqc_i << " " << rep << "));" << endl;
             d_equalityEngine->mergePredicates(*eqc_i, rep, Node::null());
-            Assert(d_equalityEngine->consistent());
+            if (!d_equalityEngine->consistent())
+            {
+              return false;
+            }
           }
         }
       } else {
@@ -413,17 +429,22 @@ void TheoryModel::assertEqualityEngine(const eq::EqualityEngine* ee, set<Node>*
           first = false;
         }
         else {
-          assertEquality(*eqc_i, rep, true);
+          if (!assertEquality(*eqc_i, rep, true))
+          {
+            return false;
+          }
         }
       }
     }
   }
+  return true;
 }
 
-void TheoryModel::assertRepresentative(TNode n )
+void TheoryModel::assertSkeleton(TNode n)
 {
-  Trace("model-builder-reps") << "Assert rep : " << n << std::endl;
-  Trace("model-builder-reps") << "Rep eqc is : " << getRepresentative( n ) << std::endl;
+  Trace("model-builder-reps") << "Assert skeleton : " << n << std::endl;
+  Trace("model-builder-reps") << "...rep eqc is : " << getRepresentative(n)
+                              << std::endl;
   d_reps[ n ] = n;
 }
 
index 600f511c8c3d2c22e79ac579fd3c829e6c1ad26e..ab844c6ec2a8e809b8f1614e84272a6d6b8e1d04 100644 (file)
@@ -55,19 +55,25 @@ namespace theory {
  *
  * These calls may modify the model object using the interface
  * functions below, including:
- * - assertEquality, assertPredicate, assertRepresentative,
+ * - assertEquality, assertPredicate, assertSkeleton,
  *   assertEqualityEngine.
  * - assignFunctionDefinition
  *
- * During and after this building process, these calls may use
- * interface functions below to guide the model construction:
+ * This class provides several interface functions:
  * - hasTerm, getRepresentative, areEqual, areDisequal
  * - getEqualityEngine
  * - getRepSet
  * - hasAssignedFunctionDefinition, getFunctionsToAssign
+ * - getValue
  *
- * After this building process, the function getValue can be
- * used to query the value of nodes.
+ * The above functions can be used for a model m after it has been
+ * successfully built, i.e. when m->isBuiltSuccess() returns true.
+ *
+ * Additionally, all of the above functions, with the exception of getValue,
+ * can be used during step (5) of TheoryEngineModelBuilder::buildModel, as
+ * documented in theory_model_builder.h. In particular, we make calls to the
+ * above functions such as getRepresentative() when assigning total
+ * interpretations for uninterpreted functions.
  */
 class TheoryModel : public Model
 {
@@ -80,7 +86,7 @@ public:
   virtual void reset();
   /** is built
    *
-   * Have we (attempted to) build this model since the last
+   * Have we attempted to build this model since the last
    * call to reset? Notice for model building techniques
    * that are not guaranteed to succeed (such as
    * when quantified formulas are enabled), a true return
@@ -88,22 +94,51 @@ public:
    * current assertions.
    */
   bool isBuilt() { return d_modelBuilt; }
+  /** is built success
+   *
+   * Was this model successfully built since the last call to reset?
+   */
+  bool isBuiltSuccess() { return d_modelBuiltSuccess; }
   //---------------------------- for building the model
   /** Adds a substitution from x to t. */
   void addSubstitution(TNode x, TNode t, bool invalidateCache = true);
-  /** assert equality holds in the model */
-  void assertEquality(TNode a, TNode b, bool polarity);
-  /** assert predicate holds in the model */
-  void assertPredicate(TNode a, bool polarity);
-  /** assert all equalities/predicates in equality engine hold in the model */
-  void assertEqualityEngine(const eq::EqualityEngine* ee, std::set<Node>* termSet = NULL);
-  /** assert representative
-    *  This function tells the model that n should be the representative of its equivalence class.
-    *  It should be called during model generation, before final representatives are chosen.  In the
-    *  case of TheoryEngineModelBuilder, it should be called during Theory's collectModelInfo( ... )
-    *  functions.
-    */
-  void assertRepresentative(TNode n);
+  /** assert equality holds in the model
+   *
+   * This method returns true if and only if the equality engine of this model
+   * is consistent after asserting the equality to this model.
+   */
+  bool assertEquality(TNode a, TNode b, bool polarity);
+  /** assert predicate holds in the model
+   *
+   * This method returns true if and only if the equality engine of this model
+   * is consistent after asserting the predicate to this model.
+   */
+  bool assertPredicate(TNode a, bool polarity);
+  /** assert all equalities/predicates in equality engine hold in the model
+   *
+   * This method returns true if and only if the equality engine of this model
+   * is consistent after asserting the equality engine to this model.
+   */
+  bool assertEqualityEngine(const eq::EqualityEngine* ee,
+                            std::set<Node>* termSet = NULL);
+  /** assert skeleton
+   *
+   * This method gives a "skeleton" for the model value of the equivalence
+   * class containing n. This should be an application of interpreted function
+   * (e.g. datatype constructor, array store, set union chain). The subterms of
+   * this term that are variables or terms that belong to other theories will
+   * be filled in with model values.
+   *
+   * For example, if we call assertSkeleton on (C x y) where C is a datatype
+   * constructor and x and y are variables, then the equivalence class of
+   * (C x y) will be interpreted in m as (C x^m y^m) where
+   * x^m = m->getValue( x ) and y^m = m->getValue( y ).
+   *
+   * It should be called during model generation, before final representatives
+   * are chosen. In the case of TheoryEngineModelBuilder, it should be called
+   * during Theory's collectModelInfo( ... ) functions.
+   */
+  void assertSkeleton(TNode n);
   //---------------------------- end building the model
 
   // ------------------- general equality queries
@@ -171,8 +206,10 @@ public:
  protected:
   /** substitution map for this model */
   SubstitutionMap d_substitutions;
-  /** whether this model has been built */
+  /** whether we have tried to build this model in the current context */
   bool d_modelBuilt;
+  /** whether this model has been built successfully */
+  bool d_modelBuiltSuccess;
   /** special local context for our equalityEngine so we can clear it
    * independently of search context */
   context::Context* d_eeContext;
index ac12b37e30594f9546b8aa034ba6b34cba08d9ba..e88d1e3be11ad408ffb1a653d6f069f86a0b3927 100644 (file)
@@ -286,11 +286,15 @@ bool TheoryEngineModelBuilder::buildModel(Model* m)
 
   // mark as built
   tm->d_modelBuilt = true;
+  tm->d_modelBuiltSuccess = false;
 
   // Collect model info from the theories
   Trace("model-builder") << "TheoryEngineModelBuilder: Collect model info..."
                          << std::endl;
-  d_te->collectModelInfo(tm);
+  if (!d_te->collectModelInfo(tm))
+  {
+    return false;
+  }
 
   // model-builder specific initialization
   if (!preProcessBuildModel(tm))
@@ -799,6 +803,7 @@ bool TheoryEngineModelBuilder::buildModel(Model* m)
   }
   else
   {
+    tm->d_modelBuiltSuccess = true;
     return true;
   }
 }
index c24d50cbf1cfa391e57a5107fe67f501ccec5a86..bb74569b7b4d790c1f5097077f9b3cd8e5e2bbfc 100644 (file)
@@ -58,7 +58,8 @@ class TheoryEngineModelBuilder : public ModelBuilder
    * (4) assign constants to all equivalence classes
    *     of m's equality engine, through alternating
    *     iterations of evaluation and enumeration,
-   * (5) builder-specific post-processing.
+   * (5) builder-specific processing, which includes assigning total
+   *     interpretations to uninterpreted functions.
    *
    * This function returns false if any of the above
    * steps results in a lemma sent on an output channel.
index f97a4b63962e5f0585b315fef2c98da29c1bb4a6..38ddb1246bc5881abd02a9c77517b42f0cd1c0dd 100644 (file)
@@ -330,14 +330,18 @@ Node TheoryUF::explain(TNode literal, eq::EqProof* pf) {
   return mkAnd(assumptions);
 }
 
-void TheoryUF::collectModelInfo( TheoryModel* m ){
+bool TheoryUF::collectModelInfo(TheoryModel* m)
+{
   Debug("uf") << "UF : collectModelInfo " << std::endl;
   set<Node> termSet;
 
   // Compute terms appearing in assertions and shared terms
   computeRelevantTerms(termSet);
 
-  m->assertEqualityEngine( &d_equalityEngine, &termSet );
+  if (!m->assertEqualityEngine(&d_equalityEngine, &termSet))
+  {
+    return false;
+  }
 
   if( options::ufHo() ){
     for( std::set<Node>::iterator it = termSet.begin(); it != termSet.end(); ++it ){
@@ -345,12 +349,16 @@ void TheoryUF::collectModelInfo( TheoryModel* m ){
       if( n.getKind()==kind::APPLY_UF ){
         // for model-building with ufHo, we require that APPLY_UF is always expanded to HO_APPLY
         Node hn = TheoryUfRewriter::getHoApplyForApplyUf( n );
-        m->assertEquality( n, hn, true );
+        if (!m->assertEquality(n, hn, true))
+        {
+          return false;
+        }
       }
     }
   }
 
   Debug("uf") << "UF : finish collectModelInfo " << std::endl;
+  return true;
 }
 
 void TheoryUF::presolve() {
index 0665b82721e07ed91dff0b5c3120560d19041d7f..269aa63db1b4eb65ae6705b1ec6cae487949caa2 100644 (file)
@@ -242,7 +242,7 @@ public:
   void preRegisterTerm(TNode term);
   Node explain(TNode n);
 
-  void collectModelInfo( TheoryModel* m );
+  bool collectModelInfo(TheoryModel* m) override;
 
   void ppStaticLearn(TNode in, NodeBuilder<>& learned);
   void presolve();