Implemented array type enumerator, more fixes for models
authorClark Barrett <barrett@cs.nyu.edu>
Thu, 4 Oct 2012 17:45:56 +0000 (17:45 +0000)
committerClark Barrett <barrett@cs.nyu.edu>
Thu, 4 Oct 2012 17:45:56 +0000 (17:45 +0000)
14 files changed:
src/expr/command.h
src/printer/printer.h
src/smt/smt_engine.h
src/theory/arrays/theory_arrays.cpp
src/theory/arrays/theory_arrays_rewriter.h
src/theory/arrays/type_enumerator.h
src/theory/bv/theory_bv.cpp
src/theory/model.cpp
src/theory/model.h
src/util/Makefile.am
src/util/model.cpp [deleted file]
src/util/model.h [deleted file]
src/util/util_model.cpp [new file with mode: 0644]
src/util/util_model.h [new file with mode: 0644]

index e120deed62910bf90c63cc7793aeb8cc072783d8..6f5b0bd4cb6e9740cf0732314e433f3c1e952464 100644 (file)
@@ -37,7 +37,7 @@
 #include "util/sexpr.h"
 #include "util/datatype.h"
 #include "util/proof.h"
-#include "util/model.h"
+#include "util/util_model.h"
 
 namespace CVC4 {
 
index 778c21f1f3aa476dcf52fc6217cb391094802ece..48b76d15ac5173194cc247710902d3d647bbf73b 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "util/language.h"
 #include "util/sexpr.h"
-#include "util/model.h"
+#include "util/util_model.h"
 #include "expr/node.h"
 #include "expr/command.h"
 
index 096708f53011ffb8ad9bcf2fc9622cb4837df01d..f30a98935c8f21c350c589e2273efacbc02bd285 100644 (file)
@@ -29,7 +29,7 @@
 #include "expr/expr.h"
 #include "expr/expr_manager.h"
 #include "util/proof.h"
-#include "util/model.h"
+#include "util/util_model.h"
 #include "smt/modal_exception.h"
 #include "util/hash.h"
 #include "options/options.h"
index 63b61995a2e7e7e663840e6b98dc67eed4f244f1..b4cc8e5f7acc1b718bf9cf7baae04887c00a104d 100644 (file)
@@ -565,11 +565,17 @@ void TheoryArrays::computeCareGraph()
           // If arrays are known to be disequal, or cannot become equal, we can continue
           Assert(d_mayEqualEqualityEngine.hasTerm(r1[0]) && d_mayEqualEqualityEngine.hasTerm(r2[0]));
           if (r1[0].getType() != r2[0].getType() ||
-              (!d_mayEqualEqualityEngine.areEqual(r1[0], r2[0])) ||
               d_equalityEngine.areDisequal(r1[0], r2[0], false)) {
             Debug("arrays::sharing") << "TheoryArrays::computeCareGraph(): arrays can't be equal, skipping" << std::endl;
             continue;
           }
+          else if (!d_mayEqualEqualityEngine.areEqual(r1[0], r2[0])) {
+            if (r2.getType().getCardinality().isInfinite()) {
+              continue;
+            }
+            // TODO: add a disequality split for these two arrays
+            continue;
+          }
         }
 
         TNode x = r1[1];
@@ -678,11 +684,17 @@ void TheoryArrays::collectModelInfo( TheoryModel* m, bool fullModel ){
     if (it == defValues.end()) {
       TypeNode valueType = n.getType().getArrayConstituentType();
       rep = defaultValuesSet.nextTypeEnum(valueType);
+      if (rep.isNull()) {
+        Assert(defaultValuesSet.getSet(valueType)->begin() != defaultValuesSet.getSet(valueType)->end());
+        rep = *(defaultValuesSet.getSet(valueType)->begin());
+      }
+      Trace("arrays-models") << "New default value = " << rep << endl;
       defValues[mayRep] = rep;
     }
     else {
       rep = (*it).second;
     }
+
     // Build the STORE_ALL term with the default value
     rep = nm->mkConst(ArrayStoreAll(n.getType().toType(), rep.toExpr()));
     // For each read, require that the rep stores the right value
index d120f8feb4fe00e15d707405261eca4af80cfe2b..0f46ffe7cc53178069a3b42ae7ab46cbeb19dbd2 100644 (file)
@@ -358,6 +358,10 @@ public:
           Trace("arrays-postrewrite") << "Arrays::postRewrite returning true" << std::endl;
           return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(true));
         }
+        else if (node[0].isConst() && node[1].isConst()) {
+          Trace("arrays-postrewrite") << "Arrays::postRewrite returning false" << std::endl;
+          return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(false));
+        }
         if (node[0] > node[1]) {
           Node newNode = NodeManager::currentNM()->mkNode(node.getKind(), node[1], node[0]);
           Trace("arrays-postrewrite") << "Arrays::postRewrite returning " << newNode << std::endl;
index f6d871c48f9f9834dcc232a210a19e469c1456fe..c6b73b9f61f0816da061069be3aa287d8667ecf5 100644 (file)
@@ -24,6 +24,7 @@
 #include "theory/type_enumerator.h"
 #include "expr/type_node.h"
 #include "expr/kind.h"
+#include "theory/rewriter.h"
 
 namespace CVC4 {
 namespace theory {
@@ -31,27 +32,94 @@ namespace arrays {
 
 class ArrayEnumerator : public TypeEnumeratorBase<ArrayEnumerator> {
   TypeEnumerator d_index;
-  TypeEnumerator d_constituent;
+  TypeNode d_constituentType;
+  NodeManager* d_nm;
+  std::vector<Node> d_indexVec;
+  std::vector<TypeEnumerator*> d_constituentVec;
+  bool d_finished;
+  Node d_arrayConst;
 
 public:
 
   ArrayEnumerator(TypeNode type) throw(AssertionException) :
     TypeEnumeratorBase<ArrayEnumerator>(type),
-    d_index(TypeEnumerator(type.getArrayIndexType())),
-    d_constituent(TypeEnumerator(type.getArrayConstituentType())) {
+    d_index(type.getArrayIndexType()),
+    d_constituentType(type.getArrayConstituentType()),
+    d_nm(NodeManager::currentNM()),
+    d_finished(false)
+  {
+    d_indexVec.push_back(*d_index);
+    d_constituentVec.push_back(new TypeEnumerator(d_constituentType));
+    d_arrayConst = d_nm->mkConst(ArrayStoreAll(type.toType(), (*(*d_constituentVec.back())).toExpr()));
+  }
+
+  ~ArrayEnumerator() {
+    while (!d_constituentVec.empty()) {
+      delete d_constituentVec.back();
+      d_constituentVec.pop_back();
+    }
   }
 
   Node operator*() throw(NoMoreValuesException) {
-    return Node::null();
-    //return NodeManager::currentNM()->mkConst(Array(d_size, d_bits));
+    if (d_finished) {
+      throw NoMoreValuesException(getType());
+    }
+    Node n = d_arrayConst;
+    for (unsigned i = 0; i < d_indexVec.size(); ++i) {
+      n = d_nm->mkNode(kind::STORE, n, d_indexVec[d_indexVec.size() - 1 - i], *(*(d_constituentVec[i])));
+    }
+    Trace("array-type-enum") << "operator * prerewrite: " << n << std::endl;
+    n = Rewriter::rewrite(n);
+    Trace("array-type-enum") << "operator * returning: " << n << std::endl;
+    return n;
   }
 
   ArrayEnumerator& operator++() throw() {
+    Trace("array-type-enum") << "operator++ called, **this = " << **this << std::endl;
+
+    if (d_finished) {
+      Trace("array-type-enum") << "operator++ finished!" << std::endl;
+      return *this;
+    }
+    while (!d_constituentVec.empty()) {
+      ++(*d_constituentVec.back());
+      if (d_constituentVec.back()->isFinished()) {
+        delete d_constituentVec.back();
+        d_constituentVec.pop_back();
+      }
+      else {
+        break;
+      }
+    }
+
+    if (d_constituentVec.empty()) {
+      ++d_index;
+      if (d_index.isFinished()) {
+        Trace("array-type-enum") << "operator++ finished!" << std::endl;
+        d_finished = true;
+        return *this;
+      }
+      d_indexVec.push_back(*d_index);
+      d_constituentVec.push_back(new TypeEnumerator(d_constituentType));
+      ++(*d_constituentVec.back());
+      if (d_constituentVec.back()->isFinished()) {
+        Trace("array-type-enum") << "operator++ finished!" << std::endl;
+        d_finished = true;
+        return *this;
+      }
+    }
+
+    while (d_constituentVec.size() < d_indexVec.size()) {
+      d_constituentVec.push_back(new TypeEnumerator(d_constituentType));
+    }
+
+    Trace("array-type-enum") << "operator++ returning, **this = " << **this << std::endl;
     return *this;
   }
 
   bool isFinished() throw() {
-    Unimplemented();
+    Trace("array-type-enum") << "isFinished returning: " << d_finished << std::endl;
+    return d_finished;
   }
 
 };/* class ArrayEnumerator */
index 51e09ee5a38443ce5806a1fb7332d0c660522b98..1c5b08546c8f9d5034a7fe9a80b2db89a52bf045 100644 (file)
@@ -127,7 +127,7 @@ void TheoryBV::check(Effort e)
 
 void TheoryBV::collectModelInfo( TheoryModel* m, bool fullModel ){
   Assert(!inConflict());
-  Assert (fullModel); // can only query full model
+  //  Assert (fullModel); // can only query full model
   d_equalitySolver.collectModelInfo(m); 
   d_bitblastSolver.collectModelInfo(m); 
   
index 4a3ddc9ca633477bcb692339a81cba0e8014aef7..d4b71c9e252fdeab54f45d3e6dd89ecdf9654390 100644 (file)
@@ -486,7 +486,7 @@ void TheoryEngineModelBuilder::buildModel(Model* m, bool fullModel)
         eq::EqClassIterator eqc_i = eq::EqClassIterator(*i2, &tm->d_equalityEngine);
         for ( ; !eqc_i.isFinished(); ++eqc_i) {
           Node n = *eqc_i;
-          Node normalized = normalize(tm, n, constantReps);
+          Node normalized = normalize(tm, n, constantReps, true);
           if (normalized.isConst()) {
             typeConstSet.add(t, normalized);
             constantReps[*i2] = normalized;
@@ -529,7 +529,7 @@ void TheoryEngineModelBuilder::buildModel(Model* m, bool fullModel)
       for (i = repSet.begin(); i != repSet.end(); ) {
         Assert(assertedReps.find(*i) != assertedReps.end());
         Node rep = assertedReps[*i];
-        Node normalized = normalize(tm, rep, constantReps);
+        Node normalized = normalize(tm, rep, constantReps, false);
         Trace("model-builder") << "  Normalizing rep (" << rep << "), normalized to (" << normalized << ")" << endl;
         if (normalized.isConst()) {
           changed = true;
@@ -602,9 +602,8 @@ void TheoryEngineModelBuilder::buildModel(Model* m, bool fullModel)
 }
 
 
-Node TheoryEngineModelBuilder::normalize(TheoryModel* m, TNode r, std::map< Node, Node >& constantReps)
+Node TheoryEngineModelBuilder::normalize(TheoryModel* m, TNode r, std::map< Node, Node >& constantReps, bool evalOnly)
 {
-  Trace("tembn") << "Normalize " << r << std::endl;
   std::map<Node, Node>::iterator itMap = constantReps.find(r);
   if (itMap != constantReps.end()) {
     return (*itMap).second;
@@ -625,8 +624,17 @@ Node TheoryEngineModelBuilder::normalize(TheoryModel* m, TNode r, std::map< Node
       if (!ri.isConst()) {
         if (m->d_equalityEngine.hasTerm(ri)) {
           ri = m->d_equalityEngine.getRepresentative(ri);
+          itMap = constantReps.find(ri);
+          if (itMap != constantReps.end()) {
+            ri = (*itMap).second;
+          }
+          else if (evalOnly) {
+            ri = normalize(m, r[i], constantReps, evalOnly);
+          }
+        }
+        else {
+          ri = normalize(m, ri, constantReps, evalOnly);
         }
-        ri = normalize(m, ri, constantReps);
         if (!ri.isConst()) {
           childrenConst = false;
         }
index 90cd1e35a04bcfabdd21d34b1783c5c3b9f2afc8..0a846a3c6108d41665ff76b6987c9225799629d9 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef __CVC4__THEORY_MODEL_H
 #define __CVC4__THEORY_MODEL_H
 
-#include "util/model.h"
+#include "util/util_model.h"
 #include "theory/uf/equality_engine.h"
 #include "theory/rep_set.h"
 #include "theory/substitutions.h"
@@ -193,7 +193,9 @@ private:
     else {
       te = (*it).second;
     }
-    Assert(!te->isFinished());
+    if (te->isFinished()) {
+      return Node();
+    }
 
     iterator itSet = d_typeSet.find(t);
     std::set<Node>* s;
@@ -206,7 +208,9 @@ private:
     }
     Node n = **te;
     while (s->find(n) != s->end()) {
-      Assert(!te->isFinished());
+      if (te->isFinished()) {
+        return Node();
+      }
       ++(*te);
       n = **te;
     }
@@ -254,7 +258,7 @@ protected:
   /** choose representative for unconstrained equivalence class */
   virtual Node chooseRepresentative(TheoryModel* m, Node eqc, bool fullModel);
   /** normalize representative */
-  Node normalize(TheoryModel* m, TNode r, std::map<Node, Node>& constantReps);
+  Node normalize(TheoryModel* m, TNode r, std::map<Node, Node>& constantReps, bool evalOnly);
 public:
   TheoryEngineModelBuilder(TheoryEngine* te);
   virtual ~TheoryEngineModelBuilder(){}
index 6c310476083d480ea400c0661a540cd6cf9f86f2..a4462d8248dcd6b217e4fa8ca67980d3e827acf2 100644 (file)
@@ -81,8 +81,8 @@ libutil_la_SOURCES = \
        uninterpreted_constant.cpp \
        array_store_all.h \
        array_store_all.cpp \
-       model.h \
-       model.cpp
+       util_model.h \
+       util_model.cpp
 
 libutil_la_LIBADD = \
        @builddir@/libutilcudd.la
diff --git a/src/util/model.cpp b/src/util/model.cpp
deleted file mode 100644 (file)
index 8b0e956..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*********************                                                        */
-/*! \file model.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: mdeters
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief implementation of Model class
- **/
-
-#include "util/model.h"
-#include "expr/command.h"
-#include "smt/smt_engine_scope.h"
-#include "smt/command_list.h"
-
-#include <vector>
-
-using namespace std;
-
-namespace CVC4 {
-
-Model::Model() :
-  d_smt(*smt::currentSmtEngine()) {
-}
-
-size_t Model::getNumCommands() const {
-  return d_smt.d_modelCommands->size();
-}
-
-const Command* Model::getCommand(size_t i) const {
-  return (*d_smt.d_modelCommands)[i];
-}
-
-}/* CVC4 namespace */
diff --git a/src/util/model.h b/src/util/model.h
deleted file mode 100644 (file)
index 97010dd..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*********************                                                        */
-/*! \file model.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: mdeters
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Model class
- **/
-
-#include "cvc4_public.h"
-
-#ifndef __CVC4__MODEL_H
-#define __CVC4__MODEL_H
-
-#include <iostream>
-#include <vector>
-
-#include "expr/expr.h"
-#include "util/cardinality.h"
-
-namespace CVC4 {
-
-class CVC4_PUBLIC Command;
-class CVC4_PUBLIC SmtEngine;
-
-class CVC4_PUBLIC Model {
-private:
-  /** The SmtEngine we're associated to */
-  const SmtEngine& d_smt;
-public:
-  /** construct the base class */
-  Model();
-  /** virtual destructor */
-  virtual ~Model() { }
-  /** get number of commands to report */
-  size_t getNumCommands() const;
-  /** get command */
-  const Command* getCommand(size_t i) const;
-public:
-  /** get value for expression */
-  virtual Expr getValue(Expr expr) = 0;
-  /** get cardinality for sort */
-  virtual Cardinality getCardinality(Type t) = 0;
-  /** write the model to a stream */
-  virtual void toStream(std::ostream& out) = 0;
-};/* class Model */
-
-class ModelBuilder
-{
-public:
-  ModelBuilder(){}
-  virtual ~ModelBuilder(){}
-  virtual void buildModel( Model* m, bool fullModel ) = 0;
-};/* class ModelBuilder */
-
-}/* CVC4 namespace */
-
-#endif  /* __CVC4__MODEL_H */
diff --git a/src/util/util_model.cpp b/src/util/util_model.cpp
new file mode 100644 (file)
index 0000000..6dfe2c5
--- /dev/null
@@ -0,0 +1,40 @@
+/*********************                                                        */
+/*! \file model.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: mdeters
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief implementation of Model class
+ **/
+
+#include "util/util_model.h"
+#include "expr/command.h"
+#include "smt/smt_engine_scope.h"
+#include "smt/command_list.h"
+
+#include <vector>
+
+using namespace std;
+
+namespace CVC4 {
+
+Model::Model() :
+  d_smt(*smt::currentSmtEngine()) {
+}
+
+size_t Model::getNumCommands() const {
+  return d_smt.d_modelCommands->size();
+}
+
+const Command* Model::getCommand(size_t i) const {
+  return (*d_smt.d_modelCommands)[i];
+}
+
+}/* CVC4 namespace */
diff --git a/src/util/util_model.h b/src/util/util_model.h
new file mode 100644 (file)
index 0000000..97010dd
--- /dev/null
@@ -0,0 +1,65 @@
+/*********************                                                        */
+/*! \file model.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: mdeters
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Model class
+ **/
+
+#include "cvc4_public.h"
+
+#ifndef __CVC4__MODEL_H
+#define __CVC4__MODEL_H
+
+#include <iostream>
+#include <vector>
+
+#include "expr/expr.h"
+#include "util/cardinality.h"
+
+namespace CVC4 {
+
+class CVC4_PUBLIC Command;
+class CVC4_PUBLIC SmtEngine;
+
+class CVC4_PUBLIC Model {
+private:
+  /** The SmtEngine we're associated to */
+  const SmtEngine& d_smt;
+public:
+  /** construct the base class */
+  Model();
+  /** virtual destructor */
+  virtual ~Model() { }
+  /** get number of commands to report */
+  size_t getNumCommands() const;
+  /** get command */
+  const Command* getCommand(size_t i) const;
+public:
+  /** get value for expression */
+  virtual Expr getValue(Expr expr) = 0;
+  /** get cardinality for sort */
+  virtual Cardinality getCardinality(Type t) = 0;
+  /** write the model to a stream */
+  virtual void toStream(std::ostream& out) = 0;
+};/* class Model */
+
+class ModelBuilder
+{
+public:
+  ModelBuilder(){}
+  virtual ~ModelBuilder(){}
+  virtual void buildModel( Model* m, bool fullModel ) = 0;
+};/* class ModelBuilder */
+
+}/* CVC4 namespace */
+
+#endif  /* __CVC4__MODEL_H */