bv static learning and rewrites for power of 2 terms
authorlianah <lianahady@gmail.com>
Sun, 15 Jun 2014 00:44:00 +0000 (20:44 -0400)
committerlianah <lianahady@gmail.com>
Sun, 15 Jun 2014 00:44:00 +0000 (20:44 -0400)
src/theory/bv/bv_subtheory_bitblast.cpp
src/theory/bv/theory_bv.cpp
src/theory/bv/theory_bv_rewrite_rules.h
src/theory/bv/theory_bv_rewrite_rules_simplification.h
src/theory/bv/theory_bv_utils.h

index d606ccee8a63d079447769df423fc421db098e2e..ebe017ee17b78d0f1229ab7da412c25e621e73d8 100644 (file)
@@ -96,6 +96,7 @@ void BitblastSolver::bitblastQueue() {
   while (!d_bitblastQueue.empty()) {
     TNode atom = d_bitblastQueue.front();
     d_bitblastQueue.pop();
+    Debug("bv-bitblast-queue") << "BitblastSolver::bitblastQueue (" << atom << ")\n";
     if (options::bvAbstraction() &&
         d_abstractionModule->isLemmaAtom(atom)) {
       // don't bit-blast lemma atoms
index 04b8e9d6e3e1a611dbb265b15d4d71c4106c2aea..5be02322db262ec34a302e7f0eb848d0b8c15d8c 100644 (file)
@@ -560,9 +560,7 @@ Node TheoryBV::ppRewrite(TNode t)
   } else if (RewriteRule<UltPlusOne>::applies(t)) {
     Node result = RewriteRule<UltPlusOne>::run<false>(t);
     res = Rewriter::rewrite(result);
-  }
-
-  if( res.getKind() == kind::EQUAL &&
+  } else if( res.getKind() == kind::EQUAL &&
       ((res[0].getKind() == kind::BITVECTOR_PLUS &&
         RewriteRule<ConcatToMult>::applies(res[1])) ||
        res[1].getKind() == kind::BITVECTOR_PLUS &&
@@ -579,6 +577,8 @@ Node TheoryBV::ppRewrite(TNode t)
     } else {
       res = t;
     }
+  } else if (RewriteRule<IsPowerOfTwo>::applies(t)) {
+    res = RewriteRule<IsPowerOfTwo>::run<false>(t);
   }
   
 
@@ -729,7 +729,35 @@ void TheoryBV::enableCoreTheorySlicer() {
 }
 
 
-void TheoryBV::ppStaticLearn(TNode in, NodeBuilder<>& learned) {}
+void TheoryBV::ppStaticLearn(TNode in, NodeBuilder<>& learned) {
+  if (in.getKind() == kind::EQUAL) {
+    if(in[0].getKind() == kind::BITVECTOR_PLUS && in[1].getKind() == kind::BITVECTOR_SHL ||
+       in[1].getKind() == kind::BITVECTOR_PLUS && in[0].getKind() == kind::BITVECTOR_SHL){
+      TNode p = in[0].getKind() == kind::BITVECTOR_PLUS ? in[0] : in[1];
+      TNode s = in[0].getKind() == kind::BITVECTOR_PLUS ? in[1] : in[0];
+
+      if(p.getNumChildren() == 2
+         && p[0].getKind()  == kind::BITVECTOR_SHL 
+         && p[1].getKind()  == kind::BITVECTOR_SHL ){
+        unsigned size = utils::getSize(s);
+        Node one = utils::mkConst(size, 1u);
+        if(s[0] == one && p[0][0] == one && p[1][0] == one){
+          Node zero = utils::mkConst(size, 0u);
+          TNode b = p[0];
+          TNode c = p[1];
+          // (s : 1 << S) = (b : 1 << B) + (c : 1 << C)
+          Node b_eq_0 = b.eqNode(zero);
+          Node c_eq_0 = c.eqNode(zero);
+          Node b_eq_c = b.eqNode(c);
+
+          Node dis = utils::mkNode(kind::OR, b_eq_0, c_eq_0, b_eq_c);
+          Node imp = in.impNode(dis);
+          learned << imp;
+        }
+      }
+    }
+  }       
+}
 
 bool TheoryBV::applyAbstraction(const std::vector<Node>& assertions, std::vector<Node>& new_assertions) {
   bool changed = d_abstractionModule->applyAbstraction(assertions, new_assertions);
index eadb63671c80c4a994711b35e1a0b8cb85d68087..5e85cb145e517a24beb65d87bdb6ba2634e4df06 100644 (file)
@@ -165,7 +165,8 @@ enum RewriteRuleId {
   // rules to simplify bitblasting
   BBPlusNeg,
   UltPlusOne,
-  ConcatToMult
+  ConcatToMult,
+  IsPowerOfTwo
 };
 
 
@@ -293,6 +294,7 @@ inline std::ostream& operator << (std::ostream& out, RewriteRuleId ruleId) {
   case MultDistrib: out << "MultDistrib"; return out;
   case UltPlusOne: out << "UltPlusOne"; return out;
   case ConcatToMult: out << "ConcatToMult"; return out;
+  case IsPowerOfTwo: out << "IsPowerOfTwo"; return out;
   default:
     Unreachable();
   }
@@ -516,6 +518,7 @@ struct AllRewriteRules {
   RewriteRule<MultDistrib> rule118;
   RewriteRule<UltPlusOne> rule119;
   RewriteRule<ConcatToMult> rule120;
+  RewriteRule<IsPowerOfTwo> rule121;
 };
 
 template<> inline
index 71df1edcad0425bdf3afbc375a1174da16e12ef4..33994782a3d1aea07123f9b5d375eab53f974e55 100644 (file)
@@ -1193,67 +1193,52 @@ Node RewriteRule<UltPlusOne>::apply(TNode node) {
   return utils::mkNode(kind::AND, not_y_eq_1, not_y_lt_x);
 }
 
+/** 
+ * x ^(x-1) = 0 => 1 << sk
+ * Note: only to be called in ppRewrite and not rewrite!
+ * (it calls the rewriter)
+ * 
+ * @param node 
+ * 
+ * @return 
+ */
+template<> inline
+bool RewriteRule<IsPowerOfTwo>::applies(TNode node) {
+  if (node.getKind()!= kind::EQUAL) return false;
+  if (node[0].getKind() != kind::BITVECTOR_AND &&
+      node[1].getKind() != kind::BITVECTOR_AND)
+    return false;
+  if (!utils::isZero(node[0]) &&
+      !utils::isZero(node[1]))
+    return false;
+
+  TNode t = !utils::isZero(node[0])? node[0]: node[1];
+  if (t.getNumChildren() != 2) return false; 
+  TNode a = t[0];
+  TNode b = t[1];
+  unsigned size = utils::getSize(t);
+  if(size < 2) return false;
+  Node diff = Rewriter::rewrite(utils::mkNode(kind::BITVECTOR_SUB, a, b));
+  return (diff.isConst() && (diff == utils::mkConst(size, 1u) || diff == utils::mkOnes(size)));
+}
+
+template<> inline
+Node RewriteRule<IsPowerOfTwo>::apply(TNode node) {
+  Debug("bv-rewrite") << "RewriteRule<IsPowerOfTwo>(" << node << ")" << std::endl;
+  TNode term = utils::isZero(node[0])? node[1] : node[0];
+  TNode a = term[0];
+  TNode b = term[1];
+  unsigned size = utils::getSize(term); 
+  Node diff = Rewriter::rewrite(utils::mkNode(kind::BITVECTOR_SUB, a, b));
+  Assert (diff.isConst());
+  TNode x = diff == utils::mkConst(size, 1u) ? a : b;
+  Node one = utils::mkConst(size, 1u);
+  Node sk = utils::mkVar(size);
+  Node sh = utils::mkNode(kind::BITVECTOR_SHL, one, sk);
+  Node x_eq_sh = utils::mkNode(kind::EQUAL, x, sh);
+  return x_eq_sh;
+}
 
-// /**
-//  * 
-//  *
-//  * 
-//  */
-
-// template<> inline
-// bool RewriteRule<BBFactorOut>::applies(TNode node) {
-//   if (node.getKind() != kind::BITVECTOR_PLUS) {
-//     return false; 
-//   }
-
-//   for (unsigned i = 0; i < node.getNumChildren(); ++i) {
-//     if (node[i].getKind() != kind::BITVECTOR_MULT) {
-//       return false; 
-//     }
-//   }
-// }
-
-// template<> inline
-// Node RewriteRule<BBFactorOut>::apply(TNode node) {
-//   Debug("bv-rewrite") << "RewriteRule<BBFactorOut>(" << node << ")" << std::endl;
-//   std::hash_set<TNode, TNodeHashFunction> factors;
-
-//   for (unsigned i = 0; i < node.getNumChildren(); ++i) {
-//     Assert (node[i].getKind() == kind::BITVECTOR_MULT);
-//     for (unsigned j = 0; j < node[i].getNumChildren(); ++j) {
-//       factors.insert(node[i][j]); 
-//     }
-//   }
-
-//   std::vector<TNode> gcd; 
-//   std::hash_set<TNode, TNodeHashFunction>::const_iterator it;
-//   for (it = factors.begin(); it != factors.end(); ++it) {
-//     // for each factor check if it occurs in all children
-//     TNode f = *it; 
-//     for (unsigned i = 0; i < node.getNumChildren
-    
-//     }
-//   }
-//   return ; 
-// }
-
-
-// /**
-//  * 
-//  *
-//  * 
-//  */
-
-// template<> inline
-// bool RewriteRule<>::applies(TNode node) {
-//   return (node.getKind() == );
-// }
-
-// template<> inline
-// Node RewriteRule<>::apply(TNode node) {
-//   Debug("bv-rewrite") << "RewriteRule<>(" << node << ")" << std::endl;
-//   return ; 
-// }
 
 
 
index 3650d3091897c89bc7bf5ccc789670d70edd944e..9679c0260db68e9d2dbc8b90fc8c2141ff9a4600 100644 (file)
@@ -332,7 +332,10 @@ inline Node mkAnd(const std::vector<Node>& conjunctions) {
   return conjunction;
 }/* mkAnd() */
 
-
+inline bool isZero(TNode node) {
+  if (!node.isConst()) return false; 
+  return node == utils::mkConst(utils::getSize(node), 0u); 
+}
 
 inline Node flattenAnd(std::vector<TNode>& queue) {
   TNodeSet nodes;