summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/theory/booleans/theory_bool_rewriter.cpp47
-rw-r--r--test/regress/CMakeLists.txt1
-rw-r--r--test/regress/regress0/bool/issue6717-ite-rewrite.smt27
3 files changed, 34 insertions, 21 deletions
diff --git a/src/theory/booleans/theory_bool_rewriter.cpp b/src/theory/booleans/theory_bool_rewriter.cpp
index a5c63522d..8f6d9d3b7 100644
--- a/src/theory/booleans/theory_bool_rewriter.cpp
+++ b/src/theory/booleans/theory_bool_rewriter.cpp
@@ -345,16 +345,6 @@ RewriteResponse TheoryBoolRewriter::preRewrite(TNode n) {
<< n << ": " << n[0].notNode() << std::endl;
return RewriteResponse(REWRITE_AGAIN, makeNegation(n[0]));
}
- if (n[1] == tt || n[1] == ff)
- {
- // ITE C true y --> C v y
- // ITE C false y --> ~C ^ y
- Node resp =
- n[1] == tt ? n[0].orNode(n[2]) : (n[0].negate()).andNode(n[2]);
- Debug("bool-ite") << "TheoryBoolRewriter::preRewrite_ITE: n[1] const "
- << n << ": " << resp << std::endl;
- return RewriteResponse(REWRITE_AGAIN, resp);
- }
}
if (n[0].getKind() == kind::NOT)
@@ -364,17 +354,6 @@ RewriteResponse TheoryBoolRewriter::preRewrite(TNode n) {
REWRITE_AGAIN, nodeManager->mkNode(kind::ITE, n[0][0], n[2], n[1]));
}
- if (n[2].isConst() && (n[2] == tt || n[2] == ff))
- {
- // ITE C x true --> ~C v x
- // ITE C x false --> C ^ x
- Node resp =
- n[2] == tt ? (n[0].negate()).orNode(n[1]) : n[0].andNode(n[1]);
- Debug("bool-ite") << "TheoryBoolRewriter::preRewrite_ITE: n[2] const "
- << n << ": " << resp << std::endl;
- return RewriteResponse(REWRITE_AGAIN, resp);
- }
-
int parityTmp;
if ((parityTmp = equalityParity(n[1], n[2])) != 0) {
Node resp = (parityTmp == 1) ? (Node)n[1] : n[0].eqNode(n[1]);
@@ -424,6 +403,32 @@ RewriteResponse TheoryBoolRewriter::preRewrite(TNode n) {
<< parityTmp << " " << n << ": " << resp << std::endl;
return RewriteResponse(REWRITE_AGAIN, resp);
}
+
+ // Rewrites for ITEs with a constant branch. These rewrites are applied
+ // after the parity rewrites above because they may simplify ITEs such as
+ // `(ite c c true)` to `(ite c true true)`. As a result, we avoid
+ // introducing an unnecessary conjunction/disjunction here.
+ if (n[1].isConst() && (n[1] == tt || n[1] == ff))
+ {
+ // ITE C true y --> C v y
+ // ITE C false y --> ~C ^ y
+ Node resp =
+ n[1] == tt ? n[0].orNode(n[2]) : (n[0].negate()).andNode(n[2]);
+ Debug("bool-ite") << "TheoryBoolRewriter::preRewrite_ITE: n[1] const "
+ << n << ": " << resp << std::endl;
+ return RewriteResponse(REWRITE_AGAIN, resp);
+ }
+ else if (n[2].isConst() && (n[2] == tt || n[2] == ff))
+ {
+ // ITE C x true --> ~C v x
+ // ITE C x false --> C ^ x
+ Node resp =
+ n[2] == tt ? (n[0].negate()).orNode(n[1]) : n[0].andNode(n[1]);
+ Debug("bool-ite") << "TheoryBoolRewriter::preRewrite_ITE: n[2] const "
+ << n << ": " << resp << std::endl;
+ return RewriteResponse(REWRITE_AGAIN, resp);
+ }
+
break;
}
default:
diff --git a/test/regress/CMakeLists.txt b/test/regress/CMakeLists.txt
index 4ee8e513e..19c689b87 100644
--- a/test/regress/CMakeLists.txt
+++ b/test/regress/CMakeLists.txt
@@ -163,6 +163,7 @@ set(regress_0_tests
regress0/auflia/fuzz05.smtv1.smt2
regress0/auflia/x2.smtv1.smt2
regress0/bool/issue1978.smt2
+ regress0/bool/issue6717-ite-rewrite.smt2
regress0/boolean-prec.cvc
regress0/boolean-terms-bug-array.smt2
regress0/boolean-terms-kernel1.smt2
diff --git a/test/regress/regress0/bool/issue6717-ite-rewrite.smt2 b/test/regress/regress0/bool/issue6717-ite-rewrite.smt2
new file mode 100644
index 000000000..3f78823df
--- /dev/null
+++ b/test/regress/regress0/bool/issue6717-ite-rewrite.smt2
@@ -0,0 +1,7 @@
+(set-logic ALL)
+(declare-fun T () Bool)
+(declare-fun v () String)
+(assert (ite T T true))
+(assert (or T (and (str.prefixof v "") (exists ((x Int)) (= "t" (str.substr v 0 x))))))
+(set-info :status sat)
+(check-sat)
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback