BitwiseIdemp,
AndZero,
AndOne,
- AndOrConcatPullUp,
+ AndOrXorConcatPullUp,
OrZero,
OrOne,
XorDuplicate,
case ConcatFlatten: out << "ConcatFlatten"; return out;
case ConcatExtractMerge: out << "ConcatExtractMerge"; return out;
case ConcatConstantMerge: out << "ConcatConstantMerge"; return out;
- case AndOrConcatPullUp: out << "AndOrConcatPullUp"; return out;
+ case AndOrXorConcatPullUp:out << "AndOrXorConcatPullUp";return out;
case ExtractExtract: out << "ExtractExtract"; return out;
case ExtractWhole: out << "ExtractWhole"; return out;
case ExtractConcat: out << "ExtractConcat"; return out;
RewriteRule<BvIteMergeElseIf> rule136;
RewriteRule<BvIteMergeThenElse> rule137;
RewriteRule<BvIteMergeElseElse> rule138;
- RewriteRule<AndOrConcatPullUp> rule139;
+ RewriteRule<AndOrXorConcatPullUp> rule139;
};
template<> inline
/* -------------------------------------------------------------------------- */
/**
- * AndOrConcatPullUp
+ * AndOrXorConcatPullUp
*
* And:
* ----------------------------------------------------------------
* Rewrites to: concat(x[m-1:m-my] | y,
* ~0_n,
* x[mz-1:0] | z)
+ *
+ * Xor:
+ * ----------------------------------------------------------------
+ * Match: x_m ^ concat(y_my, 0_n, z_mz)
+ * Rewrites to: concat(x[m-1:m-my] ^ y,
+ * x[m-my-1:mz],
+ * x[mz-1:0] ^ z)
+ *
+ * Match: x_m ^ concat(y_my, 1_n, z_mz)
+ * Rewrites to: concat(x[m-1:m-my] ^ y,
+ * x[m-my-1:mz+1],
+ * ~x[mz:mz],
+ * x[mz-1:0] ^ z)
+ *
+ * Match: x_m ^ concat(y_my, ~0_n, z_mz)
+ * Rewrites to: concat(x[m-1:m-my] ^ y,
+ * ~[m-my-1:mz],
+ * x[mz-1:0] ^ z)
*/
template <>
-inline bool RewriteRule<AndOrConcatPullUp>::applies(TNode node)
+inline bool RewriteRule<AndOrXorConcatPullUp>::applies(TNode node)
{
if (node.getKind() != kind::BITVECTOR_AND
- && node.getKind() != kind::BITVECTOR_OR)
+ && node.getKind() != kind::BITVECTOR_OR
+ && node.getKind() != kind::BITVECTOR_XOR)
{
return false;
}
}
template <>
-inline Node RewriteRule<AndOrConcatPullUp>::apply(TNode node)
+inline Node RewriteRule<AndOrXorConcatPullUp>::apply(TNode node)
{
- Debug("bv-rewrite") << "RewriteRule<AndOrConcatPullUp>(" << node << ")"
+ Debug("bv-rewrite") << "RewriteRule<AndOrXorConcatPullUp>(" << node << ")"
<< std::endl;
int32_t is_const;
uint32_t m, my, mz, n;
}
else
{
- Assert(kind == kind::BITVECTOR_OR);
+ Assert(kind == kind::BITVECTOR_OR || kind == kind::BITVECTOR_XOR);
res << utils::mkExtract(x, m - my - 1, mz);
}
}
if (n > 1) res << utils::mkZero(n - 1);
res << utils::mkExtract(x, mz, mz);
}
- else
+ else if (kind == kind::BITVECTOR_OR)
{
- Assert(kind == kind::BITVECTOR_OR);
if (n > 1) res << utils::mkExtract(x, m - my - 1, mz + 1);
res << utils::mkOne(1);
}
+ else
+ {
+ Assert(kind == kind::BITVECTOR_XOR);
+ if (n > 1) res << utils::mkExtract(x, m - my - 1, mz + 1);
+ res << nm->mkNode(kind::BITVECTOR_NOT, utils::mkExtract(x, mz, mz));
+ }
}
else
{
{
res << utils::mkExtract(x, m - my - 1, mz);
}
- else
+ else if (kind == kind::BITVECTOR_OR)
{
- Assert(kind == kind::BITVECTOR_OR);
res << c;
}
+ else
+ {
+ Assert(kind == kind::BITVECTOR_XOR);
+ res << nm->mkNode(kind::BITVECTOR_NOT,
+ utils::mkExtract(x, m - my - 1, mz));
+ }
}
if (mz)
{
resultNode =
LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
RewriteRule<AndSimplify>,
- RewriteRule<AndOrConcatPullUp>>::apply(node);
+ RewriteRule<AndOrXorConcatPullUp>>::apply(node);
if (!prerewrite)
{
resultNode =
resultNode =
LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
RewriteRule<OrSimplify>,
- RewriteRule<AndOrConcatPullUp>>::apply(node);
+ RewriteRule<AndOrXorConcatPullUp>>::apply(node);
if (!prerewrite)
{
return RewriteResponse(REWRITE_DONE, resultNode);
}
-RewriteResponse TheoryBVRewriter::RewriteXor(TNode node, bool prerewrite) {
+RewriteResponse TheoryBVRewriter::RewriteXor(TNode node, bool prerewrite)
+{
Node resultNode = node;
- resultNode = LinearRewriteStrategy
- < RewriteRule<FlattenAssocCommut>, // flatten the expression
- RewriteRule<XorSimplify>, // simplify duplicates and constants
- RewriteRule<XorZero>, // checks if the constant part is zero and eliminates it
- RewriteRule<BitwiseSlicing>
- >::apply(node);
+ resultNode = LinearRewriteStrategy<
+ RewriteRule<FlattenAssocCommut>, // flatten the expression
+ RewriteRule<XorSimplify>, // simplify duplicates and constants
+ RewriteRule<XorZero>, // checks if the constant part is zero and
+ // eliminates it
+ RewriteRule<AndOrXorConcatPullUp>,
+ RewriteRule<BitwiseSlicing>>::apply(node);
- if (!prerewrite) {
- resultNode = LinearRewriteStrategy
- < RewriteRule<XorOne>,
- RewriteRule <BitwiseSlicing>
- >::apply(resultNode);
-
- if (resultNode.getKind() != node.getKind()) {
- return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
+ if (!prerewrite)
+ {
+ resultNode =
+ LinearRewriteStrategy<RewriteRule<XorOne>,
+ RewriteRule<BitwiseSlicing>>::apply(resultNode);
+
+ if (resultNode.getKind() != node.getKind())
+ {
+ return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
}
}
- return RewriteResponse(REWRITE_DONE, resultNode);
+ return RewriteResponse(REWRITE_DONE, resultNode);
}
RewriteResponse TheoryBVRewriter::RewriteXnor(TNode node, bool prerewrite) {