--- /dev/null
+/********************* */
+/*! \file pass_bv_gauss_white.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Aina Niemetz, Mathias Preiner, Andres Noetzli
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
+ ** in the top-level source directory and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Unit tests for Gaussian Elimination preprocessing pass.
+ **
+ ** Unit tests for Gaussian Elimination preprocessing pass.
+ **/
+
+#include <iostream>
+#include <vector>
+
+#include "context/context.h"
+#include "expr/node.h"
+#include "expr/node_manager.h"
+#include "preprocessing/passes/bv_gauss.h"
+#include "smt/smt_engine.h"
+#include "smt/smt_engine_scope.h"
+#include "test_smt.h"
+#include "theory/bv/theory_bv_utils.h"
+#include "theory/rewriter.h"
+#include "util/bitvector.h"
+
+namespace CVC4 {
+
+using namespace preprocessing;
+using namespace preprocessing::passes;
+using namespace theory;
+using namespace smt;
+
+namespace test {
+
+class TestPPWhiteBVGauss : public TestSmt
+{
+ protected:
+ void SetUp() override
+ {
+ TestSmt::SetUp();
+
+ d_zero = bv::utils::mkZero(16);
+
+ d_p = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 11u)));
+ d_x = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16)));
+ d_y = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16)));
+ d_z = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16)));
+
+ d_one = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 1u)));
+ d_two = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 2u)));
+ d_three = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 3u)));
+ d_four = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 4u)));
+ d_five = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 5u)));
+ d_six = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 6u)));
+ d_seven = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 7u)));
+ d_eight = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 8u)));
+ d_nine = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 9u)));
+ d_ten = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 10u)));
+ d_twelve = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 12u)));
+ d_eighteen = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 18u)));
+ d_twentyfour = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 24u)));
+ d_thirty = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 30u)));
+
+ d_one32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 1u));
+ d_two32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 2u));
+ d_three32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 3u));
+ d_four32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 4u));
+ d_five32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 5u));
+ d_six32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 6u));
+ d_seven32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 7u));
+ d_eight32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 8u));
+ d_nine32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 9u));
+ d_ten32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 10u));
+
+ d_x_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_one);
+ d_x_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_two);
+ d_x_mul_four = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four);
+ d_y_mul_three = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three);
+ d_y_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_one);
+ d_y_mul_four = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_four);
+ d_y_mul_five = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_five);
+ d_y_mul_seven = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven);
+ d_z_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_one);
+ d_z_mul_three = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_three);
+ d_z_mul_five = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_five);
+ d_z_mul_six = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_six);
+ d_z_mul_twelve = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_twelve);
+ d_z_mul_nine = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_nine);
+ }
+
+ void print_matrix_dbg(std::vector<Integer>& rhs,
+ std::vector<std::vector<Integer>>& lhs)
+ {
+ for (size_t m = 0, nrows = lhs.size(), ncols = lhs[0].size(); m < nrows;
+ ++m)
+ {
+ for (size_t n = 0; n < ncols; ++n)
+ {
+ std::cout << " " << lhs[m][n];
+ }
+ std::cout << " " << rhs[m];
+ std::cout << std::endl;
+ }
+ }
+
+ void testGaussElimX(Integer prime,
+ std::vector<Integer> rhs,
+ std::vector<std::vector<Integer>> lhs,
+ BVGauss::Result expected,
+ std::vector<Integer>* rrhs = nullptr,
+ std::vector<std::vector<Integer>>* rlhs = nullptr)
+ {
+ size_t nrows = lhs.size();
+ size_t ncols = lhs[0].size();
+ BVGauss::Result ret;
+ std::vector<Integer> resrhs = std::vector<Integer>(rhs);
+ std::vector<std::vector<Integer>> reslhs =
+ std::vector<std::vector<Integer>>(lhs);
+
+ std::cout << "Input: " << std::endl;
+ print_matrix_dbg(rhs, lhs);
+
+ ret = BVGauss::gaussElim(prime, resrhs, reslhs);
+
+ std::cout << "BVGauss::Result: "
+ << (ret == BVGauss::Result::INVALID
+ ? "INVALID"
+ : (ret == BVGauss::Result::UNIQUE
+ ? "UNIQUE"
+ : (ret == BVGauss::Result::PARTIAL ? "PARTIAL"
+ : "NONE")))
+ << std::endl;
+ print_matrix_dbg(resrhs, reslhs);
+
+ ASSERT_EQ(expected, ret);
+
+ if (expected == BVGauss::Result::UNIQUE)
+ {
+ /* map result value to column index
+ * e.g.:
+ * 1 0 0 2 -> res = { 2, 0, 3}
+ * 0 0 1 3 */
+ std::vector<Integer> res = std::vector<Integer>(ncols, Integer(0));
+ for (size_t i = 0; i < nrows; ++i)
+ for (size_t j = 0; j < ncols; ++j)
+ {
+ if (reslhs[i][j] == 1)
+ res[j] = resrhs[i];
+ else
+ ASSERT_EQ(reslhs[i][j], 0);
+ }
+
+ for (size_t i = 0; i < nrows; ++i)
+ {
+ Integer tmp = Integer(0);
+ for (size_t j = 0; j < ncols; ++j)
+ tmp = tmp.modAdd(lhs[i][j].modMultiply(res[j], prime), prime);
+ ASSERT_EQ(tmp, rhs[i].euclidianDivideRemainder(prime));
+ }
+ }
+ if (rrhs != nullptr && rlhs != nullptr)
+ {
+ for (size_t i = 0; i < nrows; ++i)
+ {
+ for (size_t j = 0; j < ncols; ++j)
+ {
+ ASSERT_EQ(reslhs[i][j], (*rlhs)[i][j]);
+ }
+ ASSERT_EQ(resrhs[i], (*rrhs)[i]);
+ }
+ }
+ }
+
+ Node d_p;
+ Node d_x;
+ Node d_y;
+ Node d_z;
+ Node d_zero;
+ Node d_one;
+ Node d_two;
+ Node d_three;
+ Node d_four;
+ Node d_five;
+ Node d_six;
+ Node d_seven;
+ Node d_eight;
+ Node d_nine;
+ Node d_ten;
+ Node d_twelve;
+ Node d_eighteen;
+ Node d_twentyfour;
+ Node d_thirty;
+ Node d_one32;
+ Node d_two32;
+ Node d_three32;
+ Node d_four32;
+ Node d_five32;
+ Node d_six32;
+ Node d_seven32;
+ Node d_eight32;
+ Node d_nine32;
+ Node d_ten32;
+ Node d_x_mul_one;
+ Node d_x_mul_two;
+ Node d_x_mul_four;
+ Node d_y_mul_one;
+ Node d_y_mul_three;
+ Node d_y_mul_four;
+ Node d_y_mul_five;
+ Node d_y_mul_seven;
+ Node d_z_mul_one;
+ Node d_z_mul_three;
+ Node d_z_mul_five;
+ Node d_z_mul_twelve;
+ Node d_z_mul_six;
+ Node d_z_mul_nine;
+};
+
+TEST_F(TestPPWhiteBVGauss, elim_mod)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
+ * --^-- ^
+ * 1 1 1 5
+ * 2 3 5 8
+ * 4 0 5 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(2)};
+ lhs = {{Integer(1), Integer(1), Integer(1)},
+ {Integer(2), Integer(3), Integer(5)},
+ {Integer(4), Integer(0), Integer(5)}};
+ std::cout << "matrix 0, modulo 0" << std::endl; // throws
+ ASSERT_DEATH(BVGauss::gaussElim(Integer(0), rhs, lhs), "prime > 0");
+ std::cout << "matrix 0, modulo 1" << std::endl;
+ testGaussElimX(Integer(1), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 0, modulo 2" << std::endl;
+ testGaussElimX(Integer(2), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 0, modulo 3" << std::endl;
+ testGaussElimX(Integer(3), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 0, modulo 4" << std::endl; // no inverse
+ testGaussElimX(Integer(4), rhs, lhs, BVGauss::Result::INVALID);
+ std::cout << "matrix 0, modulo 5" << std::endl;
+ testGaussElimX(Integer(5), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 0, modulo 6" << std::endl; // no inverse
+ testGaussElimX(Integer(6), rhs, lhs, BVGauss::Result::INVALID);
+ std::cout << "matrix 0, modulo 7" << std::endl;
+ testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 0, modulo 8" << std::endl; // no inverse
+ testGaussElimX(Integer(8), rhs, lhs, BVGauss::Result::INVALID);
+ std::cout << "matrix 0, modulo 9" << std::endl;
+ testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 0, modulo 10" << std::endl; // no inverse
+ testGaussElimX(Integer(10), rhs, lhs, BVGauss::Result::INVALID);
+ std::cout << "matrix 0, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_unique_done)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 17
+ * --^--- ^ --^-- ^
+ * 1 0 0 4 --> 1 0 0 4
+ * 0 1 0 15 0 1 0 15
+ * 0 0 1 3 0 0 1 3
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(4), Integer(15), Integer(3)};
+ lhs = {{Integer(1), Integer(0), Integer(0)},
+ {Integer(0), Integer(1), Integer(0)},
+ {Integer(0), Integer(0), Integer(1)}};
+ std::cout << "matrix 1, modulo 17" << std::endl;
+ testGaussElimX(Integer(17), rhs, lhs, BVGauss::Result::UNIQUE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_unique)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo { 11,17,59 }
+ * --^--- ^
+ * 2 4 6 18
+ * 4 5 6 24
+ * 3 1 -2 4
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(18), Integer(24), Integer(4)};
+ lhs = {{Integer(2), Integer(4), Integer(6)},
+ {Integer(4), Integer(5), Integer(6)},
+ {Integer(3), Integer(1), Integer(-2)}};
+ std::cout << "matrix 2, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 2, modulo 17" << std::endl;
+ testGaussElimX(Integer(17), rhs, lhs, BVGauss::Result::UNIQUE);
+ std::cout << "matrix 2, modulo 59" << std::endl;
+ testGaussElimX(Integer(59), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * -----^----- ^ ---^--- ^
+ * 1 1 2 0 1 --> 1 0 0 0 1
+ * 2 -1 0 1 -2 0 1 0 0 2
+ * 1 -1 -1 -2 4 0 0 1 0 -1
+ * 2 -1 2 -1 0 0 0 0 1 -2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(1), Integer(-2), Integer(4), Integer(0)};
+ lhs = {{Integer(1), Integer(1), Integer(2), Integer(0)},
+ {Integer(2), Integer(-1), Integer(0), Integer(1)},
+ {Integer(1), Integer(-1), Integer(-1), Integer(-2)},
+ {Integer(2), Integer(-1), Integer(2), Integer(-1)}};
+ std::cout << "matrix 3, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_unique_zero1)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 0 4 5 2 --> 1 0 0 4
+ * 1 1 1 5 0 1 0 3
+ * 3 2 5 8 0 0 1 9
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(2), Integer(5), Integer(8)};
+ lhs = {{Integer(0), Integer(4), Integer(5)},
+ {Integer(1), Integer(1), Integer(1)},
+ {Integer(3), Integer(2), Integer(5)}};
+ std::cout << "matrix 4, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 1 1 5 --> 1 0 0 4
+ * 0 4 5 2 0 1 0 3
+ * 3 2 5 8 0 0 1 9
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(2), Integer(8)};
+ lhs = {{Integer(1), Integer(1), Integer(1)},
+ {Integer(0), Integer(4), Integer(5)},
+ {Integer(3), Integer(2), Integer(5)}};
+ std::cout << "matrix 5, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 1 1 5 --> 1 0 0 4
+ * 3 2 5 8 0 1 0 9
+ * 0 4 5 2 0 0 1 3
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(2)};
+ lhs = {{Integer(1), Integer(1), Integer(1)},
+ {Integer(3), Integer(2), Integer(5)},
+ {Integer(0), Integer(4), Integer(5)}};
+ std::cout << "matrix 6, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_unique_zero2)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 0 0 5 2 1 0 0 10
+ * 1 1 1 5 --> 0 1 0 10
+ * 3 2 5 8 0 0 1 7
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(2), Integer(5), Integer(8)};
+ lhs = {{Integer(0), Integer(0), Integer(5)},
+ {Integer(1), Integer(1), Integer(1)},
+ {Integer(3), Integer(2), Integer(5)}};
+ std::cout << "matrix 7, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 1 1 5 --> 1 0 0 10
+ * 0 0 5 2 0 1 0 10
+ * 3 2 5 8 0 0 1 7
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(2), Integer(8)};
+ lhs = {{Integer(1), Integer(1), Integer(1)},
+ {Integer(0), Integer(0), Integer(5)},
+ {Integer(3), Integer(2), Integer(5)}};
+ std::cout << "matrix 8, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 1 1 5 --> 1 0 0 10
+ * 3 2 5 8 0 1 0 10
+ * 0 0 5 2 0 0 1 7
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(2)};
+ lhs = {{Integer(1), Integer(1), Integer(1)},
+ {Integer(3), Integer(2), Integer(5)},
+ {Integer(0), Integer(0), Integer(5)}};
+ std::cout << "matrix 9, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_unique_zero3)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 7
+ * --^-- ^ --^-- ^
+ * 2 0 6 4 1 0 0 3
+ * 0 0 0 0 --> 0 0 0 0
+ * 4 0 6 3 0 0 1 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(4), Integer(0), Integer(3)};
+ lhs = {{Integer(2), Integer(0), Integer(6)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(4), Integer(0), Integer(6)}};
+ std::cout << "matrix 10, modulo 7" << std::endl;
+ testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 7
+ * --^-- ^ --^-- ^
+ * 2 6 0 4 1 0 0 3
+ * 0 0 0 0 --> 0 0 0 0
+ * 4 6 0 3 0 0 1 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(4), Integer(0), Integer(3)};
+ lhs = {{Integer(2), Integer(6), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(4), Integer(6), Integer(0)}};
+ std::cout << "matrix 11, modulo 7" << std::endl;
+ testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_unique_zero4)
+{
+ std::vector<Integer> rhs, resrhs;
+ std::vector<std::vector<Integer>> lhs, reslhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 0 1 1 5
+ * 0 0 0 0
+ * 0 0 5 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(0), Integer(2)};
+ lhs = {{Integer(0), Integer(1), Integer(1)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(0), Integer(0), Integer(5)}};
+ std::cout << "matrix 12, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 0 1 1 5
+ * 0 3 5 8
+ * 0 0 0 0
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(0)};
+ lhs = {{Integer(0), Integer(1), Integer(1)},
+ {Integer(0), Integer(3), Integer(5)},
+ {Integer(0), Integer(0), Integer(0)}};
+ std::cout << "matrix 13, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 0 0 0 0
+ * 0 3 5 8
+ * 0 0 5 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(0), Integer(8), Integer(2)};
+ lhs = {{Integer(0), Integer(0), Integer(0)},
+ {Integer(0), Integer(3), Integer(5)},
+ {Integer(0), Integer(0), Integer(5)}};
+ std::cout << "matrix 14, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 0 1 5
+ * 0 0 0 0
+ * 4 0 5 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(0), Integer(2)};
+ lhs = {{Integer(1), Integer(0), Integer(1)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(4), Integer(0), Integer(5)}};
+ std::cout << "matrix 15, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 0 1 5
+ * 2 0 5 8
+ * 0 0 0 0
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(0)};
+ lhs = {{Integer(1), Integer(0), Integer(1)},
+ {Integer(2), Integer(0), Integer(5)},
+ {Integer(0), Integer(0), Integer(0)}};
+ std::cout << "matrix 16, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 0 0 0 0
+ * 2 0 5 8
+ * 4 0 5 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(0), Integer(8), Integer(2)};
+ lhs = {{Integer(0), Integer(0), Integer(0)},
+ {Integer(2), Integer(0), Integer(5)},
+ {Integer(4), Integer(0), Integer(5)}};
+ std::cout << "matrix 17, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 1 0 5
+ * 0 0 0 0
+ * 4 0 0 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(0), Integer(2)};
+ lhs = {{Integer(1), Integer(1), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(4), Integer(0), Integer(0)}};
+ std::cout << "matrix 18, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 1 0 5
+ * 2 3 0 8
+ * 0 0 0 0
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(0)};
+ lhs = {{Integer(1), Integer(1), Integer(0)},
+ {Integer(2), Integer(3), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)}};
+ std::cout << "matrix 18, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 0 0 0 0
+ * 2 3 0 8
+ * 4 0 0 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(0), Integer(8), Integer(2)};
+ lhs = {{Integer(0), Integer(0), Integer(0)},
+ {Integer(2), Integer(3), Integer(0)},
+ {Integer(4), Integer(0), Integer(0)}};
+ std::cout << "matrix 19, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 2
+ * ----^--- ^
+ * 2 4 6 18 0 0 0 0
+ * 4 5 6 24 = 0 1 0 0
+ * 2 7 12 30 0 1 0 0
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(18), Integer(24), Integer(30)};
+ lhs = {{Integer(2), Integer(4), Integer(6)},
+ {Integer(4), Integer(5), Integer(6)},
+ {Integer(2), Integer(7), Integer(12)}};
+ std::cout << "matrix 20, modulo 2" << std::endl;
+ resrhs = {Integer(0), Integer(0), Integer(0)};
+ reslhs = {{Integer(0), Integer(1), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(2), rhs, lhs, BVGauss::Result::UNIQUE, &resrhs, &reslhs);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_unique_partial)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 7
+ * --^-- ^ --^-- ^
+ * 2 0 6 4 1 0 0 3
+ * 4 0 6 3 0 0 1 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(4), Integer(3)};
+ lhs = {{Integer(2), Integer(0), Integer(6)},
+ {Integer(4), Integer(0), Integer(6)}};
+ std::cout << "matrix 21, modulo 7" << std::endl;
+ testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 7
+ * --^-- ^ --^-- ^
+ * 2 6 0 4 1 0 0 3
+ * 4 6 0 3 0 1 0 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(4), Integer(3)};
+ lhs = {{Integer(2), Integer(6), Integer(0)},
+ {Integer(4), Integer(6), Integer(0)}};
+ std::cout << "matrix 22, modulo 7" << std::endl;
+ testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_none)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 9
+ * --^--- ^
+ * 2 4 6 18 --> not coprime (no inverse)
+ * 4 5 6 24
+ * 3 1 -2 4
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(18), Integer(24), Integer(4)};
+ lhs = {{Integer(2), Integer(4), Integer(6)},
+ {Integer(4), Integer(5), Integer(6)},
+ {Integer(3), Integer(1), Integer(-2)}};
+ std::cout << "matrix 23, modulo 9" << std::endl;
+ testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::INVALID);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 59
+ * ----^--- ^
+ * 1 -2 -6 12 --> no solution
+ * 2 4 12 -17
+ * 1 -4 -12 22
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(12), Integer(-17), Integer(22)};
+ lhs = {{Integer(1), Integer(-2), Integer(-6)},
+ {Integer(2), Integer(4), Integer(12)},
+ {Integer(1), Integer(-4), Integer(-12)}};
+ std::cout << "matrix 24, modulo 59" << std::endl;
+ testGaussElimX(Integer(59), rhs, lhs, BVGauss::Result::NONE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 9
+ * ----^--- ^
+ * 2 4 6 18 --> not coprime (no inverse)
+ * 4 5 6 24
+ * 2 7 12 30
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(18), Integer(24), Integer(30)};
+ lhs = {{Integer(2), Integer(4), Integer(6)},
+ {Integer(4), Integer(5), Integer(6)},
+ {Integer(2), Integer(7), Integer(12)}};
+ std::cout << "matrix 25, modulo 9" << std::endl;
+ testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::INVALID);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_none_zero)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 0 1 1 5
+ * 0 3 5 8
+ * 0 0 5 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(2)};
+ lhs = {{Integer(0), Integer(1), Integer(1)},
+ {Integer(0), Integer(3), Integer(5)},
+ {Integer(0), Integer(0), Integer(5)}};
+ std::cout << "matrix 26, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 0 1 5
+ * 2 0 5 8
+ * 4 0 5 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(2)};
+ lhs = {{Integer(1), Integer(0), Integer(1)},
+ {Integer(2), Integer(0), Integer(5)},
+ {Integer(4), Integer(0), Integer(5)}};
+ std::cout << "matrix 27, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 1 0 5
+ * 2 3 0 8
+ * 4 0 0 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8), Integer(2)};
+ lhs = {{Integer(1), Integer(1), Integer(0)},
+ {Integer(2), Integer(3), Integer(0)},
+ {Integer(4), Integer(0), Integer(0)}};
+ std::cout << "matrix 28, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_partial1)
+{
+ std::vector<Integer> rhs, resrhs;
+ std::vector<std::vector<Integer>> lhs, reslhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(7), Integer(9)};
+ lhs = {{Integer(1), Integer(0), Integer(9)},
+ {Integer(0), Integer(1), Integer(3)}};
+ std::cout << "matrix 29, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 3 0 7 --> 1 3 0 7
+ * 0 0 1 9 0 0 1 9
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(7), Integer(9)};
+ lhs = {{Integer(1), Integer(3), Integer(0)},
+ {Integer(0), Integer(0), Integer(1)}};
+ std::cout << "matrix 30, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 1 1 5 --> 1 0 9 7
+ * 2 3 5 8 0 1 3 9
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(5), Integer(8)};
+ lhs = {{Integer(1), Integer(1), Integer(1)},
+ {Integer(2), Integer(3), Integer(5)}};
+ std::cout << "matrix 31, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo { 3, 5, 7, 11, 17, 31, 59 }
+ * ----^--- ^
+ * 2 4 6 18
+ * 4 5 6 24
+ * 2 7 12 30
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(18), Integer(24), Integer(30)};
+ lhs = {{Integer(2), Integer(4), Integer(6)},
+ {Integer(4), Integer(5), Integer(6)},
+ {Integer(2), Integer(7), Integer(12)}};
+ std::cout << "matrix 32, modulo 3" << std::endl;
+ resrhs = {Integer(0), Integer(0), Integer(0)};
+ reslhs = {{Integer(1), Integer(2), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(3), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
+ resrhs = {Integer(1), Integer(4), Integer(0)};
+ std::cout << "matrix 32, modulo 5" << std::endl;
+ reslhs = {{Integer(1), Integer(0), Integer(4)},
+ {Integer(0), Integer(1), Integer(2)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(5), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
+ std::cout << "matrix 32, modulo 7" << std::endl;
+ reslhs = {{Integer(1), Integer(0), Integer(6)},
+ {Integer(0), Integer(1), Integer(2)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(7), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
+ std::cout << "matrix 32, modulo 11" << std::endl;
+ reslhs = {{Integer(1), Integer(0), Integer(10)},
+ {Integer(0), Integer(1), Integer(2)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(11), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
+ std::cout << "matrix 32, modulo 17" << std::endl;
+ reslhs = {{Integer(1), Integer(0), Integer(16)},
+ {Integer(0), Integer(1), Integer(2)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(17), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
+ std::cout << "matrix 32, modulo 59" << std::endl;
+ reslhs = {{Integer(1), Integer(0), Integer(58)},
+ {Integer(0), Integer(1), Integer(2)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(59), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 3
+ * ----^--- ^ --^-- ^
+ * 4 6 2 18 --> 1 0 2 0
+ * 5 6 4 24 0 0 0 0
+ * 7 12 2 30 0 0 0 0
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(18), Integer(24), Integer(30)};
+ lhs = {{Integer(4), Integer(6), Integer(2)},
+ {Integer(5), Integer(6), Integer(4)},
+ {Integer(7), Integer(12), Integer(2)}};
+ std::cout << "matrix 33, modulo 3" << std::endl;
+ resrhs = {Integer(0), Integer(0), Integer(0)};
+ reslhs = {{Integer(1), Integer(0), Integer(2)},
+ {Integer(0), Integer(0), Integer(0)},
+ {Integer(0), Integer(0), Integer(0)}};
+ testGaussElimX(
+ Integer(3), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_partial2)
+{
+ std::vector<Integer> rhs;
+ std::vector<std::vector<Integer>> lhs;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs --> lhs rhs modulo 11
+ * ---^--- ^ ---^--- ^
+ * x y z w x y z w
+ * 1 2 0 6 2 1 2 0 0 1
+ * 0 0 2 2 2 0 0 1 0 10
+ * 0 0 0 1 2 0 0 0 1 2
+ * ------------------------------------------------------------------- */
+ rhs = {Integer(2), Integer(2), Integer(2)};
+ lhs = {{Integer(1), Integer(2), Integer(6), Integer(0)},
+ {Integer(0), Integer(0), Integer(2), Integer(2)},
+ {Integer(0), Integer(0), Integer(1), Integer(0)}};
+ std::cout << "matrix 34, modulo 11" << std::endl;
+ testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_unique1)
+{
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 1 1 5
+ * 2 3 5 8
+ * 4 0 5 2
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_one),
+ d_z_mul_one),
+ d_p),
+ d_five);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
+ d_z_mul_five),
+ d_p),
+ d_eight);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_four, d_z_mul_five),
+ d_p),
+ d_two);
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
+ ASSERT_EQ(res.size(), 3);
+ ASSERT_EQ(res[d_x], d_three32);
+ ASSERT_EQ(res[d_y], d_four32);
+ ASSERT_EQ(res[d_z], d_nine32);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_unique2)
+{
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 1 1 5
+ * 2 3 5 8
+ * 4 0 5 2
+ * ------------------------------------------------------------------- */
+
+ Node zextop6 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(6));
+
+ Node p = d_nodeManager->mkNode(
+ zextop6,
+ bv::utils::mkConcat(bv::utils::mkZero(6),
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS,
+ bv::utils::mkConst(20, 7),
+ bv::utils::mkConst(20, 4))));
+
+ Node x_mul_one = d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(kind::BITVECTOR_SUB, d_five, d_four),
+ d_x);
+ Node y_mul_one = d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM_TOTAL, d_one, d_five),
+ d_y);
+ Node z_mul_one =
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, bv::utils::mkOne(32), d_z);
+
+ Node x_mul_two = d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_SHL, bv::utils::mkOne(32), bv::utils::mkOne(32)),
+ d_x);
+ Node y_mul_three =
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(kind::BITVECTOR_LSHR,
+ bv::utils::mkOnes(32),
+ bv::utils::mkConst(32, 30)),
+ d_y);
+ Node z_mul_five = d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT,
+ bv::utils::mkExtract(
+ d_nodeManager->mkNode(
+ zextop6,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, d_three, d_two)),
+ 31,
+ 0),
+ d_z);
+
+ Node x_mul_four = d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UDIV_TOTAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT,
+ bv::utils::mkConst(32, 4),
+ bv::utils::mkConst(32, 5)),
+ bv::utils::mkConst(32, 4)),
+ bv::utils::mkConst(32, 6)),
+ d_x);
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, x_mul_one, y_mul_one),
+ z_mul_one),
+ p),
+ d_five);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, x_mul_two, y_mul_three),
+ z_mul_five),
+ p),
+ d_eight);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, x_mul_four, z_mul_five),
+ d_p),
+ d_two);
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
+ ASSERT_EQ(res.size(), 3);
+ ASSERT_EQ(res[d_x], d_three32);
+ ASSERT_EQ(res[d_y], d_four32);
+ ASSERT_EQ(res[d_z], d_nine32);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial1a)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_one, d_z_mul_nine),
+ d_p),
+ d_seven);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_y_mul_one, d_z_mul_three),
+ d_p),
+ d_nine);
+
+ std::vector<Node> eqs = {eq1, eq2};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 2);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_seven32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
+ d_p);
+ Node y1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nine32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
+ d_p);
+
+ Node x2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
+ d_p);
+ Node z2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
+ d_p);
+
+ Node y3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
+ d_p);
+ Node z3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
+ d_p);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(d_x) == res.end())
+ {
+ /*
+ * y z x y z x
+ * 0 9 1 7 --> 1 0 7 3
+ * 1 3 0 9 0 1 5 2
+ *
+ * z y x z y x
+ * 9 0 1 7 --> 1 0 5 2
+ * 3 1 0 9 0 1 7 3
+ */
+ ASSERT_EQ(res[d_y], y3);
+ ASSERT_EQ(res[d_z], z3);
+ }
+ else if (res.find(d_y) == res.end())
+ {
+ /*
+ * x z y x z y
+ * 1 9 0 7 --> 1 0 8 2
+ * 0 3 1 9 0 1 4 3
+ *
+ * z x y z x y
+ * 9 1 0 7 --> 1 0 4 3
+ * 3 0 1 9 0 1 8 2
+ */
+ ASSERT_EQ(res[d_x], x2);
+ ASSERT_EQ(res[d_z], z2);
+ }
+ else
+ {
+ ASSERT_EQ(res.find(d_z), res.end());
+ /*
+ * x y z x y z
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ *
+ * y x z y x z
+ * 0 1 9 7 --> 1 0 3 9
+ * 1 0 3 9 0 1 9 7
+ */
+ ASSERT_EQ(res[d_x], x1);
+ ASSERT_EQ(res[d_y], y1);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial1b)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, d_x, d_z_mul_nine),
+ d_p),
+ d_seven);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, d_y, d_z_mul_three),
+ d_p),
+ d_nine);
+
+ std::vector<Node> eqs = {eq1, eq2};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 2);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_seven32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
+ d_p);
+ Node y1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nine32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
+ d_p);
+
+ Node x2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
+ d_p);
+ Node z2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
+ d_p);
+
+ Node y3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
+ d_p);
+ Node z3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
+ d_p);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(d_x) == res.end())
+ {
+ /*
+ * y z x y z x
+ * 0 9 1 7 --> 1 0 7 3
+ * 1 3 0 9 0 1 5 2
+ *
+ * z y x z y x
+ * 9 0 1 7 --> 1 0 5 2
+ * 3 1 0 9 0 1 7 3
+ */
+ ASSERT_EQ(res[d_y], y3);
+ ASSERT_EQ(res[d_z], z3);
+ }
+ else if (res.find(d_y) == res.end())
+ {
+ /*
+ * x z y x z y
+ * 1 9 0 7 --> 1 0 8 2
+ * 0 3 1 9 0 1 4 3
+ *
+ * z x y z x y
+ * 9 1 0 7 --> 1 0 4 3
+ * 3 0 1 9 0 1 8 2
+ */
+ ASSERT_EQ(res[d_x], x2);
+ ASSERT_EQ(res[d_z], z2);
+ }
+ else
+ {
+ ASSERT_EQ(res.find(d_z), res.end());
+ /*
+ * x y z x y z
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ *
+ * y x z y x z
+ * 0 1 9 7 --> 1 0 3 9
+ * 1 0 3 9 0 1 9 7
+ */
+ ASSERT_EQ(res[d_x], x1);
+ ASSERT_EQ(res[d_y], y1);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial2)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 3 0 7 --> 1 3 0 7
+ * 0 0 1 9 0 0 1 9
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_three),
+ d_p),
+ d_seven);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM, d_z_mul_one, d_p),
+ d_nine);
+
+ std::vector<Node> eqs = {eq1, eq2};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 2);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_seven32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_eight32)),
+ d_p);
+ Node y2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_six32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_seven32)),
+ d_p);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(d_x) == res.end())
+ {
+ /*
+ * x y z x y z
+ * 1 3 0 7 --> 1 3 0 7
+ * 0 0 1 9 0 0 1 9
+ *
+ * x z y x z y
+ * 1 0 3 7 --> 1 0 3 7
+ * 0 1 0 9 0 1 0 9
+ *
+ * z x y z x y
+ * 0 1 3 7 --> 1 0 0 9
+ * 1 0 0 9 0 1 3 7
+ */
+ ASSERT_EQ(res[d_y], y2);
+ ASSERT_EQ(res[d_z], d_nine32);
+ }
+ else if (res.find(d_y) == res.end())
+ {
+ /*
+ * z y x z y x
+ * 0 3 1 7 --> 1 0 0 9
+ * 1 0 0 9 0 1 4 6
+ *
+ * y x z y x z
+ * 3 1 0 7 --> 1 4 0 6
+ * 0 0 1 9 0 0 1 9
+ *
+ * y z x y z x
+ * 3 0 1 7 --> 1 0 4 6
+ * 0 1 0 9 0 1 0 9
+ */
+ ASSERT_EQ(res[d_x], x1);
+ ASSERT_EQ(res[d_z], d_nine32);
+ }
+ else
+ {
+ ASSERT_TRUE(false);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial3)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 1 1 5 --> 1 0 9 7
+ * 2 3 5 8 0 1 3 9
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_y),
+ d_z_mul_one),
+ d_p),
+ d_five);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
+ d_z_mul_five),
+ d_p),
+ d_eight);
+
+ std::vector<Node> eqs = {eq1, eq2};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 2);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_seven32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
+ d_p);
+ Node y1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nine32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
+ d_p);
+ Node x2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
+ d_p);
+ Node z2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
+ d_p);
+ Node y3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
+ d_p);
+ Node z3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
+ d_p);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(d_x) == res.end())
+ {
+ /*
+ * y z x y z x
+ * 1 1 1 5 --> 1 0 7 3
+ * 3 5 2 8 0 1 5 2
+ *
+ * z y x z y x
+ * 1 1 1 5 --> 1 0 5 2
+ * 5 3 2 8 0 1 7 3
+ */
+ ASSERT_EQ(res[d_y], y3);
+ ASSERT_EQ(res[d_z], z3);
+ }
+ else if (res.find(d_y) == res.end())
+ {
+ /*
+ * x z y x z y
+ * 1 1 1 5 --> 1 0 8 2
+ * 2 5 3 8 0 1 4 3
+ *
+ * z x y z x y
+ * 1 1 1 5 --> 1 0 4 3
+ * 5 2 3 9 0 1 8 2
+ */
+ ASSERT_EQ(res[d_x], x2);
+ ASSERT_EQ(res[d_z], z2);
+ }
+ else
+ {
+ ASSERT_EQ(res.find(d_z), res.end());
+ /*
+ * x y z x y z
+ * 1 1 1 5 --> 1 0 9 7
+ * 2 3 5 8 0 1 3 9
+ *
+ * y x z y x z
+ * 1 1 1 5 --> 1 0 3 9
+ * 3 2 5 8 0 1 9 7
+ */
+ ASSERT_EQ(res[d_x], x1);
+ ASSERT_EQ(res[d_y], y1);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial4)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * ----^--- ^ ---^--- ^
+ * 2 4 6 18 --> 1 0 10 1
+ * 4 5 6 24 0 1 2 4
+ * 2 7 12 30 0 0 0 0
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_four),
+ d_z_mul_six),
+ d_p),
+ d_eighteen);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_four, d_y_mul_five),
+ d_z_mul_six),
+ d_p),
+ d_twentyfour);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_seven),
+ d_z_mul_twelve),
+ d_p),
+ d_thirty);
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 2);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_one32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_one32)),
+ d_p);
+ Node y1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_four32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_nine32)),
+ d_p);
+ Node x2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_five32)),
+ d_p);
+ Node z2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_five32)),
+ d_p);
+ Node y3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_six32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_nine32)),
+ d_p);
+ Node z3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_ten32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_one32)),
+ d_p);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(d_x) == res.end())
+ {
+ /*
+ * y z x y z x
+ * 4 6 2 18 --> 1 0 2 6
+ * 5 6 4 24 0 1 10 10
+ * 7 12 2 30 0 0 0 0
+ *
+ * z y x z y x
+ * 6 4 2 18 --> 1 0 10 10
+ * 6 5 4 24 0 1 2 6
+ * 12 12 2 30 0 0 0 0
+ *
+ */
+ ASSERT_EQ(res[d_y], y3);
+ ASSERT_EQ(res[d_z], z3);
+ }
+ else if (res.find(d_y) == res.end())
+ {
+ /*
+ * x z y x z y
+ * 2 6 4 18 --> 1 0 6 3
+ * 4 6 5 24 0 1 6 2
+ * 2 12 7 30 0 0 0 0
+ *
+ * z x y z x y
+ * 6 2 4 18 --> 1 0 6 2
+ * 6 4 5 24 0 1 6 3
+ * 12 2 12 30 0 0 0 0
+ *
+ */
+ ASSERT_EQ(res[d_x], x2);
+ ASSERT_EQ(res[d_z], z2);
+ }
+ else
+ {
+ ASSERT_EQ(res.find(d_z), res.end());
+ /*
+ * x y z x y z
+ * 2 4 6 18 --> 1 0 10 1
+ * 4 5 6 24 0 1 2 4
+ * 2 7 12 30 0 0 0 0
+ *
+ * y x z y x z
+ * 4 2 6 18 --> 1 0 2 49
+ * 5 4 6 24 0 1 10 1
+ * 7 2 12 30 0 0 0 0
+ */
+ ASSERT_EQ(res[d_x], x1);
+ ASSERT_EQ(res[d_y], y1);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial5)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 3
+ * ----^--- ^ --^-- ^
+ * 2 4 6 18 --> 1 2 0 0
+ * 4 5 6 24 0 0 0 0
+ * 2 7 12 30 0 0 0 0
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_four),
+ d_z_mul_six),
+ d_three),
+ d_eighteen);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_four, d_y_mul_five),
+ d_z_mul_six),
+ d_three),
+ d_twentyfour);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_seven),
+ d_z_mul_twelve),
+ d_three),
+ d_thirty);
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 1);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_one32),
+ d_three);
+ Node y2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_one32),
+ d_three);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(d_x) == res.end())
+ {
+ /*
+ * y x z y x z
+ * 4 2 6 18 --> 1 2 0 0
+ * 5 4 6 24 0 0 0 0
+ * 7 2 12 30 0 0 0 0
+ *
+ * y z x y z x
+ * 4 6 2 18 --> 1 0 2 0
+ * 5 6 4 24 0 0 0 0
+ * 7 12 2 30 0 0 0 0
+ *
+ * z y x z y x
+ * 6 4 2 18 --> 0 1 2 0
+ * 6 5 4 24 0 0 0 0
+ * 12 12 2 30 0 0 0 0
+ *
+ */
+ ASSERT_EQ(res[d_y], y2);
+ }
+ else if (res.find(d_y) == res.end())
+ {
+ /*
+ * x y z x y z
+ * 2 4 6 18 --> 1 2 0 0
+ * 4 5 6 24 0 0 0 0
+ * 2 7 12 30 0 0 0 0
+ *
+ * x z y x z y
+ * 2 6 4 18 --> 1 0 2 0
+ * 4 6 5 24 0 0 0 0
+ * 2 12 7 30 0 0 0 0
+ *
+ * z x y z x y
+ * 6 2 4 18 --> 0 1 2 0
+ * 6 4 5 24 0 0 0 0
+ * 12 2 12 30 0 0 0 0
+ *
+ */
+ ASSERT_EQ(res[d_x], x1);
+ }
+ else
+ {
+ ASSERT_TRUE(false);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial6)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs --> lhs rhs modulo 11
+ * ---^--- ^ ---^--- ^
+ * x y z w x y z w
+ * 1 2 0 6 2 1 2 0 6 2
+ * 0 0 2 2 2 0 0 1 1 1
+ * 0 0 0 1 2 0 0 0 1 2
+ * ------------------------------------------------------------------- */
+
+ Node y_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_two);
+ Node z_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two);
+ Node w = bv::utils::mkConcat(
+ d_zero, d_nodeManager->mkVar("w", d_nodeManager->mkBitVectorType(16)));
+ Node w_mul_six = d_nodeManager->mkNode(kind::BITVECTOR_MULT, w, d_six);
+ Node w_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, w, d_two);
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_one, y_mul_two),
+ w_mul_six),
+ d_p),
+ d_two);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, z_mul_two, w_mul_two),
+ d_p),
+ d_two);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL, d_nodeManager->mkNode(kind::BITVECTOR_UREM, w, d_p), d_two);
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 3);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_one32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_nine32)),
+ d_p);
+ Node z1 = d_ten32;
+ Node w1 = d_two32;
+
+ Node y2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_six32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_five32)),
+ d_p);
+ Node z2 = d_ten32;
+ Node w2 = d_two32;
+
+ /* result depends on order of variables in matrix */
+ if (res.find(d_x) == res.end())
+ {
+ ASSERT_EQ(res[d_y], y2);
+ ASSERT_EQ(res[d_z], z2);
+ ASSERT_EQ(res[w], w2);
+ }
+ else if (res.find(d_y) == res.end())
+ {
+ ASSERT_EQ(res[d_x], x1);
+ ASSERT_EQ(res[d_z], z1);
+ ASSERT_EQ(res[w], w1);
+ }
+ else
+ {
+ ASSERT_TRUE(false);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_with_expr_partial)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ * ------------------------------------------------------------------- */
+
+ Node zero = bv::utils::mkZero(8);
+ Node xx = d_nodeManager->mkVar("xx", d_nodeManager->mkBitVectorType(8));
+ Node yy = d_nodeManager->mkVar("yy", d_nodeManager->mkBitVectorType(8));
+ Node zz = d_nodeManager->mkVar("zz", d_nodeManager->mkBitVectorType(8));
+
+ Node x = bv::utils::mkConcat(
+ d_zero,
+ bv::utils::mkConcat(
+ zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, xx), 7, 0)));
+ Node y = bv::utils::mkConcat(
+ d_zero,
+ bv::utils::mkConcat(
+ zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, yy), 7, 0)));
+ Node z = bv::utils::mkConcat(
+ d_zero,
+ bv::utils::mkConcat(
+ zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, zz), 7, 0)));
+
+ Node x_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, d_one32);
+ Node nine_mul_z = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_nine32, z);
+ Node one_mul_y = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_one, y);
+ Node z_mul_three = d_nodeManager->mkNode(kind::BITVECTOR_MULT, z, d_three);
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, x_mul_one, nine_mul_z),
+ d_p),
+ d_seven);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, one_mul_y, z_mul_three),
+ d_p),
+ d_nine);
+
+ std::vector<Node> eqs = {eq1, eq2};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 2);
+
+ x = Rewriter::rewrite(x);
+ y = Rewriter::rewrite(y);
+ z = Rewriter::rewrite(z);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_seven32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, z, d_two32)),
+ d_p);
+ Node y1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nine32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, z, d_eight32)),
+ d_p);
+
+ Node x2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, y, d_three32)),
+ d_p);
+ Node z2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, y, d_seven32)),
+ d_p);
+
+ Node y3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, d_four32)),
+ d_p);
+ Node z3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, d_six32)),
+ d_p);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(x) == res.end())
+ {
+ /*
+ * y z x y z x
+ * 0 9 1 7 --> 1 0 7 3
+ * 1 3 0 9 0 1 5 2
+ *
+ * z y x z y x
+ * 9 0 1 7 --> 1 0 5 2
+ * 3 1 0 9 0 1 7 3
+ */
+ ASSERT_EQ(res[Rewriter::rewrite(y)], y3);
+ ASSERT_EQ(res[Rewriter::rewrite(z)], z3);
+ }
+ else if (res.find(y) == res.end())
+ {
+ /*
+ * x z y x z y
+ * 1 9 0 7 --> 1 0 8 2
+ * 0 3 1 9 0 1 4 3
+ *
+ * z x y z x y
+ * 9 1 0 7 --> 1 0 4 3
+ * 3 0 1 9 0 1 8 2
+ */
+ ASSERT_EQ(res[x], x2);
+ ASSERT_EQ(res[z], z2);
+ }
+ else
+ {
+ ASSERT_EQ(res.find(z), res.end());
+ /*
+ * x y z x y z
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ *
+ * y x z y x z
+ * 0 1 9 7 --> 1 0 3 9
+ * 1 0 3 9 0 1 9 7
+ */
+ ASSERT_EQ(res[x], x1);
+ ASSERT_EQ(res[y], y1);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_nary_partial)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ * ------------------------------------------------------------------- */
+
+ Node zero = bv::utils::mkZero(8);
+ Node xx = d_nodeManager->mkVar("xx", d_nodeManager->mkBitVectorType(8));
+ Node yy = d_nodeManager->mkVar("yy", d_nodeManager->mkBitVectorType(8));
+ Node zz = d_nodeManager->mkVar("zz", d_nodeManager->mkBitVectorType(8));
+
+ Node x = bv::utils::mkConcat(
+ d_zero,
+ bv::utils::mkConcat(
+ zero,
+ bv::utils::mkExtract(
+ d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, zero, xx), 7, 0)));
+ Node y = bv::utils::mkConcat(
+ d_zero,
+ bv::utils::mkConcat(
+ zero,
+ bv::utils::mkExtract(
+ d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, zero, yy), 7, 0)));
+ Node z = bv::utils::mkConcat(
+ d_zero,
+ bv::utils::mkConcat(
+ zero,
+ bv::utils::mkExtract(
+ d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, zero, zz), 7, 0)));
+
+ NodeBuilder<> nbx(d_nodeManager.get(), kind::BITVECTOR_MULT);
+ nbx << d_x << d_one << x;
+ Node x_mul_one_mul_xx = nbx.constructNode();
+ NodeBuilder<> nby(d_nodeManager.get(), kind::BITVECTOR_MULT);
+ nby << d_y << y << d_one;
+ Node y_mul_yy_mul_one = nby.constructNode();
+ NodeBuilder<> nbz(d_nodeManager.get(), kind::BITVECTOR_MULT);
+ nbz << d_three << d_z << z;
+ Node three_mul_z_mul_zz = nbz.constructNode();
+ NodeBuilder<> nbz2(d_nodeManager.get(), kind::BITVECTOR_MULT);
+ nbz2 << d_z << d_nine << z;
+ Node z_mul_nine_mul_zz = nbz2.constructNode();
+
+ Node x_mul_xx = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, x);
+ Node y_mul_yy = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, y);
+ Node z_mul_zz = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, z);
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, x_mul_one_mul_xx, z_mul_nine_mul_zz),
+ d_p),
+ d_seven);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, y_mul_yy_mul_one, three_mul_z_mul_zz),
+ d_p),
+ d_nine);
+
+ std::vector<Node> eqs = {eq1, eq2};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
+ ASSERT_EQ(res.size(), 2);
+
+ x_mul_xx = Rewriter::rewrite(x_mul_xx);
+ y_mul_yy = Rewriter::rewrite(y_mul_yy);
+ z_mul_zz = Rewriter::rewrite(z_mul_zz);
+
+ Node x1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_seven32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, z_mul_zz, d_two32)),
+ d_p);
+ Node y1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nine32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, z_mul_zz, d_eight32)),
+ d_p);
+
+ Node x2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, y_mul_yy, d_three32)),
+ d_p);
+ Node z2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, y_mul_yy, d_seven32)),
+ d_p);
+
+ Node y3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x_mul_xx, d_four32)),
+ d_p);
+ Node z3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x_mul_xx, d_six32)),
+ d_p);
+
+ /* result depends on order of variables in matrix */
+ if (res.find(x_mul_xx) == res.end())
+ {
+ /*
+ * y z x y z x
+ * 0 9 1 7 --> 1 0 7 3
+ * 1 3 0 9 0 1 5 2
+ *
+ * z y x z y x
+ * 9 0 1 7 --> 1 0 5 2
+ * 3 1 0 9 0 1 7 3
+ */
+ ASSERT_EQ(res[y_mul_yy], y3);
+ ASSERT_EQ(res[z_mul_zz], z3);
+ }
+ else if (res.find(y_mul_yy) == res.end())
+ {
+ /*
+ * x z y x z y
+ * 1 9 0 7 --> 1 0 8 2
+ * 0 3 1 9 0 1 4 3
+ *
+ * z x y z x y
+ * 9 1 0 7 --> 1 0 4 3
+ * 3 0 1 9 0 1 8 2
+ */
+ ASSERT_EQ(res[x_mul_xx], x2);
+ ASSERT_EQ(res[z_mul_zz], z2);
+ }
+ else
+ {
+ ASSERT_EQ(res.find(z_mul_zz), res.end());
+ /*
+ * x y z x y z
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ *
+ * y x z y x z
+ * 0 1 9 7 --> 1 0 3 9
+ * 1 0 3 9 0 1 9 7
+ */
+ ASSERT_EQ(res[x_mul_xx], x1);
+ ASSERT_EQ(res[y_mul_yy], y1);
+ }
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_not_invalid1)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * 3x / 2z = 4 modulo 11
+ * 2x % 5y = 2
+ * y O z = 5
+ * ------------------------------------------------------------------- */
+
+ Node n1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UDIV_TOTAL,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_three, d_x),
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_two, d_y));
+ Node n2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM_TOTAL,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_two, d_x),
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_five, d_y));
+
+ Node n3 = bv::utils::mkConcat(
+ d_zero,
+ bv::utils::mkExtract(
+ d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, d_y, d_z), 15, 0));
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM, n1, d_p),
+ d_four);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL, d_nodeManager->mkNode(kind::BITVECTOR_UREM, n2, d_p), d_two);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM, n3, d_p),
+ d_five);
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
+ ASSERT_EQ(res.size(), 3);
+
+ ASSERT_EQ(res[n1], d_four32);
+ ASSERT_EQ(res[n2], d_two32);
+ ASSERT_EQ(res[n3], d_five32);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_not_invalid2)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * x*y = 4 modulo 11
+ * x*y*z = 2
+ * 2*x*y + 2*z = 9
+ * ------------------------------------------------------------------- */
+
+ Node zero32 = bv::utils::mkZero(32);
+
+ Node x = bv::utils::mkConcat(
+ zero32, d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16)));
+ Node y = bv::utils::mkConcat(
+ zero32, d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16)));
+ Node z = bv::utils::mkConcat(
+ zero32, d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16)));
+
+ Node n1 = d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y);
+ Node n2 =
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
+ z);
+ Node n3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
+ bv::utils::mkConcat(d_zero, d_two)),
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConcat(d_zero, d_two), z));
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM, n1, bv::utils::mkConcat(d_zero, d_p)),
+ bv::utils::mkConcat(d_zero, d_four));
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM, n2, bv::utils::mkConcat(d_zero, d_p)),
+ bv::utils::mkConcat(d_zero, d_two));
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM, n3, bv::utils::mkConcat(d_zero, d_p)),
+ bv::utils::mkConcat(d_zero, d_nine));
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
+ ASSERT_EQ(res.size(), 3);
+
+ n1 = Rewriter::rewrite(n1);
+ n2 = Rewriter::rewrite(n2);
+ z = Rewriter::rewrite(z);
+
+ ASSERT_EQ(res[n1], bv::utils::mkConst(48, 4));
+ ASSERT_EQ(res[n2], bv::utils::mkConst(48, 2));
+
+ Integer twoxy = (res[n1].getConst<BitVector>().getValue() * Integer(2))
+ .euclidianDivideRemainder(Integer(48));
+ Integer twoz = (res[z].getConst<BitVector>().getValue() * Integer(2))
+ .euclidianDivideRemainder(Integer(48));
+ Integer r = (twoxy + twoz).euclidianDivideRemainder(Integer(11));
+ ASSERT_EQ(r, Integer(9));
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_invalid)
+{
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ BVGauss::Result ret;
+
+ /* -------------------------------------------------------------------
+ * x*y = 4 modulo 11
+ * x*y*z = 2
+ * 2*x*y = 9
+ * ------------------------------------------------------------------- */
+
+ Node zero32 = bv::utils::mkZero(32);
+
+ Node x = bv::utils::mkConcat(
+ zero32, d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16)));
+ Node y = bv::utils::mkConcat(
+ zero32, d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16)));
+ Node z = bv::utils::mkConcat(
+ zero32, d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16)));
+
+ Node n1 = d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y);
+ Node n2 =
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
+ z);
+ Node n3 =
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
+ bv::utils::mkConcat(d_zero, d_two));
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM, n1, bv::utils::mkConcat(d_zero, d_p)),
+ bv::utils::mkConcat(d_zero, d_four));
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM, n2, bv::utils::mkConcat(d_zero, d_p)),
+ bv::utils::mkConcat(d_zero, d_two));
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM, n3, bv::utils::mkConcat(d_zero, d_p)),
+ bv::utils::mkConcat(d_zero, d_nine));
+
+ std::vector<Node> eqs = {eq1, eq2, eq3};
+ ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
+ ASSERT_EQ(ret, BVGauss::Result::INVALID);
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_unique1)
+{
+ /* -------------------------------------------------------------------
+ * lhs rhs modulo 11
+ * --^-- ^
+ * 1 1 1 5
+ * 2 3 5 8
+ * 4 0 5 2
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_one),
+ d_z_mul_one),
+ d_p),
+ d_five);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
+ d_z_mul_five),
+ d_p),
+ d_eight);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_four, d_z_mul_five),
+ d_p),
+ d_two);
+
+ Node a = d_nodeManager->mkNode(
+ kind::AND, d_nodeManager->mkNode(kind::AND, eq1, eq2), eq3);
+
+ AssertionPipeline apipe;
+ apipe.push_back(a);
+ passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
+ ASSERT_EQ(pres, PreprocessingPassResult::NO_CONFLICT);
+ Node resx = d_nodeManager->mkNode(
+ kind::EQUAL, d_x, d_nodeManager->mkConst<BitVector>(BitVector(32, 3u)));
+ Node resy = d_nodeManager->mkNode(
+ kind::EQUAL, d_y, d_nodeManager->mkConst<BitVector>(BitVector(32, 4u)));
+ Node resz = d_nodeManager->mkNode(
+ kind::EQUAL, d_z, d_nodeManager->mkConst<BitVector>(BitVector(32, 9u)));
+ ASSERT_EQ(apipe.size(), 4);
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resx), apipe.end());
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resy), apipe.end());
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resz), apipe.end());
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_unique2)
+{
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 1 1 5 1 0 0 3
+ * 2 3 5 8 0 1 0 4
+ * 4 0 5 2 0 0 1 9
+ *
+ * lhs rhs lhs rhs modulo 7
+ * --^-- ^ --^-- ^
+ * 2 6 0 4 1 0 0 3
+ * 4 6 0 3 0 1 0 2
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_one),
+ d_z_mul_one),
+ d_p),
+ d_five);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
+ d_z_mul_five),
+ d_p),
+ d_eight);
+
+ Node eq3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_four, d_z_mul_five),
+ d_p),
+ d_two);
+
+ Node y_mul_six = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_six);
+
+ Node eq4 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, y_mul_six),
+ d_seven),
+ d_four);
+
+ Node eq5 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(kind::BITVECTOR_PLUS, d_x_mul_four, y_mul_six),
+ d_seven),
+ d_three);
+
+ Node a = d_nodeManager->mkNode(
+ kind::AND, d_nodeManager->mkNode(kind::AND, eq1, eq2), eq3);
+
+ AssertionPipeline apipe;
+ apipe.push_back(a);
+ apipe.push_back(eq4);
+ apipe.push_back(eq5);
+ passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
+ ASSERT_EQ(pres, PreprocessingPassResult::NO_CONFLICT);
+ Node resx1 = d_nodeManager->mkNode(
+ kind::EQUAL, d_x, d_nodeManager->mkConst<BitVector>(BitVector(32, 3u)));
+ Node resx2 = d_nodeManager->mkNode(
+ kind::EQUAL, d_x, d_nodeManager->mkConst<BitVector>(BitVector(32, 3u)));
+ Node resy1 = d_nodeManager->mkNode(
+ kind::EQUAL, d_y, d_nodeManager->mkConst<BitVector>(BitVector(32, 4u)));
+ Node resy2 = d_nodeManager->mkNode(
+ kind::EQUAL, d_y, d_nodeManager->mkConst<BitVector>(BitVector(32, 2u)));
+ Node resz = d_nodeManager->mkNode(
+ kind::EQUAL, d_z, d_nodeManager->mkConst<BitVector>(BitVector(32, 9u)));
+ ASSERT_EQ(apipe.size(), 8);
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resx1), apipe.end());
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resx2), apipe.end());
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resy1), apipe.end());
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resy2), apipe.end());
+ ASSERT_NE(std::find(apipe.begin(), apipe.end(), resz), apipe.end());
+}
+
+TEST_F(TestPPWhiteBVGauss, elim_rewrite_partial)
+{
+ /* -------------------------------------------------------------------
+ * lhs rhs lhs rhs modulo 11
+ * --^-- ^ --^-- ^
+ * 1 0 9 7 --> 1 0 9 7
+ * 0 1 3 9 0 1 3 9
+ * ------------------------------------------------------------------- */
+
+ Node eq1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_x_mul_one, d_z_mul_nine),
+ d_p),
+ d_seven);
+
+ Node eq2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS, d_y_mul_one, d_z_mul_three),
+ d_p),
+ d_nine);
+
+ AssertionPipeline apipe;
+ apipe.push_back(eq1);
+ apipe.push_back(eq2);
+ passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
+ std::unordered_map<Node, Node, NodeHashFunction> res;
+ PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
+ ASSERT_EQ(pres, PreprocessingPassResult::NO_CONFLICT);
+ ASSERT_EQ(apipe.size(), 4);
+
+ Node resx1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_x,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_seven32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
+ d_p));
+ Node resy1 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_y,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nine32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
+ d_p));
+
+ Node resx2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_x,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
+ d_p));
+ Node resz2 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_z,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
+ d_p));
+
+ Node resy3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_y,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_three32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
+ d_p));
+ Node resz3 = d_nodeManager->mkNode(
+ kind::EQUAL,
+ d_z,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_UREM,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_two32,
+ d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
+ d_p));
+
+ bool fx1 = std::find(apipe.begin(), apipe.end(), resx1) != apipe.end();
+ bool fy1 = std::find(apipe.begin(), apipe.end(), resy1) != apipe.end();
+ bool fx2 = std::find(apipe.begin(), apipe.end(), resx2) != apipe.end();
+ bool fz2 = std::find(apipe.begin(), apipe.end(), resz2) != apipe.end();
+ bool fy3 = std::find(apipe.begin(), apipe.end(), resy3) != apipe.end();
+ bool fz3 = std::find(apipe.begin(), apipe.end(), resz3) != apipe.end();
+
+ /* result depends on order of variables in matrix */
+ ASSERT_TRUE((fx1 && fy1) || (fx2 && fz2) || (fy3 && fz3));
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw1)
+{
+ ASSERT_EQ(BVGauss::getMinBwExpr(bv::utils::mkConst(32, 11)), 4);
+
+ ASSERT_EQ(BVGauss::getMinBwExpr(d_p), 4);
+ ASSERT_EQ(BVGauss::getMinBwExpr(d_x), 16);
+
+ Node extp = bv::utils::mkExtract(d_p, 4, 0);
+ ASSERT_EQ(BVGauss::getMinBwExpr(extp), 4);
+ Node extx = bv::utils::mkExtract(d_x, 4, 0);
+ ASSERT_EQ(BVGauss::getMinBwExpr(extx), 5);
+
+ Node zextop8 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(8));
+ Node zextop16 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(16));
+ Node zextop32 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(32));
+ Node zextop40 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(40));
+
+ Node zext40p = d_nodeManager->mkNode(zextop8, d_p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext40p), 4);
+ Node zext40x = d_nodeManager->mkNode(zextop8, d_x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext40x), 16);
+
+ Node zext48p = d_nodeManager->mkNode(zextop16, d_p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext48p), 4);
+ Node zext48x = d_nodeManager->mkNode(zextop16, d_x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext48x), 16);
+
+ Node p8 = d_nodeManager->mkConst<BitVector>(BitVector(8, 11u));
+ Node x8 = d_nodeManager->mkVar("x8", d_nodeManager->mkBitVectorType(8));
+
+ Node zext48p8 = d_nodeManager->mkNode(zextop40, p8);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext48p8), 4);
+ Node zext48x8 = d_nodeManager->mkNode(zextop40, x8);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext48x8), 8);
+
+ Node mult1p = d_nodeManager->mkNode(kind::BITVECTOR_MULT, extp, extp);
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult1p), 5);
+ Node mult1x = d_nodeManager->mkNode(kind::BITVECTOR_MULT, extx, extx);
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult1x), 0);
+
+ Node mult2p = d_nodeManager->mkNode(kind::BITVECTOR_MULT, zext40p, zext40p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult2p), 7);
+ Node mult2x = d_nodeManager->mkNode(kind::BITVECTOR_MULT, zext40x, zext40x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult2x), 32);
+
+ NodeBuilder<> nbmult3p(kind::BITVECTOR_MULT);
+ nbmult3p << zext48p << zext48p << zext48p;
+ Node mult3p = nbmult3p;
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult3p), 11);
+ NodeBuilder<> nbmult3x(kind::BITVECTOR_MULT);
+ nbmult3x << zext48x << zext48x << zext48x;
+ Node mult3x = nbmult3x;
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult3x), 48);
+
+ NodeBuilder<> nbmult4p(kind::BITVECTOR_MULT);
+ nbmult4p << zext48p << zext48p8 << zext48p;
+ Node mult4p = nbmult4p;
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult4p), 11);
+ NodeBuilder<> nbmult4x(kind::BITVECTOR_MULT);
+ nbmult4x << zext48x << zext48x8 << zext48x;
+ Node mult4x = nbmult4x;
+ ASSERT_EQ(BVGauss::getMinBwExpr(mult4x), 40);
+
+ Node concat1p = bv::utils::mkConcat(d_p, zext48p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(concat1p), 52);
+ Node concat1x = bv::utils::mkConcat(d_x, zext48x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(concat1x), 64);
+
+ Node concat2p = bv::utils::mkConcat(bv::utils::mkZero(16), zext48p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(concat2p), 4);
+ Node concat2x = bv::utils::mkConcat(bv::utils::mkZero(16), zext48x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(concat2x), 16);
+
+ Node udiv1p =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48p, zext48p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(udiv1p), 1);
+ Node udiv1x =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48x, zext48x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(udiv1x), 48);
+
+ Node udiv2p =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48p, zext48p8);
+ ASSERT_EQ(BVGauss::getMinBwExpr(udiv2p), 1);
+ Node udiv2x =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48x, zext48x8);
+ ASSERT_EQ(BVGauss::getMinBwExpr(udiv2x), 48);
+
+ Node urem1p =
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48p, zext48p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(urem1p), 1);
+ Node urem1x =
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48x, zext48x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(urem1x), 1);
+
+ Node urem2p =
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48p, zext48p8);
+ ASSERT_EQ(BVGauss::getMinBwExpr(urem2p), 1);
+ Node urem2x =
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48x, zext48x8);
+ ASSERT_EQ(BVGauss::getMinBwExpr(urem2x), 16);
+
+ Node urem3p =
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48p8, zext48p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(urem3p), 1);
+ Node urem3x =
+ d_nodeManager->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48x8, zext48x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(urem3x), 8);
+
+ Node add1p = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, extp, extp);
+ ASSERT_EQ(BVGauss::getMinBwExpr(add1p), 5);
+ Node add1x = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, extx, extx);
+ ASSERT_EQ(BVGauss::getMinBwExpr(add1x), 0);
+
+ Node add2p = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, zext40p, zext40p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(add2p), 5);
+ Node add2x = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, zext40x, zext40x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(add2x), 17);
+
+ Node add3p = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, zext48p8, zext48p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(add3p), 5);
+ Node add3x = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, zext48x8, zext48x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(add3x), 17);
+
+ NodeBuilder<> nbadd4p(kind::BITVECTOR_PLUS);
+ nbadd4p << zext48p << zext48p << zext48p;
+ Node add4p = nbadd4p;
+ ASSERT_EQ(BVGauss::getMinBwExpr(add4p), 6);
+ NodeBuilder<> nbadd4x(kind::BITVECTOR_PLUS);
+ nbadd4x << zext48x << zext48x << zext48x;
+ Node add4x = nbadd4x;
+ ASSERT_EQ(BVGauss::getMinBwExpr(add4x), 18);
+
+ NodeBuilder<> nbadd5p(kind::BITVECTOR_PLUS);
+ nbadd5p << zext48p << zext48p8 << zext48p;
+ Node add5p = nbadd5p;
+ ASSERT_EQ(BVGauss::getMinBwExpr(add5p), 6);
+ NodeBuilder<> nbadd5x(kind::BITVECTOR_PLUS);
+ nbadd5x << zext48x << zext48x8 << zext48x;
+ Node add5x = nbadd5x;
+ ASSERT_EQ(BVGauss::getMinBwExpr(add5x), 18);
+
+ NodeBuilder<> nbadd6p(kind::BITVECTOR_PLUS);
+ nbadd6p << zext48p << zext48p << zext48p << zext48p;
+ Node add6p = nbadd6p;
+ ASSERT_EQ(BVGauss::getMinBwExpr(add6p), 6);
+ NodeBuilder<> nbadd6x(kind::BITVECTOR_PLUS);
+ nbadd6x << zext48x << zext48x << zext48x << zext48x;
+ Node add6x = nbadd6x;
+ ASSERT_EQ(BVGauss::getMinBwExpr(add6x), 18);
+
+ Node not1p = d_nodeManager->mkNode(kind::BITVECTOR_NOT, zext40p);
+ ASSERT_EQ(BVGauss::getMinBwExpr(not1p), 40);
+ Node not1x = d_nodeManager->mkNode(kind::BITVECTOR_NOT, zext40x);
+ ASSERT_EQ(BVGauss::getMinBwExpr(not1x), 40);
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw2)
+{
+ /* ((_ zero_extend 5)
+ * ((_ extract 7 0) ((_ zero_extend 15) d_p))) */
+ Node zextop5 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
+ Node zextop15 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
+ Node zext1 = d_nodeManager->mkNode(zextop15, d_p);
+ Node ext = bv::utils::mkExtract(zext1, 7, 0);
+ Node zext2 = d_nodeManager->mkNode(zextop5, ext);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext2), 4);
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw3a)
+{
+ /* ((_ zero_extend 5)
+ * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x z)))
+ * ((_ extract 4 0) z))) */
+ Node x = d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16));
+ Node y = d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16));
+ Node z = d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16));
+ Node zextop5 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
+ Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, x, y);
+ Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
+ Node ext1 = bv::utils::mkExtract(zext1, 4, 0);
+ Node ext2 = bv::utils::mkExtract(z, 4, 0);
+ Node udiv2 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1, ext2);
+ Node zext2 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext2), 5);
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw3b)
+{
+ /* ((_ zero_extend 5)
+ * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x z)))
+ * ((_ extract 4 0) z))) */
+ Node zextop5 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
+ Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, d_x, d_y);
+ Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
+ Node ext1 = bv::utils::mkExtract(zext1, 4, 0);
+ Node ext2 = bv::utils::mkExtract(d_z, 4, 0);
+ Node udiv2 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1, ext2);
+ Node zext2 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2);
+ ASSERT_EQ(BVGauss::getMinBwExpr(zext2), 5);
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw4a)
+{
+ /* (bvadd
+ * ((_ zero_extend 5)
+ * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x y)))
+ * ((_ extract 4 0) z)))
+ * ((_ zero_extend 7)
+ * (bvudiv ((_ extract 2 0) ((_ zero_extend 5) (bvudiv x y)))
+ * ((_ extract 2 0) z))) */
+ Node x = d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16));
+ Node y = d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16));
+ Node z = d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16));
+ Node zextop5 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
+ Node zextop7 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(7));
+
+ Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, x, y);
+ Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
+
+ Node ext1_1 = bv::utils::mkExtract(zext1, 4, 0);
+ Node ext2_1 = bv::utils::mkExtract(z, 4, 0);
+ Node udiv2_1 =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_1, ext2_1);
+ Node zext2_1 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2_1);
+
+ Node ext1_2 = bv::utils::mkExtract(zext1, 2, 0);
+ Node ext2_2 = bv::utils::mkExtract(z, 2, 0);
+ Node udiv2_2 =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_2, ext2_2);
+ Node zext2_2 = d_nodeManager->mkNode(zextop7, udiv2_2);
+
+ Node plus = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, zext2_1, zext2_2);
+
+ ASSERT_EQ(BVGauss::getMinBwExpr(plus), 6);
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw4b)
+{
+ /* (bvadd
+ * ((_ zero_extend 5)
+ * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x y)))
+ * ((_ extract 4 0) z)))
+ * ((_ zero_extend 7)
+ * (bvudiv ((_ extract 2 0) ((_ zero_extend 5) (bvudiv x y)))
+ * ((_ extract 2 0) z))) */
+ Node zextop5 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
+ Node zextop7 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(7));
+
+ Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, d_x, d_y);
+ Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
+
+ Node ext1_1 = bv::utils::mkExtract(zext1, 4, 0);
+ Node ext2_1 = bv::utils::mkExtract(d_z, 4, 0);
+ Node udiv2_1 =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_1, ext2_1);
+ Node zext2_1 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2_1);
+
+ Node ext1_2 = bv::utils::mkExtract(zext1, 2, 0);
+ Node ext2_2 = bv::utils::mkExtract(d_z, 2, 0);
+ Node udiv2_2 =
+ d_nodeManager->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_2, ext2_2);
+ Node zext2_2 = d_nodeManager->mkNode(zextop7, udiv2_2);
+
+ Node plus = d_nodeManager->mkNode(kind::BITVECTOR_PLUS, zext2_1, zext2_2);
+
+ ASSERT_EQ(BVGauss::getMinBwExpr(plus), 6);
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw5a)
+{
+ /* (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd (bvmul (_ bv86 13)
+ * ((_ zero_extend 5)
+ * ((_ extract 7 0) ((_ zero_extend 15) x))))
+ * (bvmul (_ bv41 13)
+ * ((_ zero_extend 5)
+ * ((_ extract 7 0) ((_ zero_extend 15) y)))))
+ * (bvmul (_ bv37 13)
+ * ((_ zero_extend 5)
+ * ((_ extract 7 0) ((_ zero_extend 15) z)))))
+ * (bvmul (_ bv170 13)
+ * ((_ zero_extend 5)
+ * ((_ extract 7 0) ((_ zero_extend 15) u)))))
+ * (bvmul (_ bv112 13)
+ * ((_ zero_extend 5)
+ * ((_ extract 7 0) ((_ zero_extend 15) v)))))
+ * (bvmul (_ bv195 13) ((_ zero_extend 5) ((_ extract 15 8) s))))
+ * (bvmul (_ bv124 13) ((_ zero_extend 5) ((_ extract 7 0) s))))
+ * (bvmul (_ bv83 13)
+ * ((_ zero_extend 5) ((_ extract 7 0) ((_ zero_extend 15) w)))))
+ */
+ Node x = bv::utils::mkVar(1);
+ Node y = bv::utils::mkVar(1);
+ Node z = bv::utils::mkVar(1);
+ Node u = bv::utils::mkVar(1);
+ Node v = bv::utils::mkVar(1);
+ Node w = bv::utils::mkVar(1);
+ Node s = bv::utils::mkVar(16);
+
+ Node zextop5 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
+ Node zextop15 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
+
+ Node zext15x = d_nodeManager->mkNode(zextop15, x);
+ Node zext15y = d_nodeManager->mkNode(zextop15, y);
+ Node zext15z = d_nodeManager->mkNode(zextop15, z);
+ Node zext15u = d_nodeManager->mkNode(zextop15, u);
+ Node zext15v = d_nodeManager->mkNode(zextop15, v);
+ Node zext15w = d_nodeManager->mkNode(zextop15, w);
+
+ Node ext7x = bv::utils::mkExtract(zext15x, 7, 0);
+ Node ext7y = bv::utils::mkExtract(zext15y, 7, 0);
+ Node ext7z = bv::utils::mkExtract(zext15z, 7, 0);
+ Node ext7u = bv::utils::mkExtract(zext15u, 7, 0);
+ Node ext7v = bv::utils::mkExtract(zext15v, 7, 0);
+ Node ext7w = bv::utils::mkExtract(zext15w, 7, 0);
+ Node ext7s = bv::utils::mkExtract(s, 7, 0);
+ Node ext15s = bv::utils::mkExtract(s, 15, 8);
+
+ Node xx = bv::utils::mkConcat(bv::utils::mkZero(5), ext7x);
+ Node yy = bv::utils::mkConcat(bv::utils::mkZero(5), ext7y);
+ Node zz = bv::utils::mkConcat(bv::utils::mkZero(5), ext7z);
+ Node uu = bv::utils::mkConcat(bv::utils::mkZero(5), ext7u);
+ Node vv = bv::utils::mkConcat(bv::utils::mkZero(5), ext7v);
+ Node ww = bv::utils::mkConcat(bv::utils::mkZero(5), ext7w);
+ Node s7 = bv::utils::mkConcat(bv::utils::mkZero(5), ext7s);
+ Node s15 = bv::utils::mkConcat(bv::utils::mkZero(5), ext15s);
+
+ Node plus1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 86), xx),
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 41), yy));
+ Node plus2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus1,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 37), zz));
+ Node plus3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus2,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 170), uu));
+ Node plus4 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus3,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 112), uu));
+ Node plus5 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus4,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 195), s15));
+ Node plus6 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus5,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 124), s7));
+ Node plus7 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus6,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(13, 83), ww));
+
+ ASSERT_EQ(BVGauss::getMinBwExpr(plus7), 0);
+}
+
+TEST_F(TestPPWhiteBVGauss, get_min_bw5b)
+{
+ /* (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd
+ * (bvadd (bvmul (_ bv86 20)
+ * ((_ zero_extend 12)
+ * ((_ extract 7 0) ((_ zero_extend 15) x))))
+ * (bvmul (_ bv41 20)
+ * ((_ zero_extend 12)
+ * ((_ extract 7 0) ((_ zero_extend 15) y)))))
+ * (bvmul (_ bv37 20)
+ * ((_ zero_extend 12)
+ * ((_ extract 7 0) ((_ zero_extend 15) z)))))
+ * (bvmul (_ bv170 20)
+ * ((_ zero_extend 12)
+ * ((_ extract 7 0) ((_ zero_extend 15) u)))))
+ * (bvmul (_ bv112 20)
+ * ((_ zero_extend 12)
+ * ((_ extract 7 0) ((_ zero_extend 15) v)))))
+ * (bvmul (_ bv195 20) ((_ zero_extend 12) ((_ extract 15 8) s))))
+ * (bvmul (_ bv124 20) ((_ zero_extend 12) ((_ extract 7 0) s))))
+ * (bvmul (_ bv83 20)
+ * ((_ zero_extend 12) ((_ extract 7 0) ((_ zero_extend 15) w)))))
+ */
+ Node x = bv::utils::mkVar(1);
+ Node y = bv::utils::mkVar(1);
+ Node z = bv::utils::mkVar(1);
+ Node u = bv::utils::mkVar(1);
+ Node v = bv::utils::mkVar(1);
+ Node w = bv::utils::mkVar(1);
+ Node s = bv::utils::mkVar(16);
+
+ Node zextop15 =
+ d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
+
+ Node zext15x = d_nodeManager->mkNode(zextop15, x);
+ Node zext15y = d_nodeManager->mkNode(zextop15, y);
+ Node zext15z = d_nodeManager->mkNode(zextop15, z);
+ Node zext15u = d_nodeManager->mkNode(zextop15, u);
+ Node zext15v = d_nodeManager->mkNode(zextop15, v);
+ Node zext15w = d_nodeManager->mkNode(zextop15, w);
+
+ Node ext7x = bv::utils::mkExtract(zext15x, 7, 0);
+ Node ext7y = bv::utils::mkExtract(zext15y, 7, 0);
+ Node ext7z = bv::utils::mkExtract(zext15z, 7, 0);
+ Node ext7u = bv::utils::mkExtract(zext15u, 7, 0);
+ Node ext7v = bv::utils::mkExtract(zext15v, 7, 0);
+ Node ext7w = bv::utils::mkExtract(zext15w, 7, 0);
+ Node ext7s = bv::utils::mkExtract(s, 7, 0);
+ Node ext15s = bv::utils::mkExtract(s, 15, 8);
+
+ Node xx = bv::utils::mkConcat(bv::utils::mkZero(12), ext7x);
+ Node yy = bv::utils::mkConcat(bv::utils::mkZero(12), ext7y);
+ Node zz = bv::utils::mkConcat(bv::utils::mkZero(12), ext7z);
+ Node uu = bv::utils::mkConcat(bv::utils::mkZero(12), ext7u);
+ Node vv = bv::utils::mkConcat(bv::utils::mkZero(12), ext7v);
+ Node ww = bv::utils::mkConcat(bv::utils::mkZero(12), ext7w);
+ Node s7 = bv::utils::mkConcat(bv::utils::mkZero(12), ext7s);
+ Node s15 = bv::utils::mkConcat(bv::utils::mkZero(12), ext15s);
+
+ Node plus1 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 86), xx),
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 41), yy));
+ Node plus2 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus1,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 37), zz));
+ Node plus3 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus2,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 170), uu));
+ Node plus4 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus3,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 112), uu));
+ Node plus5 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus4,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 195), s15));
+ Node plus6 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus5,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 124), s7));
+ Node plus7 = d_nodeManager->mkNode(
+ kind::BITVECTOR_PLUS,
+ plus6,
+ d_nodeManager->mkNode(
+ kind::BITVECTOR_MULT, bv::utils::mkConst(20, 83), ww));
+
+ ASSERT_EQ(BVGauss::getMinBwExpr(plus7), 19);
+ ASSERT_EQ(BVGauss::getMinBwExpr(Rewriter::rewrite(plus7)), 17);
+}
+} // namespace test
+} // namespace CVC4
+++ /dev/null
-/********************* */
-/*! \file pass_bv_gauss_white.h
- ** \verbatim
- ** Top contributors (to current version):
- ** Aina Niemetz, Mathias Preiner, Andres Noetzli
- ** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
- ** in the top-level source directory and their institutional affiliations.
- ** All rights reserved. See the file COPYING in the top-level source
- ** directory for licensing information.\endverbatim
- **
- ** \brief Unit tests for Gaussian Elimination preprocessing pass.
- **
- ** Unit tests for Gaussian Elimination preprocessing pass.
- **/
-
-#include "context/context.h"
-#include "expr/node.h"
-#include "expr/node_manager.h"
-#include "preprocessing/passes/bv_gauss.h"
-#include "smt/smt_engine.h"
-#include "smt/smt_engine_scope.h"
-#include "test_utils.h"
-#include "theory/bv/theory_bv_utils.h"
-#include "theory/rewriter.h"
-#include "util/bitvector.h"
-
-#include <cxxtest/TestSuite.h>
-#include <iostream>
-#include <vector>
-
-using namespace CVC4;
-using namespace CVC4::preprocessing;
-using namespace CVC4::preprocessing::passes;
-using namespace CVC4::theory;
-using namespace CVC4::smt;
-
-static void print_matrix_dbg(std::vector<Integer> &rhs,
- std::vector<std::vector<Integer>> &lhs)
-{
- for (size_t m = 0, nrows = lhs.size(), ncols = lhs[0].size(); m < nrows; ++m)
- {
- for (size_t n = 0; n < ncols; ++n)
- {
- std::cout << " " << lhs[m][n];
- }
- std::cout << " " << rhs[m];
- std::cout << std::endl;
- }
-}
-
-static void testGaussElimX(Integer prime,
- std::vector<Integer> rhs,
- std::vector<std::vector<Integer>> lhs,
- BVGauss::Result expected,
- std::vector<Integer>* rrhs = nullptr,
- std::vector<std::vector<Integer>>* rlhs = nullptr)
-{
- size_t nrows = lhs.size();
- size_t ncols = lhs[0].size();
- BVGauss::Result ret;
- std::vector<Integer> resrhs = std::vector<Integer>(rhs);
- std::vector<std::vector<Integer>> reslhs =
- std::vector<std::vector<Integer>>(lhs);
-
- std::cout << "Input: " << std::endl;
- print_matrix_dbg(rhs, lhs);
-
- ret = BVGauss::gaussElim(prime, resrhs, reslhs);
-
- std::cout << "BVGauss::Result: "
- << (ret == BVGauss::Result::INVALID
- ? "INVALID"
- : (ret == BVGauss::Result::UNIQUE
- ? "UNIQUE"
- : (ret == BVGauss::Result::PARTIAL ? "PARTIAL"
- : "NONE")))
- << std::endl;
- print_matrix_dbg(resrhs, reslhs);
-
- TS_ASSERT_EQUALS(expected, ret);
-
- if (expected == BVGauss::Result::UNIQUE)
- {
- /* map result value to column index
- * e.g.:
- * 1 0 0 2 -> res = { 2, 0, 3}
- * 0 0 1 3 */
- std::vector<Integer> res = std::vector<Integer>(ncols, Integer(0));
- for (size_t i = 0; i < nrows; ++i)
- for (size_t j = 0; j < ncols; ++j)
- {
- if (reslhs[i][j] == 1)
- res[j] = resrhs[i];
- else
- TS_ASSERT(reslhs[i][j] == 0);
- }
-
- for (size_t i = 0; i < nrows; ++i)
- {
- Integer tmp = Integer(0);
- for (size_t j = 0; j < ncols; ++j)
- tmp = tmp.modAdd(lhs[i][j].modMultiply(res[j], prime), prime);
- TS_ASSERT(tmp == rhs[i].euclidianDivideRemainder(prime));
- }
- }
- if (rrhs != nullptr && rlhs != nullptr)
- {
- for (size_t i = 0; i < nrows; ++i)
- {
- for (size_t j = 0; j < ncols; ++j)
- {
- TS_ASSERT(reslhs[i][j] == (*rlhs)[i][j]);
- }
- TS_ASSERT(resrhs[i] == (*rrhs)[i]);
- }
- }
-}
-
-class TheoryBVGaussWhite : public CxxTest::TestSuite
-{
- ExprManager *d_em;
- NodeManager *d_nm;
- SmtEngine *d_smt;
- SmtScope *d_scope;
- Node d_p;
- Node d_x;
- Node d_y;
- Node d_z;
- Node d_zero;
- Node d_one;
- Node d_two;
- Node d_three;
- Node d_four;
- Node d_five;
- Node d_six;
- Node d_seven;
- Node d_eight;
- Node d_nine;
- Node d_ten;
- Node d_twelve;
- Node d_eighteen;
- Node d_twentyfour;
- Node d_thirty;
- Node d_one32;
- Node d_two32;
- Node d_three32;
- Node d_four32;
- Node d_five32;
- Node d_six32;
- Node d_seven32;
- Node d_eight32;
- Node d_nine32;
- Node d_ten32;
- Node d_x_mul_one;
- Node d_x_mul_two;
- Node d_x_mul_four;
- Node d_y_mul_one;
- Node d_y_mul_three;
- Node d_y_mul_four;
- Node d_y_mul_five;
- Node d_y_mul_seven;
- Node d_z_mul_one;
- Node d_z_mul_three;
- Node d_z_mul_five;
- Node d_z_mul_twelve;
- Node d_z_mul_six;
- Node d_z_mul_nine;
-
- public:
- TheoryBVGaussWhite() {}
-
- void setUp() override
- {
- d_em = new ExprManager();
- d_nm = NodeManager::fromExprManager(d_em);
- d_smt = new SmtEngine(d_nm);
- d_scope = new SmtScope(d_smt);
- d_smt->finishInit();
-
- d_zero = bv::utils::mkZero(16);
-
- d_p = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 11u)));
- d_x = bv::utils::mkConcat(
- d_zero, d_nm->mkVar("x", d_nm->mkBitVectorType(16)));
- d_y = bv::utils::mkConcat(
- d_zero, d_nm->mkVar("y", d_nm->mkBitVectorType(16)));
- d_z = bv::utils::mkConcat(
- d_zero, d_nm->mkVar("z", d_nm->mkBitVectorType(16)));
-
- d_one = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 1u)));
- d_two = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 2u)));
- d_three = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 3u)));
- d_four = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 4u)));
- d_five = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 5u)));
- d_six = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 6u)));
- d_seven = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 7u)));
- d_eight = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 8u)));
- d_nine = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 9u)));
- d_ten = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 10u)));
- d_twelve = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 12u)));
- d_eighteen = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 18u)));
- d_twentyfour = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 24u)));
- d_thirty = bv::utils::mkConcat(
- d_zero, d_nm->mkConst<BitVector>(BitVector(16, 30u)));
-
- d_one32 = d_nm->mkConst<BitVector>(BitVector(32, 1u));
- d_two32 = d_nm->mkConst<BitVector>(BitVector(32, 2u));
- d_three32 = d_nm->mkConst<BitVector>(BitVector(32, 3u));
- d_four32 = d_nm->mkConst<BitVector>(BitVector(32, 4u));
- d_five32 = d_nm->mkConst<BitVector>(BitVector(32, 5u));
- d_six32 = d_nm->mkConst<BitVector>(BitVector(32, 6u));
- d_seven32 = d_nm->mkConst<BitVector>(BitVector(32, 7u));
- d_eight32 = d_nm->mkConst<BitVector>(BitVector(32, 8u));
- d_nine32 = d_nm->mkConst<BitVector>(BitVector(32, 9u));
- d_ten32 = d_nm->mkConst<BitVector>(BitVector(32, 10u));
-
- d_x_mul_one = d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_one);
- d_x_mul_two = d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_two);
- d_x_mul_four = d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_four);
- d_y_mul_three = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_three);
- d_y_mul_one = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_one);
- d_y_mul_four = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_four);
- d_y_mul_five = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_five);
- d_y_mul_seven = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_seven);
- d_z_mul_one = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_one);
- d_z_mul_three = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_three);
- d_z_mul_five = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_five);
- d_z_mul_six = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_six);
- d_z_mul_twelve = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_twelve);
- d_z_mul_nine = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_nine);
- }
-
- void tearDown() override
- {
- (void)d_scope;
- d_p = Node::null();
- d_x = Node::null();
- d_y = Node::null();
- d_z = Node::null();
- d_zero = Node::null();
- d_one = Node::null();
- d_two = Node::null();
- d_three = Node::null();
- d_four = Node::null();
- d_five = Node::null();
- d_six = Node::null();
- d_seven = Node::null();
- d_eight = Node::null();
- d_nine = Node::null();
- d_ten = Node::null();
- d_twelve = Node::null();
- d_eighteen = Node::null();
- d_twentyfour = Node::null();
- d_thirty = Node::null();
- d_one32 = Node::null();
- d_two32 = Node::null();
- d_three32 = Node::null();
- d_four32 = Node::null();
- d_five32 = Node::null();
- d_six32 = Node::null();
- d_seven32 = Node::null();
- d_eight32 = Node::null();
- d_nine32 = Node::null();
- d_ten32 = Node::null();
- d_x_mul_one = Node::null();
- d_x_mul_two = Node::null();
- d_x_mul_four = Node::null();
- d_y_mul_one = Node::null();
- d_y_mul_four = Node::null();
- d_y_mul_seven = Node::null();
- d_y_mul_five = Node::null();
- d_y_mul_three = Node::null();
- d_z_mul_one = Node::null();
- d_z_mul_three = Node::null();
- d_z_mul_five = Node::null();
- d_z_mul_six = Node::null();
- d_z_mul_twelve = Node::null();
- d_z_mul_nine = Node::null();
- delete d_scope;
- delete d_smt;
- delete d_em;
- }
-
- void testGaussElimMod()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
- * --^-- ^
- * 1 1 1 5
- * 2 3 5 8
- * 4 0 5 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(2)};
- lhs = {{Integer(1), Integer(1), Integer(1)},
- {Integer(2), Integer(3), Integer(5)},
- {Integer(4), Integer(0), Integer(5)}};
- std::cout << "matrix 0, modulo 0" << std::endl; // throws
- TS_UTILS_EXPECT_ABORT(BVGauss::gaussElim(Integer(0), rhs, lhs));
- std::cout << "matrix 0, modulo 1" << std::endl;
- testGaussElimX(Integer(1), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 0, modulo 2" << std::endl;
- testGaussElimX(Integer(2), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 0, modulo 3" << std::endl;
- testGaussElimX(Integer(3), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 0, modulo 4" << std::endl; // no inverse
- testGaussElimX(Integer(4), rhs, lhs, BVGauss::Result::INVALID);
- std::cout << "matrix 0, modulo 5" << std::endl;
- testGaussElimX(Integer(5), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 0, modulo 6" << std::endl; // no inverse
- testGaussElimX(Integer(6), rhs, lhs, BVGauss::Result::INVALID);
- std::cout << "matrix 0, modulo 7" << std::endl;
- testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 0, modulo 8" << std::endl; // no inverse
- testGaussElimX(Integer(8), rhs, lhs, BVGauss::Result::INVALID);
- std::cout << "matrix 0, modulo 9" << std::endl;
- testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 0, modulo 10" << std::endl; // no inverse
- testGaussElimX(Integer(10), rhs, lhs, BVGauss::Result::INVALID);
- std::cout << "matrix 0, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
- }
-
- void testGaussElimUniqueDone()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 17
- * --^--- ^ --^-- ^
- * 1 0 0 4 --> 1 0 0 4
- * 0 1 0 15 0 1 0 15
- * 0 0 1 3 0 0 1 3
- * ------------------------------------------------------------------- */
- rhs = {Integer(4), Integer(15), Integer(3)};
- lhs = {{Integer(1), Integer(0), Integer(0)},
- {Integer(0), Integer(1), Integer(0)},
- {Integer(0), Integer(0), Integer(1)}};
- std::cout << "matrix 1, modulo 17" << std::endl;
- testGaussElimX(Integer(17), rhs, lhs, BVGauss::Result::UNIQUE);
- }
-
- void testGaussElimUnique()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo { 11,17,59 }
- * --^--- ^
- * 2 4 6 18
- * 4 5 6 24
- * 3 1 -2 4
- * ------------------------------------------------------------------- */
- rhs = {Integer(18), Integer(24), Integer(4)};
- lhs = {{Integer(2), Integer(4), Integer(6)},
- {Integer(4), Integer(5), Integer(6)},
- {Integer(3), Integer(1), Integer(-2)}};
- std::cout << "matrix 2, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 2, modulo 17" << std::endl;
- testGaussElimX(Integer(17), rhs, lhs, BVGauss::Result::UNIQUE);
- std::cout << "matrix 2, modulo 59" << std::endl;
- testGaussElimX(Integer(59), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * -----^----- ^ ---^--- ^
- * 1 1 2 0 1 --> 1 0 0 0 1
- * 2 -1 0 1 -2 0 1 0 0 2
- * 1 -1 -1 -2 4 0 0 1 0 -1
- * 2 -1 2 -1 0 0 0 0 1 -2
- * ------------------------------------------------------------------- */
- rhs = {Integer(1), Integer(-2), Integer(4), Integer(0)};
- lhs = {{Integer(1), Integer(1), Integer(2), Integer(0)},
- {Integer(2), Integer(-1), Integer(0), Integer(1)},
- {Integer(1), Integer(-1), Integer(-1), Integer(-2)},
- {Integer(2), Integer(-1), Integer(2), Integer(-1)}};
- std::cout << "matrix 3, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
- }
-
- void testGaussElimUniqueZero1()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 0 4 5 2 --> 1 0 0 4
- * 1 1 1 5 0 1 0 3
- * 3 2 5 8 0 0 1 9
- * ------------------------------------------------------------------- */
- rhs = {Integer(2), Integer(5), Integer(8)};
- lhs = {{Integer(0), Integer(4), Integer(5)},
- {Integer(1), Integer(1), Integer(1)},
- {Integer(3), Integer(2), Integer(5)}};
- std::cout << "matrix 4, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 1 1 5 --> 1 0 0 4
- * 0 4 5 2 0 1 0 3
- * 3 2 5 8 0 0 1 9
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(2), Integer(8)};
- lhs = {{Integer(1), Integer(1), Integer(1)},
- {Integer(0), Integer(4), Integer(5)},
- {Integer(3), Integer(2), Integer(5)}};
- std::cout << "matrix 5, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 1 1 5 --> 1 0 0 4
- * 3 2 5 8 0 1 0 9
- * 0 4 5 2 0 0 1 3
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(2)};
- lhs = {{Integer(1), Integer(1), Integer(1)},
- {Integer(3), Integer(2), Integer(5)},
- {Integer(0), Integer(4), Integer(5)}};
- std::cout << "matrix 6, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
- }
-
- void testGaussElimUniqueZero2()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 0 0 5 2 1 0 0 10
- * 1 1 1 5 --> 0 1 0 10
- * 3 2 5 8 0 0 1 7
- * ------------------------------------------------------------------- */
- rhs = {Integer(2), Integer(5), Integer(8)};
- lhs = {{Integer(0), Integer(0), Integer(5)},
- {Integer(1), Integer(1), Integer(1)},
- {Integer(3), Integer(2), Integer(5)}};
- std::cout << "matrix 7, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 1 1 5 --> 1 0 0 10
- * 0 0 5 2 0 1 0 10
- * 3 2 5 8 0 0 1 7
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(2), Integer(8)};
- lhs = {{Integer(1), Integer(1), Integer(1)},
- {Integer(0), Integer(0), Integer(5)},
- {Integer(3), Integer(2), Integer(5)}};
- std::cout << "matrix 8, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 1 1 5 --> 1 0 0 10
- * 3 2 5 8 0 1 0 10
- * 0 0 5 2 0 0 1 7
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(2)};
- lhs = {{Integer(1), Integer(1), Integer(1)},
- {Integer(3), Integer(2), Integer(5)},
- {Integer(0), Integer(0), Integer(5)}};
- std::cout << "matrix 9, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
- }
-
- void testGaussElimUniqueZero3()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 7
- * --^-- ^ --^-- ^
- * 2 0 6 4 1 0 0 3
- * 0 0 0 0 --> 0 0 0 0
- * 4 0 6 3 0 0 1 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(4), Integer(0), Integer(3)};
- lhs = {{Integer(2), Integer(0), Integer(6)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(4), Integer(0), Integer(6)}};
- std::cout << "matrix 10, modulo 7" << std::endl;
- testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 7
- * --^-- ^ --^-- ^
- * 2 6 0 4 1 0 0 3
- * 0 0 0 0 --> 0 0 0 0
- * 4 6 0 3 0 0 1 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(4), Integer(0), Integer(3)};
- lhs = {{Integer(2), Integer(6), Integer(0)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(4), Integer(6), Integer(0)}};
- std::cout << "matrix 11, modulo 7" << std::endl;
- testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
- }
-
- void testGaussElimUniqueZero4()
- {
- std::vector<Integer> rhs, resrhs;
- std::vector<std::vector<Integer>> lhs, reslhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 0 1 1 5
- * 0 0 0 0
- * 0 0 5 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(0), Integer(2)};
- lhs = {{Integer(0), Integer(1), Integer(1)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(0), Integer(0), Integer(5)}};
- std::cout << "matrix 12, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 0 1 1 5
- * 0 3 5 8
- * 0 0 0 0
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(0)};
- lhs = {{Integer(0), Integer(1), Integer(1)},
- {Integer(0), Integer(3), Integer(5)},
- {Integer(0), Integer(0), Integer(0)}};
- std::cout << "matrix 13, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 0 0 0 0
- * 0 3 5 8
- * 0 0 5 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(0), Integer(8), Integer(2)};
- lhs = {{Integer(0), Integer(0), Integer(0)},
- {Integer(0), Integer(3), Integer(5)},
- {Integer(0), Integer(0), Integer(5)}};
- std::cout << "matrix 14, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 0 1 5
- * 0 0 0 0
- * 4 0 5 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(0), Integer(2)};
- lhs = {{Integer(1), Integer(0), Integer(1)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(4), Integer(0), Integer(5)}};
- std::cout << "matrix 15, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 0 1 5
- * 2 0 5 8
- * 0 0 0 0
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(0)};
- lhs = {{Integer(1), Integer(0), Integer(1)},
- {Integer(2), Integer(0), Integer(5)},
- {Integer(0), Integer(0), Integer(0)}};
- std::cout << "matrix 16, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 0 0 0 0
- * 2 0 5 8
- * 4 0 5 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(0), Integer(8), Integer(2)};
- lhs = {{Integer(0), Integer(0), Integer(0)},
- {Integer(2), Integer(0), Integer(5)},
- {Integer(4), Integer(0), Integer(5)}};
- std::cout << "matrix 17, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 1 0 5
- * 0 0 0 0
- * 4 0 0 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(0), Integer(2)};
- lhs = {{Integer(1), Integer(1), Integer(0)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(4), Integer(0), Integer(0)}};
- std::cout << "matrix 18, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 1 0 5
- * 2 3 0 8
- * 0 0 0 0
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(0)};
- lhs = {{Integer(1), Integer(1), Integer(0)},
- {Integer(2), Integer(3), Integer(0)},
- {Integer(0), Integer(0), Integer(0)}};
- std::cout << "matrix 18, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 0 0 0 0
- * 2 3 0 8
- * 4 0 0 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(0), Integer(8), Integer(2)};
- lhs = {{Integer(0), Integer(0), Integer(0)},
- {Integer(2), Integer(3), Integer(0)},
- {Integer(4), Integer(0), Integer(0)}};
- std::cout << "matrix 19, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 2
- * ----^--- ^
- * 2 4 6 18 0 0 0 0
- * 4 5 6 24 = 0 1 0 0
- * 2 7 12 30 0 1 0 0
- * ------------------------------------------------------------------- */
- rhs = {Integer(18), Integer(24), Integer(30)};
- lhs = {{Integer(2), Integer(4), Integer(6)},
- {Integer(4), Integer(5), Integer(6)},
- {Integer(2), Integer(7), Integer(12)}};
- std::cout << "matrix 20, modulo 2" << std::endl;
- resrhs = {Integer(0), Integer(0), Integer(0)};
- reslhs = {{Integer(0), Integer(1), Integer(0)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(2), rhs, lhs, BVGauss::Result::UNIQUE, &resrhs, &reslhs);
- }
-
- void testGaussElimUniquePartial()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 7
- * --^-- ^ --^-- ^
- * 2 0 6 4 1 0 0 3
- * 4 0 6 3 0 0 1 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(4), Integer(3)};
- lhs = {{Integer(2), Integer(0), Integer(6)},
- {Integer(4), Integer(0), Integer(6)}};
- std::cout << "matrix 21, modulo 7" << std::endl;
- testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 7
- * --^-- ^ --^-- ^
- * 2 6 0 4 1 0 0 3
- * 4 6 0 3 0 1 0 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(4), Integer(3)};
- lhs = {{Integer(2), Integer(6), Integer(0)},
- {Integer(4), Integer(6), Integer(0)}};
- std::cout << "matrix 22, modulo 7" << std::endl;
- testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
- }
-
- void testGaussElimNone()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 9
- * --^--- ^
- * 2 4 6 18 --> not coprime (no inverse)
- * 4 5 6 24
- * 3 1 -2 4
- * ------------------------------------------------------------------- */
- rhs = {Integer(18), Integer(24), Integer(4)};
- lhs = {{Integer(2), Integer(4), Integer(6)},
- {Integer(4), Integer(5), Integer(6)},
- {Integer(3), Integer(1), Integer(-2)}};
- std::cout << "matrix 23, modulo 9" << std::endl;
- testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::INVALID);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 59
- * ----^--- ^
- * 1 -2 -6 12 --> no solution
- * 2 4 12 -17
- * 1 -4 -12 22
- * ------------------------------------------------------------------- */
- rhs = {Integer(12), Integer(-17), Integer(22)};
- lhs = {{Integer(1), Integer(-2), Integer(-6)},
- {Integer(2), Integer(4), Integer(12)},
- {Integer(1), Integer(-4), Integer(-12)}};
- std::cout << "matrix 24, modulo 59" << std::endl;
- testGaussElimX(Integer(59), rhs, lhs, BVGauss::Result::NONE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 9
- * ----^--- ^
- * 2 4 6 18 --> not coprime (no inverse)
- * 4 5 6 24
- * 2 7 12 30
- * ------------------------------------------------------------------- */
- rhs = {Integer(18), Integer(24), Integer(30)};
- lhs = {{Integer(2), Integer(4), Integer(6)},
- {Integer(4), Integer(5), Integer(6)},
- {Integer(2), Integer(7), Integer(12)}};
- std::cout << "matrix 25, modulo 9" << std::endl;
- testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::INVALID);
- }
-
- void testGaussElimNoneZero()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 0 1 1 5
- * 0 3 5 8
- * 0 0 5 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(2)};
- lhs = {{Integer(0), Integer(1), Integer(1)},
- {Integer(0), Integer(3), Integer(5)},
- {Integer(0), Integer(0), Integer(5)}};
- std::cout << "matrix 26, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 0 1 5
- * 2 0 5 8
- * 4 0 5 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(2)};
- lhs = {{Integer(1), Integer(0), Integer(1)},
- {Integer(2), Integer(0), Integer(5)},
- {Integer(4), Integer(0), Integer(5)}};
- std::cout << "matrix 27, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 1 0 5
- * 2 3 0 8
- * 4 0 0 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8), Integer(2)};
- lhs = {{Integer(1), Integer(1), Integer(0)},
- {Integer(2), Integer(3), Integer(0)},
- {Integer(4), Integer(0), Integer(0)}};
- std::cout << "matrix 28, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
- }
-
- void testGaussElimPartial1()
- {
- std::vector<Integer> rhs, resrhs;
- std::vector<std::vector<Integer>> lhs, reslhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- * ------------------------------------------------------------------- */
- rhs = {Integer(7), Integer(9)};
- lhs = {{Integer(1), Integer(0), Integer(9)},
- {Integer(0), Integer(1), Integer(3)}};
- std::cout << "matrix 29, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 3 0 7 --> 1 3 0 7
- * 0 0 1 9 0 0 1 9
- * ------------------------------------------------------------------- */
- rhs = {Integer(7), Integer(9)};
- lhs = {{Integer(1), Integer(3), Integer(0)},
- {Integer(0), Integer(0), Integer(1)}};
- std::cout << "matrix 30, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 1 1 5 --> 1 0 9 7
- * 2 3 5 8 0 1 3 9
- * ------------------------------------------------------------------- */
- rhs = {Integer(5), Integer(8)};
- lhs = {{Integer(1), Integer(1), Integer(1)},
- {Integer(2), Integer(3), Integer(5)}};
- std::cout << "matrix 31, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
-
- /* -------------------------------------------------------------------
- * lhs rhs modulo { 3, 5, 7, 11, 17, 31, 59 }
- * ----^--- ^
- * 2 4 6 18
- * 4 5 6 24
- * 2 7 12 30
- * ------------------------------------------------------------------- */
- rhs = {Integer(18), Integer(24), Integer(30)};
- lhs = {{Integer(2), Integer(4), Integer(6)},
- {Integer(4), Integer(5), Integer(6)},
- {Integer(2), Integer(7), Integer(12)}};
- std::cout << "matrix 32, modulo 3" << std::endl;
- resrhs = {Integer(0), Integer(0), Integer(0)};
- reslhs = {{Integer(1), Integer(2), Integer(0)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(3), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
- resrhs = {Integer(1), Integer(4), Integer(0)};
- std::cout << "matrix 32, modulo 5" << std::endl;
- reslhs = {{Integer(1), Integer(0), Integer(4)},
- {Integer(0), Integer(1), Integer(2)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(5), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
- std::cout << "matrix 32, modulo 7" << std::endl;
- reslhs = {{Integer(1), Integer(0), Integer(6)},
- {Integer(0), Integer(1), Integer(2)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(7), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
- std::cout << "matrix 32, modulo 11" << std::endl;
- reslhs = {{Integer(1), Integer(0), Integer(10)},
- {Integer(0), Integer(1), Integer(2)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(11), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
- std::cout << "matrix 32, modulo 17" << std::endl;
- reslhs = {{Integer(1), Integer(0), Integer(16)},
- {Integer(0), Integer(1), Integer(2)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(17), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
- std::cout << "matrix 32, modulo 59" << std::endl;
- reslhs = {{Integer(1), Integer(0), Integer(58)},
- {Integer(0), Integer(1), Integer(2)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(59), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 3
- * ----^--- ^ --^-- ^
- * 4 6 2 18 --> 1 0 2 0
- * 5 6 4 24 0 0 0 0
- * 7 12 2 30 0 0 0 0
- * ------------------------------------------------------------------- */
- rhs = {Integer(18), Integer(24), Integer(30)};
- lhs = {{Integer(4), Integer(6), Integer(2)},
- {Integer(5), Integer(6), Integer(4)},
- {Integer(7), Integer(12), Integer(2)}};
- std::cout << "matrix 33, modulo 3" << std::endl;
- resrhs = {Integer(0), Integer(0), Integer(0)};
- reslhs = {{Integer(1), Integer(0), Integer(2)},
- {Integer(0), Integer(0), Integer(0)},
- {Integer(0), Integer(0), Integer(0)}};
- testGaussElimX(
- Integer(3), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
- }
-
- void testGaussElimPartial2()
- {
- std::vector<Integer> rhs;
- std::vector<std::vector<Integer>> lhs;
-
- /* -------------------------------------------------------------------
- * lhs rhs --> lhs rhs modulo 11
- * ---^--- ^ ---^--- ^
- * x y z w x y z w
- * 1 2 0 6 2 1 2 0 0 1
- * 0 0 2 2 2 0 0 1 0 10
- * 0 0 0 1 2 0 0 0 1 2
- * ------------------------------------------------------------------- */
- rhs = {Integer(2), Integer(2), Integer(2)};
- lhs = {{Integer(1), Integer(2), Integer(6), Integer(0)},
- {Integer(0), Integer(0), Integer(2), Integer(2)},
- {Integer(0), Integer(0), Integer(1), Integer(0)}};
- std::cout << "matrix 34, modulo 11" << std::endl;
- testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
- }
- void testGaussElimRewriteForUremUnique1()
- {
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 1 1 5
- * 2 3 5 8
- * 4 0 5 2
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_one),
- d_z_mul_one),
- d_p),
- d_five);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
- d_z_mul_five),
- d_p),
- d_eight);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_four, d_z_mul_five),
- d_p),
- d_two);
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::UNIQUE);
- TS_ASSERT(res.size() == 3);
- TS_ASSERT(res[d_x] == d_three32);
- TS_ASSERT(res[d_y] == d_four32);
- TS_ASSERT(res[d_z] == d_nine32);
- }
-
- void testGaussElimRewriteForUremUnique2()
- {
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 1 1 5
- * 2 3 5 8
- * 4 0 5 2
- * ------------------------------------------------------------------- */
-
- Node zextop6 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(6));
-
- Node p = d_nm->mkNode(
- zextop6,
- bv::utils::mkConcat(bv::utils::mkZero(6),
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- bv::utils::mkConst(20, 7),
- bv::utils::mkConst(20, 4))));
-
- Node x_mul_one =
- d_nm->mkNode(kind::BITVECTOR_MULT,
- d_nm->mkNode(kind::BITVECTOR_SUB, d_five, d_four),
- d_x);
- Node y_mul_one =
- d_nm->mkNode(kind::BITVECTOR_MULT,
- d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL, d_one, d_five),
- d_y);
- Node z_mul_one =
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkOne(32), d_z);
-
- Node x_mul_two = d_nm->mkNode(
- kind::BITVECTOR_MULT,
- d_nm->mkNode(
- kind::BITVECTOR_SHL, bv::utils::mkOne(32), bv::utils::mkOne(32)),
- d_x);
- Node y_mul_three = d_nm->mkNode(kind::BITVECTOR_MULT,
- d_nm->mkNode(kind::BITVECTOR_LSHR,
- bv::utils::mkOnes(32),
- bv::utils::mkConst(32, 30)),
- d_y);
- Node z_mul_five = d_nm->mkNode(kind::BITVECTOR_MULT,
- bv::utils::mkExtract(
- d_nm->mkNode(
- zextop6, d_nm->mkNode(kind::BITVECTOR_PLUS, d_three, d_two)),
- 31, 0),
- d_z);
-
- Node x_mul_four = d_nm->mkNode(kind::BITVECTOR_MULT,
- d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_MULT,
- bv::utils::mkConst(32, 4),
- bv::utils::mkConst(32, 5)),
- bv::utils::mkConst(32, 4)),
- bv::utils::mkConst(32, 6)),
- d_x);
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- x_mul_one,
- y_mul_one),
- z_mul_one),
- p),
- d_five);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, x_mul_two, y_mul_three),
- z_mul_five),
- p),
- d_eight);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, x_mul_four, z_mul_five),
- d_p),
- d_two);
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::UNIQUE);
- TS_ASSERT(res.size() == 3);
- TS_ASSERT(res[d_x] == d_three32);
- TS_ASSERT(res[d_y] == d_four32);
- TS_ASSERT(res[d_z] == d_nine32);
- }
-
- void testGaussElimRewriteForUremPartial1()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_z_mul_nine),
- d_p),
- d_seven);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_y_mul_one, d_z_mul_three),
- d_p),
- d_nine);
-
- std::vector<Node> eqs = {eq1, eq2};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 2);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_seven32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
- d_p);
- Node y1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nine32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
- d_p);
-
- Node x2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
- d_p);
- Node z2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
- d_p);
-
- Node y3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
- d_p);
- Node z3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
- d_p);
-
- /* result depends on order of variables in matrix */
- if (res.find(d_x) == res.end())
- {
- /*
- * y z x y z x
- * 0 9 1 7 --> 1 0 7 3
- * 1 3 0 9 0 1 5 2
- *
- * z y x z y x
- * 9 0 1 7 --> 1 0 5 2
- * 3 1 0 9 0 1 7 3
- */
- TS_ASSERT(res[d_y] == y3);
- TS_ASSERT(res[d_z] == z3);
- }
- else if (res.find(d_y) == res.end())
- {
- /*
- * x z y x z y
- * 1 9 0 7 --> 1 0 8 2
- * 0 3 1 9 0 1 4 3
- *
- * z x y z x y
- * 9 1 0 7 --> 1 0 4 3
- * 3 0 1 9 0 1 8 2
- */
- TS_ASSERT(res[d_x] == x2);
- TS_ASSERT(res[d_z] == z2);
- }
- else
- {
- TS_ASSERT(res.find(d_z) == res.end());
- /*
- * x y z x y z
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- *
- * y x z y x z
- * 0 1 9 7 --> 1 0 3 9
- * 1 0 3 9 0 1 9 7
- */
- TS_ASSERT(res[d_x] == x1);
- TS_ASSERT(res[d_y] == y1);
- }
- }
-
- void testGaussElimRewriteForUremPartial1a()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x, d_z_mul_nine),
- d_p),
- d_seven);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_y, d_z_mul_three),
- d_p),
- d_nine);
-
- std::vector<Node> eqs = {eq1, eq2};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 2);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_seven32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
- d_p);
- Node y1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nine32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
- d_p);
-
- Node x2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
- d_p);
- Node z2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
- d_p);
-
- Node y3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
- d_p);
- Node z3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
- d_p);
-
- /* result depends on order of variables in matrix */
- if (res.find(d_x) == res.end())
- {
- /*
- * y z x y z x
- * 0 9 1 7 --> 1 0 7 3
- * 1 3 0 9 0 1 5 2
- *
- * z y x z y x
- * 9 0 1 7 --> 1 0 5 2
- * 3 1 0 9 0 1 7 3
- */
- TS_ASSERT(res[d_y] == y3);
- TS_ASSERT(res[d_z] == z3);
- }
- else if (res.find(d_y) == res.end())
- {
- /*
- * x z y x z y
- * 1 9 0 7 --> 1 0 8 2
- * 0 3 1 9 0 1 4 3
- *
- * z x y z x y
- * 9 1 0 7 --> 1 0 4 3
- * 3 0 1 9 0 1 8 2
- */
- TS_ASSERT(res[d_x] == x2);
- TS_ASSERT(res[d_z] == z2);
- }
- else
- {
- TS_ASSERT(res.find(d_z) == res.end());
- /*
- * x y z x y z
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- *
- * y x z y x z
- * 0 1 9 7 --> 1 0 3 9
- * 1 0 3 9 0 1 9 7
- */
- TS_ASSERT(res[d_x] == x1);
- TS_ASSERT(res[d_y] == y1);
- }
- }
-
- void testGaussElimRewriteForUremPartial2()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 3 0 7 --> 1 3 0 7
- * 0 0 1 9 0 0 1 9
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_three),
- d_p),
- d_seven);
-
- Node eq2 =
- d_nm->mkNode(kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM, d_z_mul_one, d_p),
- d_nine);
-
- std::vector<Node> eqs = {eq1, eq2};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 2);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_seven32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_eight32)),
- d_p);
- Node y2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_six32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_seven32)),
- d_p);
-
- /* result depends on order of variables in matrix */
- if (res.find(d_x) == res.end())
- {
- /*
- * x y z x y z
- * 1 3 0 7 --> 1 3 0 7
- * 0 0 1 9 0 0 1 9
- *
- * x z y x z y
- * 1 0 3 7 --> 1 0 3 7
- * 0 1 0 9 0 1 0 9
- *
- * z x y z x y
- * 0 1 3 7 --> 1 0 0 9
- * 1 0 0 9 0 1 3 7
- */
- TS_ASSERT(res[d_y] == y2);
- TS_ASSERT(res[d_z] == d_nine32);
- }
- else if (res.find(d_y) == res.end())
- {
- /*
- * z y x z y x
- * 0 3 1 7 --> 1 0 0 9
- * 1 0 0 9 0 1 4 6
- *
- * y x z y x z
- * 3 1 0 7 --> 1 4 0 6
- * 0 0 1 9 0 0 1 9
- *
- * y z x y z x
- * 3 0 1 7 --> 1 0 4 6
- * 0 1 0 9 0 1 0 9
- */
- TS_ASSERT(res[d_x] == x1);
- TS_ASSERT(res[d_z] == d_nine32);
- }
- else
- {
- TS_ASSERT(false);
- }
- }
-
- void testGaussElimRewriteForUremPartial3()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 1 1 5 --> 1 0 9 7
- * 2 3 5 8 0 1 3 9
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_y),
- d_z_mul_one),
- d_p),
- d_five);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
- d_z_mul_five),
- d_p),
- d_eight);
-
- std::vector<Node> eqs = {eq1, eq2};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 2);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_seven32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
- d_p);
- Node y1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nine32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
- d_p);
- Node x2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
- d_p);
- Node z2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
- d_p);
- Node y3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
- d_p);
- Node z3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
- d_p);
-
- /* result depends on order of variables in matrix */
- if (res.find(d_x) == res.end())
- {
- /*
- * y z x y z x
- * 1 1 1 5 --> 1 0 7 3
- * 3 5 2 8 0 1 5 2
- *
- * z y x z y x
- * 1 1 1 5 --> 1 0 5 2
- * 5 3 2 8 0 1 7 3
- */
- TS_ASSERT(res[d_y] == y3);
- TS_ASSERT(res[d_z] == z3);
- }
- else if (res.find(d_y) == res.end())
- {
- /*
- * x z y x z y
- * 1 1 1 5 --> 1 0 8 2
- * 2 5 3 8 0 1 4 3
- *
- * z x y z x y
- * 1 1 1 5 --> 1 0 4 3
- * 5 2 3 9 0 1 8 2
- */
- TS_ASSERT(res[d_x] == x2);
- TS_ASSERT(res[d_z] == z2);
- }
- else
- {
- TS_ASSERT(res.find(d_z) == res.end());
- /*
- * x y z x y z
- * 1 1 1 5 --> 1 0 9 7
- * 2 3 5 8 0 1 3 9
- *
- * y x z y x z
- * 1 1 1 5 --> 1 0 3 9
- * 3 2 5 8 0 1 9 7
- */
- TS_ASSERT(res[d_x] == x1);
- TS_ASSERT(res[d_y] == y1);
- }
- }
-
- void testGaussElimRewriteForUremPartial4()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * ----^--- ^ ---^--- ^
- * 2 4 6 18 --> 1 0 10 1
- * 4 5 6 24 0 1 2 4
- * 2 7 12 30 0 0 0 0
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_four),
- d_z_mul_six),
- d_p),
- d_eighteen);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_four, d_y_mul_five),
- d_z_mul_six),
- d_p),
- d_twentyfour);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_seven),
- d_z_mul_twelve),
- d_p),
- d_thirty);
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 2);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_one32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_one32)),
- d_p);
- Node y1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_four32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_nine32)),
- d_p);
- Node x2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_five32)),
- d_p);
- Node z2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_five32)),
- d_p);
- Node y3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_six32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_nine32)),
- d_p);
- Node z3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_ten32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_one32)),
- d_p);
-
- /* result depends on order of variables in matrix */
- if (res.find(d_x) == res.end())
- {
- /*
- * y z x y z x
- * 4 6 2 18 --> 1 0 2 6
- * 5 6 4 24 0 1 10 10
- * 7 12 2 30 0 0 0 0
- *
- * z y x z y x
- * 6 4 2 18 --> 1 0 10 10
- * 6 5 4 24 0 1 2 6
- * 12 12 2 30 0 0 0 0
- *
- */
- TS_ASSERT(res[d_y] == y3);
- TS_ASSERT(res[d_z] == z3);
- }
- else if (res.find(d_y) == res.end())
- {
- /*
- * x z y x z y
- * 2 6 4 18 --> 1 0 6 3
- * 4 6 5 24 0 1 6 2
- * 2 12 7 30 0 0 0 0
- *
- * z x y z x y
- * 6 2 4 18 --> 1 0 6 2
- * 6 4 5 24 0 1 6 3
- * 12 2 12 30 0 0 0 0
- *
- */
- TS_ASSERT(res[d_x] == x2);
- TS_ASSERT(res[d_z] == z2);
- }
- else
- {
- TS_ASSERT(res.find(d_z) == res.end());
- /*
- * x y z x y z
- * 2 4 6 18 --> 1 0 10 1
- * 4 5 6 24 0 1 2 4
- * 2 7 12 30 0 0 0 0
- *
- * y x z y x z
- * 4 2 6 18 --> 1 0 2 49
- * 5 4 6 24 0 1 10 1
- * 7 2 12 30 0 0 0 0
- */
- TS_ASSERT(res[d_x] == x1);
- TS_ASSERT(res[d_y] == y1);
- }
- }
-
- void testGaussElimRewriteForUremPartial5()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 3
- * ----^--- ^ --^-- ^
- * 2 4 6 18 --> 1 2 0 0
- * 4 5 6 24 0 0 0 0
- * 2 7 12 30 0 0 0 0
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_four),
- d_z_mul_six),
- d_three),
- d_eighteen);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_four, d_y_mul_five),
- d_z_mul_six),
- d_three),
- d_twentyfour);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_seven),
- d_z_mul_twelve),
- d_three),
- d_thirty);
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 1);
-
- Node x1 = d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_one32),
- d_three);
- Node y2 = d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_one32),
- d_three);
-
- /* result depends on order of variables in matrix */
- if (res.find(d_x) == res.end())
- {
- /*
- * y x z y x z
- * 4 2 6 18 --> 1 2 0 0
- * 5 4 6 24 0 0 0 0
- * 7 2 12 30 0 0 0 0
- *
- * y z x y z x
- * 4 6 2 18 --> 1 0 2 0
- * 5 6 4 24 0 0 0 0
- * 7 12 2 30 0 0 0 0
- *
- * z y x z y x
- * 6 4 2 18 --> 0 1 2 0
- * 6 5 4 24 0 0 0 0
- * 12 12 2 30 0 0 0 0
- *
- */
- TS_ASSERT(res[d_y] == y2);
- }
- else if (res.find(d_y) == res.end())
- {
- /*
- * x y z x y z
- * 2 4 6 18 --> 1 2 0 0
- * 4 5 6 24 0 0 0 0
- * 2 7 12 30 0 0 0 0
- *
- * x z y x z y
- * 2 6 4 18 --> 1 0 2 0
- * 4 6 5 24 0 0 0 0
- * 2 12 7 30 0 0 0 0
- *
- * z x y z x y
- * 6 2 4 18 --> 0 1 2 0
- * 6 4 5 24 0 0 0 0
- * 12 2 12 30 0 0 0 0
- *
- */
- TS_ASSERT(res[d_x] == x1);
- }
- else
- {
- TS_ASSERT(false);
- }
- }
-
- void testGaussElimRewriteForUremPartial6()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs --> lhs rhs modulo 11
- * ---^--- ^ ---^--- ^
- * x y z w x y z w
- * 1 2 0 6 2 1 2 0 6 2
- * 0 0 2 2 2 0 0 1 1 1
- * 0 0 0 1 2 0 0 0 1 2
- * ------------------------------------------------------------------- */
-
- Node y_mul_two = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_two);
- Node z_mul_two = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_two);
- Node w = bv::utils::mkConcat(
- d_zero, d_nm->mkVar("w", d_nm->mkBitVectorType(16)));
- Node w_mul_six = d_nm->mkNode(kind::BITVECTOR_MULT, w, d_six);
- Node w_mul_two = d_nm->mkNode(kind::BITVECTOR_MULT, w, d_two);
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, y_mul_two),
- w_mul_six),
- d_p),
- d_two);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, z_mul_two, w_mul_two),
- d_p),
- d_two);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM, w, d_p),
- d_two);
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 3);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_one32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_nine32)),
- d_p);
- Node z1 = d_ten32;
- Node w1 = d_two32;
-
- Node y2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_six32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_five32)),
- d_p);
- Node z2 = d_ten32;
- Node w2 = d_two32;
-
- /* result depends on order of variables in matrix */
- if (res.find(d_x) == res.end())
- {
- TS_ASSERT(res[d_y] == y2);
- TS_ASSERT(res[d_z] == z2);
- TS_ASSERT(res[w] == w2);
- }
- else if (res.find(d_y) == res.end())
- {
- TS_ASSERT(res[d_x] == x1);
- TS_ASSERT(res[d_z] == z1);
- TS_ASSERT(res[w] == w1);
- }
- else
- {
- TS_ASSERT(false);
- }
- }
-
- void testGaussElimRewriteForUremWithExprPartial()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- * ------------------------------------------------------------------- */
-
- Node zero = bv::utils::mkZero(8);
- Node xx = d_nm->mkVar("xx", d_nm->mkBitVectorType(8));
- Node yy = d_nm->mkVar("yy", d_nm->mkBitVectorType(8));
- Node zz = d_nm->mkVar("zz", d_nm->mkBitVectorType(8));
-
- Node x = bv::utils::mkConcat(
- d_zero,
- bv::utils::mkConcat(
- zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, xx), 7, 0)));
- Node y = bv::utils::mkConcat(
- d_zero,
- bv::utils::mkConcat(
- zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, yy), 7, 0)));
- Node z = bv::utils::mkConcat(
- d_zero,
- bv::utils::mkConcat(
- zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, zz), 7, 0)));
-
- Node x_mul_one = d_nm->mkNode(kind::BITVECTOR_MULT, x, d_one32);
- Node nine_mul_z = d_nm->mkNode(kind::BITVECTOR_MULT, d_nine32, z);
- Node one_mul_y = d_nm->mkNode(kind::BITVECTOR_MULT, d_one, y);
- Node z_mul_three = d_nm->mkNode(kind::BITVECTOR_MULT, z, d_three);
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, x_mul_one, nine_mul_z),
- d_p),
- d_seven);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, one_mul_y, z_mul_three),
- d_p),
- d_nine);
-
- std::vector<Node> eqs = {eq1, eq2};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 2);
-
- x = Rewriter::rewrite(x);
- y = Rewriter::rewrite(y);
- z = Rewriter::rewrite(z);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_seven32,
- d_nm->mkNode(kind::BITVECTOR_MULT, z, d_two32)),
- d_p);
- Node y1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nine32,
- d_nm->mkNode(kind::BITVECTOR_MULT, z, d_eight32)),
- d_p);
-
- Node x2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, y, d_three32)),
- d_p);
- Node z2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, y, d_seven32)),
- d_p);
-
- Node y3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, x, d_four32)),
- d_p);
- Node z3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, x, d_six32)),
- d_p);
-
- /* result depends on order of variables in matrix */
- if (res.find(x) == res.end())
- {
- /*
- * y z x y z x
- * 0 9 1 7 --> 1 0 7 3
- * 1 3 0 9 0 1 5 2
- *
- * z y x z y x
- * 9 0 1 7 --> 1 0 5 2
- * 3 1 0 9 0 1 7 3
- */
- TS_ASSERT(res[Rewriter::rewrite(y)] == y3);
- TS_ASSERT(res[Rewriter::rewrite(z)] == z3);
- }
- else if (res.find(y) == res.end())
- {
- /*
- * x z y x z y
- * 1 9 0 7 --> 1 0 8 2
- * 0 3 1 9 0 1 4 3
- *
- * z x y z x y
- * 9 1 0 7 --> 1 0 4 3
- * 3 0 1 9 0 1 8 2
- */
- TS_ASSERT(res[x] == x2);
- TS_ASSERT(res[z] == z2);
- }
- else
- {
- TS_ASSERT(res.find(z) == res.end());
- /*
- * x y z x y z
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- *
- * y x z y x z
- * 0 1 9 7 --> 1 0 3 9
- * 1 0 3 9 0 1 9 7
- */
- TS_ASSERT(res[x] == x1);
- TS_ASSERT(res[y] == y1);
- }
- }
-
- void testGaussElimRewriteForUremNAryPartial()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- * ------------------------------------------------------------------- */
-
- Node zero = bv::utils::mkZero(8);
- Node xx = d_nm->mkVar("xx", d_nm->mkBitVectorType(8));
- Node yy = d_nm->mkVar("yy", d_nm->mkBitVectorType(8));
- Node zz = d_nm->mkVar("zz", d_nm->mkBitVectorType(8));
-
- Node x = bv::utils::mkConcat(
- d_zero,
- bv::utils::mkConcat(
- zero,
- bv::utils::mkExtract(
- d_nm->mkNode(kind::BITVECTOR_CONCAT, zero, xx), 7, 0)));
- Node y = bv::utils::mkConcat(
- d_zero,
- bv::utils::mkConcat(
- zero,
- bv::utils::mkExtract(
- d_nm->mkNode(kind::BITVECTOR_CONCAT, zero, yy), 7, 0)));
- Node z = bv::utils::mkConcat(
- d_zero,
- bv::utils::mkConcat(
- zero,
- bv::utils::mkExtract(
- d_nm->mkNode(kind::BITVECTOR_CONCAT, zero, zz), 7, 0)));
-
- NodeBuilder<> nbx(d_nm, kind::BITVECTOR_MULT);
- nbx << d_x << d_one << x;
- Node x_mul_one_mul_xx = nbx.constructNode();
- NodeBuilder<> nby(d_nm, kind::BITVECTOR_MULT);
- nby << d_y << y << d_one;
- Node y_mul_yy_mul_one = nby.constructNode();
- NodeBuilder<> nbz(d_nm, kind::BITVECTOR_MULT);
- nbz << d_three << d_z << z;
- Node three_mul_z_mul_zz = nbz.constructNode();
- NodeBuilder<> nbz2(d_nm, kind::BITVECTOR_MULT);
- nbz2 << d_z << d_nine << z;
- Node z_mul_nine_mul_zz = nbz2.constructNode();
-
- Node x_mul_xx = d_nm->mkNode(kind::BITVECTOR_MULT, d_x, x);
- Node y_mul_yy = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, y);
- Node z_mul_zz = d_nm->mkNode(kind::BITVECTOR_MULT, d_z, z);
-
- Node eq1 = d_nm->mkNode(kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- x_mul_one_mul_xx,
- z_mul_nine_mul_zz),
- d_p),
- d_seven);
-
- Node eq2 = d_nm->mkNode(kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- y_mul_yy_mul_one,
- three_mul_z_mul_zz),
- d_p),
- d_nine);
-
- std::vector<Node> eqs = {eq1, eq2};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::PARTIAL);
- TS_ASSERT(res.size() == 2);
-
- x_mul_xx = Rewriter::rewrite(x_mul_xx);
- y_mul_yy = Rewriter::rewrite(y_mul_yy);
- z_mul_zz = Rewriter::rewrite(z_mul_zz);
-
- Node x1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_seven32,
- d_nm->mkNode(kind::BITVECTOR_MULT, z_mul_zz, d_two32)),
- d_p);
- Node y1 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nine32,
- d_nm->mkNode(kind::BITVECTOR_MULT, z_mul_zz, d_eight32)),
- d_p);
-
- Node x2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, y_mul_yy, d_three32)),
- d_p);
- Node z2 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, y_mul_yy, d_seven32)),
- d_p);
-
- Node y3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, x_mul_xx, d_four32)),
- d_p);
- Node z3 = d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, x_mul_xx, d_six32)),
- d_p);
-
- /* result depends on order of variables in matrix */
- if (res.find(x_mul_xx) == res.end())
- {
- /*
- * y z x y z x
- * 0 9 1 7 --> 1 0 7 3
- * 1 3 0 9 0 1 5 2
- *
- * z y x z y x
- * 9 0 1 7 --> 1 0 5 2
- * 3 1 0 9 0 1 7 3
- */
- TS_ASSERT(res[y_mul_yy] == y3);
- TS_ASSERT(res[z_mul_zz] == z3);
- }
- else if (res.find(y_mul_yy) == res.end())
- {
- /*
- * x z y x z y
- * 1 9 0 7 --> 1 0 8 2
- * 0 3 1 9 0 1 4 3
- *
- * z x y z x y
- * 9 1 0 7 --> 1 0 4 3
- * 3 0 1 9 0 1 8 2
- */
- TS_ASSERT(res[x_mul_xx] == x2);
- TS_ASSERT(res[z_mul_zz] == z2);
- }
- else
- {
- TS_ASSERT(res.find(z_mul_zz) == res.end());
- /*
- * x y z x y z
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- *
- * y x z y x z
- * 0 1 9 7 --> 1 0 3 9
- * 1 0 3 9 0 1 9 7
- */
- TS_ASSERT(res[x_mul_xx] == x1);
- TS_ASSERT(res[y_mul_yy] == y1);
- }
- }
-
- void testGaussElimRewriteForUremNotInvalid1()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * 3x / 2z = 4 modulo 11
- * 2x % 5y = 2
- * y O z = 5
- * ------------------------------------------------------------------- */
-
- Node n1 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_three, d_x),
- d_nm->mkNode(kind::BITVECTOR_MULT, d_two, d_y));
- Node n2 = d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_two, d_x),
- d_nm->mkNode(kind::BITVECTOR_MULT, d_five, d_y));
-
- Node n3 = bv::utils::mkConcat(
- d_zero,
- bv::utils::mkExtract(
- d_nm->mkNode(kind::BITVECTOR_CONCAT, d_y, d_z), 15, 0));
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL, d_nm->mkNode(kind::BITVECTOR_UREM, n1, d_p), d_four);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL, d_nm->mkNode(kind::BITVECTOR_UREM, n2, d_p), d_two);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL, d_nm->mkNode(kind::BITVECTOR_UREM, n3, d_p), d_five);
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::UNIQUE);
- TS_ASSERT(res.size() == 3);
-
- TS_ASSERT(res[n1] == d_four32);
- TS_ASSERT(res[n2] == d_two32);
- TS_ASSERT(res[n3] == d_five32);
- }
-
- void testGaussElimRewriteForUremNotInvalid2()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * x*y = 4 modulo 11
- * x*y*z = 2
- * 2*x*y + 2*z = 9
- * ------------------------------------------------------------------- */
-
- Node zero32 = bv::utils::mkZero(32);
-
- Node x = bv::utils::mkConcat(zero32,
- d_nm->mkVar("x", d_nm->mkBitVectorType(16)));
- Node y = bv::utils::mkConcat(zero32,
- d_nm->mkVar("y", d_nm->mkBitVectorType(16)));
- Node z = bv::utils::mkConcat(zero32,
- d_nm->mkVar("z", d_nm->mkBitVectorType(16)));
-
- Node n1 = d_nm->mkNode(kind::BITVECTOR_MULT, x, y);
- Node n2 = d_nm->mkNode(
- kind::BITVECTOR_MULT, d_nm->mkNode(kind::BITVECTOR_MULT, x, y), z);
- Node n3 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_MULT,
- d_nm->mkNode(kind::BITVECTOR_MULT, x, y),
- bv::utils::mkConcat(d_zero, d_two)),
- d_nm->mkNode(
- kind::BITVECTOR_MULT, bv::utils::mkConcat(d_zero, d_two), z));
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM, n1, bv::utils::mkConcat(d_zero, d_p)),
- bv::utils::mkConcat(d_zero, d_four));
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM, n2, bv::utils::mkConcat(d_zero, d_p)),
- bv::utils::mkConcat(d_zero, d_two));
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM, n3, bv::utils::mkConcat(d_zero, d_p)),
- bv::utils::mkConcat(d_zero, d_nine));
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::UNIQUE);
- TS_ASSERT(res.size() == 3);
-
- n1 = Rewriter::rewrite(n1);
- n2 = Rewriter::rewrite(n2);
- z = Rewriter::rewrite(z);
-
- TS_ASSERT(res[n1] ==bv::utils::mkConst(48, 4));
- TS_ASSERT(res[n2] ==bv::utils::mkConst(48, 2));
-
- Integer twoxy = (res[n1].getConst<BitVector>().getValue() * Integer(2))
- .euclidianDivideRemainder(Integer(48));
- Integer twoz = (res[z].getConst<BitVector>().getValue() * Integer(2))
- .euclidianDivideRemainder(Integer(48));
- Integer r = (twoxy + twoz).euclidianDivideRemainder(Integer(11));
- TS_ASSERT(r == Integer(9));
- }
-
- void testGaussElimRewriteForUremInvalid()
- {
- std::unordered_map<Node, Node, NodeHashFunction> res;
- BVGauss::Result ret;
-
- /* -------------------------------------------------------------------
- * x*y = 4 modulo 11
- * x*y*z = 2
- * 2*x*y = 9
- * ------------------------------------------------------------------- */
-
- Node zero32 = bv::utils::mkZero(32);
-
- Node x = bv::utils::mkConcat(zero32,
- d_nm->mkVar("x", d_nm->mkBitVectorType(16)));
- Node y = bv::utils::mkConcat(zero32,
- d_nm->mkVar("y", d_nm->mkBitVectorType(16)));
- Node z = bv::utils::mkConcat(zero32,
- d_nm->mkVar("z", d_nm->mkBitVectorType(16)));
-
- Node n1 = d_nm->mkNode(kind::BITVECTOR_MULT, x, y);
- Node n2 = d_nm->mkNode(
- kind::BITVECTOR_MULT, d_nm->mkNode(kind::BITVECTOR_MULT, x, y), z);
- Node n3 = d_nm->mkNode(kind::BITVECTOR_MULT,
- d_nm->mkNode(kind::BITVECTOR_MULT, x, y),
- bv::utils::mkConcat(d_zero, d_two));
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM, n1, bv::utils::mkConcat(d_zero, d_p)),
- bv::utils::mkConcat(d_zero, d_four));
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM, n2, bv::utils::mkConcat(d_zero, d_p)),
- bv::utils::mkConcat(d_zero, d_two));
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM, n3, bv::utils::mkConcat(d_zero, d_p)),
- bv::utils::mkConcat(d_zero, d_nine));
-
- std::vector<Node> eqs = {eq1, eq2, eq3};
- ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
- TS_ASSERT(ret == BVGauss::Result::INVALID);
- }
-
- void testGaussElimRewriteUnique1()
- {
- /* -------------------------------------------------------------------
- * lhs rhs modulo 11
- * --^-- ^
- * 1 1 1 5
- * 2 3 5 8
- * 4 0 5 2
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_one),
- d_z_mul_one),
- d_p),
- d_five);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
- d_z_mul_five),
- d_p),
- d_eight);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_four, d_z_mul_five),
- d_p),
- d_two);
-
- Node a = d_nm->mkNode(kind::AND, d_nm->mkNode(kind::AND, eq1, eq2), eq3);
-
- AssertionPipeline apipe;
- apipe.push_back(a);
- passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
- std::unordered_map<Node, Node, NodeHashFunction> res;
- PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
- TS_ASSERT (pres == PreprocessingPassResult::NO_CONFLICT);
- Node resx = d_nm->mkNode(
- kind::EQUAL, d_x, d_nm->mkConst<BitVector>(BitVector(32, 3u)));
- Node resy = d_nm->mkNode(
- kind::EQUAL, d_y, d_nm->mkConst<BitVector>(BitVector(32, 4u)));
- Node resz = d_nm->mkNode(
- kind::EQUAL, d_z, d_nm->mkConst<BitVector>(BitVector(32, 9u)));
- TS_ASSERT(apipe.size() == 4);
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resx) != apipe.end());
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resy) != apipe.end());
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resz) != apipe.end());
- }
-
- void testGaussElimRewriteUnique2()
- {
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 1 1 5 1 0 0 3
- * 2 3 5 8 0 1 0 4
- * 4 0 5 2 0 0 1 9
- *
- * lhs rhs lhs rhs modulo 7
- * --^-- ^ --^-- ^
- * 2 6 0 4 1 0 0 3
- * 4 6 0 3 0 1 0 2
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_y_mul_one),
- d_z_mul_one),
- d_p),
- d_five);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, d_y_mul_three),
- d_z_mul_five),
- d_p),
- d_eight);
-
- Node eq3 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_four, d_z_mul_five),
- d_p),
- d_two);
-
- Node y_mul_six = d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_six);
-
- Node eq4 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_two, y_mul_six),
- d_seven),
- d_four);
-
- Node eq5 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_four, y_mul_six),
- d_seven),
- d_three);
-
- Node a = d_nm->mkNode(kind::AND, d_nm->mkNode(kind::AND, eq1, eq2), eq3);
-
- AssertionPipeline apipe;
- apipe.push_back(a);
- apipe.push_back(eq4);
- apipe.push_back(eq5);
- passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
- std::unordered_map<Node, Node, NodeHashFunction> res;
- PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
- TS_ASSERT (pres == PreprocessingPassResult::NO_CONFLICT);
- Node resx1 = d_nm->mkNode(
- kind::EQUAL, d_x, d_nm->mkConst<BitVector>(BitVector(32, 3u)));
- Node resx2 = d_nm->mkNode(
- kind::EQUAL, d_x, d_nm->mkConst<BitVector>(BitVector(32, 3u)));
- Node resy1 = d_nm->mkNode(
- kind::EQUAL, d_y, d_nm->mkConst<BitVector>(BitVector(32, 4u)));
- Node resy2 = d_nm->mkNode(
- kind::EQUAL, d_y, d_nm->mkConst<BitVector>(BitVector(32, 2u)));
- Node resz = d_nm->mkNode(
- kind::EQUAL, d_z, d_nm->mkConst<BitVector>(BitVector(32, 9u)));
- TS_ASSERT(apipe.size() == 8);
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resx1) != apipe.end());
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resx2) != apipe.end());
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resy1) != apipe.end());
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resy2) != apipe.end());
- TS_ASSERT(std::find(apipe.begin(), apipe.end(), resz) != apipe.end());
- }
-
- void testGaussElimRewritePartial()
- {
- /* -------------------------------------------------------------------
- * lhs rhs lhs rhs modulo 11
- * --^-- ^ --^-- ^
- * 1 0 9 7 --> 1 0 9 7
- * 0 1 3 9 0 1 3 9
- * ------------------------------------------------------------------- */
-
- Node eq1 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_x_mul_one, d_z_mul_nine),
- d_p),
- d_seven);
-
- Node eq2 = d_nm->mkNode(
- kind::EQUAL,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS, d_y_mul_one, d_z_mul_three),
- d_p),
- d_nine);
-
- AssertionPipeline apipe;
- apipe.push_back(eq1);
- apipe.push_back(eq2);
- passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
- std::unordered_map<Node, Node, NodeHashFunction> res;
- PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
- TS_ASSERT (pres == PreprocessingPassResult::NO_CONFLICT);
- TS_ASSERT(apipe.size() == 4);
-
- Node resx1 = d_nm->mkNode(
- kind::EQUAL,
- d_x,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_seven32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
- d_p));
- Node resy1 = d_nm->mkNode(
- kind::EQUAL,
- d_y,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_nine32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
- d_p));
-
- Node resx2 = d_nm->mkNode(
- kind::EQUAL,
- d_x,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
- d_p));
- Node resz2 = d_nm->mkNode(
- kind::EQUAL,
- d_z,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
- d_p));
-
- Node resy3 = d_nm->mkNode(
- kind::EQUAL,
- d_y,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_three32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
- d_p));
- Node resz3 = d_nm->mkNode(
- kind::EQUAL,
- d_z,
- d_nm->mkNode(
- kind::BITVECTOR_UREM,
- d_nm->mkNode(kind::BITVECTOR_PLUS,
- d_two32,
- d_nm->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
- d_p));
-
- bool fx1 = std::find(apipe.begin(), apipe.end(), resx1) != apipe.end();
- bool fy1 = std::find(apipe.begin(), apipe.end(), resy1) != apipe.end();
- bool fx2 = std::find(apipe.begin(), apipe.end(), resx2) != apipe.end();
- bool fz2 = std::find(apipe.begin(), apipe.end(), resz2) != apipe.end();
- bool fy3 = std::find(apipe.begin(), apipe.end(), resy3) != apipe.end();
- bool fz3 = std::find(apipe.begin(), apipe.end(), resz3) != apipe.end();
-
- /* result depends on order of variables in matrix */
- TS_ASSERT((fx1 && fy1) || (fx2 && fz2) || (fy3 && fz3));
- }
-
- void testGetMinBw1()
- {
- TS_ASSERT(BVGauss::getMinBwExpr(bv::utils::mkConst(32, 11)) == 4);
-
- TS_ASSERT(BVGauss::getMinBwExpr(d_p) == 4);
- TS_ASSERT(BVGauss::getMinBwExpr(d_x) == 16);
-
- Node extp = bv::utils::mkExtract(d_p, 4, 0);
- TS_ASSERT(BVGauss::getMinBwExpr(extp) == 4);
- Node extx = bv::utils::mkExtract(d_x, 4, 0);
- TS_ASSERT(BVGauss::getMinBwExpr(extx) == 5);
-
- Node zextop8 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(8));
- Node zextop16 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(16));
- Node zextop32 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(32));
- Node zextop40 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(40));
-
- Node zext40p = d_nm->mkNode(zextop8, d_p);
- TS_ASSERT(BVGauss::getMinBwExpr(zext40p) == 4);
- Node zext40x = d_nm->mkNode(zextop8, d_x);
- TS_ASSERT(BVGauss::getMinBwExpr(zext40x) == 16);
-
- Node zext48p = d_nm->mkNode(zextop16, d_p);
- TS_ASSERT(BVGauss::getMinBwExpr(zext48p) == 4);
- Node zext48x = d_nm->mkNode(zextop16, d_x);
- TS_ASSERT(BVGauss::getMinBwExpr(zext48x) == 16);
-
- Node p8 = d_nm->mkConst<BitVector>(BitVector(8, 11u));
- Node x8 = d_nm->mkVar("x8", d_nm->mkBitVectorType(8));
-
- Node zext48p8 = d_nm->mkNode(zextop40, p8);
- TS_ASSERT(BVGauss::getMinBwExpr(zext48p8) == 4);
- Node zext48x8 = d_nm->mkNode(zextop40, x8);
- TS_ASSERT(BVGauss::getMinBwExpr(zext48x8) == 8);
-
- Node mult1p = d_nm->mkNode(kind::BITVECTOR_MULT, extp, extp);
- TS_ASSERT(BVGauss::getMinBwExpr(mult1p) == 5);
- Node mult1x = d_nm->mkNode(kind::BITVECTOR_MULT, extx, extx);
- TS_ASSERT(BVGauss::getMinBwExpr(mult1x) == 0);
-
- Node mult2p = d_nm->mkNode(kind::BITVECTOR_MULT, zext40p, zext40p);
- TS_ASSERT(BVGauss::getMinBwExpr(mult2p) == 7);
- Node mult2x = d_nm->mkNode(kind::BITVECTOR_MULT, zext40x, zext40x);
- TS_ASSERT(BVGauss::getMinBwExpr(mult2x) == 32);
-
- NodeBuilder<> nbmult3p(kind::BITVECTOR_MULT);
- nbmult3p << zext48p << zext48p << zext48p;
- Node mult3p = nbmult3p;
- TS_ASSERT(BVGauss::getMinBwExpr(mult3p) == 11);
- NodeBuilder<> nbmult3x(kind::BITVECTOR_MULT);
- nbmult3x << zext48x << zext48x << zext48x;
- Node mult3x = nbmult3x;
- TS_ASSERT(BVGauss::getMinBwExpr(mult3x) == 48);
-
- NodeBuilder<> nbmult4p(kind::BITVECTOR_MULT);
- nbmult4p << zext48p << zext48p8 << zext48p;
- Node mult4p = nbmult4p;
- TS_ASSERT(BVGauss::getMinBwExpr(mult4p) == 11);
- NodeBuilder<> nbmult4x(kind::BITVECTOR_MULT);
- nbmult4x << zext48x << zext48x8 << zext48x;
- Node mult4x = nbmult4x;
- TS_ASSERT(BVGauss::getMinBwExpr(mult4x) == 40);
-
- Node concat1p = bv::utils::mkConcat(d_p, zext48p);
- TS_ASSERT(BVGauss::getMinBwExpr(concat1p) == 52);
- Node concat1x = bv::utils::mkConcat(d_x, zext48x);
- TS_ASSERT(BVGauss::getMinBwExpr(concat1x) == 64);
-
- Node concat2p = bv::utils::mkConcat(bv::utils::mkZero(16), zext48p);
- TS_ASSERT(BVGauss::getMinBwExpr(concat2p) == 4);
- Node concat2x = bv::utils::mkConcat(bv::utils::mkZero(16), zext48x);
- TS_ASSERT(BVGauss::getMinBwExpr(concat2x) == 16);
-
- Node udiv1p = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48p, zext48p);
- TS_ASSERT(BVGauss::getMinBwExpr(udiv1p) == 1);
- Node udiv1x = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48x, zext48x);
- TS_ASSERT(BVGauss::getMinBwExpr(udiv1x) == 48);
-
- Node udiv2p = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48p, zext48p8);
- TS_ASSERT(BVGauss::getMinBwExpr(udiv2p) == 1);
- Node udiv2x = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, zext48x, zext48x8);
- TS_ASSERT(BVGauss::getMinBwExpr(udiv2x) == 48);
-
- Node urem1p = d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48p, zext48p);
- TS_ASSERT(BVGauss::getMinBwExpr(urem1p) == 1);
- Node urem1x = d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48x, zext48x);
- TS_ASSERT(BVGauss::getMinBwExpr(urem1x) == 1);
-
- Node urem2p = d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48p, zext48p8);
- TS_ASSERT(BVGauss::getMinBwExpr(urem2p) == 1);
- Node urem2x = d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48x, zext48x8);
- TS_ASSERT(BVGauss::getMinBwExpr(urem2x) == 16);
-
- Node urem3p = d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48p8, zext48p);
- TS_ASSERT(BVGauss::getMinBwExpr(urem3p) == 1);
- Node urem3x = d_nm->mkNode(kind::BITVECTOR_UREM_TOTAL, zext48x8, zext48x);
- TS_ASSERT(BVGauss::getMinBwExpr(urem3x) == 8);
-
- Node add1p = d_nm->mkNode(kind::BITVECTOR_PLUS, extp, extp);
- TS_ASSERT(BVGauss::getMinBwExpr(add1p) == 5);
- Node add1x = d_nm->mkNode(kind::BITVECTOR_PLUS, extx, extx);
- TS_ASSERT(BVGauss::getMinBwExpr(add1x) == 0);
-
- Node add2p = d_nm->mkNode(kind::BITVECTOR_PLUS, zext40p, zext40p);
- TS_ASSERT(BVGauss::getMinBwExpr(add2p) == 5);
- Node add2x = d_nm->mkNode(kind::BITVECTOR_PLUS, zext40x, zext40x);
- TS_ASSERT(BVGauss::getMinBwExpr(add2x) == 17);
-
- Node add3p = d_nm->mkNode(kind::BITVECTOR_PLUS, zext48p8, zext48p);
- TS_ASSERT(BVGauss::getMinBwExpr(add3p) == 5);
- Node add3x = d_nm->mkNode(kind::BITVECTOR_PLUS, zext48x8, zext48x);
- TS_ASSERT(BVGauss::getMinBwExpr(add3x) == 17);
-
- NodeBuilder<> nbadd4p(kind::BITVECTOR_PLUS);
- nbadd4p << zext48p << zext48p << zext48p;
- Node add4p = nbadd4p;
- TS_ASSERT(BVGauss::getMinBwExpr(add4p) == 6);
- NodeBuilder<> nbadd4x(kind::BITVECTOR_PLUS);
- nbadd4x << zext48x << zext48x << zext48x;
- Node add4x = nbadd4x;
- TS_ASSERT(BVGauss::getMinBwExpr(add4x) == 18);
-
- NodeBuilder<> nbadd5p(kind::BITVECTOR_PLUS);
- nbadd5p << zext48p << zext48p8 << zext48p;
- Node add5p = nbadd5p;
- TS_ASSERT(BVGauss::getMinBwExpr(add5p) == 6);
- NodeBuilder<> nbadd5x(kind::BITVECTOR_PLUS);
- nbadd5x << zext48x << zext48x8 << zext48x;
- Node add5x = nbadd5x;
- TS_ASSERT(BVGauss::getMinBwExpr(add5x) == 18);
-
- NodeBuilder<> nbadd6p(kind::BITVECTOR_PLUS);
- nbadd6p << zext48p << zext48p << zext48p << zext48p;
- Node add6p = nbadd6p;
- TS_ASSERT(BVGauss::getMinBwExpr(add6p) == 6);
- NodeBuilder<> nbadd6x(kind::BITVECTOR_PLUS);
- nbadd6x << zext48x << zext48x << zext48x << zext48x;
- Node add6x = nbadd6x;
- TS_ASSERT(BVGauss::getMinBwExpr(add6x) == 18);
-
- Node not1p = d_nm->mkNode(kind::BITVECTOR_NOT, zext40p);
- TS_ASSERT(BVGauss::getMinBwExpr(not1p) == 40);
- Node not1x = d_nm->mkNode(kind::BITVECTOR_NOT, zext40x);
- TS_ASSERT(BVGauss::getMinBwExpr(not1x) == 40);
- }
-
- void testGetMinBw2()
- {
- /* ((_ zero_extend 5)
- * ((_ extract 7 0) ((_ zero_extend 15) d_p))) */
- Node zextop5 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
- Node zextop15 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
- Node zext1 = d_nm->mkNode(zextop15, d_p);
- Node ext = bv::utils::mkExtract(zext1, 7, 0);
- Node zext2 = d_nm->mkNode(zextop5, ext);
- TS_ASSERT(BVGauss::getMinBwExpr(zext2) == 4);
- }
-
- void testGetMinBw3a()
- {
- /* ((_ zero_extend 5)
- * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x z)))
- * ((_ extract 4 0) z))) */
- Node x = d_nm->mkVar("x", d_nm->mkBitVectorType(16));
- Node y = d_nm->mkVar("y", d_nm->mkBitVectorType(16));
- Node z = d_nm->mkVar("z", d_nm->mkBitVectorType(16));
- Node zextop5 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
- Node udiv1 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, x, y);
- Node zext1 = d_nm->mkNode(zextop5, udiv1);
- Node ext1 = bv::utils::mkExtract(zext1, 4, 0);
- Node ext2 = bv::utils::mkExtract(z, 4, 0);
- Node udiv2 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1, ext2);
- Node zext2 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2);
- TS_ASSERT(BVGauss::getMinBwExpr(zext2) == 5);
- }
-
- void testGetMinBw3b()
- {
- /* ((_ zero_extend 5)
- * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x z)))
- * ((_ extract 4 0) z))) */
- Node zextop5 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
- Node udiv1 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, d_x, d_y);
- Node zext1 = d_nm->mkNode(zextop5, udiv1);
- Node ext1 = bv::utils::mkExtract(zext1, 4, 0);
- Node ext2 = bv::utils::mkExtract(d_z, 4, 0);
- Node udiv2 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1, ext2);
- Node zext2 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2);
- TS_ASSERT(BVGauss::getMinBwExpr(zext2) == 5);
- }
-
- void testGetMinBw4a()
- {
- /* (bvadd
- * ((_ zero_extend 5)
- * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x y)))
- * ((_ extract 4 0) z)))
- * ((_ zero_extend 7)
- * (bvudiv ((_ extract 2 0) ((_ zero_extend 5) (bvudiv x y)))
- * ((_ extract 2 0) z))) */
- Node x = d_nm->mkVar("x", d_nm->mkBitVectorType(16));
- Node y = d_nm->mkVar("y", d_nm->mkBitVectorType(16));
- Node z = d_nm->mkVar("z", d_nm->mkBitVectorType(16));
- Node zextop5 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
- Node zextop7 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(7));
-
- Node udiv1 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, x, y);
- Node zext1 = d_nm->mkNode(zextop5, udiv1);
-
- Node ext1_1 = bv::utils::mkExtract(zext1, 4, 0);
- Node ext2_1 = bv::utils::mkExtract(z, 4, 0);
- Node udiv2_1 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_1, ext2_1);
- Node zext2_1 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2_1);
-
- Node ext1_2 = bv::utils::mkExtract(zext1, 2, 0);
- Node ext2_2 = bv::utils::mkExtract(z, 2, 0);
- Node udiv2_2 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_2, ext2_2);
- Node zext2_2 = d_nm->mkNode(zextop7, udiv2_2);
-
- Node plus = d_nm->mkNode(kind::BITVECTOR_PLUS, zext2_1, zext2_2);
-
- TS_ASSERT(BVGauss::getMinBwExpr(plus) == 6);
- }
-
- void testGetMinBw4b()
- {
- /* (bvadd
- * ((_ zero_extend 5)
- * (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x y)))
- * ((_ extract 4 0) z)))
- * ((_ zero_extend 7)
- * (bvudiv ((_ extract 2 0) ((_ zero_extend 5) (bvudiv x y)))
- * ((_ extract 2 0) z))) */
- Node zextop5 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
- Node zextop7 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(7));
-
- Node udiv1 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, d_x, d_y);
- Node zext1 = d_nm->mkNode(zextop5, udiv1);
-
- Node ext1_1 = bv::utils::mkExtract(zext1, 4, 0);
- Node ext2_1 = bv::utils::mkExtract(d_z, 4, 0);
- Node udiv2_1 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_1, ext2_1);
- Node zext2_1 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2_1);
-
- Node ext1_2 = bv::utils::mkExtract(zext1, 2, 0);
- Node ext2_2 = bv::utils::mkExtract(d_z, 2, 0);
- Node udiv2_2 = d_nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, ext1_2, ext2_2);
- Node zext2_2 = d_nm->mkNode(zextop7, udiv2_2);
-
- Node plus = d_nm->mkNode(kind::BITVECTOR_PLUS, zext2_1, zext2_2);
-
- TS_ASSERT(BVGauss::getMinBwExpr(plus) == 6);
- }
-
- void testGetMinBw5a()
- {
- /* (bvadd
- * (bvadd
- * (bvadd
- * (bvadd
- * (bvadd
- * (bvadd
- * (bvadd (bvmul (_ bv86 13)
- * ((_ zero_extend 5)
- * ((_ extract 7 0) ((_ zero_extend 15) x))))
- * (bvmul (_ bv41 13)
- * ((_ zero_extend 5)
- * ((_ extract 7 0) ((_ zero_extend 15) y)))))
- * (bvmul (_ bv37 13)
- * ((_ zero_extend 5)
- * ((_ extract 7 0) ((_ zero_extend 15) z)))))
- * (bvmul (_ bv170 13)
- * ((_ zero_extend 5)
- * ((_ extract 7 0) ((_ zero_extend 15) u)))))
- * (bvmul (_ bv112 13)
- * ((_ zero_extend 5)
- * ((_ extract 7 0) ((_ zero_extend 15) v)))))
- * (bvmul (_ bv195 13) ((_ zero_extend 5) ((_ extract 15 8) s))))
- * (bvmul (_ bv124 13) ((_ zero_extend 5) ((_ extract 7 0) s))))
- * (bvmul (_ bv83 13)
- * ((_ zero_extend 5) ((_ extract 7 0) ((_ zero_extend 15) w)))))
- */
- Node x =bv::utils::mkVar(1);
- Node y =bv::utils::mkVar(1);
- Node z =bv::utils::mkVar(1);
- Node u =bv::utils::mkVar(1);
- Node v =bv::utils::mkVar(1);
- Node w =bv::utils::mkVar(1);
- Node s =bv::utils::mkVar(16);
-
- Node zextop5 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
- Node zextop15 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
-
- Node zext15x = d_nm->mkNode(zextop15, x);
- Node zext15y = d_nm->mkNode(zextop15, y);
- Node zext15z = d_nm->mkNode(zextop15, z);
- Node zext15u = d_nm->mkNode(zextop15, u);
- Node zext15v = d_nm->mkNode(zextop15, v);
- Node zext15w = d_nm->mkNode(zextop15, w);
-
- Node ext7x = bv::utils::mkExtract(zext15x, 7, 0);
- Node ext7y = bv::utils::mkExtract(zext15y, 7, 0);
- Node ext7z = bv::utils::mkExtract(zext15z, 7, 0);
- Node ext7u = bv::utils::mkExtract(zext15u, 7, 0);
- Node ext7v = bv::utils::mkExtract(zext15v, 7, 0);
- Node ext7w = bv::utils::mkExtract(zext15w, 7, 0);
- Node ext7s = bv::utils::mkExtract(s, 7, 0);
- Node ext15s = bv::utils::mkExtract(s, 15, 8);
-
- Node xx = bv::utils::mkConcat(bv::utils::mkZero(5), ext7x);
- Node yy = bv::utils::mkConcat(bv::utils::mkZero(5), ext7y);
- Node zz = bv::utils::mkConcat(bv::utils::mkZero(5), ext7z);
- Node uu = bv::utils::mkConcat(bv::utils::mkZero(5), ext7u);
- Node vv = bv::utils::mkConcat(bv::utils::mkZero(5), ext7v);
- Node ww = bv::utils::mkConcat(bv::utils::mkZero(5), ext7w);
- Node s7 = bv::utils::mkConcat(bv::utils::mkZero(5), ext7s);
- Node s15 = bv::utils::mkConcat(bv::utils::mkZero(5), ext15s);
-
- Node plus1 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 86), xx),
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 41), yy));
- Node plus2 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus1,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 37), zz));
- Node plus3 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus2,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 170), uu));
- Node plus4 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus3,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 112), uu));
- Node plus5 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus4,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 195), s15));
- Node plus6 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus5,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 124), s7));
- Node plus7 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus6,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(13, 83), ww));
-
- TS_ASSERT(BVGauss::getMinBwExpr(plus7) == 0);
- }
-
- void testGetMinBw5b()
- {
- /* (bvadd
- * (bvadd
- * (bvadd
- * (bvadd
- * (bvadd
- * (bvadd
- * (bvadd (bvmul (_ bv86 20)
- * ((_ zero_extend 12)
- * ((_ extract 7 0) ((_ zero_extend 15) x))))
- * (bvmul (_ bv41 20)
- * ((_ zero_extend 12)
- * ((_ extract 7 0) ((_ zero_extend 15) y)))))
- * (bvmul (_ bv37 20)
- * ((_ zero_extend 12)
- * ((_ extract 7 0) ((_ zero_extend 15) z)))))
- * (bvmul (_ bv170 20)
- * ((_ zero_extend 12)
- * ((_ extract 7 0) ((_ zero_extend 15) u)))))
- * (bvmul (_ bv112 20)
- * ((_ zero_extend 12)
- * ((_ extract 7 0) ((_ zero_extend 15) v)))))
- * (bvmul (_ bv195 20) ((_ zero_extend 12) ((_ extract 15 8) s))))
- * (bvmul (_ bv124 20) ((_ zero_extend 12) ((_ extract 7 0) s))))
- * (bvmul (_ bv83 20)
- * ((_ zero_extend 12) ((_ extract 7 0) ((_ zero_extend 15) w)))))
- */
- Node x =bv::utils::mkVar(1);
- Node y =bv::utils::mkVar(1);
- Node z =bv::utils::mkVar(1);
- Node u =bv::utils::mkVar(1);
- Node v =bv::utils::mkVar(1);
- Node w =bv::utils::mkVar(1);
- Node s =bv::utils::mkVar(16);
-
- Node zextop15 = d_nm->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
-
- Node zext15x = d_nm->mkNode(zextop15, x);
- Node zext15y = d_nm->mkNode(zextop15, y);
- Node zext15z = d_nm->mkNode(zextop15, z);
- Node zext15u = d_nm->mkNode(zextop15, u);
- Node zext15v = d_nm->mkNode(zextop15, v);
- Node zext15w = d_nm->mkNode(zextop15, w);
-
- Node ext7x = bv::utils::mkExtract(zext15x, 7, 0);
- Node ext7y = bv::utils::mkExtract(zext15y, 7, 0);
- Node ext7z = bv::utils::mkExtract(zext15z, 7, 0);
- Node ext7u = bv::utils::mkExtract(zext15u, 7, 0);
- Node ext7v = bv::utils::mkExtract(zext15v, 7, 0);
- Node ext7w = bv::utils::mkExtract(zext15w, 7, 0);
- Node ext7s = bv::utils::mkExtract(s, 7, 0);
- Node ext15s = bv::utils::mkExtract(s, 15, 8);
-
- Node xx = bv::utils::mkConcat(bv::utils::mkZero(12), ext7x);
- Node yy = bv::utils::mkConcat(bv::utils::mkZero(12), ext7y);
- Node zz = bv::utils::mkConcat(bv::utils::mkZero(12), ext7z);
- Node uu = bv::utils::mkConcat(bv::utils::mkZero(12), ext7u);
- Node vv = bv::utils::mkConcat(bv::utils::mkZero(12), ext7v);
- Node ww = bv::utils::mkConcat(bv::utils::mkZero(12), ext7w);
- Node s7 = bv::utils::mkConcat(bv::utils::mkZero(12), ext7s);
- Node s15 = bv::utils::mkConcat(bv::utils::mkZero(12), ext15s);
-
- Node plus1 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 86), xx),
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 41), yy));
- Node plus2 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus1,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 37), zz));
- Node plus3 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus2,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 170), uu));
- Node plus4 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus3,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 112), uu));
- Node plus5 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus4,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 195), s15));
- Node plus6 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus5,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 124), s7));
- Node plus7 = d_nm->mkNode(
- kind::BITVECTOR_PLUS,
- plus6,
- d_nm->mkNode(kind::BITVECTOR_MULT, bv::utils::mkConst(20, 83), ww));
-
- TS_ASSERT(BVGauss::getMinBwExpr(plus7) == 19);
- TS_ASSERT(BVGauss::getMinBwExpr(Rewriter::rewrite(plus7)) == 17);
- }
-
-};