]> git.unchartedbackwaters.co.uk Git - francis/stp.git/commitdiff
Improvement. Use the results of bit-blasting to detect equivalent predicates. Current...
authortrevor_hansen <trevor_hansen@e59a4935-1847-0410-ae03-e826735625c1>
Fri, 3 Feb 2012 03:41:30 +0000 (03:41 +0000)
committertrevor_hansen <trevor_hansen@e59a4935-1847-0410-ae03-e826735625c1>
Fri, 3 Feb 2012 03:41:30 +0000 (03:41 +0000)
git-svn-id: https://stp-fast-prover.svn.sourceforge.net/svnroot/stp-fast-prover/trunk/stp@1552 e59a4935-1847-0410-ae03-e826735625c1

src/STPManager/STP.cpp
src/simplifier/SubstitutionMap.cpp
src/simplifier/SubstitutionMap.h
src/simplifier/simplifier.cpp
src/to-sat/AIG/BBNodeAIG.h
src/to-sat/BitBlaster.cpp
src/to-sat/BitBlaster.h

index 142f5932435dd347dcc670d7e1b2b47707a42544..e14d99e75620842915adb824b9c76f4f731aeb62 100644 (file)
@@ -112,11 +112,27 @@ namespace BEEV {
         SimplifyingNodeFactory nf(*(bm->hashingNodeFactory), *bm);
         BitBlaster<BBNodeAIG, BBNodeManagerAIG> bb(&bbnm, simp, &nf , &(bm->UserFlags));
         ASTNodeMap fromTo;
-        bb.getConsts(simplified_solved_InputToSAT, fromTo);
+        ASTNodeMap equivs;
+        bb.getConsts(simplified_solved_InputToSAT, fromTo,equivs);
+        if (equivs.size() > 0)
+          {
+            /* These nodes have equivalent AIG representations, so even though they have different
+             * word level expressions they are identical semantically. So we pick one of the ASTnodes
+             * and replace the others with it.
+             * TODO: Currently only for booleans,
+             * TODO: Isn't applied transitively because it infinite loops.
+             * TODO: I replace with the lower id node, sometimes though we replace with much more
+             * difficult looking ASTNodes.
+            */
+            ASTNodeMap cache;
+            simplified_solved_InputToSAT = SubstitutionMap::simple_replace(simplified_solved_InputToSAT, fromTo, cache,&nf);
+            bm->ASTNodeStats(bb_message.c_str(), simplified_solved_InputToSAT);
+          }
+
         if (fromTo.size() > 0)
           {
             ASTNodeMap cache;
-            simplified_solved_InputToSAT = SubstitutionMap::replace(simplified_solved_InputToSAT, fromTo, cache,&nf);
+            simplified_solved_InputToSAT = SubstitutionMap:: replace(simplified_solved_InputToSAT, fromTo, cache,&nf);
             bm->ASTNodeStats(bb_message.c_str(), simplified_solved_InputToSAT);
           }
         actualBBSize =  bbnm.totalNumberOfNodes();
index a726ca2ded155754c9ee39fb2fc37121f11035e1..84e4b909571f91b1759e4992199516d41d9768de 100644 (file)
@@ -311,4 +311,78 @@ bool SubstitutionMap::loops(const ASTNode& n0, const ASTNode& n1)
        return (loops);
        }
 
+ASTNode
+SubstitutionMap::simple_replace(const ASTNode& n, ASTNodeMap& fromTo, ASTNodeMap& cache, NodeFactory * nf)
+{
+  const Kind k = n.GetKind();
+  if (k == BVCONST || k == TRUE || k == FALSE)
+    return n;
+
+  ASTNodeMap::const_iterator it;
+
+  if ((it = cache.find(n)) != cache.end())
+    return it->second;
+
+  if ((it = fromTo.find(n)) != fromTo.end())
+    {
+      const ASTNode& r = it->second;
+      assert(r.GetIndexWidth() == n.GetIndexWidth());
+      cache.insert(make_pair(n, r));
+      return r;
+    }
+
+  // These can't be created like regular nodes are
+  if (k == SYMBOL)
+    return n;
+
+  const unsigned int indexWidth = n.GetIndexWidth();
+
+  const ASTVec& children = n.GetChildren();
+  assert(children.size() > 0);
+  // Should have no leaves left here.
+
+  ASTVec new_children;
+  new_children.reserve(children.size());
+
+  for (ASTVec::const_iterator it = children.begin(); it != children.end(); it++)
+    {
+      new_children.push_back(simple_replace(*it, fromTo, cache, nf));
+    }
+
+  assert(new_children.size() == children.size());
+
+  // This code short-cuts if the children are the same. Nodes with the same children,
+  // won't have necessarily given the same node if the simplifyingNodeFactory is enabled
+  // now, but wasn't enabled when the node was created. Shortcutting saves lots of time.
+  if (new_children == children)
+    {
+      cache.insert(make_pair(n, n));
+      return n;
+    }
+
+  ASTNode result;
+  const unsigned int valueWidth = n.GetValueWidth();
+
+  if (valueWidth == 0) // n.GetType() == BOOLEAN_TYPE
+    {
+      result = nf->CreateNode(k, new_children);
+    }
+  else
+    {
+      // If the index and value width aren't saved, they are reset sometimes (??)
+      result = nf->CreateArrayTerm(k, indexWidth, valueWidth, new_children);
+    }
+
+  // We may have created something that should be mapped. For instance,
+  // if n is READ(A, x), and the fromTo is: {x==0, READ(A,0) == 1}, then
+  // by here the result will be READ(A,0). Which needs to be mapped again..
+  // I hope that this makes it idempotent.
+
+  assert(result.GetValueWidth() == valueWidth);
+  assert(result.GetIndexWidth() == indexWidth);
+
+  cache.insert(make_pair(n, result));
+  return result;
+}
+
 };
index 08bb9d061eefb70f27208ef80a963e1164307f3a..08138d3e260de0cf19f1801faffbf10b27778999 100644 (file)
@@ -201,6 +201,7 @@ public:
 
        // Replace any nodes in "n" that exist in the fromTo map.
        // NB the fromTo map is changed.
+        static ASTNode simple_replace(const ASTNode& n, ASTNodeMap& fromTo, ASTNodeMap& cache, NodeFactory *nf);
        static ASTNode replace(const ASTNode& n, ASTNodeMap& fromTo, ASTNodeMap& cache, NodeFactory *nf);
        static ASTNode replace(const ASTNode& n, ASTNodeMap& fromTo, ASTNodeMap& cache, NodeFactory *nf, bool stopAtArrays);
 
index 1afbb20ae07f0ab351c070987dd6aa5a98d22d8d..5edf37fb0382c8fd487fb21249eab772fd5fb8f2 100644 (file)
@@ -213,7 +213,14 @@ namespace BEEV
   void
   Simplifier::UpdateAlwaysTrueFormSet(const ASTNode& key)
   {
-    AlwaysTrueHashSet.insert(key.GetNodeNum());
+    // The always true/ always false relies on the top level constraint not being removed.
+    // however with bb equivalence checking, AIGs can figure out that the outer constraint
+    // is unncessary because it's enforced by the implicit constraint---removing it. That
+    // leaves just one instance of the constraint, so it we replace it with true/false
+    // the constraint is lost. This is subsumed by constant bit propagation, so I suspect
+    // it's not a big loss.
+    if (!_bm->UserFlags.isSet("bb-equiv","0"))
+      AlwaysTrueHashSet.insert(key.GetNodeNum());
   }
 
   ASTNode
index a00208f6d62cecf3513ca0ac42d964e984b419f2..846ebb52e6387829a1302b155f57b2ff060d4405 100644 (file)
@@ -57,6 +57,12 @@ namespace BEEV
         print(c1);
     }
 public:
+
+    intptr_t GetNodeNum() const
+        {
+          return (intptr_t)n;
+        }
+
     // If the pointer is odd. Then it's the NOT of the pointer one less.
        Aig_Obj_t * n;
 
@@ -90,7 +96,7 @@ public:
 
        bool operator==(const BBNodeAIG &other) const
        {
-               return n == other.n;
+         return n == other.n;
        }
 
        bool operator!=(const BBNodeAIG &other) const
index c056ce382ff535a0fc2979083f24e43fa293b0e3..c5cbd1835aa98507c35fe862a32f0cf25c3b24e7 100644 (file)
@@ -58,7 +58,7 @@ namespace BEEV
 // Look through the maps to see what the bitblaster has discovered (if anything) is constant.
   template<class BBNode, class BBNodeManagerT>
     void
-    BitBlaster<BBNode, BBNodeManagerT>::getConsts(const ASTNode& form, ASTNodeMap& fromTo)
+    BitBlaster<BBNode, BBNodeManagerT>::getConsts(const ASTNode& form, ASTNodeMap& fromTo, ASTNodeMap& equivs)
     {
       assert(form.GetType() == BOOLEAN_TYPE);
 
@@ -132,6 +132,41 @@ namespace BEEV
           fromTo.insert(make_pair(n, r));
 
         }
+
+      if (form.GetSTPMgr()->UserFlags.isSet("bb-equiv","0"))
+      {
+        HASHMAP <intptr_t ,ASTNode> nodeToFn;
+        typename map<ASTNode, BBNode>::iterator it;
+        for (it = BBFormMemo.begin(); it != BBFormMemo.end(); it++)
+          {
+          const ASTNode& n = it->first;
+          if (n.isConstant())
+            continue;
+
+          const BBNode& x = it->second;
+          if (x == BBTrue || x == BBFalse)
+            continue;
+
+          if (nodeToFn.find(x.GetNodeNum()) == nodeToFn.end())
+            {
+              nodeToFn.insert(make_pair(x.GetNodeNum(),n));
+            }
+          else
+            {
+              const ASTNode other = (nodeToFn.find(x.GetNodeNum()))->second;
+              std::pair<ASTNode,ASTNode> p;
+              if (other.GetNodeNum() > n.GetNodeNum())
+                p = make_pair(other,n);
+              else
+                p = make_pair(n,other);
+
+              equivs.insert(p);
+              //std::cerr << "from" << p.first << " to" << p.second;
+              //ASTNode equals = ASTNF->CreateNode(NOT,ASTNF->CreateNode(EQ,p.first,p.second));
+              //printer::SMTLIB2_PrintBack(std::cerr,p.second);
+            }
+          }
+      }
     }
 
   template<class BBNode, class BBNodeManagerT>
index 30fdc77f5e471544258ffeb4fdad3f2be2bfa24f..9113f77e255261cbd48f6171c378e14c7db681b2 100644 (file)
@@ -292,7 +292,7 @@ namespace BEEV
       BBForm(const ASTNode& form);
 
       void
-      getConsts(const ASTNode& n, ASTNodeMap& fromTo);
+      getConsts(const ASTNode& n, ASTNodeMap& fromTo, ASTNodeMap& equivs);
 
     };
 //end of class BitBlaster