Normalize negated bit-vector terms over equalities. (#2017)
authorMathias Preiner <mathias.preiner@gmail.com>
Wed, 30 May 2018 18:42:40 +0000 (11:42 -0700)
committerAndres Noetzli <andres.noetzli@gmail.com>
Wed, 30 May 2018 18:42:40 +0000 (11:42 -0700)
src/theory/bv/theory_bv.cpp
src/theory/bv/theory_bv_rewrite_rules.h
src/theory/bv/theory_bv_rewrite_rules_normalization.h

index 107cb96724943bc5a3966cdfc2db594d948e08c7..638715ae49a40e093cda8d9ea1f9ca3350b0f1bd 100644 (file)
@@ -767,6 +767,10 @@ Node TheoryBV::ppRewrite(TNode t)
   } else if (RewriteRule<ZeroExtendEqConst>::applies(t)) {
     res = RewriteRule<ZeroExtendEqConst>::run<false>(t);
   }
+  else if (RewriteRule<NormalizeEqPlusNeg>::applies(t))
+  {
+    res = RewriteRule<NormalizeEqPlusNeg>::run<false>(t);
+  }
 
   // if(t.getKind() == kind::EQUAL &&
   //    ((t[0].getKind() == kind::BITVECTOR_MULT && t[1].getKind() ==
index 1d2e7d9a399fa589dfe2bf9f4b81b36f8443665a..c6fa42ab09ee1faa246439dbe1babbe597107bfd 100644 (file)
@@ -31,7 +31,8 @@ namespace CVC4 {
 namespace theory {
 namespace bv {
 
-enum RewriteRuleId {
+enum RewriteRuleId
+{
 
   /// core normalization rules
   EmptyRule,
@@ -175,6 +176,7 @@ enum RewriteRuleId {
   OrSimplify,
   XorSimplify,
   BitwiseSlicing,
+  NormalizeEqPlusNeg,
   // rules to simplify bitblasting
   BBPlusNeg,
   UltPlusOne,
@@ -321,6 +323,7 @@ inline std::ostream& operator << (std::ostream& out, RewriteRuleId ruleId) {
   case ConcatToMult: out << "ConcatToMult"; return out;
   case IsPowerOfTwo: out << "IsPowerOfTwo"; return out;
   case MultSltMult: out << "MultSltMult"; return out;
+  case NormalizeEqPlusNeg: out << "NormalizeEqPlusNeg"; return out;
   default:
     Unreachable();
   }
@@ -548,6 +551,7 @@ struct AllRewriteRules {
   RewriteRule<SignExtendUltConst> rule126;
   RewriteRule<ZeroExtendUltConst> rule127;
   RewriteRule<MultSltMult> rule128;
+  RewriteRule<NormalizeEqPlusNeg> rule129;
 };
 
 template<> inline
index c2f6620aadd9f4372ac527fb3f19fe02562ea901..a02bf305f95c2c170f645deb112fc97704320804 100644 (file)
@@ -1451,6 +1451,84 @@ inline Node RewriteRule<BitwiseSlicing>::apply(TNode node)
   return result;
 }
 
+template <>
+inline bool RewriteRule<NormalizeEqPlusNeg>::applies(TNode node)
+{
+  return node.getKind() == kind::EQUAL
+         && (node[0].getKind() == kind::BITVECTOR_PLUS
+             || node[1].getKind() == kind::BITVECTOR_PLUS);
+}
+
+template <>
+inline Node RewriteRule<NormalizeEqPlusNeg>::apply(TNode node)
+{
+  Debug("bv-rewrite") << "RewriteRule<NormalizeEqPlusNeg>(" << node << ")"
+                      << std::endl;
+
+  NodeBuilder<> nb_lhs(kind::BITVECTOR_PLUS);
+  NodeBuilder<> nb_rhs(kind::BITVECTOR_PLUS);
+  NodeManager *nm = NodeManager::currentNM();
+
+  if (node[0].getKind() == kind::BITVECTOR_PLUS)
+  {
+    for (const TNode &n : node[0])
+    {
+      if (n.getKind() == kind::BITVECTOR_NEG)
+        nb_rhs << n[0];
+      else
+        nb_lhs << n;
+    }
+  }
+  else
+  {
+    nb_lhs << node[0];
+  }
+
+  if (node[1].getKind() == kind::BITVECTOR_PLUS)
+  {
+    for (const TNode &n : node[1])
+    {
+      if (n.getKind() == kind::BITVECTOR_NEG)
+        nb_lhs << n[0];
+      else
+        nb_rhs << n;
+    }
+  }
+  else
+  {
+    nb_rhs << node[1];
+  }
+
+  Node zero = utils::mkZero(utils::getSize(node[0]));
+
+  Node lhs, rhs;
+  if (nb_lhs.getNumChildren() == 0)
+  {
+    lhs = zero;
+  }
+  else if (nb_lhs.getNumChildren() == 1)
+  {
+    lhs = nb_lhs[0];
+  }
+  else
+  {
+    lhs = nb_lhs.constructNode();
+  }
+  if (nb_rhs.getNumChildren() == 0)
+  {
+    rhs = zero;
+  }
+  else if (nb_rhs.getNumChildren() == 1)
+  {
+    rhs = nb_rhs[0];
+  }
+  else
+  {
+    rhs = nb_rhs.constructNode();
+  }
+  return nm->mkNode(node.getKind(), lhs, rhs);
+}
+
 // template<> inline
 // bool RewriteRule<>::applies(TNode node) {
 //   return (node.getKind() == kind::BITVECTOR_CONCAT);