Fixes for getModelVal in bv theory
authorClark Barrett <barrett@cs.nyu.edu>
Thu, 11 Apr 2013 15:50:41 +0000 (11:50 -0400)
committerClark Barrett <barrett@cs.nyu.edu>
Thu, 11 Apr 2013 15:50:41 +0000 (11:50 -0400)
src/theory/bv/bv_subtheory_bitblast.cpp
src/theory/bv/bv_subtheory_bitblast.h

index 613300f9ee60df72e06b1dda384474092df25d5b..997244c405c896c7217669dabfafe3be71a1fe3a 100644 (file)
@@ -31,8 +31,8 @@ BitblastSolver::BitblastSolver(context::Context* c, TheoryBV* bv)
   : SubtheorySolver(c, bv),
     d_bitblaster(new Bitblaster(c, bv)),
     d_bitblastQueue(c),
-    d_modelValuesCache(c), 
-    d_statistics()
+    d_statistics(),
+    d_validModelCache(c, true)
 {}
 
 BitblastSolver::~BitblastSolver() {
@@ -88,6 +88,7 @@ bool BitblastSolver::check(Theory::Effort e) {
   // Processing assertions  
   while (!done()) {
     TNode fact = get();
+    d_validModelCache = false;
     Debug("bv-bitblast") << "  fact " << fact << ")\n"; 
     if (!d_bv->inConflict() && (!d_bv->wasPropagatedBySubtheory(fact) || d_bv->getPropagatingSubtheory(fact) != SUB_BITBLAST)) {
       // Some atoms have not been bit-blasted yet
@@ -139,62 +140,46 @@ void BitblastSolver::collectModelInfo(TheoryModel* m) {
   return d_bitblaster->collectModelInfo(m); 
 }
 
-Node BitblastSolver::getModelValue(TNode node) {
-  Debug("bitvector-model") << "BitblastSolver::getModelValue (" << node <<")";
-  std::vector<TNode> stack;
-  __gnu_cxx::hash_set<TNode, TNodeHashFunction> processed; 
-  stack.push_back(node);
-
-  while (!stack.empty()) {
-    TNode current = stack.back();
-    stack.pop_back();
-    processed.insert(current);
-    
-    if (d_modelValuesCache.hasSubstitution(current) ||
-        processed.count(current) != 0) {
-      // if it has a subsitution or we have already processed it nothing to do
-      continue; 
-    }
+Node BitblastSolver::getModelValue(TNode node)
+{
+  if (!d_validModelCache) {
+    d_modelCache.clear();
+    d_validModelCache = true;
+  }
+  return getModelValueRec(node);
+}
 
-    // see if the node itself has a value in the bit-blaster
-    // this can happen if say select (...) = x has been asserted
-    // to the bit-blaster
-    Node current_val = d_bitblaster->getVarValue(current);
-    if (current_val != Node()) {
-      d_modelValuesCache.addSubstitution(current, current_val); 
-    } else {
-      // if not process all of the children 
-      for (unsigned i = 0; i < current.getNumChildren(); ++i) {
-        TNode child = current[i];
-        if (current[i].getType().isBitVector() &&
-            ( current[i].getKind() == kind::VARIABLE ||
-              current[i].getKind() == kind::STORE ||
-              current[i].getKind() == kind::SKOLEM)) {
-          // we only want the values of variables 
-          Node child_value = d_bitblaster->getVarValue(child);
-          Debug("bitvector-model") << child << " => " << child_value <<"\n"; 
-          if (child_value == Node()) {
-            return Node(); 
-          }
-          d_modelValuesCache.addSubstitution(child, child_value);
-        }
-        stack.push_back(child);
-      }
-    }
+Node BitblastSolver::getModelValueRec(TNode node)
+{
+  Node val;
+  if (node.isConst()) {
+    return node;
   }
-  
-  Node val = Rewriter::rewrite(d_modelValuesCache.apply(node));
-  Debug("bitvector-model") << " => " << val <<"\n";
-  Assert (val != Node() || d_bv->isSharedTerm(node));
-  
-  if (val.getKind() != kind::CONST_BITVECTOR) {
-    // if we could not reduce the value to a constant return Null
-    return Node(); 
+  NodeMap::iterator it = d_modelCache.find(node);
+  if (it != d_modelCache.end()) {
+    val = (*it).second;
+    Debug("bitvector-model") << node << " => (cached) " << val <<"\n";
+    return val;
   }
-  
-  if (node != val) {
-    d_modelValuesCache.addSubstitution(node, val);
+  if (d_bv->isLeaf(node)) {
+    val = d_bitblaster->getVarValue(node);
+    if (val == Node()) {
+      // If no value in model, just set to 0
+      val = utils::mkConst(utils::getSize(node), (unsigned)0);
+    }
+  } else {
+    NodeBuilder<> valBuilder(node.getKind());
+    if (node.getMetaKind() == kind::metakind::PARAMETERIZED) {
+      valBuilder << node.getOperator();
+    }
+    for (unsigned i = 0; i < node.getNumChildren(); ++i) {
+      valBuilder << getModelValueRec(node[i]);
+    }
+    val = valBuilder;
+    val = Rewriter::rewrite(val);
   }
-  
+  Assert(val.isConst());
+  d_modelCache[node] = val;
+  Debug("bitvector-model") << node << " => " << val <<"\n";
   return val; 
 }
index d508a83d496aaaa1d2f20b63e61ea82040406c78..819b3d62c8d7687c0f21e5b33836496951895884 100644 (file)
@@ -40,8 +40,13 @@ class BitblastSolver : public SubtheorySolver {
 
   /** Nodes that still need to be bit-blasted */
   context::CDQueue<TNode> d_bitblastQueue;
-  SubstitutionMap d_modelValuesCache; 
   Statistics d_statistics; 
+
+  typedef std::hash_map<Node, Node, NodeHashFunction> NodeMap;
+  NodeMap d_modelCache;
+  context::CDO<bool> d_validModelCache;
+  Node getModelValueRec(TNode node);
+
 public:
   BitblastSolver(context::Context* c, TheoryBV* bv);
   ~BitblastSolver();