diff options
author | Andrew Reynolds <andrew.j.reynolds@gmail.com> | 2020-01-28 13:31:44 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-28 13:31:44 -0600 |
commit | 9bb84e49df11dd669db1fff22cb69a08dfaa7bb4 (patch) | |
tree | 7c645b65a754df2d590849c166024ec829815694 /src/theory/bv | |
parent | bde056be1c65a77f0f5ca4389edc910b530ed436 (diff) |
Avoid PLUS with one child for bv2nat elimination (#3639)
Diffstat (limited to 'src/theory/bv')
-rw-r--r-- | src/theory/bv/theory_bv.cpp | 16 | ||||
-rw-r--r-- | src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h | 15 | ||||
-rw-r--r-- | src/theory/bv/theory_bv_utils.cpp | 22 | ||||
-rw-r--r-- | src/theory/bv/theory_bv_utils.h | 9 |
4 files changed, 33 insertions, 29 deletions
diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp index afd99647b..48168d7d6 100644 --- a/src/theory/bv/theory_bv.cpp +++ b/src/theory/bv/theory_bv.cpp @@ -618,21 +618,7 @@ int TheoryBV::getReduction(int effort, Node n, Node& nr) NodeManager* const nm = NodeManager::currentNM(); if (n.getKind() == kind::BITVECTOR_TO_NAT) { - // taken from rewrite code - const unsigned size = utils::getSize(n[0]); - const Node z = nm->mkConst(Rational(0)); - const Node bvone = utils::mkOne(1); - NodeBuilder<> result(kind::PLUS); - Integer i = 1; - for (unsigned bit = 0; bit < size; ++bit, i *= 2) - { - Node cond = - nm->mkNode(kind::EQUAL, - nm->mkNode(nm->mkConst(BitVectorExtract(bit, bit)), n[0]), - bvone); - result << nm->mkNode(kind::ITE, cond, nm->mkConst(Rational(i)), z); - } - nr = Node(result); + nr = utils::eliminateBv2Nat(n); return -1; } else if (n.getKind() == kind::INT_TO_BITVECTOR) diff --git a/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h b/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h index 0ae082adc..c9f814be6 100644 --- a/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h +++ b/src/theory/bv/theory_bv_rewrite_rules_operator_elimination.h @@ -275,20 +275,7 @@ inline Node RewriteRule<BVToNatEliminate>::apply(TNode node) //if( node[0].isConst() ){ //TODO? direct computation instead of term construction+rewriting //} - - const unsigned size = utils::getSize(node[0]); - NodeManager* const nm = NodeManager::currentNM(); - const Node z = nm->mkConst(Rational(0)); - const Node bvone = utils::mkOne(1); - - NodeBuilder<> result(kind::PLUS); - Integer i = 1; - for(unsigned bit = 0; bit < size; ++bit, i *= 2) { - Node cond = nm->mkNode(kind::EQUAL, nm->mkNode(nm->mkConst(BitVectorExtract(bit, bit)), node[0]), bvone); - result << nm->mkNode(kind::ITE, cond, nm->mkConst(Rational(i)), z); - } - - return Node(result); + return utils::eliminateBv2Nat(node); } template <> diff --git a/src/theory/bv/theory_bv_utils.cpp b/src/theory/bv/theory_bv_utils.cpp index 765541150..2094e804f 100644 --- a/src/theory/bv/theory_bv_utils.cpp +++ b/src/theory/bv/theory_bv_utils.cpp @@ -459,6 +459,28 @@ Node flattenAnd(std::vector<TNode>& queue) /* ------------------------------------------------------------------------- */ +Node eliminateBv2Nat(TNode node) +{ + const unsigned size = utils::getSize(node[0]); + NodeManager* const nm = NodeManager::currentNM(); + const Node z = nm->mkConst(Rational(0)); + const Node bvone = utils::mkOne(1); + + Integer i = 1; + std::vector<Node> children; + for (unsigned bit = 0; bit < size; ++bit, i *= 2) + { + Node cond = + nm->mkNode(kind::EQUAL, + nm->mkNode(nm->mkConst(BitVectorExtract(bit, bit)), node[0]), + bvone); + children.push_back( + nm->mkNode(kind::ITE, cond, nm->mkConst(Rational(i)), z)); + } + // avoid plus with one child + return children.size() == 1 ? children[0] : nm->mkNode(kind::PLUS, children); +} + }/* CVC4::theory::bv::utils namespace */ }/* CVC4::theory::bv namespace */ }/* CVC4::theory namespace */ diff --git a/src/theory/bv/theory_bv_utils.h b/src/theory/bv/theory_bv_utils.h index 23eaab3f8..30454be4a 100644 --- a/src/theory/bv/theory_bv_utils.h +++ b/src/theory/bv/theory_bv_utils.h @@ -206,6 +206,15 @@ void intersect(const std::vector<uint32_t>& v1, const std::vector<uint32_t>& v2, std::vector<uint32_t>& intersection); +/** + * Returns the rewritten form of node, which is a term of the form bv2nat(x). + * The return value of this method is the integer sum: + * (+ ite( (= ((_ extract (n-1) (n-1)) x) 1) (^ 2 (n-1)) 0) + * ... + * ite( (= ((_ extract 0 0) x) 1) (^ 2 0) 0)) + * where n is the bitwidth of x. + */ +Node eliminateBv2Nat(TNode node); } } } |