GCC Code Coverage Report
Directory: . Exec Total Coverage
File: test/unit/preprocessing/pass_bv_gauss_white.cpp Lines: 1279 1314 97.3 %
Date: 2021-05-22 Branches: 4785 11225 42.6 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Aina Niemetz, Mathias Preiner, Andres Noetzli
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * Unit tests for Gaussian Elimination preprocessing pass.
14
 */
15
16
#include <iostream>
17
#include <vector>
18
19
#include "context/context.h"
20
#include "expr/node.h"
21
#include "expr/node_manager.h"
22
#include "preprocessing/assertion_pipeline.h"
23
#include "preprocessing/passes/bv_gauss.h"
24
#include "smt/smt_engine.h"
25
#include "smt/smt_engine_scope.h"
26
#include "test_smt.h"
27
#include "theory/bv/theory_bv_utils.h"
28
#include "theory/rewriter.h"
29
#include "util/bitvector.h"
30
31
namespace cvc5 {
32
33
using namespace preprocessing;
34
using namespace preprocessing::passes;
35
using namespace theory;
36
using namespace smt;
37
38
namespace test {
39
40
148
class TestPPWhiteBVGauss : public TestSmt
41
{
42
 protected:
43
74
  void SetUp() override
44
  {
45
74
    TestSmt::SetUp();
46
47
74
    d_zero = bv::utils::mkZero(16);
48
49
148
    d_p = bv::utils::mkConcat(
50
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 11u)));
51
148
    d_x = bv::utils::mkConcat(
52
222
        d_zero, d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16)));
53
148
    d_y = bv::utils::mkConcat(
54
222
        d_zero, d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16)));
55
148
    d_z = bv::utils::mkConcat(
56
222
        d_zero, d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16)));
57
58
148
    d_one = bv::utils::mkConcat(
59
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 1u)));
60
148
    d_two = bv::utils::mkConcat(
61
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 2u)));
62
148
    d_three = bv::utils::mkConcat(
63
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 3u)));
64
148
    d_four = bv::utils::mkConcat(
65
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 4u)));
66
148
    d_five = bv::utils::mkConcat(
67
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 5u)));
68
148
    d_six = bv::utils::mkConcat(
69
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 6u)));
70
148
    d_seven = bv::utils::mkConcat(
71
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 7u)));
72
148
    d_eight = bv::utils::mkConcat(
73
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 8u)));
74
148
    d_nine = bv::utils::mkConcat(
75
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 9u)));
76
148
    d_ten = bv::utils::mkConcat(
77
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 10u)));
78
148
    d_twelve = bv::utils::mkConcat(
79
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 12u)));
80
148
    d_eighteen = bv::utils::mkConcat(
81
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 18u)));
82
148
    d_twentyfour = bv::utils::mkConcat(
83
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 24u)));
84
148
    d_thirty = bv::utils::mkConcat(
85
222
        d_zero, d_nodeManager->mkConst<BitVector>(BitVector(16, 30u)));
86
87
74
    d_one32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 1u));
88
74
    d_two32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 2u));
89
74
    d_three32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 3u));
90
74
    d_four32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 4u));
91
74
    d_five32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 5u));
92
74
    d_six32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 6u));
93
74
    d_seven32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 7u));
94
74
    d_eight32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 8u));
95
74
    d_nine32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 9u));
96
74
    d_ten32 = d_nodeManager->mkConst<BitVector>(BitVector(32, 10u));
97
98
74
    d_x_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_one);
99
74
    d_x_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_two);
100
74
    d_x_mul_four = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four);
101
74
    d_y_mul_three = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three);
102
74
    d_y_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_one);
103
74
    d_y_mul_four = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_four);
104
74
    d_y_mul_five = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_five);
105
74
    d_y_mul_seven = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven);
106
74
    d_z_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_one);
107
74
    d_z_mul_three = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_three);
108
74
    d_z_mul_five = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_five);
109
74
    d_z_mul_six = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_six);
110
74
    d_z_mul_twelve = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_twelve);
111
74
    d_z_mul_nine = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_nine);
112
74
  }
113
114
212
  void print_matrix_dbg(std::vector<Integer>& rhs,
115
                        std::vector<std::vector<Integer>>& lhs)
116
  {
117
832
    for (size_t m = 0, nrows = lhs.size(), ncols = lhs[0].size(); m < nrows;
118
         ++m)
119
    {
120
2508
      for (size_t n = 0; n < ncols; ++n)
121
      {
122
1888
        std::cout << " " << lhs[m][n];
123
      }
124
620
      std::cout << " " << rhs[m];
125
620
      std::cout << std::endl;
126
    }
127
212
  }
128
129
106
  void testGaussElimX(Integer prime,
130
                      std::vector<Integer> rhs,
131
                      std::vector<std::vector<Integer>> lhs,
132
                      BVGauss::Result expected,
133
                      std::vector<Integer>* rrhs = nullptr,
134
                      std::vector<std::vector<Integer>>* rlhs = nullptr)
135
  {
136
106
    size_t nrows = lhs.size();
137
106
    size_t ncols = lhs[0].size();
138
    BVGauss::Result ret;
139
212
    std::vector<Integer> resrhs = std::vector<Integer>(rhs);
140
    std::vector<std::vector<Integer>> reslhs =
141
212
        std::vector<std::vector<Integer>>(lhs);
142
143
106
    std::cout << "Input: " << std::endl;
144
106
    print_matrix_dbg(rhs, lhs);
145
146
106
    ret = BVGauss::gaussElim(prime, resrhs, reslhs);
147
148
    std::cout << "BVGauss::Result: "
149
106
              << (ret == BVGauss::Result::INVALID
150
                      ? "INVALID"
151
94
                      : (ret == BVGauss::Result::UNIQUE
152
124
                             ? "UNIQUE"
153
30
                             : (ret == BVGauss::Result::PARTIAL ? "PARTIAL"
154
306
                                                                : "NONE")))
155
106
              << std::endl;
156
106
    print_matrix_dbg(resrhs, reslhs);
157
158
106
    ASSERT_EQ(expected, ret);
159
160
106
    if (expected == BVGauss::Result::UNIQUE)
161
    {
162
      /* map result value to column index
163
       * e.g.:
164
       * 1 0 0 2  -> res = { 2, 0, 3}
165
       * 0 0 1 3 */
166
128
      std::vector<Integer> res = std::vector<Integer>(ncols, Integer(0));
167
254
      for (size_t i = 0; i < nrows; ++i)
168
768
        for (size_t j = 0; j < ncols; ++j)
169
        {
170
578
          if (reslhs[i][j] == 1)
171
158
            res[j] = resrhs[i];
172
          else
173
420
            ASSERT_EQ(reslhs[i][j], 0);
174
        }
175
176
254
      for (size_t i = 0; i < nrows; ++i)
177
      {
178
380
        Integer tmp = Integer(0);
179
768
        for (size_t j = 0; j < ncols; ++j)
180
578
          tmp = tmp.modAdd(lhs[i][j].modMultiply(res[j], prime), prime);
181
190
        ASSERT_EQ(tmp, rhs[i].euclidianDivideRemainder(prime));
182
      }
183
    }
184
106
    if (rrhs != nullptr && rlhs != nullptr)
185
    {
186
64
      for (size_t i = 0; i < nrows; ++i)
187
      {
188
192
        for (size_t j = 0; j < ncols; ++j)
189
        {
190
144
          ASSERT_EQ(reslhs[i][j], (*rlhs)[i][j]);
191
        }
192
48
        ASSERT_EQ(resrhs[i], (*rrhs)[i]);
193
      }
194
    }
195
  }
196
197
  Node d_p;
198
  Node d_x;
199
  Node d_y;
200
  Node d_z;
201
  Node d_zero;
202
  Node d_one;
203
  Node d_two;
204
  Node d_three;
205
  Node d_four;
206
  Node d_five;
207
  Node d_six;
208
  Node d_seven;
209
  Node d_eight;
210
  Node d_nine;
211
  Node d_ten;
212
  Node d_twelve;
213
  Node d_eighteen;
214
  Node d_twentyfour;
215
  Node d_thirty;
216
  Node d_one32;
217
  Node d_two32;
218
  Node d_three32;
219
  Node d_four32;
220
  Node d_five32;
221
  Node d_six32;
222
  Node d_seven32;
223
  Node d_eight32;
224
  Node d_nine32;
225
  Node d_ten32;
226
  Node d_x_mul_one;
227
  Node d_x_mul_two;
228
  Node d_x_mul_four;
229
  Node d_y_mul_one;
230
  Node d_y_mul_three;
231
  Node d_y_mul_four;
232
  Node d_y_mul_five;
233
  Node d_y_mul_seven;
234
  Node d_z_mul_one;
235
  Node d_z_mul_three;
236
  Node d_z_mul_five;
237
  Node d_z_mul_twelve;
238
  Node d_z_mul_six;
239
  Node d_z_mul_nine;
240
};
241
242
46
TEST_F(TestPPWhiteBVGauss, elim_mod)
243
{
244
4
  std::vector<Integer> rhs;
245
4
  std::vector<std::vector<Integer>> lhs;
246
247
  /* -------------------------------------------------------------------
248
   *   lhs   rhs  modulo { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
249
   *  --^--   ^
250
   *  1 1 1   5
251
   *  2 3 5   8
252
   *  4 0 5   2
253
   * ------------------------------------------------------------------- */
254
2
  rhs = {Integer(5), Integer(8), Integer(2)};
255
26
  lhs = {{Integer(1), Integer(1), Integer(1)},
256
         {Integer(2), Integer(3), Integer(5)},
257
24
         {Integer(4), Integer(0), Integer(5)}};
258
2
  std::cout << "matrix 0, modulo 0" << std::endl;  // throws
259
2
  ASSERT_DEATH(BVGauss::gaussElim(Integer(0), rhs, lhs), "prime > 0");
260
2
  std::cout << "matrix 0, modulo 1" << std::endl;
261
2
  testGaussElimX(Integer(1), rhs, lhs, BVGauss::Result::UNIQUE);
262
2
  std::cout << "matrix 0, modulo 2" << std::endl;
263
2
  testGaussElimX(Integer(2), rhs, lhs, BVGauss::Result::UNIQUE);
264
2
  std::cout << "matrix 0, modulo 3" << std::endl;
265
2
  testGaussElimX(Integer(3), rhs, lhs, BVGauss::Result::UNIQUE);
266
2
  std::cout << "matrix 0, modulo 4" << std::endl;  // no inverse
267
2
  testGaussElimX(Integer(4), rhs, lhs, BVGauss::Result::INVALID);
268
2
  std::cout << "matrix 0, modulo 5" << std::endl;
269
2
  testGaussElimX(Integer(5), rhs, lhs, BVGauss::Result::UNIQUE);
270
2
  std::cout << "matrix 0, modulo 6" << std::endl;  // no inverse
271
2
  testGaussElimX(Integer(6), rhs, lhs, BVGauss::Result::INVALID);
272
2
  std::cout << "matrix 0, modulo 7" << std::endl;
273
2
  testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
274
2
  std::cout << "matrix 0, modulo 8" << std::endl;  // no inverse
275
2
  testGaussElimX(Integer(8), rhs, lhs, BVGauss::Result::INVALID);
276
2
  std::cout << "matrix 0, modulo 9" << std::endl;
277
2
  testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::UNIQUE);
278
2
  std::cout << "matrix 0, modulo 10" << std::endl;  // no inverse
279
2
  testGaussElimX(Integer(10), rhs, lhs, BVGauss::Result::INVALID);
280
2
  std::cout << "matrix 0, modulo 11" << std::endl;
281
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
282
}
283
284
46
TEST_F(TestPPWhiteBVGauss, elim_unique_done)
285
{
286
4
  std::vector<Integer> rhs;
287
4
  std::vector<std::vector<Integer>> lhs;
288
289
  /* -------------------------------------------------------------------
290
   *   lhs     rhs        lhs    rhs  modulo 17
291
   *  --^---    ^        --^--    ^
292
   *  1 0 0    4   -->   1 0 0    4
293
   *  0 1 0   15         0 1 0   15
294
   *  0 0 1    3         0 0 1    3
295
   * ------------------------------------------------------------------- */
296
2
  rhs = {Integer(4), Integer(15), Integer(3)};
297
26
  lhs = {{Integer(1), Integer(0), Integer(0)},
298
         {Integer(0), Integer(1), Integer(0)},
299
24
         {Integer(0), Integer(0), Integer(1)}};
300
2
  std::cout << "matrix 1, modulo 17" << std::endl;
301
2
  testGaussElimX(Integer(17), rhs, lhs, BVGauss::Result::UNIQUE);
302
2
}
303
304
46
TEST_F(TestPPWhiteBVGauss, elim_unique)
305
{
306
4
  std::vector<Integer> rhs;
307
4
  std::vector<std::vector<Integer>> lhs;
308
309
  /* -------------------------------------------------------------------
310
   *   lhs     rhs  modulo { 11,17,59 }
311
   *  --^---    ^
312
   *  2 4  6   18
313
   *  4 5  6   24
314
   *  3 1 -2    4
315
   * ------------------------------------------------------------------- */
316
2
  rhs = {Integer(18), Integer(24), Integer(4)};
317
26
  lhs = {{Integer(2), Integer(4), Integer(6)},
318
         {Integer(4), Integer(5), Integer(6)},
319
24
         {Integer(3), Integer(1), Integer(-2)}};
320
2
  std::cout << "matrix 2, modulo 11" << std::endl;
321
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
322
2
  std::cout << "matrix 2, modulo 17" << std::endl;
323
2
  testGaussElimX(Integer(17), rhs, lhs, BVGauss::Result::UNIQUE);
324
2
  std::cout << "matrix 2, modulo 59" << std::endl;
325
2
  testGaussElimX(Integer(59), rhs, lhs, BVGauss::Result::UNIQUE);
326
327
  /* -------------------------------------------------------------------
328
   *      lhs       rhs         lhs     rhs   modulo 11
329
   *  -----^-----    ^        ---^---    ^
330
   *  1  1  2   0    1   -->  1 0 0 0    1
331
   *  2 -1  0   1   -2        0 1 0 0    2
332
   *  1 -1 -1  -2    4        0 0 1 0   -1
333
   *  2 -1  2  -1    0        0 0 0 1   -2
334
   * ------------------------------------------------------------------- */
335
2
  rhs = {Integer(1), Integer(-2), Integer(4), Integer(0)};
336
42
  lhs = {{Integer(1), Integer(1), Integer(2), Integer(0)},
337
         {Integer(2), Integer(-1), Integer(0), Integer(1)},
338
         {Integer(1), Integer(-1), Integer(-1), Integer(-2)},
339
40
         {Integer(2), Integer(-1), Integer(2), Integer(-1)}};
340
2
  std::cout << "matrix 3, modulo 11" << std::endl;
341
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
342
2
}
343
344
46
TEST_F(TestPPWhiteBVGauss, elim_unique_zero1)
345
{
346
4
  std::vector<Integer> rhs;
347
4
  std::vector<std::vector<Integer>> lhs;
348
349
  /* -------------------------------------------------------------------
350
   *   lhs   rhs        lhs   rhs   modulo 11
351
   *  --^--   ^        --^--   ^
352
   *  0 4 5   2   -->  1 0 0   4
353
   *  1 1 1   5        0 1 0   3
354
   *  3 2 5   8        0 0 1   9
355
   * ------------------------------------------------------------------- */
356
2
  rhs = {Integer(2), Integer(5), Integer(8)};
357
26
  lhs = {{Integer(0), Integer(4), Integer(5)},
358
         {Integer(1), Integer(1), Integer(1)},
359
24
         {Integer(3), Integer(2), Integer(5)}};
360
2
  std::cout << "matrix 4, modulo 11" << std::endl;
361
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
362
363
  /* -------------------------------------------------------------------
364
   *   lhs   rhs        lhs   rhs   modulo 11
365
   *  --^--   ^        --^--   ^
366
   *  1 1 1   5   -->  1 0 0   4
367
   *  0 4 5   2        0 1 0   3
368
   *  3 2 5   8        0 0 1   9
369
   * ------------------------------------------------------------------- */
370
2
  rhs = {Integer(5), Integer(2), Integer(8)};
371
26
  lhs = {{Integer(1), Integer(1), Integer(1)},
372
         {Integer(0), Integer(4), Integer(5)},
373
24
         {Integer(3), Integer(2), Integer(5)}};
374
2
  std::cout << "matrix 5, modulo 11" << std::endl;
375
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
376
377
  /* -------------------------------------------------------------------
378
   *   lhs   rhs        lhs   rhs   modulo 11
379
   *  --^--   ^        --^--   ^
380
   *  1 1 1   5   -->  1 0 0   4
381
   *  3 2 5   8        0 1 0   9
382
   *  0 4 5   2        0 0 1   3
383
   * ------------------------------------------------------------------- */
384
2
  rhs = {Integer(5), Integer(8), Integer(2)};
385
26
  lhs = {{Integer(1), Integer(1), Integer(1)},
386
         {Integer(3), Integer(2), Integer(5)},
387
24
         {Integer(0), Integer(4), Integer(5)}};
388
2
  std::cout << "matrix 6, modulo 11" << std::endl;
389
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
390
2
}
391
392
46
TEST_F(TestPPWhiteBVGauss, elim_unique_zero2)
393
{
394
4
  std::vector<Integer> rhs;
395
4
  std::vector<std::vector<Integer>> lhs;
396
397
  /* -------------------------------------------------------------------
398
   *   lhs   rhs        lhs   rhs   modulo 11
399
   *  --^--   ^        --^--   ^
400
   *  0 0 5   2        1 0 0   10
401
   *  1 1 1   5   -->  0 1 0   10
402
   *  3 2 5   8        0 0 1   7
403
   * ------------------------------------------------------------------- */
404
2
  rhs = {Integer(2), Integer(5), Integer(8)};
405
26
  lhs = {{Integer(0), Integer(0), Integer(5)},
406
         {Integer(1), Integer(1), Integer(1)},
407
24
         {Integer(3), Integer(2), Integer(5)}};
408
2
  std::cout << "matrix 7, modulo 11" << std::endl;
409
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
410
411
  /* -------------------------------------------------------------------
412
   *   lhs   rhs        lhs   rhs   modulo 11
413
   *  --^--   ^        --^--   ^
414
   *  1 1 1   5   -->  1 0 0   10
415
   *  0 0 5   2        0 1 0   10
416
   *  3 2 5   8        0 0 1   7
417
   * ------------------------------------------------------------------- */
418
2
  rhs = {Integer(5), Integer(2), Integer(8)};
419
26
  lhs = {{Integer(1), Integer(1), Integer(1)},
420
         {Integer(0), Integer(0), Integer(5)},
421
24
         {Integer(3), Integer(2), Integer(5)}};
422
2
  std::cout << "matrix 8, modulo 11" << std::endl;
423
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
424
425
  /* -------------------------------------------------------------------
426
   *   lhs   rhs        lhs   rhs   modulo 11
427
   *  --^--   ^        --^--   ^
428
   *  1 1 1   5   -->  1 0 0   10
429
   *  3 2 5   8        0 1 0   10
430
   *  0 0 5   2        0 0 1    7
431
   * ------------------------------------------------------------------- */
432
2
  rhs = {Integer(5), Integer(8), Integer(2)};
433
26
  lhs = {{Integer(1), Integer(1), Integer(1)},
434
         {Integer(3), Integer(2), Integer(5)},
435
24
         {Integer(0), Integer(0), Integer(5)}};
436
2
  std::cout << "matrix 9, modulo 11" << std::endl;
437
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
438
2
}
439
440
46
TEST_F(TestPPWhiteBVGauss, elim_unique_zero3)
441
{
442
4
  std::vector<Integer> rhs;
443
4
  std::vector<std::vector<Integer>> lhs;
444
445
  /* -------------------------------------------------------------------
446
   *   lhs   rhs        lhs   rhs   modulo 7
447
   *  --^--   ^        --^--   ^
448
   *  2 0 6   4        1 0 0   3
449
   *  0 0 0   0   -->  0 0 0   0
450
   *  4 0 6   3        0 0 1   2
451
   * ------------------------------------------------------------------- */
452
2
  rhs = {Integer(4), Integer(0), Integer(3)};
453
26
  lhs = {{Integer(2), Integer(0), Integer(6)},
454
         {Integer(0), Integer(0), Integer(0)},
455
24
         {Integer(4), Integer(0), Integer(6)}};
456
2
  std::cout << "matrix 10, modulo 7" << std::endl;
457
2
  testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
458
459
  /* -------------------------------------------------------------------
460
   *   lhs   rhs        lhs   rhs   modulo 7
461
   *  --^--   ^        --^--   ^
462
   *  2 6 0   4        1 0 0   3
463
   *  0 0 0   0   -->  0 0 0   0
464
   *  4 6 0   3        0 0 1   2
465
   * ------------------------------------------------------------------- */
466
2
  rhs = {Integer(4), Integer(0), Integer(3)};
467
26
  lhs = {{Integer(2), Integer(6), Integer(0)},
468
         {Integer(0), Integer(0), Integer(0)},
469
24
         {Integer(4), Integer(6), Integer(0)}};
470
2
  std::cout << "matrix 11, modulo 7" << std::endl;
471
2
  testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
472
2
}
473
474
46
TEST_F(TestPPWhiteBVGauss, elim_unique_zero4)
475
{
476
4
  std::vector<Integer> rhs, resrhs;
477
4
  std::vector<std::vector<Integer>> lhs, reslhs;
478
479
  /* -------------------------------------------------------------------
480
   *   lhs   rhs  modulo 11
481
   *  --^--   ^
482
   *  0 1 1   5
483
   *  0 0 0   0
484
   *  0 0 5   2
485
   * ------------------------------------------------------------------- */
486
2
  rhs = {Integer(5), Integer(0), Integer(2)};
487
26
  lhs = {{Integer(0), Integer(1), Integer(1)},
488
         {Integer(0), Integer(0), Integer(0)},
489
24
         {Integer(0), Integer(0), Integer(5)}};
490
2
  std::cout << "matrix 12, modulo 11" << std::endl;
491
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
492
493
  /* -------------------------------------------------------------------
494
   *   lhs   rhs  modulo 11
495
   *  --^--   ^
496
   *  0 1 1   5
497
   *  0 3 5   8
498
   *  0 0 0   0
499
   * ------------------------------------------------------------------- */
500
2
  rhs = {Integer(5), Integer(8), Integer(0)};
501
26
  lhs = {{Integer(0), Integer(1), Integer(1)},
502
         {Integer(0), Integer(3), Integer(5)},
503
24
         {Integer(0), Integer(0), Integer(0)}};
504
2
  std::cout << "matrix 13, modulo 11" << std::endl;
505
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
506
507
  /* -------------------------------------------------------------------
508
   *   lhs   rhs  modulo 11
509
   *  --^--   ^
510
   *  0 0 0   0
511
   *  0 3 5   8
512
   *  0 0 5   2
513
   * ------------------------------------------------------------------- */
514
2
  rhs = {Integer(0), Integer(8), Integer(2)};
515
26
  lhs = {{Integer(0), Integer(0), Integer(0)},
516
         {Integer(0), Integer(3), Integer(5)},
517
24
         {Integer(0), Integer(0), Integer(5)}};
518
2
  std::cout << "matrix 14, modulo 11" << std::endl;
519
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
520
521
  /* -------------------------------------------------------------------
522
   *   lhs   rhs  modulo 11
523
   *  --^--   ^
524
   *  1 0 1   5
525
   *  0 0 0   0
526
   *  4 0 5   2
527
   * ------------------------------------------------------------------- */
528
2
  rhs = {Integer(5), Integer(0), Integer(2)};
529
26
  lhs = {{Integer(1), Integer(0), Integer(1)},
530
         {Integer(0), Integer(0), Integer(0)},
531
24
         {Integer(4), Integer(0), Integer(5)}};
532
2
  std::cout << "matrix 15, modulo 11" << std::endl;
533
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
534
535
  /* -------------------------------------------------------------------
536
   *   lhs   rhs  modulo 11
537
   *  --^--   ^
538
   *  1 0 1   5
539
   *  2 0 5   8
540
   *  0 0 0   0
541
   * ------------------------------------------------------------------- */
542
2
  rhs = {Integer(5), Integer(8), Integer(0)};
543
26
  lhs = {{Integer(1), Integer(0), Integer(1)},
544
         {Integer(2), Integer(0), Integer(5)},
545
24
         {Integer(0), Integer(0), Integer(0)}};
546
2
  std::cout << "matrix 16, modulo 11" << std::endl;
547
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
548
549
  /* -------------------------------------------------------------------
550
   *   lhs   rhs  modulo 11
551
   *  --^--   ^
552
   *  0 0 0   0
553
   *  2 0 5   8
554
   *  4 0 5   2
555
   * ------------------------------------------------------------------- */
556
2
  rhs = {Integer(0), Integer(8), Integer(2)};
557
26
  lhs = {{Integer(0), Integer(0), Integer(0)},
558
         {Integer(2), Integer(0), Integer(5)},
559
24
         {Integer(4), Integer(0), Integer(5)}};
560
2
  std::cout << "matrix 17, modulo 11" << std::endl;
561
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
562
563
  /* -------------------------------------------------------------------
564
   *   lhs   rhs  modulo 11
565
   *  --^--   ^
566
   *  1 1 0   5
567
   *  0 0 0   0
568
   *  4 0 0   2
569
   * ------------------------------------------------------------------- */
570
2
  rhs = {Integer(5), Integer(0), Integer(2)};
571
26
  lhs = {{Integer(1), Integer(1), Integer(0)},
572
         {Integer(0), Integer(0), Integer(0)},
573
24
         {Integer(4), Integer(0), Integer(0)}};
574
2
  std::cout << "matrix 18, modulo 11" << std::endl;
575
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
576
577
  /* -------------------------------------------------------------------
578
   *   lhs   rhs  modulo 11
579
   *  --^--   ^
580
   *  1 1 0   5
581
   *  2 3 0   8
582
   *  0 0 0   0
583
   * ------------------------------------------------------------------- */
584
2
  rhs = {Integer(5), Integer(8), Integer(0)};
585
26
  lhs = {{Integer(1), Integer(1), Integer(0)},
586
         {Integer(2), Integer(3), Integer(0)},
587
24
         {Integer(0), Integer(0), Integer(0)}};
588
2
  std::cout << "matrix 18, modulo 11" << std::endl;
589
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
590
591
  /* -------------------------------------------------------------------
592
   *   lhs   rhs  modulo 11
593
   *  --^--   ^
594
   *  0 0 0   0
595
   *  2 3 0   8
596
   *  4 0 0   2
597
   * ------------------------------------------------------------------- */
598
2
  rhs = {Integer(0), Integer(8), Integer(2)};
599
26
  lhs = {{Integer(0), Integer(0), Integer(0)},
600
         {Integer(2), Integer(3), Integer(0)},
601
24
         {Integer(4), Integer(0), Integer(0)}};
602
2
  std::cout << "matrix 19, modulo 11" << std::endl;
603
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::UNIQUE);
604
605
  /* -------------------------------------------------------------------
606
   *     lhs    rhs  modulo 2
607
   *  ----^---   ^
608
   *  2  4   6   18     0 0 0   0
609
   *  4  5   6   24  =  0 1 0   0
610
   *  2  7  12   30     0 1 0   0
611
   * ------------------------------------------------------------------- */
612
2
  rhs = {Integer(18), Integer(24), Integer(30)};
613
26
  lhs = {{Integer(2), Integer(4), Integer(6)},
614
         {Integer(4), Integer(5), Integer(6)},
615
24
         {Integer(2), Integer(7), Integer(12)}};
616
2
  std::cout << "matrix 20, modulo 2" << std::endl;
617
2
  resrhs = {Integer(0), Integer(0), Integer(0)};
618
26
  reslhs = {{Integer(0), Integer(1), Integer(0)},
619
            {Integer(0), Integer(0), Integer(0)},
620
24
            {Integer(0), Integer(0), Integer(0)}};
621
6
  testGaussElimX(
622
4
      Integer(2), rhs, lhs, BVGauss::Result::UNIQUE, &resrhs, &reslhs);
623
2
}
624
625
46
TEST_F(TestPPWhiteBVGauss, elim_unique_partial)
626
{
627
4
  std::vector<Integer> rhs;
628
4
  std::vector<std::vector<Integer>> lhs;
629
630
  /* -------------------------------------------------------------------
631
   *   lhs   rhs        lhs   rhs   modulo 7
632
   *  --^--   ^        --^--   ^
633
   *  2 0 6   4        1 0 0   3
634
   *  4 0 6   3        0 0 1   2
635
   * ------------------------------------------------------------------- */
636
2
  rhs = {Integer(4), Integer(3)};
637
18
  lhs = {{Integer(2), Integer(0), Integer(6)},
638
16
         {Integer(4), Integer(0), Integer(6)}};
639
2
  std::cout << "matrix 21, modulo 7" << std::endl;
640
2
  testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
641
642
  /* -------------------------------------------------------------------
643
   *   lhs   rhs        lhs   rhs   modulo 7
644
   *  --^--   ^        --^--   ^
645
   *  2 6 0   4        1 0 0   3
646
   *  4 6 0   3        0 1 0   2
647
   * ------------------------------------------------------------------- */
648
2
  rhs = {Integer(4), Integer(3)};
649
18
  lhs = {{Integer(2), Integer(6), Integer(0)},
650
16
         {Integer(4), Integer(6), Integer(0)}};
651
2
  std::cout << "matrix 22, modulo 7" << std::endl;
652
2
  testGaussElimX(Integer(7), rhs, lhs, BVGauss::Result::UNIQUE);
653
2
}
654
655
46
TEST_F(TestPPWhiteBVGauss, elim_none)
656
{
657
4
  std::vector<Integer> rhs;
658
4
  std::vector<std::vector<Integer>> lhs;
659
660
  /* -------------------------------------------------------------------
661
   *   lhs     rhs       modulo 9
662
   *  --^---    ^
663
   *  2 4  6   18   -->  not coprime (no inverse)
664
   *  4 5  6   24
665
   *  3 1 -2    4
666
   * ------------------------------------------------------------------- */
667
2
  rhs = {Integer(18), Integer(24), Integer(4)};
668
26
  lhs = {{Integer(2), Integer(4), Integer(6)},
669
         {Integer(4), Integer(5), Integer(6)},
670
24
         {Integer(3), Integer(1), Integer(-2)}};
671
2
  std::cout << "matrix 23, modulo 9" << std::endl;
672
2
  testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::INVALID);
673
674
  /* -------------------------------------------------------------------
675
   *     lhs    rhs       modulo 59
676
   *  ----^---   ^
677
   *  1 -2  -6   12   --> no solution
678
   *  2  4  12  -17
679
   *  1 -4 -12   22
680
   * ------------------------------------------------------------------- */
681
2
  rhs = {Integer(12), Integer(-17), Integer(22)};
682
26
  lhs = {{Integer(1), Integer(-2), Integer(-6)},
683
         {Integer(2), Integer(4), Integer(12)},
684
24
         {Integer(1), Integer(-4), Integer(-12)}};
685
2
  std::cout << "matrix 24, modulo 59" << std::endl;
686
2
  testGaussElimX(Integer(59), rhs, lhs, BVGauss::Result::NONE);
687
688
  /* -------------------------------------------------------------------
689
   *     lhs    rhs       modulo 9
690
   *  ----^---   ^
691
   *  2  4   6   18   --> not coprime (no inverse)
692
   *  4  5   6   24
693
   *  2  7  12   30
694
   * ------------------------------------------------------------------- */
695
2
  rhs = {Integer(18), Integer(24), Integer(30)};
696
26
  lhs = {{Integer(2), Integer(4), Integer(6)},
697
         {Integer(4), Integer(5), Integer(6)},
698
24
         {Integer(2), Integer(7), Integer(12)}};
699
2
  std::cout << "matrix 25, modulo 9" << std::endl;
700
2
  testGaussElimX(Integer(9), rhs, lhs, BVGauss::Result::INVALID);
701
2
}
702
703
46
TEST_F(TestPPWhiteBVGauss, elim_none_zero)
704
{
705
4
  std::vector<Integer> rhs;
706
4
  std::vector<std::vector<Integer>> lhs;
707
708
  /* -------------------------------------------------------------------
709
   *   lhs   rhs  modulo 11
710
   *  --^--   ^
711
   *  0 1 1   5
712
   *  0 3 5   8
713
   *  0 0 5   2
714
   * ------------------------------------------------------------------- */
715
2
  rhs = {Integer(5), Integer(8), Integer(2)};
716
26
  lhs = {{Integer(0), Integer(1), Integer(1)},
717
         {Integer(0), Integer(3), Integer(5)},
718
24
         {Integer(0), Integer(0), Integer(5)}};
719
2
  std::cout << "matrix 26, modulo 11" << std::endl;
720
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
721
722
  /* -------------------------------------------------------------------
723
   *   lhs   rhs  modulo 11
724
   *  --^--   ^
725
   *  1 0 1   5
726
   *  2 0 5   8
727
   *  4 0 5   2
728
   * ------------------------------------------------------------------- */
729
2
  rhs = {Integer(5), Integer(8), Integer(2)};
730
26
  lhs = {{Integer(1), Integer(0), Integer(1)},
731
         {Integer(2), Integer(0), Integer(5)},
732
24
         {Integer(4), Integer(0), Integer(5)}};
733
2
  std::cout << "matrix 27, modulo 11" << std::endl;
734
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
735
736
  /* -------------------------------------------------------------------
737
   *   lhs   rhs  modulo 11
738
   *  --^--   ^
739
   *  1 1 0   5
740
   *  2 3 0   8
741
   *  4 0 0   2
742
   * ------------------------------------------------------------------- */
743
2
  rhs = {Integer(5), Integer(8), Integer(2)};
744
26
  lhs = {{Integer(1), Integer(1), Integer(0)},
745
         {Integer(2), Integer(3), Integer(0)},
746
24
         {Integer(4), Integer(0), Integer(0)}};
747
2
  std::cout << "matrix 28, modulo 11" << std::endl;
748
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::NONE);
749
2
}
750
751
46
TEST_F(TestPPWhiteBVGauss, elim_partial1)
752
{
753
4
  std::vector<Integer> rhs, resrhs;
754
4
  std::vector<std::vector<Integer>> lhs, reslhs;
755
756
  /* -------------------------------------------------------------------
757
   *   lhs   rhs        lhs   rhs  modulo 11
758
   *  --^--   ^        --^--   ^
759
   *  1 0 9   7   -->  1 0 9   7
760
   *  0 1 3   9        0 1 3   9
761
   * ------------------------------------------------------------------- */
762
2
  rhs = {Integer(7), Integer(9)};
763
18
  lhs = {{Integer(1), Integer(0), Integer(9)},
764
16
         {Integer(0), Integer(1), Integer(3)}};
765
2
  std::cout << "matrix 29, modulo 11" << std::endl;
766
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
767
768
  /* -------------------------------------------------------------------
769
   *   lhs   rhs        lhs   rhs  modulo 11
770
   *  --^--   ^        --^--   ^
771
   *  1 3 0   7   -->  1 3 0   7
772
   *  0 0 1   9        0 0 1   9
773
   * ------------------------------------------------------------------- */
774
2
  rhs = {Integer(7), Integer(9)};
775
18
  lhs = {{Integer(1), Integer(3), Integer(0)},
776
16
         {Integer(0), Integer(0), Integer(1)}};
777
2
  std::cout << "matrix 30, modulo 11" << std::endl;
778
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
779
780
  /* -------------------------------------------------------------------
781
   *   lhs   rhs        lhs   rhs  modulo 11
782
   *  --^--   ^        --^--   ^
783
   *  1 1 1   5   -->  1 0 9   7
784
   *  2 3 5   8        0 1 3   9
785
   * ------------------------------------------------------------------- */
786
2
  rhs = {Integer(5), Integer(8)};
787
18
  lhs = {{Integer(1), Integer(1), Integer(1)},
788
16
         {Integer(2), Integer(3), Integer(5)}};
789
2
  std::cout << "matrix 31, modulo 11" << std::endl;
790
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
791
792
  /* -------------------------------------------------------------------
793
   *     lhs    rhs  modulo { 3, 5, 7, 11, 17, 31, 59 }
794
   *  ----^---   ^
795
   *  2  4   6   18
796
   *  4  5   6   24
797
   *  2  7  12   30
798
   * ------------------------------------------------------------------- */
799
2
  rhs = {Integer(18), Integer(24), Integer(30)};
800
26
  lhs = {{Integer(2), Integer(4), Integer(6)},
801
         {Integer(4), Integer(5), Integer(6)},
802
24
         {Integer(2), Integer(7), Integer(12)}};
803
2
  std::cout << "matrix 32, modulo 3" << std::endl;
804
2
  resrhs = {Integer(0), Integer(0), Integer(0)};
805
26
  reslhs = {{Integer(1), Integer(2), Integer(0)},
806
            {Integer(0), Integer(0), Integer(0)},
807
24
            {Integer(0), Integer(0), Integer(0)}};
808
6
  testGaussElimX(
809
4
      Integer(3), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
810
2
  resrhs = {Integer(1), Integer(4), Integer(0)};
811
2
  std::cout << "matrix 32, modulo 5" << std::endl;
812
26
  reslhs = {{Integer(1), Integer(0), Integer(4)},
813
            {Integer(0), Integer(1), Integer(2)},
814
24
            {Integer(0), Integer(0), Integer(0)}};
815
6
  testGaussElimX(
816
4
      Integer(5), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
817
2
  std::cout << "matrix 32, modulo 7" << std::endl;
818
26
  reslhs = {{Integer(1), Integer(0), Integer(6)},
819
            {Integer(0), Integer(1), Integer(2)},
820
24
            {Integer(0), Integer(0), Integer(0)}};
821
6
  testGaussElimX(
822
4
      Integer(7), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
823
2
  std::cout << "matrix 32, modulo 11" << std::endl;
824
26
  reslhs = {{Integer(1), Integer(0), Integer(10)},
825
            {Integer(0), Integer(1), Integer(2)},
826
24
            {Integer(0), Integer(0), Integer(0)}};
827
6
  testGaussElimX(
828
4
      Integer(11), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
829
2
  std::cout << "matrix 32, modulo 17" << std::endl;
830
26
  reslhs = {{Integer(1), Integer(0), Integer(16)},
831
            {Integer(0), Integer(1), Integer(2)},
832
24
            {Integer(0), Integer(0), Integer(0)}};
833
6
  testGaussElimX(
834
4
      Integer(17), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
835
2
  std::cout << "matrix 32, modulo 59" << std::endl;
836
26
  reslhs = {{Integer(1), Integer(0), Integer(58)},
837
            {Integer(0), Integer(1), Integer(2)},
838
24
            {Integer(0), Integer(0), Integer(0)}};
839
6
  testGaussElimX(
840
4
      Integer(59), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
841
842
  /* -------------------------------------------------------------------
843
   *     lhs    rhs        lhs   rhs   modulo 3
844
   *  ----^---   ^        --^--   ^
845
   *   4  6 2   18   -->  1 0 2   0
846
   *   5  6 4   24        0 0 0   0
847
   *   7 12 2   30        0 0 0   0
848
   * ------------------------------------------------------------------- */
849
2
  rhs = {Integer(18), Integer(24), Integer(30)};
850
26
  lhs = {{Integer(4), Integer(6), Integer(2)},
851
         {Integer(5), Integer(6), Integer(4)},
852
24
         {Integer(7), Integer(12), Integer(2)}};
853
2
  std::cout << "matrix 33, modulo 3" << std::endl;
854
2
  resrhs = {Integer(0), Integer(0), Integer(0)};
855
26
  reslhs = {{Integer(1), Integer(0), Integer(2)},
856
            {Integer(0), Integer(0), Integer(0)},
857
24
            {Integer(0), Integer(0), Integer(0)}};
858
6
  testGaussElimX(
859
4
      Integer(3), rhs, lhs, BVGauss::Result::PARTIAL, &resrhs, &reslhs);
860
2
}
861
862
46
TEST_F(TestPPWhiteBVGauss, elim_partial2)
863
{
864
4
  std::vector<Integer> rhs;
865
4
  std::vector<std::vector<Integer>> lhs;
866
867
  /* -------------------------------------------------------------------
868
   *    lhs    rhs  -->    lhs    rhs  modulo 11
869
   *  ---^---   ^        ---^---   ^
870
   *  x y z w            x y z w
871
   *  1 2 0 6   2        1 2 0 0   1
872
   *  0 0 2 2   2        0 0 1 0   10
873
   *  0 0 0 1   2        0 0 0 1   2
874
   * ------------------------------------------------------------------- */
875
2
  rhs = {Integer(2), Integer(2), Integer(2)};
876
32
  lhs = {{Integer(1), Integer(2), Integer(6), Integer(0)},
877
         {Integer(0), Integer(0), Integer(2), Integer(2)},
878
30
         {Integer(0), Integer(0), Integer(1), Integer(0)}};
879
2
  std::cout << "matrix 34, modulo 11" << std::endl;
880
2
  testGaussElimX(Integer(11), rhs, lhs, BVGauss::Result::PARTIAL);
881
2
}
882
883
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_unique1)
884
{
885
  /* -------------------------------------------------------------------
886
   *   lhs   rhs  modulo 11
887
   *  --^--   ^
888
   *  1 1 1   5
889
   *  2 3 5   8
890
   *  4 0 5   2
891
   * ------------------------------------------------------------------- */
892
893
  Node eq1 = d_nodeManager->mkNode(
894
      kind::EQUAL,
895
8
      d_nodeManager->mkNode(
896
          kind::BITVECTOR_UREM,
897
8
          d_nodeManager->mkNode(
898
              kind::BITVECTOR_ADD,
899
4
              d_nodeManager->mkNode(
900
                  kind::BITVECTOR_ADD, d_x_mul_one, d_y_mul_one),
901
              d_z_mul_one),
902
          d_p),
903
8
      d_five);
904
905
  Node eq2 = d_nodeManager->mkNode(
906
      kind::EQUAL,
907
8
      d_nodeManager->mkNode(
908
          kind::BITVECTOR_UREM,
909
8
          d_nodeManager->mkNode(
910
              kind::BITVECTOR_ADD,
911
4
              d_nodeManager->mkNode(
912
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_three),
913
              d_z_mul_five),
914
          d_p),
915
8
      d_eight);
916
917
  Node eq3 = d_nodeManager->mkNode(
918
      kind::EQUAL,
919
8
      d_nodeManager->mkNode(
920
          kind::BITVECTOR_UREM,
921
4
          d_nodeManager->mkNode(
922
              kind::BITVECTOR_ADD, d_x_mul_four, d_z_mul_five),
923
          d_p),
924
8
      d_two);
925
926
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
927
4
  std::unordered_map<Node, Node> res;
928
2
  BVGauss::Result ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
929
2
  ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
930
2
  ASSERT_EQ(res.size(), 3);
931
2
  ASSERT_EQ(res[d_x], d_three32);
932
2
  ASSERT_EQ(res[d_y], d_four32);
933
2
  ASSERT_EQ(res[d_z], d_nine32);
934
}
935
936
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_unique2)
937
{
938
  /* -------------------------------------------------------------------
939
   *   lhs   rhs  modulo 11
940
   *  --^--   ^
941
   *  1 1 1   5
942
   *  2 3 5   8
943
   *  4 0 5   2
944
   * ------------------------------------------------------------------- */
945
946
  Node zextop6 =
947
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(6));
948
949
  Node p = d_nodeManager->mkNode(
950
      zextop6,
951
4
      bv::utils::mkConcat(bv::utils::mkZero(6),
952
10
                          d_nodeManager->mkNode(kind::BITVECTOR_ADD,
953
4
                                                bv::utils::mkConst(20, 7),
954
10
                                                bv::utils::mkConst(20, 4))));
955
956
  Node x_mul_one = d_nodeManager->mkNode(
957
      kind::BITVECTOR_MULT,
958
4
      d_nodeManager->mkNode(kind::BITVECTOR_SUB, d_five, d_four),
959
8
      d_x);
960
  Node y_mul_one = d_nodeManager->mkNode(
961
      kind::BITVECTOR_MULT,
962
4
      d_nodeManager->mkNode(kind::BITVECTOR_UREM, d_one, d_five),
963
8
      d_y);
964
  Node z_mul_one =
965
4
      d_nodeManager->mkNode(kind::BITVECTOR_MULT, bv::utils::mkOne(32), d_z);
966
967
  Node x_mul_two = d_nodeManager->mkNode(
968
      kind::BITVECTOR_MULT,
969
10
      d_nodeManager->mkNode(
970
8
          kind::BITVECTOR_SHL, bv::utils::mkOne(32), bv::utils::mkOne(32)),
971
8
      d_x);
972
  Node y_mul_three =
973
      d_nodeManager->mkNode(kind::BITVECTOR_MULT,
974
10
                            d_nodeManager->mkNode(kind::BITVECTOR_LSHR,
975
4
                                                  bv::utils::mkOnes(32),
976
4
                                                  bv::utils::mkConst(32, 30)),
977
8
                            d_y);
978
  Node z_mul_five = d_nodeManager->mkNode(
979
      kind::BITVECTOR_MULT,
980
4
      bv::utils::mkExtract(
981
6
          d_nodeManager->mkNode(
982
              zextop6,
983
4
              d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_three, d_two)),
984
          31,
985
          0),
986
8
      d_z);
987
988
  Node x_mul_four = d_nodeManager->mkNode(
989
      kind::BITVECTOR_MULT,
990
10
      d_nodeManager->mkNode(
991
          kind::BITVECTOR_UDIV,
992
10
          d_nodeManager->mkNode(
993
              kind::BITVECTOR_ADD,
994
10
              d_nodeManager->mkNode(kind::BITVECTOR_MULT,
995
4
                                    bv::utils::mkConst(32, 4),
996
4
                                    bv::utils::mkConst(32, 5)),
997
4
              bv::utils::mkConst(32, 4)),
998
4
          bv::utils::mkConst(32, 6)),
999
8
      d_x);
1000
1001
  Node eq1 = d_nodeManager->mkNode(
1002
      kind::EQUAL,
1003
8
      d_nodeManager->mkNode(
1004
          kind::BITVECTOR_UREM,
1005
8
          d_nodeManager->mkNode(
1006
              kind::BITVECTOR_ADD,
1007
4
              d_nodeManager->mkNode(kind::BITVECTOR_ADD, x_mul_one, y_mul_one),
1008
              z_mul_one),
1009
          p),
1010
8
      d_five);
1011
1012
  Node eq2 = d_nodeManager->mkNode(
1013
      kind::EQUAL,
1014
8
      d_nodeManager->mkNode(
1015
          kind::BITVECTOR_UREM,
1016
8
          d_nodeManager->mkNode(
1017
              kind::BITVECTOR_ADD,
1018
4
              d_nodeManager->mkNode(
1019
                  kind::BITVECTOR_ADD, x_mul_two, y_mul_three),
1020
              z_mul_five),
1021
          p),
1022
8
      d_eight);
1023
1024
  Node eq3 = d_nodeManager->mkNode(
1025
      kind::EQUAL,
1026
8
      d_nodeManager->mkNode(
1027
          kind::BITVECTOR_UREM,
1028
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, x_mul_four, z_mul_five),
1029
          d_p),
1030
8
      d_two);
1031
1032
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
1033
4
  std::unordered_map<Node, Node> res;
1034
2
  BVGauss::Result ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1035
2
  ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
1036
2
  ASSERT_EQ(res.size(), 3);
1037
2
  ASSERT_EQ(res[d_x], d_three32);
1038
2
  ASSERT_EQ(res[d_y], d_four32);
1039
2
  ASSERT_EQ(res[d_z], d_nine32);
1040
}
1041
1042
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial1a)
1043
{
1044
4
  std::unordered_map<Node, Node> res;
1045
  BVGauss::Result ret;
1046
1047
  /* -------------------------------------------------------------------
1048
   *   lhs   rhs        lhs   rhs  modulo 11
1049
   *  --^--   ^        --^--   ^
1050
   *  1 0 9   7   -->  1 0 9   7
1051
   *  0 1 3   9        0 1 3   9
1052
   * ------------------------------------------------------------------- */
1053
1054
  Node eq1 = d_nodeManager->mkNode(
1055
      kind::EQUAL,
1056
8
      d_nodeManager->mkNode(
1057
          kind::BITVECTOR_UREM,
1058
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_x_mul_one, d_z_mul_nine),
1059
          d_p),
1060
8
      d_seven);
1061
1062
  Node eq2 = d_nodeManager->mkNode(
1063
      kind::EQUAL,
1064
8
      d_nodeManager->mkNode(
1065
          kind::BITVECTOR_UREM,
1066
4
          d_nodeManager->mkNode(
1067
              kind::BITVECTOR_ADD, d_y_mul_one, d_z_mul_three),
1068
          d_p),
1069
8
      d_nine);
1070
1071
4
  std::vector<Node> eqs = {eq1, eq2};
1072
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1073
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1074
2
  ASSERT_EQ(res.size(), 2);
1075
1076
  Node x1 = d_nodeManager->mkNode(
1077
      kind::BITVECTOR_UREM,
1078
6
      d_nodeManager->mkNode(
1079
          kind::BITVECTOR_ADD,
1080
          d_seven32,
1081
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
1082
8
      d_p);
1083
  Node y1 = d_nodeManager->mkNode(
1084
      kind::BITVECTOR_UREM,
1085
6
      d_nodeManager->mkNode(
1086
          kind::BITVECTOR_ADD,
1087
          d_nine32,
1088
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
1089
8
      d_p);
1090
1091
  Node x2 = d_nodeManager->mkNode(
1092
      kind::BITVECTOR_UREM,
1093
6
      d_nodeManager->mkNode(
1094
          kind::BITVECTOR_ADD,
1095
          d_two32,
1096
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
1097
8
      d_p);
1098
  Node z2 = d_nodeManager->mkNode(
1099
      kind::BITVECTOR_UREM,
1100
6
      d_nodeManager->mkNode(
1101
          kind::BITVECTOR_ADD,
1102
          d_three32,
1103
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
1104
8
      d_p);
1105
1106
  Node y3 = d_nodeManager->mkNode(
1107
      kind::BITVECTOR_UREM,
1108
6
      d_nodeManager->mkNode(
1109
          kind::BITVECTOR_ADD,
1110
          d_three32,
1111
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
1112
8
      d_p);
1113
  Node z3 = d_nodeManager->mkNode(
1114
      kind::BITVECTOR_UREM,
1115
6
      d_nodeManager->mkNode(
1116
          kind::BITVECTOR_ADD,
1117
          d_two32,
1118
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
1119
8
      d_p);
1120
1121
  /* result depends on order of variables in matrix */
1122
2
  if (res.find(d_x) == res.end())
1123
  {
1124
    /*
1125
     *  y z x           y z x
1126
     *  0 9 1  7   -->  1 0 7  3
1127
     *  1 3 0  9        0 1 5  2
1128
     *
1129
     *  z y x           z y x
1130
     *  9 0 1  7   -->  1 0 5  2
1131
     *  3 1 0  9        0 1 7  3
1132
     */
1133
    ASSERT_EQ(res[d_y], y3);
1134
    ASSERT_EQ(res[d_z], z3);
1135
  }
1136
2
  else if (res.find(d_y) == res.end())
1137
  {
1138
    /*
1139
     *  x z y           x z y
1140
     *  1 9 0  7   -->  1 0 8  2
1141
     *  0 3 1  9        0 1 4  3
1142
     *
1143
     *  z x y           z x y
1144
     *  9 1 0  7   -->  1 0 4  3
1145
     *  3 0 1  9        0 1 8  2
1146
     */
1147
    ASSERT_EQ(res[d_x], x2);
1148
    ASSERT_EQ(res[d_z], z2);
1149
  }
1150
  else
1151
  {
1152
2
    ASSERT_EQ(res.find(d_z), res.end());
1153
    /*
1154
     *  x y z           x y z
1155
     *  1 0 9  7   -->  1 0 9  7
1156
     *  0 1 3  9        0 1 3  9
1157
     *
1158
     *  y x z           y x z
1159
     *  0 1 9  7   -->  1 0 3  9
1160
     *  1 0 3  9        0 1 9  7
1161
     */
1162
2
    ASSERT_EQ(res[d_x], x1);
1163
2
    ASSERT_EQ(res[d_y], y1);
1164
  }
1165
}
1166
1167
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial1b)
1168
{
1169
4
  std::unordered_map<Node, Node> res;
1170
  BVGauss::Result ret;
1171
1172
  /* -------------------------------------------------------------------
1173
   *   lhs   rhs        lhs   rhs  modulo 11
1174
   *  --^--   ^        --^--   ^
1175
   *  1 0 9   7   -->  1 0 9   7
1176
   *  0 1 3   9        0 1 3   9
1177
   * ------------------------------------------------------------------- */
1178
1179
  Node eq1 = d_nodeManager->mkNode(
1180
      kind::EQUAL,
1181
8
      d_nodeManager->mkNode(
1182
          kind::BITVECTOR_UREM,
1183
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_x, d_z_mul_nine),
1184
          d_p),
1185
8
      d_seven);
1186
1187
  Node eq2 = d_nodeManager->mkNode(
1188
      kind::EQUAL,
1189
8
      d_nodeManager->mkNode(
1190
          kind::BITVECTOR_UREM,
1191
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_y, d_z_mul_three),
1192
          d_p),
1193
8
      d_nine);
1194
1195
4
  std::vector<Node> eqs = {eq1, eq2};
1196
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1197
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1198
2
  ASSERT_EQ(res.size(), 2);
1199
1200
  Node x1 = d_nodeManager->mkNode(
1201
      kind::BITVECTOR_UREM,
1202
6
      d_nodeManager->mkNode(
1203
          kind::BITVECTOR_ADD,
1204
          d_seven32,
1205
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
1206
8
      d_p);
1207
  Node y1 = d_nodeManager->mkNode(
1208
      kind::BITVECTOR_UREM,
1209
6
      d_nodeManager->mkNode(
1210
          kind::BITVECTOR_ADD,
1211
          d_nine32,
1212
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
1213
8
      d_p);
1214
1215
  Node x2 = d_nodeManager->mkNode(
1216
      kind::BITVECTOR_UREM,
1217
6
      d_nodeManager->mkNode(
1218
          kind::BITVECTOR_ADD,
1219
          d_two32,
1220
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
1221
8
      d_p);
1222
  Node z2 = d_nodeManager->mkNode(
1223
      kind::BITVECTOR_UREM,
1224
6
      d_nodeManager->mkNode(
1225
          kind::BITVECTOR_ADD,
1226
          d_three32,
1227
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
1228
8
      d_p);
1229
1230
  Node y3 = d_nodeManager->mkNode(
1231
      kind::BITVECTOR_UREM,
1232
6
      d_nodeManager->mkNode(
1233
          kind::BITVECTOR_ADD,
1234
          d_three32,
1235
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
1236
8
      d_p);
1237
  Node z3 = d_nodeManager->mkNode(
1238
      kind::BITVECTOR_UREM,
1239
6
      d_nodeManager->mkNode(
1240
          kind::BITVECTOR_ADD,
1241
          d_two32,
1242
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
1243
8
      d_p);
1244
1245
  /* result depends on order of variables in matrix */
1246
2
  if (res.find(d_x) == res.end())
1247
  {
1248
    /*
1249
     *  y z x           y z x
1250
     *  0 9 1  7   -->  1 0 7  3
1251
     *  1 3 0  9        0 1 5  2
1252
     *
1253
     *  z y x           z y x
1254
     *  9 0 1  7   -->  1 0 5  2
1255
     *  3 1 0  9        0 1 7  3
1256
     */
1257
    ASSERT_EQ(res[d_y], y3);
1258
    ASSERT_EQ(res[d_z], z3);
1259
  }
1260
2
  else if (res.find(d_y) == res.end())
1261
  {
1262
    /*
1263
     *  x z y           x z y
1264
     *  1 9 0  7   -->  1 0 8  2
1265
     *  0 3 1  9        0 1 4  3
1266
     *
1267
     *  z x y           z x y
1268
     *  9 1 0  7   -->  1 0 4  3
1269
     *  3 0 1  9        0 1 8  2
1270
     */
1271
    ASSERT_EQ(res[d_x], x2);
1272
    ASSERT_EQ(res[d_z], z2);
1273
  }
1274
  else
1275
  {
1276
2
    ASSERT_EQ(res.find(d_z), res.end());
1277
    /*
1278
     *  x y z           x y z
1279
     *  1 0 9  7   -->  1 0 9  7
1280
     *  0 1 3  9        0 1 3  9
1281
     *
1282
     *  y x z           y x z
1283
     *  0 1 9  7   -->  1 0 3  9
1284
     *  1 0 3  9        0 1 9  7
1285
     */
1286
2
    ASSERT_EQ(res[d_x], x1);
1287
2
    ASSERT_EQ(res[d_y], y1);
1288
  }
1289
}
1290
1291
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial2)
1292
{
1293
4
  std::unordered_map<Node, Node> res;
1294
  BVGauss::Result ret;
1295
1296
  /* -------------------------------------------------------------------
1297
   *   lhs   rhs        lhs   rhs  modulo 11
1298
   *  --^--   ^        --^--   ^
1299
   *  1 3 0   7   -->  1 3 0   7
1300
   *  0 0 1   9        0 0 1   9
1301
   * ------------------------------------------------------------------- */
1302
1303
  Node eq1 = d_nodeManager->mkNode(
1304
      kind::EQUAL,
1305
8
      d_nodeManager->mkNode(
1306
          kind::BITVECTOR_UREM,
1307
4
          d_nodeManager->mkNode(
1308
              kind::BITVECTOR_ADD, d_x_mul_one, d_y_mul_three),
1309
          d_p),
1310
8
      d_seven);
1311
1312
  Node eq2 = d_nodeManager->mkNode(
1313
      kind::EQUAL,
1314
4
      d_nodeManager->mkNode(kind::BITVECTOR_UREM, d_z_mul_one, d_p),
1315
8
      d_nine);
1316
1317
4
  std::vector<Node> eqs = {eq1, eq2};
1318
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1319
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1320
2
  ASSERT_EQ(res.size(), 2);
1321
1322
  Node x1 = d_nodeManager->mkNode(
1323
      kind::BITVECTOR_UREM,
1324
6
      d_nodeManager->mkNode(
1325
          kind::BITVECTOR_ADD,
1326
          d_seven32,
1327
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_eight32)),
1328
8
      d_p);
1329
  Node y2 = d_nodeManager->mkNode(
1330
      kind::BITVECTOR_UREM,
1331
6
      d_nodeManager->mkNode(
1332
          kind::BITVECTOR_ADD,
1333
          d_six32,
1334
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_seven32)),
1335
8
      d_p);
1336
1337
  /* result depends on order of variables in matrix */
1338
2
  if (res.find(d_x) == res.end())
1339
  {
1340
    /*
1341
     *  x y z           x y z
1342
     *  1 3 0  7   -->  1 3 0  7
1343
     *  0 0 1  9        0 0 1  9
1344
     *
1345
     *  x z y           x z y
1346
     *  1 0 3  7   -->  1 0 3  7
1347
     *  0 1 0  9        0 1 0  9
1348
     *
1349
     *  z x y           z x y
1350
     *  0 1 3  7   -->  1 0 0  9
1351
     *  1 0 0  9        0 1 3  7
1352
     */
1353
    ASSERT_EQ(res[d_y], y2);
1354
    ASSERT_EQ(res[d_z], d_nine32);
1355
  }
1356
2
  else if (res.find(d_y) == res.end())
1357
  {
1358
    /*
1359
     *  z y x           z y x
1360
     *  0 3 1  7   -->  1 0 0  9
1361
     *  1 0 0  9        0 1 4  6
1362
     *
1363
     *  y x z           y x z
1364
     *  3 1 0  7   -->  1 4 0  6
1365
     *  0 0 1  9        0 0 1  9
1366
     *
1367
     *  y z x           y z x
1368
     *  3 0 1  7   -->  1 0 4  6
1369
     *  0 1 0  9        0 1 0  9
1370
     */
1371
2
    ASSERT_EQ(res[d_x], x1);
1372
2
    ASSERT_EQ(res[d_z], d_nine32);
1373
  }
1374
  else
1375
  {
1376
    ASSERT_TRUE(false);
1377
  }
1378
}
1379
1380
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial3)
1381
{
1382
4
  std::unordered_map<Node, Node> res;
1383
  BVGauss::Result ret;
1384
1385
  /* -------------------------------------------------------------------
1386
   *   lhs   rhs        lhs   rhs  modulo 11
1387
   *  --^--   ^        --^--   ^
1388
   *  1 1 1   5   -->  1 0 9   7
1389
   *  2 3 5   8        0 1 3   9
1390
   * ------------------------------------------------------------------- */
1391
1392
  Node eq1 = d_nodeManager->mkNode(
1393
      kind::EQUAL,
1394
8
      d_nodeManager->mkNode(
1395
          kind::BITVECTOR_UREM,
1396
8
          d_nodeManager->mkNode(
1397
              kind::BITVECTOR_ADD,
1398
4
              d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_x_mul_one, d_y),
1399
              d_z_mul_one),
1400
          d_p),
1401
8
      d_five);
1402
1403
  Node eq2 = d_nodeManager->mkNode(
1404
      kind::EQUAL,
1405
8
      d_nodeManager->mkNode(
1406
          kind::BITVECTOR_UREM,
1407
8
          d_nodeManager->mkNode(
1408
              kind::BITVECTOR_ADD,
1409
4
              d_nodeManager->mkNode(
1410
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_three),
1411
              d_z_mul_five),
1412
          d_p),
1413
8
      d_eight);
1414
1415
4
  std::vector<Node> eqs = {eq1, eq2};
1416
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1417
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1418
2
  ASSERT_EQ(res.size(), 2);
1419
1420
  Node x1 = d_nodeManager->mkNode(
1421
      kind::BITVECTOR_UREM,
1422
6
      d_nodeManager->mkNode(
1423
          kind::BITVECTOR_ADD,
1424
          d_seven32,
1425
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
1426
8
      d_p);
1427
  Node y1 = d_nodeManager->mkNode(
1428
      kind::BITVECTOR_UREM,
1429
6
      d_nodeManager->mkNode(
1430
          kind::BITVECTOR_ADD,
1431
          d_nine32,
1432
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
1433
8
      d_p);
1434
  Node x2 = d_nodeManager->mkNode(
1435
      kind::BITVECTOR_UREM,
1436
6
      d_nodeManager->mkNode(
1437
          kind::BITVECTOR_ADD,
1438
          d_two32,
1439
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
1440
8
      d_p);
1441
  Node z2 = d_nodeManager->mkNode(
1442
      kind::BITVECTOR_UREM,
1443
6
      d_nodeManager->mkNode(
1444
          kind::BITVECTOR_ADD,
1445
          d_three32,
1446
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
1447
8
      d_p);
1448
  Node y3 = d_nodeManager->mkNode(
1449
      kind::BITVECTOR_UREM,
1450
6
      d_nodeManager->mkNode(
1451
          kind::BITVECTOR_ADD,
1452
          d_three32,
1453
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
1454
8
      d_p);
1455
  Node z3 = d_nodeManager->mkNode(
1456
      kind::BITVECTOR_UREM,
1457
6
      d_nodeManager->mkNode(
1458
          kind::BITVECTOR_ADD,
1459
          d_two32,
1460
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
1461
8
      d_p);
1462
1463
  /* result depends on order of variables in matrix */
1464
2
  if (res.find(d_x) == res.end())
1465
  {
1466
    /*
1467
     *  y z x           y z x
1468
     *  1 1 1  5   -->  1 0 7  3
1469
     *  3 5 2  8        0 1 5  2
1470
     *
1471
     *  z y x           z y x
1472
     *  1 1 1  5   -->  1 0 5  2
1473
     *  5 3 2  8        0 1 7  3
1474
     */
1475
    ASSERT_EQ(res[d_y], y3);
1476
    ASSERT_EQ(res[d_z], z3);
1477
  }
1478
2
  else if (res.find(d_y) == res.end())
1479
  {
1480
    /*
1481
     *  x z y           x z y
1482
     *  1 1 1  5   -->  1 0 8  2
1483
     *  2 5 3  8        0 1 4  3
1484
     *
1485
     *  z x y           z x y
1486
     *  1 1 1  5   -->  1 0 4  3
1487
     *  5 2 3  9        0 1 8  2
1488
     */
1489
    ASSERT_EQ(res[d_x], x2);
1490
    ASSERT_EQ(res[d_z], z2);
1491
  }
1492
  else
1493
  {
1494
2
    ASSERT_EQ(res.find(d_z), res.end());
1495
    /*
1496
     *  x y z           x y z
1497
     *  1 1 1  5   -->  1 0 9  7
1498
     *  2 3 5  8        0 1 3  9
1499
     *
1500
     *  y x z           y x z
1501
     *  1 1 1  5   -->  1 0 3  9
1502
     *  3 2 5  8        0 1 9  7
1503
     */
1504
2
    ASSERT_EQ(res[d_x], x1);
1505
2
    ASSERT_EQ(res[d_y], y1);
1506
  }
1507
}
1508
1509
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial4)
1510
{
1511
4
  std::unordered_map<Node, Node> res;
1512
  BVGauss::Result ret;
1513
1514
  /* -------------------------------------------------------------------
1515
   *     lhs    rhs          lhs    rhs  modulo 11
1516
   *  ----^---   ^         ---^---   ^
1517
   *  2  4   6   18   -->  1 0 10    1
1518
   *  4  5   6   24        0 1  2    4
1519
   *  2  7  12   30        0 0  0    0
1520
   * ------------------------------------------------------------------- */
1521
1522
  Node eq1 = d_nodeManager->mkNode(
1523
      kind::EQUAL,
1524
8
      d_nodeManager->mkNode(
1525
          kind::BITVECTOR_UREM,
1526
8
          d_nodeManager->mkNode(
1527
              kind::BITVECTOR_ADD,
1528
4
              d_nodeManager->mkNode(
1529
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_four),
1530
              d_z_mul_six),
1531
          d_p),
1532
8
      d_eighteen);
1533
1534
  Node eq2 = d_nodeManager->mkNode(
1535
      kind::EQUAL,
1536
8
      d_nodeManager->mkNode(
1537
          kind::BITVECTOR_UREM,
1538
8
          d_nodeManager->mkNode(
1539
              kind::BITVECTOR_ADD,
1540
4
              d_nodeManager->mkNode(
1541
                  kind::BITVECTOR_ADD, d_x_mul_four, d_y_mul_five),
1542
              d_z_mul_six),
1543
          d_p),
1544
8
      d_twentyfour);
1545
1546
  Node eq3 = d_nodeManager->mkNode(
1547
      kind::EQUAL,
1548
8
      d_nodeManager->mkNode(
1549
          kind::BITVECTOR_UREM,
1550
8
          d_nodeManager->mkNode(
1551
              kind::BITVECTOR_ADD,
1552
4
              d_nodeManager->mkNode(
1553
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_seven),
1554
              d_z_mul_twelve),
1555
          d_p),
1556
8
      d_thirty);
1557
1558
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
1559
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1560
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1561
2
  ASSERT_EQ(res.size(), 2);
1562
1563
  Node x1 = d_nodeManager->mkNode(
1564
      kind::BITVECTOR_UREM,
1565
6
      d_nodeManager->mkNode(
1566
          kind::BITVECTOR_ADD,
1567
          d_one32,
1568
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_one32)),
1569
8
      d_p);
1570
  Node y1 = d_nodeManager->mkNode(
1571
      kind::BITVECTOR_UREM,
1572
6
      d_nodeManager->mkNode(
1573
          kind::BITVECTOR_ADD,
1574
          d_four32,
1575
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_nine32)),
1576
8
      d_p);
1577
  Node x2 = d_nodeManager->mkNode(
1578
      kind::BITVECTOR_UREM,
1579
6
      d_nodeManager->mkNode(
1580
          kind::BITVECTOR_ADD,
1581
          d_three32,
1582
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_five32)),
1583
8
      d_p);
1584
  Node z2 = d_nodeManager->mkNode(
1585
      kind::BITVECTOR_UREM,
1586
6
      d_nodeManager->mkNode(
1587
          kind::BITVECTOR_ADD,
1588
          d_two32,
1589
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_five32)),
1590
8
      d_p);
1591
  Node y3 = d_nodeManager->mkNode(
1592
      kind::BITVECTOR_UREM,
1593
6
      d_nodeManager->mkNode(
1594
          kind::BITVECTOR_ADD,
1595
          d_six32,
1596
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_nine32)),
1597
8
      d_p);
1598
  Node z3 = d_nodeManager->mkNode(
1599
      kind::BITVECTOR_UREM,
1600
6
      d_nodeManager->mkNode(
1601
          kind::BITVECTOR_ADD,
1602
          d_ten32,
1603
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_one32)),
1604
8
      d_p);
1605
1606
  /* result depends on order of variables in matrix */
1607
2
  if (res.find(d_x) == res.end())
1608
  {
1609
    /*
1610
     *  y  z x           y z  x
1611
     *  4  6 2  18  -->  1 0  2   6
1612
     *  5  6 4  24       0 1 10  10
1613
     *  7 12 2  30       0 0  0   0
1614
     *
1615
     *  z  y x           z y  x
1616
     *  6  4 2  18  -->  1 0 10  10
1617
     *  6  5 4  24       0 1  2   6
1618
     * 12 12 2  30       0 0  0   0
1619
     *
1620
     */
1621
    ASSERT_EQ(res[d_y], y3);
1622
    ASSERT_EQ(res[d_z], z3);
1623
  }
1624
2
  else if (res.find(d_y) == res.end())
1625
  {
1626
    /*
1627
     *  x  z y           x z y
1628
     *  2  6 4  18  -->  1 0 6  3
1629
     *  4  6 5  24       0 1 6  2
1630
     *  2 12 7  30       0 0 0  0
1631
     *
1632
     *  z x  y           z  x y
1633
     *  6 2  4  18  -->  1  0 6  2
1634
     *  6 4  5  24       0  1 6  3
1635
     * 12 2 12  30       0  0 0  0
1636
     *
1637
     */
1638
    ASSERT_EQ(res[d_x], x2);
1639
    ASSERT_EQ(res[d_z], z2);
1640
  }
1641
  else
1642
  {
1643
2
    ASSERT_EQ(res.find(d_z), res.end());
1644
    /*
1645
     *  x y  z           x y  z
1646
     *  2 4  6  18  -->  1 0 10  1
1647
     *  4 5  6  24       0 1  2  4
1648
     *  2 7 12  30       0 0  0  0
1649
     *
1650
     *  y x  z            y x  z
1651
     *  4 2  6  18   -->  1 0  2 49
1652
     *  5 4  6  24        0 1 10  1
1653
     *  7 2 12  30        0 0  0  0
1654
     */
1655
2
    ASSERT_EQ(res[d_x], x1);
1656
2
    ASSERT_EQ(res[d_y], y1);
1657
  }
1658
}
1659
1660
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial5)
1661
{
1662
4
  std::unordered_map<Node, Node> res;
1663
  BVGauss::Result ret;
1664
1665
  /* -------------------------------------------------------------------
1666
   *     lhs    rhs         lhs   rhs  modulo 3
1667
   *  ----^---   ^         --^--   ^
1668
   *  2  4   6   18   -->  1 2 0   0
1669
   *  4  5   6   24        0 0 0   0
1670
   *  2  7  12   30        0 0 0   0
1671
   * ------------------------------------------------------------------- */
1672
1673
  Node eq1 = d_nodeManager->mkNode(
1674
      kind::EQUAL,
1675
8
      d_nodeManager->mkNode(
1676
          kind::BITVECTOR_UREM,
1677
8
          d_nodeManager->mkNode(
1678
              kind::BITVECTOR_ADD,
1679
4
              d_nodeManager->mkNode(
1680
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_four),
1681
              d_z_mul_six),
1682
          d_three),
1683
8
      d_eighteen);
1684
1685
  Node eq2 = d_nodeManager->mkNode(
1686
      kind::EQUAL,
1687
8
      d_nodeManager->mkNode(
1688
          kind::BITVECTOR_UREM,
1689
8
          d_nodeManager->mkNode(
1690
              kind::BITVECTOR_ADD,
1691
4
              d_nodeManager->mkNode(
1692
                  kind::BITVECTOR_ADD, d_x_mul_four, d_y_mul_five),
1693
              d_z_mul_six),
1694
          d_three),
1695
8
      d_twentyfour);
1696
1697
  Node eq3 = d_nodeManager->mkNode(
1698
      kind::EQUAL,
1699
8
      d_nodeManager->mkNode(
1700
          kind::BITVECTOR_UREM,
1701
8
          d_nodeManager->mkNode(
1702
              kind::BITVECTOR_ADD,
1703
4
              d_nodeManager->mkNode(
1704
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_seven),
1705
              d_z_mul_twelve),
1706
          d_three),
1707
8
      d_thirty);
1708
1709
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
1710
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1711
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1712
2
  ASSERT_EQ(res.size(), 1);
1713
1714
  Node x1 = d_nodeManager->mkNode(
1715
      kind::BITVECTOR_UREM,
1716
4
      d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_one32),
1717
8
      d_three);
1718
  Node y2 = d_nodeManager->mkNode(
1719
      kind::BITVECTOR_UREM,
1720
4
      d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_one32),
1721
8
      d_three);
1722
1723
  /* result depends on order of variables in matrix */
1724
2
  if (res.find(d_x) == res.end())
1725
  {
1726
    /*
1727
     *  y x  z           y x z
1728
     *  4 2  6  18  -->  1 2 0 0
1729
     *  5 4  6  24       0 0 0 0
1730
     *  7 2 12  30       0 0 0 0
1731
     *
1732
     *  y  z x            y z x
1733
     *  4  6 2  18  -->  1 0 2  0
1734
     *  5  6 4  24       0 0 0  0
1735
     *  7 12 2  30       0 0 0  0
1736
     *
1737
     *  z  y x           z y x
1738
     *  6  4 2  18  -->  0 1 2  0
1739
     *  6  5 4  24       0 0 0  0
1740
     * 12 12 2  30       0 0 0  0
1741
     *
1742
     */
1743
2
    ASSERT_EQ(res[d_y], y2);
1744
  }
1745
  else if (res.find(d_y) == res.end())
1746
  {
1747
    /*
1748
     *  x y  z           x y z
1749
     *  2 4  6  18  -->  1 2 0  0
1750
     *  4 5  6  24       0 0 0  0
1751
     *  2 7 12  30       0 0 0  0
1752
     *
1753
     *  x  z y           x z y
1754
     *  2  6 4  18  -->  1 0 2  0
1755
     *  4  6 5  24       0 0 0  0
1756
     *  2 12 7  30       0 0 0  0
1757
     *
1758
     *  z x  y           z  x y
1759
     *  6 2  4  18  -->  0  1 2  0
1760
     *  6 4  5  24       0  0 0  0
1761
     * 12 2 12  30       0  0 0  0
1762
     *
1763
     */
1764
    ASSERT_EQ(res[d_x], x1);
1765
  }
1766
  else
1767
  {
1768
    ASSERT_TRUE(false);
1769
  }
1770
}
1771
1772
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_partial6)
1773
{
1774
4
  std::unordered_map<Node, Node> res;
1775
  BVGauss::Result ret;
1776
1777
  /* -------------------------------------------------------------------
1778
   *    lhs    rhs  -->    lhs    rhs  modulo 11
1779
   *  ---^---   ^        ---^---   ^
1780
   *  x y z w            x y z w
1781
   *  1 2 0 6   2        1 2 0 6   2
1782
   *  0 0 2 2   2        0 0 1 1   1
1783
   *  0 0 0 1   2        0 0 0 1   2
1784
   * ------------------------------------------------------------------- */
1785
1786
4
  Node y_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_two);
1787
4
  Node z_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two);
1788
  Node w = bv::utils::mkConcat(
1789
4
      d_zero, d_nodeManager->mkVar("w", d_nodeManager->mkBitVectorType(16)));
1790
4
  Node w_mul_six = d_nodeManager->mkNode(kind::BITVECTOR_MULT, w, d_six);
1791
4
  Node w_mul_two = d_nodeManager->mkNode(kind::BITVECTOR_MULT, w, d_two);
1792
1793
  Node eq1 = d_nodeManager->mkNode(
1794
      kind::EQUAL,
1795
8
      d_nodeManager->mkNode(
1796
          kind::BITVECTOR_UREM,
1797
8
          d_nodeManager->mkNode(
1798
              kind::BITVECTOR_ADD,
1799
4
              d_nodeManager->mkNode(
1800
                  kind::BITVECTOR_ADD, d_x_mul_one, y_mul_two),
1801
              w_mul_six),
1802
          d_p),
1803
8
      d_two);
1804
1805
  Node eq2 = d_nodeManager->mkNode(
1806
      kind::EQUAL,
1807
8
      d_nodeManager->mkNode(
1808
          kind::BITVECTOR_UREM,
1809
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, z_mul_two, w_mul_two),
1810
          d_p),
1811
8
      d_two);
1812
1813
  Node eq3 = d_nodeManager->mkNode(
1814
4
      kind::EQUAL, d_nodeManager->mkNode(kind::BITVECTOR_UREM, w, d_p), d_two);
1815
1816
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
1817
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1818
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1819
2
  ASSERT_EQ(res.size(), 3);
1820
1821
  Node x1 = d_nodeManager->mkNode(
1822
      kind::BITVECTOR_UREM,
1823
6
      d_nodeManager->mkNode(
1824
          kind::BITVECTOR_ADD,
1825
          d_one32,
1826
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_nine32)),
1827
8
      d_p);
1828
4
  Node z1 = d_ten32;
1829
4
  Node w1 = d_two32;
1830
1831
  Node y2 = d_nodeManager->mkNode(
1832
      kind::BITVECTOR_UREM,
1833
6
      d_nodeManager->mkNode(
1834
          kind::BITVECTOR_ADD,
1835
          d_six32,
1836
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_five32)),
1837
8
      d_p);
1838
4
  Node z2 = d_ten32;
1839
4
  Node w2 = d_two32;
1840
1841
  /* result depends on order of variables in matrix */
1842
2
  if (res.find(d_x) == res.end())
1843
  {
1844
2
    ASSERT_EQ(res[d_y], y2);
1845
2
    ASSERT_EQ(res[d_z], z2);
1846
2
    ASSERT_EQ(res[w], w2);
1847
  }
1848
  else if (res.find(d_y) == res.end())
1849
  {
1850
    ASSERT_EQ(res[d_x], x1);
1851
    ASSERT_EQ(res[d_z], z1);
1852
    ASSERT_EQ(res[w], w1);
1853
  }
1854
  else
1855
  {
1856
    ASSERT_TRUE(false);
1857
  }
1858
}
1859
1860
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_with_expr_partial)
1861
{
1862
4
  std::unordered_map<Node, Node> res;
1863
  BVGauss::Result ret;
1864
1865
  /* -------------------------------------------------------------------
1866
   *   lhs   rhs        lhs   rhs  modulo 11
1867
   *  --^--   ^        --^--   ^
1868
   *  1 0 9   7   -->  1 0 9   7
1869
   *  0 1 3   9        0 1 3   9
1870
   * ------------------------------------------------------------------- */
1871
1872
4
  Node zero = bv::utils::mkZero(8);
1873
4
  Node xx = d_nodeManager->mkVar("xx", d_nodeManager->mkBitVectorType(8));
1874
4
  Node yy = d_nodeManager->mkVar("yy", d_nodeManager->mkBitVectorType(8));
1875
4
  Node zz = d_nodeManager->mkVar("zz", d_nodeManager->mkBitVectorType(8));
1876
1877
  Node x = bv::utils::mkConcat(
1878
      d_zero,
1879
4
      bv::utils::mkConcat(
1880
8
          zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, xx), 7, 0)));
1881
  Node y = bv::utils::mkConcat(
1882
      d_zero,
1883
4
      bv::utils::mkConcat(
1884
8
          zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, yy), 7, 0)));
1885
  Node z = bv::utils::mkConcat(
1886
      d_zero,
1887
4
      bv::utils::mkConcat(
1888
8
          zero, bv::utils::mkExtract(bv::utils::mkConcat(zero, zz), 7, 0)));
1889
1890
4
  Node x_mul_one = d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, d_one32);
1891
4
  Node nine_mul_z = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_nine32, z);
1892
4
  Node one_mul_y = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_one, y);
1893
4
  Node z_mul_three = d_nodeManager->mkNode(kind::BITVECTOR_MULT, z, d_three);
1894
1895
  Node eq1 = d_nodeManager->mkNode(
1896
      kind::EQUAL,
1897
8
      d_nodeManager->mkNode(
1898
          kind::BITVECTOR_UREM,
1899
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, x_mul_one, nine_mul_z),
1900
          d_p),
1901
8
      d_seven);
1902
1903
  Node eq2 = d_nodeManager->mkNode(
1904
      kind::EQUAL,
1905
8
      d_nodeManager->mkNode(
1906
          kind::BITVECTOR_UREM,
1907
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, one_mul_y, z_mul_three),
1908
          d_p),
1909
8
      d_nine);
1910
1911
4
  std::vector<Node> eqs = {eq1, eq2};
1912
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
1913
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
1914
2
  ASSERT_EQ(res.size(), 2);
1915
1916
2
  x = Rewriter::rewrite(x);
1917
2
  y = Rewriter::rewrite(y);
1918
2
  z = Rewriter::rewrite(z);
1919
1920
  Node x1 = d_nodeManager->mkNode(
1921
      kind::BITVECTOR_UREM,
1922
6
      d_nodeManager->mkNode(
1923
          kind::BITVECTOR_ADD,
1924
          d_seven32,
1925
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, z, d_two32)),
1926
8
      d_p);
1927
  Node y1 = d_nodeManager->mkNode(
1928
      kind::BITVECTOR_UREM,
1929
6
      d_nodeManager->mkNode(
1930
          kind::BITVECTOR_ADD,
1931
          d_nine32,
1932
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, z, d_eight32)),
1933
8
      d_p);
1934
1935
  Node x2 = d_nodeManager->mkNode(
1936
      kind::BITVECTOR_UREM,
1937
6
      d_nodeManager->mkNode(
1938
          kind::BITVECTOR_ADD,
1939
          d_two32,
1940
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, y, d_three32)),
1941
8
      d_p);
1942
  Node z2 = d_nodeManager->mkNode(
1943
      kind::BITVECTOR_UREM,
1944
6
      d_nodeManager->mkNode(
1945
          kind::BITVECTOR_ADD,
1946
          d_three32,
1947
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, y, d_seven32)),
1948
8
      d_p);
1949
1950
  Node y3 = d_nodeManager->mkNode(
1951
      kind::BITVECTOR_UREM,
1952
6
      d_nodeManager->mkNode(
1953
          kind::BITVECTOR_ADD,
1954
          d_three32,
1955
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, d_four32)),
1956
8
      d_p);
1957
  Node z3 = d_nodeManager->mkNode(
1958
      kind::BITVECTOR_UREM,
1959
6
      d_nodeManager->mkNode(
1960
          kind::BITVECTOR_ADD,
1961
          d_two32,
1962
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, d_six32)),
1963
8
      d_p);
1964
1965
  /* result depends on order of variables in matrix */
1966
2
  if (res.find(x) == res.end())
1967
  {
1968
    /*
1969
     *  y z x           y z x
1970
     *  0 9 1  7   -->  1 0 7  3
1971
     *  1 3 0  9        0 1 5  2
1972
     *
1973
     *  z y x           z y x
1974
     *  9 0 1  7   -->  1 0 5  2
1975
     *  3 1 0  9        0 1 7  3
1976
     */
1977
    ASSERT_EQ(res[Rewriter::rewrite(y)], y3);
1978
    ASSERT_EQ(res[Rewriter::rewrite(z)], z3);
1979
  }
1980
2
  else if (res.find(y) == res.end())
1981
  {
1982
    /*
1983
     *  x z y           x z y
1984
     *  1 9 0  7   -->  1 0 8  2
1985
     *  0 3 1  9        0 1 4  3
1986
     *
1987
     *  z x y           z x y
1988
     *  9 1 0  7   -->  1 0 4  3
1989
     *  3 0 1  9        0 1 8  2
1990
     */
1991
    ASSERT_EQ(res[x], x2);
1992
    ASSERT_EQ(res[z], z2);
1993
  }
1994
  else
1995
  {
1996
2
    ASSERT_EQ(res.find(z), res.end());
1997
    /*
1998
     *  x y z           x y z
1999
     *  1 0 9  7   -->  1 0 9  7
2000
     *  0 1 3  9        0 1 3  9
2001
     *
2002
     *  y x z           y x z
2003
     *  0 1 9  7   -->  1 0 3  9
2004
     *  1 0 3  9        0 1 9  7
2005
     */
2006
2
    ASSERT_EQ(res[x], x1);
2007
2
    ASSERT_EQ(res[y], y1);
2008
  }
2009
}
2010
2011
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_nary_partial)
2012
{
2013
4
  std::unordered_map<Node, Node> res;
2014
  BVGauss::Result ret;
2015
2016
  /* -------------------------------------------------------------------
2017
   *   lhs   rhs        lhs   rhs  modulo 11
2018
   *  --^--   ^        --^--   ^
2019
   *  1 0 9   7   -->  1 0 9   7
2020
   *  0 1 3   9        0 1 3   9
2021
   * ------------------------------------------------------------------- */
2022
2023
4
  Node zero = bv::utils::mkZero(8);
2024
4
  Node xx = d_nodeManager->mkVar("xx", d_nodeManager->mkBitVectorType(8));
2025
4
  Node yy = d_nodeManager->mkVar("yy", d_nodeManager->mkBitVectorType(8));
2026
4
  Node zz = d_nodeManager->mkVar("zz", d_nodeManager->mkBitVectorType(8));
2027
2028
  Node x = bv::utils::mkConcat(
2029
      d_zero,
2030
4
      bv::utils::mkConcat(
2031
          zero,
2032
4
          bv::utils::mkExtract(
2033
8
              d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, zero, xx), 7, 0)));
2034
  Node y = bv::utils::mkConcat(
2035
      d_zero,
2036
4
      bv::utils::mkConcat(
2037
          zero,
2038
4
          bv::utils::mkExtract(
2039
8
              d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, zero, yy), 7, 0)));
2040
  Node z = bv::utils::mkConcat(
2041
      d_zero,
2042
4
      bv::utils::mkConcat(
2043
          zero,
2044
4
          bv::utils::mkExtract(
2045
8
              d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, zero, zz), 7, 0)));
2046
2047
4
  NodeBuilder nbx(d_nodeManager.get(), kind::BITVECTOR_MULT);
2048
2
  nbx << d_x << d_one << x;
2049
4
  Node x_mul_one_mul_xx = nbx.constructNode();
2050
4
  NodeBuilder nby(d_nodeManager.get(), kind::BITVECTOR_MULT);
2051
2
  nby << d_y << y << d_one;
2052
4
  Node y_mul_yy_mul_one = nby.constructNode();
2053
4
  NodeBuilder nbz(d_nodeManager.get(), kind::BITVECTOR_MULT);
2054
2
  nbz << d_three << d_z << z;
2055
4
  Node three_mul_z_mul_zz = nbz.constructNode();
2056
4
  NodeBuilder nbz2(d_nodeManager.get(), kind::BITVECTOR_MULT);
2057
2
  nbz2 << d_z << d_nine << z;
2058
4
  Node z_mul_nine_mul_zz = nbz2.constructNode();
2059
2060
4
  Node x_mul_xx = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, x);
2061
4
  Node y_mul_yy = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, y);
2062
4
  Node z_mul_zz = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, z);
2063
2064
  Node eq1 = d_nodeManager->mkNode(
2065
      kind::EQUAL,
2066
8
      d_nodeManager->mkNode(
2067
          kind::BITVECTOR_UREM,
2068
4
          d_nodeManager->mkNode(
2069
              kind::BITVECTOR_ADD, x_mul_one_mul_xx, z_mul_nine_mul_zz),
2070
          d_p),
2071
8
      d_seven);
2072
2073
  Node eq2 = d_nodeManager->mkNode(
2074
      kind::EQUAL,
2075
8
      d_nodeManager->mkNode(
2076
          kind::BITVECTOR_UREM,
2077
4
          d_nodeManager->mkNode(
2078
              kind::BITVECTOR_ADD, y_mul_yy_mul_one, three_mul_z_mul_zz),
2079
          d_p),
2080
8
      d_nine);
2081
2082
4
  std::vector<Node> eqs = {eq1, eq2};
2083
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
2084
2
  ASSERT_EQ(ret, BVGauss::Result::PARTIAL);
2085
2
  ASSERT_EQ(res.size(), 2);
2086
2087
2
  x_mul_xx = Rewriter::rewrite(x_mul_xx);
2088
2
  y_mul_yy = Rewriter::rewrite(y_mul_yy);
2089
2
  z_mul_zz = Rewriter::rewrite(z_mul_zz);
2090
2091
  Node x1 = d_nodeManager->mkNode(
2092
      kind::BITVECTOR_UREM,
2093
6
      d_nodeManager->mkNode(
2094
          kind::BITVECTOR_ADD,
2095
          d_seven32,
2096
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, z_mul_zz, d_two32)),
2097
8
      d_p);
2098
  Node y1 = d_nodeManager->mkNode(
2099
      kind::BITVECTOR_UREM,
2100
6
      d_nodeManager->mkNode(
2101
          kind::BITVECTOR_ADD,
2102
          d_nine32,
2103
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, z_mul_zz, d_eight32)),
2104
8
      d_p);
2105
2106
  Node x2 = d_nodeManager->mkNode(
2107
      kind::BITVECTOR_UREM,
2108
6
      d_nodeManager->mkNode(
2109
          kind::BITVECTOR_ADD,
2110
          d_two32,
2111
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, y_mul_yy, d_three32)),
2112
8
      d_p);
2113
  Node z2 = d_nodeManager->mkNode(
2114
      kind::BITVECTOR_UREM,
2115
6
      d_nodeManager->mkNode(
2116
          kind::BITVECTOR_ADD,
2117
          d_three32,
2118
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, y_mul_yy, d_seven32)),
2119
8
      d_p);
2120
2121
  Node y3 = d_nodeManager->mkNode(
2122
      kind::BITVECTOR_UREM,
2123
6
      d_nodeManager->mkNode(
2124
          kind::BITVECTOR_ADD,
2125
          d_three32,
2126
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, x_mul_xx, d_four32)),
2127
8
      d_p);
2128
  Node z3 = d_nodeManager->mkNode(
2129
      kind::BITVECTOR_UREM,
2130
6
      d_nodeManager->mkNode(
2131
          kind::BITVECTOR_ADD,
2132
          d_two32,
2133
4
          d_nodeManager->mkNode(kind::BITVECTOR_MULT, x_mul_xx, d_six32)),
2134
8
      d_p);
2135
2136
  /* result depends on order of variables in matrix */
2137
2
  if (res.find(x_mul_xx) == res.end())
2138
  {
2139
    /*
2140
     *  y z x           y z x
2141
     *  0 9 1  7   -->  1 0 7  3
2142
     *  1 3 0  9        0 1 5  2
2143
     *
2144
     *  z y x           z y x
2145
     *  9 0 1  7   -->  1 0 5  2
2146
     *  3 1 0  9        0 1 7  3
2147
     */
2148
    ASSERT_EQ(res[y_mul_yy], y3);
2149
    ASSERT_EQ(res[z_mul_zz], z3);
2150
  }
2151
2
  else if (res.find(y_mul_yy) == res.end())
2152
  {
2153
    /*
2154
     *  x z y           x z y
2155
     *  1 9 0  7   -->  1 0 8  2
2156
     *  0 3 1  9        0 1 4  3
2157
     *
2158
     *  z x y           z x y
2159
     *  9 1 0  7   -->  1 0 4  3
2160
     *  3 0 1  9        0 1 8  2
2161
     */
2162
    ASSERT_EQ(res[x_mul_xx], x2);
2163
    ASSERT_EQ(res[z_mul_zz], z2);
2164
  }
2165
  else
2166
  {
2167
2
    ASSERT_EQ(res.find(z_mul_zz), res.end());
2168
    /*
2169
     *  x y z           x y z
2170
     *  1 0 9  7   -->  1 0 9  7
2171
     *  0 1 3  9        0 1 3  9
2172
     *
2173
     *  y x z           y x z
2174
     *  0 1 9  7   -->  1 0 3  9
2175
     *  1 0 3  9        0 1 9  7
2176
     */
2177
2
    ASSERT_EQ(res[x_mul_xx], x1);
2178
2
    ASSERT_EQ(res[y_mul_yy], y1);
2179
  }
2180
}
2181
2182
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_not_invalid1)
2183
{
2184
4
  std::unordered_map<Node, Node> res;
2185
  BVGauss::Result ret;
2186
2187
  /* -------------------------------------------------------------------
2188
   * 3x / 2z = 4  modulo 11
2189
   * 2x % 5y = 2
2190
   * y O z = 5
2191
   * ------------------------------------------------------------------- */
2192
2193
  Node n1 = d_nodeManager->mkNode(
2194
      kind::BITVECTOR_UDIV,
2195
4
      d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_three, d_x),
2196
8
      d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_two, d_y));
2197
  Node n2 = d_nodeManager->mkNode(
2198
      kind::BITVECTOR_UREM,
2199
4
      d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_two, d_x),
2200
8
      d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_five, d_y));
2201
2202
  Node n3 = bv::utils::mkConcat(
2203
      d_zero,
2204
4
      bv::utils::mkExtract(
2205
8
          d_nodeManager->mkNode(kind::BITVECTOR_CONCAT, d_y, d_z), 15, 0));
2206
2207
  Node eq1 = d_nodeManager->mkNode(
2208
      kind::EQUAL,
2209
4
      d_nodeManager->mkNode(kind::BITVECTOR_UREM, n1, d_p),
2210
8
      d_four);
2211
2212
  Node eq2 = d_nodeManager->mkNode(
2213
4
      kind::EQUAL, d_nodeManager->mkNode(kind::BITVECTOR_UREM, n2, d_p), d_two);
2214
2215
  Node eq3 = d_nodeManager->mkNode(
2216
      kind::EQUAL,
2217
4
      d_nodeManager->mkNode(kind::BITVECTOR_UREM, n3, d_p),
2218
8
      d_five);
2219
2220
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
2221
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
2222
2
  ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
2223
2
  ASSERT_EQ(res.size(), 3);
2224
2225
2
  ASSERT_EQ(res[n1], d_four32);
2226
2
  ASSERT_EQ(res[n2], d_two32);
2227
2
  ASSERT_EQ(res[n3], d_five32);
2228
}
2229
2230
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_not_invalid2)
2231
{
2232
4
  std::unordered_map<Node, Node> res;
2233
  BVGauss::Result ret;
2234
2235
  /* -------------------------------------------------------------------
2236
   * x*y = 4  modulo 11
2237
   * x*y*z = 2
2238
   * 2*x*y + 2*z = 9
2239
   * ------------------------------------------------------------------- */
2240
2241
4
  Node zero32 = bv::utils::mkZero(32);
2242
2243
  Node x = bv::utils::mkConcat(
2244
4
      zero32, d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16)));
2245
  Node y = bv::utils::mkConcat(
2246
4
      zero32, d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16)));
2247
  Node z = bv::utils::mkConcat(
2248
4
      zero32, d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16)));
2249
2250
4
  Node n1 = d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y);
2251
  Node n2 =
2252
      d_nodeManager->mkNode(kind::BITVECTOR_MULT,
2253
4
                            d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
2254
8
                            z);
2255
  Node n3 = d_nodeManager->mkNode(
2256
      kind::BITVECTOR_ADD,
2257
10
      d_nodeManager->mkNode(kind::BITVECTOR_MULT,
2258
4
                            d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
2259
4
                            bv::utils::mkConcat(d_zero, d_two)),
2260
8
      d_nodeManager->mkNode(
2261
14
          kind::BITVECTOR_MULT, bv::utils::mkConcat(d_zero, d_two), z));
2262
2263
  Node eq1 = d_nodeManager->mkNode(
2264
      kind::EQUAL,
2265
6
      d_nodeManager->mkNode(
2266
4
          kind::BITVECTOR_UREM, n1, bv::utils::mkConcat(d_zero, d_p)),
2267
8
      bv::utils::mkConcat(d_zero, d_four));
2268
2269
  Node eq2 = d_nodeManager->mkNode(
2270
      kind::EQUAL,
2271
6
      d_nodeManager->mkNode(
2272
4
          kind::BITVECTOR_UREM, n2, bv::utils::mkConcat(d_zero, d_p)),
2273
8
      bv::utils::mkConcat(d_zero, d_two));
2274
2275
  Node eq3 = d_nodeManager->mkNode(
2276
      kind::EQUAL,
2277
6
      d_nodeManager->mkNode(
2278
4
          kind::BITVECTOR_UREM, n3, bv::utils::mkConcat(d_zero, d_p)),
2279
8
      bv::utils::mkConcat(d_zero, d_nine));
2280
2281
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
2282
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
2283
2
  ASSERT_EQ(ret, BVGauss::Result::UNIQUE);
2284
2
  ASSERT_EQ(res.size(), 3);
2285
2286
2
  n1 = Rewriter::rewrite(n1);
2287
2
  n2 = Rewriter::rewrite(n2);
2288
2
  z = Rewriter::rewrite(z);
2289
2290
2
  ASSERT_EQ(res[n1], bv::utils::mkConst(48, 4));
2291
2
  ASSERT_EQ(res[n2], bv::utils::mkConst(48, 2));
2292
2293
4
  Integer twoxy = (res[n1].getConst<BitVector>().getValue() * Integer(2))
2294
4
                      .euclidianDivideRemainder(Integer(48));
2295
4
  Integer twoz = (res[z].getConst<BitVector>().getValue() * Integer(2))
2296
4
                     .euclidianDivideRemainder(Integer(48));
2297
4
  Integer r = (twoxy + twoz).euclidianDivideRemainder(Integer(11));
2298
2
  ASSERT_EQ(r, Integer(9));
2299
}
2300
2301
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_for_urem_invalid)
2302
{
2303
4
  std::unordered_map<Node, Node> res;
2304
  BVGauss::Result ret;
2305
2306
  /* -------------------------------------------------------------------
2307
   * x*y = 4  modulo 11
2308
   * x*y*z = 2
2309
   * 2*x*y = 9
2310
   * ------------------------------------------------------------------- */
2311
2312
4
  Node zero32 = bv::utils::mkZero(32);
2313
2314
  Node x = bv::utils::mkConcat(
2315
4
      zero32, d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16)));
2316
  Node y = bv::utils::mkConcat(
2317
4
      zero32, d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16)));
2318
  Node z = bv::utils::mkConcat(
2319
4
      zero32, d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16)));
2320
2321
4
  Node n1 = d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y);
2322
  Node n2 =
2323
      d_nodeManager->mkNode(kind::BITVECTOR_MULT,
2324
4
                            d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
2325
8
                            z);
2326
  Node n3 =
2327
      d_nodeManager->mkNode(kind::BITVECTOR_MULT,
2328
4
                            d_nodeManager->mkNode(kind::BITVECTOR_MULT, x, y),
2329
8
                            bv::utils::mkConcat(d_zero, d_two));
2330
2331
  Node eq1 = d_nodeManager->mkNode(
2332
      kind::EQUAL,
2333
6
      d_nodeManager->mkNode(
2334
4
          kind::BITVECTOR_UREM, n1, bv::utils::mkConcat(d_zero, d_p)),
2335
8
      bv::utils::mkConcat(d_zero, d_four));
2336
2337
  Node eq2 = d_nodeManager->mkNode(
2338
      kind::EQUAL,
2339
6
      d_nodeManager->mkNode(
2340
4
          kind::BITVECTOR_UREM, n2, bv::utils::mkConcat(d_zero, d_p)),
2341
8
      bv::utils::mkConcat(d_zero, d_two));
2342
2343
  Node eq3 = d_nodeManager->mkNode(
2344
      kind::EQUAL,
2345
6
      d_nodeManager->mkNode(
2346
4
          kind::BITVECTOR_UREM, n3, bv::utils::mkConcat(d_zero, d_p)),
2347
8
      bv::utils::mkConcat(d_zero, d_nine));
2348
2349
4
  std::vector<Node> eqs = {eq1, eq2, eq3};
2350
2
  ret = BVGauss::gaussElimRewriteForUrem(eqs, res);
2351
2
  ASSERT_EQ(ret, BVGauss::Result::INVALID);
2352
}
2353
2354
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_unique1)
2355
{
2356
  /* -------------------------------------------------------------------
2357
   *   lhs   rhs  modulo 11
2358
   *  --^--   ^
2359
   *  1 1 1   5
2360
   *  2 3 5   8
2361
   *  4 0 5   2
2362
   * ------------------------------------------------------------------- */
2363
2364
  Node eq1 = d_nodeManager->mkNode(
2365
      kind::EQUAL,
2366
8
      d_nodeManager->mkNode(
2367
          kind::BITVECTOR_UREM,
2368
8
          d_nodeManager->mkNode(
2369
              kind::BITVECTOR_ADD,
2370
4
              d_nodeManager->mkNode(
2371
                  kind::BITVECTOR_ADD, d_x_mul_one, d_y_mul_one),
2372
              d_z_mul_one),
2373
          d_p),
2374
8
      d_five);
2375
2376
  Node eq2 = d_nodeManager->mkNode(
2377
      kind::EQUAL,
2378
8
      d_nodeManager->mkNode(
2379
          kind::BITVECTOR_UREM,
2380
8
          d_nodeManager->mkNode(
2381
              kind::BITVECTOR_ADD,
2382
4
              d_nodeManager->mkNode(
2383
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_three),
2384
              d_z_mul_five),
2385
          d_p),
2386
8
      d_eight);
2387
2388
  Node eq3 = d_nodeManager->mkNode(
2389
      kind::EQUAL,
2390
8
      d_nodeManager->mkNode(
2391
          kind::BITVECTOR_UREM,
2392
4
          d_nodeManager->mkNode(
2393
              kind::BITVECTOR_ADD, d_x_mul_four, d_z_mul_five),
2394
          d_p),
2395
8
      d_two);
2396
2397
  Node a = d_nodeManager->mkNode(
2398
4
      kind::AND, d_nodeManager->mkNode(kind::AND, eq1, eq2), eq3);
2399
2400
4
  AssertionPipeline apipe;
2401
2
  apipe.push_back(a);
2402
4
  passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
2403
4
  std::unordered_map<Node, Node> res;
2404
2
  PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
2405
2
  ASSERT_EQ(pres, PreprocessingPassResult::NO_CONFLICT);
2406
  Node resx = d_nodeManager->mkNode(
2407
4
      kind::EQUAL, d_x, d_nodeManager->mkConst<BitVector>(BitVector(32, 3u)));
2408
  Node resy = d_nodeManager->mkNode(
2409
4
      kind::EQUAL, d_y, d_nodeManager->mkConst<BitVector>(BitVector(32, 4u)));
2410
  Node resz = d_nodeManager->mkNode(
2411
4
      kind::EQUAL, d_z, d_nodeManager->mkConst<BitVector>(BitVector(32, 9u)));
2412
2
  ASSERT_EQ(apipe.size(), 4);
2413
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resx), apipe.end());
2414
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resy), apipe.end());
2415
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resz), apipe.end());
2416
}
2417
2418
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_unique2)
2419
{
2420
  /* -------------------------------------------------------------------
2421
   *   lhs   rhs        lhs   rhs   modulo 11
2422
   *  --^--   ^        --^--   ^
2423
   *  1 1 1   5        1 0 0   3
2424
   *  2 3 5   8        0 1 0   4
2425
   *  4 0 5   2        0 0 1   9
2426
   *
2427
   *   lhs   rhs        lhs   rhs   modulo 7
2428
   *  --^--   ^        --^--   ^
2429
   *  2 6 0   4        1 0 0   3
2430
   *  4 6 0   3        0 1 0   2
2431
   * ------------------------------------------------------------------- */
2432
2433
  Node eq1 = d_nodeManager->mkNode(
2434
      kind::EQUAL,
2435
8
      d_nodeManager->mkNode(
2436
          kind::BITVECTOR_UREM,
2437
8
          d_nodeManager->mkNode(
2438
              kind::BITVECTOR_ADD,
2439
4
              d_nodeManager->mkNode(
2440
                  kind::BITVECTOR_ADD, d_x_mul_one, d_y_mul_one),
2441
              d_z_mul_one),
2442
          d_p),
2443
8
      d_five);
2444
2445
  Node eq2 = d_nodeManager->mkNode(
2446
      kind::EQUAL,
2447
8
      d_nodeManager->mkNode(
2448
          kind::BITVECTOR_UREM,
2449
8
          d_nodeManager->mkNode(
2450
              kind::BITVECTOR_ADD,
2451
4
              d_nodeManager->mkNode(
2452
                  kind::BITVECTOR_ADD, d_x_mul_two, d_y_mul_three),
2453
              d_z_mul_five),
2454
          d_p),
2455
8
      d_eight);
2456
2457
  Node eq3 = d_nodeManager->mkNode(
2458
      kind::EQUAL,
2459
8
      d_nodeManager->mkNode(
2460
          kind::BITVECTOR_UREM,
2461
4
          d_nodeManager->mkNode(
2462
              kind::BITVECTOR_ADD, d_x_mul_four, d_z_mul_five),
2463
          d_p),
2464
8
      d_two);
2465
2466
4
  Node y_mul_six = d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_six);
2467
2468
  Node eq4 = d_nodeManager->mkNode(
2469
      kind::EQUAL,
2470
8
      d_nodeManager->mkNode(
2471
          kind::BITVECTOR_UREM,
2472
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_x_mul_two, y_mul_six),
2473
          d_seven),
2474
8
      d_four);
2475
2476
  Node eq5 = d_nodeManager->mkNode(
2477
      kind::EQUAL,
2478
8
      d_nodeManager->mkNode(
2479
          kind::BITVECTOR_UREM,
2480
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_x_mul_four, y_mul_six),
2481
          d_seven),
2482
8
      d_three);
2483
2484
  Node a = d_nodeManager->mkNode(
2485
4
      kind::AND, d_nodeManager->mkNode(kind::AND, eq1, eq2), eq3);
2486
2487
4
  AssertionPipeline apipe;
2488
2
  apipe.push_back(a);
2489
2
  apipe.push_back(eq4);
2490
2
  apipe.push_back(eq5);
2491
4
  passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
2492
4
  std::unordered_map<Node, Node> res;
2493
2
  PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
2494
2
  ASSERT_EQ(pres, PreprocessingPassResult::NO_CONFLICT);
2495
  Node resx1 = d_nodeManager->mkNode(
2496
4
      kind::EQUAL, d_x, d_nodeManager->mkConst<BitVector>(BitVector(32, 3u)));
2497
  Node resx2 = d_nodeManager->mkNode(
2498
4
      kind::EQUAL, d_x, d_nodeManager->mkConst<BitVector>(BitVector(32, 3u)));
2499
  Node resy1 = d_nodeManager->mkNode(
2500
4
      kind::EQUAL, d_y, d_nodeManager->mkConst<BitVector>(BitVector(32, 4u)));
2501
  Node resy2 = d_nodeManager->mkNode(
2502
4
      kind::EQUAL, d_y, d_nodeManager->mkConst<BitVector>(BitVector(32, 2u)));
2503
  Node resz = d_nodeManager->mkNode(
2504
4
      kind::EQUAL, d_z, d_nodeManager->mkConst<BitVector>(BitVector(32, 9u)));
2505
2
  ASSERT_EQ(apipe.size(), 8);
2506
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resx1), apipe.end());
2507
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resx2), apipe.end());
2508
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resy1), apipe.end());
2509
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resy2), apipe.end());
2510
2
  ASSERT_NE(std::find(apipe.begin(), apipe.end(), resz), apipe.end());
2511
}
2512
2513
46
TEST_F(TestPPWhiteBVGauss, elim_rewrite_partial)
2514
{
2515
  /* -------------------------------------------------------------------
2516
   *   lhs   rhs        lhs   rhs  modulo 11
2517
   *  --^--   ^        --^--   ^
2518
   *  1 0 9   7   -->  1 0 9   7
2519
   *  0 1 3   9        0 1 3   9
2520
   * ------------------------------------------------------------------- */
2521
2522
  Node eq1 = d_nodeManager->mkNode(
2523
      kind::EQUAL,
2524
8
      d_nodeManager->mkNode(
2525
          kind::BITVECTOR_UREM,
2526
4
          d_nodeManager->mkNode(kind::BITVECTOR_ADD, d_x_mul_one, d_z_mul_nine),
2527
          d_p),
2528
8
      d_seven);
2529
2530
  Node eq2 = d_nodeManager->mkNode(
2531
      kind::EQUAL,
2532
8
      d_nodeManager->mkNode(
2533
          kind::BITVECTOR_UREM,
2534
4
          d_nodeManager->mkNode(
2535
              kind::BITVECTOR_ADD, d_y_mul_one, d_z_mul_three),
2536
          d_p),
2537
8
      d_nine);
2538
2539
4
  AssertionPipeline apipe;
2540
2
  apipe.push_back(eq1);
2541
2
  apipe.push_back(eq2);
2542
4
  passes::BVGauss bgauss(nullptr, "bv-gauss-unit");
2543
4
  std::unordered_map<Node, Node> res;
2544
2
  PreprocessingPassResult pres = bgauss.applyInternal(&apipe);
2545
2
  ASSERT_EQ(pres, PreprocessingPassResult::NO_CONFLICT);
2546
2
  ASSERT_EQ(apipe.size(), 4);
2547
2548
  Node resx1 = d_nodeManager->mkNode(
2549
      kind::EQUAL,
2550
      d_x,
2551
8
      d_nodeManager->mkNode(
2552
          kind::BITVECTOR_UREM,
2553
6
          d_nodeManager->mkNode(
2554
              kind::BITVECTOR_ADD,
2555
              d_seven32,
2556
4
              d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_two32)),
2557
6
          d_p));
2558
  Node resy1 = d_nodeManager->mkNode(
2559
      kind::EQUAL,
2560
      d_y,
2561
8
      d_nodeManager->mkNode(
2562
          kind::BITVECTOR_UREM,
2563
6
          d_nodeManager->mkNode(
2564
              kind::BITVECTOR_ADD,
2565
              d_nine32,
2566
4
              d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_z, d_eight32)),
2567
6
          d_p));
2568
2569
  Node resx2 = d_nodeManager->mkNode(
2570
      kind::EQUAL,
2571
      d_x,
2572
8
      d_nodeManager->mkNode(
2573
          kind::BITVECTOR_UREM,
2574
6
          d_nodeManager->mkNode(
2575
              kind::BITVECTOR_ADD,
2576
              d_two32,
2577
4
              d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_three32)),
2578
6
          d_p));
2579
  Node resz2 = d_nodeManager->mkNode(
2580
      kind::EQUAL,
2581
      d_z,
2582
8
      d_nodeManager->mkNode(
2583
          kind::BITVECTOR_UREM,
2584
6
          d_nodeManager->mkNode(
2585
              kind::BITVECTOR_ADD,
2586
              d_three32,
2587
4
              d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_y, d_seven32)),
2588
6
          d_p));
2589
2590
  Node resy3 = d_nodeManager->mkNode(
2591
      kind::EQUAL,
2592
      d_y,
2593
8
      d_nodeManager->mkNode(
2594
          kind::BITVECTOR_UREM,
2595
6
          d_nodeManager->mkNode(
2596
              kind::BITVECTOR_ADD,
2597
              d_three32,
2598
4
              d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_four32)),
2599
6
          d_p));
2600
  Node resz3 = d_nodeManager->mkNode(
2601
      kind::EQUAL,
2602
      d_z,
2603
8
      d_nodeManager->mkNode(
2604
          kind::BITVECTOR_UREM,
2605
6
          d_nodeManager->mkNode(
2606
              kind::BITVECTOR_ADD,
2607
              d_two32,
2608
4
              d_nodeManager->mkNode(kind::BITVECTOR_MULT, d_x, d_six32)),
2609
6
          d_p));
2610
2611
2
  bool fx1 = std::find(apipe.begin(), apipe.end(), resx1) != apipe.end();
2612
2
  bool fy1 = std::find(apipe.begin(), apipe.end(), resy1) != apipe.end();
2613
2
  bool fx2 = std::find(apipe.begin(), apipe.end(), resx2) != apipe.end();
2614
2
  bool fz2 = std::find(apipe.begin(), apipe.end(), resz2) != apipe.end();
2615
2
  bool fy3 = std::find(apipe.begin(), apipe.end(), resy3) != apipe.end();
2616
2
  bool fz3 = std::find(apipe.begin(), apipe.end(), resz3) != apipe.end();
2617
2618
  /* result depends on order of variables in matrix */
2619
2
  ASSERT_TRUE((fx1 && fy1) || (fx2 && fz2) || (fy3 && fz3));
2620
}
2621
2622
46
TEST_F(TestPPWhiteBVGauss, get_min_bw1)
2623
{
2624
2
  ASSERT_EQ(BVGauss::getMinBwExpr(bv::utils::mkConst(32, 11)), 4);
2625
2626
2
  ASSERT_EQ(BVGauss::getMinBwExpr(d_p), 4);
2627
2
  ASSERT_EQ(BVGauss::getMinBwExpr(d_x), 16);
2628
2629
4
  Node extp = bv::utils::mkExtract(d_p, 4, 0);
2630
2
  ASSERT_EQ(BVGauss::getMinBwExpr(extp), 4);
2631
4
  Node extx = bv::utils::mkExtract(d_x, 4, 0);
2632
2
  ASSERT_EQ(BVGauss::getMinBwExpr(extx), 5);
2633
2634
  Node zextop8 =
2635
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(8));
2636
  Node zextop16 =
2637
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(16));
2638
  Node zextop32 =
2639
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(32));
2640
  Node zextop40 =
2641
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(40));
2642
2643
4
  Node zext40p = d_nodeManager->mkNode(zextop8, d_p);
2644
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext40p), 4);
2645
4
  Node zext40x = d_nodeManager->mkNode(zextop8, d_x);
2646
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext40x), 16);
2647
2648
4
  Node zext48p = d_nodeManager->mkNode(zextop16, d_p);
2649
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext48p), 4);
2650
4
  Node zext48x = d_nodeManager->mkNode(zextop16, d_x);
2651
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext48x), 16);
2652
2653
4
  Node p8 = d_nodeManager->mkConst<BitVector>(BitVector(8, 11u));
2654
4
  Node x8 = d_nodeManager->mkVar("x8", d_nodeManager->mkBitVectorType(8));
2655
2656
4
  Node zext48p8 = d_nodeManager->mkNode(zextop40, p8);
2657
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext48p8), 4);
2658
4
  Node zext48x8 = d_nodeManager->mkNode(zextop40, x8);
2659
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext48x8), 8);
2660
2661
4
  Node mult1p = d_nodeManager->mkNode(kind::BITVECTOR_MULT, extp, extp);
2662
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult1p), 5);
2663
4
  Node mult1x = d_nodeManager->mkNode(kind::BITVECTOR_MULT, extx, extx);
2664
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult1x), 0);
2665
2666
4
  Node mult2p = d_nodeManager->mkNode(kind::BITVECTOR_MULT, zext40p, zext40p);
2667
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult2p), 7);
2668
4
  Node mult2x = d_nodeManager->mkNode(kind::BITVECTOR_MULT, zext40x, zext40x);
2669
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult2x), 32);
2670
2671
4
  NodeBuilder nbmult3p(kind::BITVECTOR_MULT);
2672
2
  nbmult3p << zext48p << zext48p << zext48p;
2673
4
  Node mult3p = nbmult3p;
2674
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult3p), 11);
2675
4
  NodeBuilder nbmult3x(kind::BITVECTOR_MULT);
2676
2
  nbmult3x << zext48x << zext48x << zext48x;
2677
4
  Node mult3x = nbmult3x;
2678
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult3x), 48);
2679
2680
4
  NodeBuilder nbmult4p(kind::BITVECTOR_MULT);
2681
2
  nbmult4p << zext48p << zext48p8 << zext48p;
2682
4
  Node mult4p = nbmult4p;
2683
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult4p), 11);
2684
4
  NodeBuilder nbmult4x(kind::BITVECTOR_MULT);
2685
2
  nbmult4x << zext48x << zext48x8 << zext48x;
2686
4
  Node mult4x = nbmult4x;
2687
2
  ASSERT_EQ(BVGauss::getMinBwExpr(mult4x), 40);
2688
2689
4
  Node concat1p = bv::utils::mkConcat(d_p, zext48p);
2690
2
  ASSERT_EQ(BVGauss::getMinBwExpr(concat1p), 52);
2691
4
  Node concat1x = bv::utils::mkConcat(d_x, zext48x);
2692
2
  ASSERT_EQ(BVGauss::getMinBwExpr(concat1x), 64);
2693
2694
4
  Node concat2p = bv::utils::mkConcat(bv::utils::mkZero(16), zext48p);
2695
2
  ASSERT_EQ(BVGauss::getMinBwExpr(concat2p), 4);
2696
4
  Node concat2x = bv::utils::mkConcat(bv::utils::mkZero(16), zext48x);
2697
2
  ASSERT_EQ(BVGauss::getMinBwExpr(concat2x), 16);
2698
2699
4
  Node udiv1p = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, zext48p, zext48p);
2700
2
  ASSERT_EQ(BVGauss::getMinBwExpr(udiv1p), 1);
2701
4
  Node udiv1x = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, zext48x, zext48x);
2702
2
  ASSERT_EQ(BVGauss::getMinBwExpr(udiv1x), 48);
2703
2704
4
  Node udiv2p = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, zext48p, zext48p8);
2705
2
  ASSERT_EQ(BVGauss::getMinBwExpr(udiv2p), 1);
2706
4
  Node udiv2x = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, zext48x, zext48x8);
2707
2
  ASSERT_EQ(BVGauss::getMinBwExpr(udiv2x), 48);
2708
2709
4
  Node urem1p = d_nodeManager->mkNode(kind::BITVECTOR_UREM, zext48p, zext48p);
2710
2
  ASSERT_EQ(BVGauss::getMinBwExpr(urem1p), 1);
2711
4
  Node urem1x = d_nodeManager->mkNode(kind::BITVECTOR_UREM, zext48x, zext48x);
2712
2
  ASSERT_EQ(BVGauss::getMinBwExpr(urem1x), 1);
2713
2714
4
  Node urem2p = d_nodeManager->mkNode(kind::BITVECTOR_UREM, zext48p, zext48p8);
2715
2
  ASSERT_EQ(BVGauss::getMinBwExpr(urem2p), 1);
2716
4
  Node urem2x = d_nodeManager->mkNode(kind::BITVECTOR_UREM, zext48x, zext48x8);
2717
2
  ASSERT_EQ(BVGauss::getMinBwExpr(urem2x), 16);
2718
2719
4
  Node urem3p = d_nodeManager->mkNode(kind::BITVECTOR_UREM, zext48p8, zext48p);
2720
2
  ASSERT_EQ(BVGauss::getMinBwExpr(urem3p), 1);
2721
4
  Node urem3x = d_nodeManager->mkNode(kind::BITVECTOR_UREM, zext48x8, zext48x);
2722
2
  ASSERT_EQ(BVGauss::getMinBwExpr(urem3x), 8);
2723
2724
4
  Node add1p = d_nodeManager->mkNode(kind::BITVECTOR_ADD, extp, extp);
2725
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add1p), 5);
2726
4
  Node add1x = d_nodeManager->mkNode(kind::BITVECTOR_ADD, extx, extx);
2727
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add1x), 0);
2728
2729
4
  Node add2p = d_nodeManager->mkNode(kind::BITVECTOR_ADD, zext40p, zext40p);
2730
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add2p), 5);
2731
4
  Node add2x = d_nodeManager->mkNode(kind::BITVECTOR_ADD, zext40x, zext40x);
2732
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add2x), 17);
2733
2734
4
  Node add3p = d_nodeManager->mkNode(kind::BITVECTOR_ADD, zext48p8, zext48p);
2735
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add3p), 5);
2736
4
  Node add3x = d_nodeManager->mkNode(kind::BITVECTOR_ADD, zext48x8, zext48x);
2737
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add3x), 17);
2738
2739
4
  NodeBuilder nbadd4p(kind::BITVECTOR_ADD);
2740
2
  nbadd4p << zext48p << zext48p << zext48p;
2741
4
  Node add4p = nbadd4p;
2742
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add4p), 6);
2743
4
  NodeBuilder nbadd4x(kind::BITVECTOR_ADD);
2744
2
  nbadd4x << zext48x << zext48x << zext48x;
2745
4
  Node add4x = nbadd4x;
2746
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add4x), 18);
2747
2748
4
  NodeBuilder nbadd5p(kind::BITVECTOR_ADD);
2749
2
  nbadd5p << zext48p << zext48p8 << zext48p;
2750
4
  Node add5p = nbadd5p;
2751
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add5p), 6);
2752
4
  NodeBuilder nbadd5x(kind::BITVECTOR_ADD);
2753
2
  nbadd5x << zext48x << zext48x8 << zext48x;
2754
4
  Node add5x = nbadd5x;
2755
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add5x), 18);
2756
2757
4
  NodeBuilder nbadd6p(kind::BITVECTOR_ADD);
2758
2
  nbadd6p << zext48p << zext48p << zext48p << zext48p;
2759
4
  Node add6p = nbadd6p;
2760
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add6p), 6);
2761
4
  NodeBuilder nbadd6x(kind::BITVECTOR_ADD);
2762
2
  nbadd6x << zext48x << zext48x << zext48x << zext48x;
2763
4
  Node add6x = nbadd6x;
2764
2
  ASSERT_EQ(BVGauss::getMinBwExpr(add6x), 18);
2765
2766
4
  Node not1p = d_nodeManager->mkNode(kind::BITVECTOR_NOT, zext40p);
2767
2
  ASSERT_EQ(BVGauss::getMinBwExpr(not1p), 40);
2768
4
  Node not1x = d_nodeManager->mkNode(kind::BITVECTOR_NOT, zext40x);
2769
2
  ASSERT_EQ(BVGauss::getMinBwExpr(not1x), 40);
2770
}
2771
2772
46
TEST_F(TestPPWhiteBVGauss, get_min_bw2)
2773
{
2774
  /* ((_ zero_extend 5)
2775
   *     ((_ extract 7 0) ((_ zero_extend 15) d_p)))  */
2776
  Node zextop5 =
2777
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
2778
  Node zextop15 =
2779
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
2780
4
  Node zext1 = d_nodeManager->mkNode(zextop15, d_p);
2781
4
  Node ext = bv::utils::mkExtract(zext1, 7, 0);
2782
4
  Node zext2 = d_nodeManager->mkNode(zextop5, ext);
2783
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext2), 4);
2784
}
2785
2786
46
TEST_F(TestPPWhiteBVGauss, get_min_bw3a)
2787
{
2788
  /* ((_ zero_extend 5)
2789
   *     (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x z)))
2790
   *             ((_ extract 4 0) z)))  */
2791
4
  Node x = d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16));
2792
4
  Node y = d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16));
2793
4
  Node z = d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16));
2794
  Node zextop5 =
2795
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
2796
4
  Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, x, y);
2797
4
  Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
2798
4
  Node ext1 = bv::utils::mkExtract(zext1, 4, 0);
2799
4
  Node ext2 = bv::utils::mkExtract(z, 4, 0);
2800
4
  Node udiv2 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, ext1, ext2);
2801
4
  Node zext2 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2);
2802
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext2), 5);
2803
}
2804
2805
46
TEST_F(TestPPWhiteBVGauss, get_min_bw3b)
2806
{
2807
  /* ((_ zero_extend 5)
2808
   *     (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x z)))
2809
   *             ((_ extract 4 0) z)))  */
2810
  Node zextop5 =
2811
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
2812
4
  Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, d_x, d_y);
2813
4
  Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
2814
4
  Node ext1 = bv::utils::mkExtract(zext1, 4, 0);
2815
4
  Node ext2 = bv::utils::mkExtract(d_z, 4, 0);
2816
4
  Node udiv2 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, ext1, ext2);
2817
4
  Node zext2 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2);
2818
2
  ASSERT_EQ(BVGauss::getMinBwExpr(zext2), 5);
2819
}
2820
2821
46
TEST_F(TestPPWhiteBVGauss, get_min_bw4a)
2822
{
2823
  /* (bvadd
2824
   *     ((_ zero_extend 5)
2825
   *         (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x y)))
2826
   *                 ((_ extract 4 0) z)))
2827
   *     ((_ zero_extend 7)
2828
   *         (bvudiv ((_ extract 2 0) ((_ zero_extend 5) (bvudiv x y)))
2829
   *                 ((_ extract 2 0) z)))  */
2830
4
  Node x = d_nodeManager->mkVar("x", d_nodeManager->mkBitVectorType(16));
2831
4
  Node y = d_nodeManager->mkVar("y", d_nodeManager->mkBitVectorType(16));
2832
4
  Node z = d_nodeManager->mkVar("z", d_nodeManager->mkBitVectorType(16));
2833
  Node zextop5 =
2834
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
2835
  Node zextop7 =
2836
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(7));
2837
2838
4
  Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, x, y);
2839
4
  Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
2840
2841
4
  Node ext1_1 = bv::utils::mkExtract(zext1, 4, 0);
2842
4
  Node ext2_1 = bv::utils::mkExtract(z, 4, 0);
2843
4
  Node udiv2_1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, ext1_1, ext2_1);
2844
4
  Node zext2_1 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2_1);
2845
2846
4
  Node ext1_2 = bv::utils::mkExtract(zext1, 2, 0);
2847
4
  Node ext2_2 = bv::utils::mkExtract(z, 2, 0);
2848
4
  Node udiv2_2 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, ext1_2, ext2_2);
2849
4
  Node zext2_2 = d_nodeManager->mkNode(zextop7, udiv2_2);
2850
2851
4
  Node plus = d_nodeManager->mkNode(kind::BITVECTOR_ADD, zext2_1, zext2_2);
2852
2853
2
  ASSERT_EQ(BVGauss::getMinBwExpr(plus), 6);
2854
}
2855
2856
46
TEST_F(TestPPWhiteBVGauss, get_min_bw4b)
2857
{
2858
  /* (bvadd
2859
   *     ((_ zero_extend 5)
2860
   *         (bvudiv ((_ extract 4 0) ((_ zero_extend 5) (bvudiv x y)))
2861
   *                 ((_ extract 4 0) z)))
2862
   *     ((_ zero_extend 7)
2863
   *         (bvudiv ((_ extract 2 0) ((_ zero_extend 5) (bvudiv x y)))
2864
   *                 ((_ extract 2 0) z)))  */
2865
  Node zextop5 =
2866
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
2867
  Node zextop7 =
2868
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(7));
2869
2870
4
  Node udiv1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, d_x, d_y);
2871
4
  Node zext1 = d_nodeManager->mkNode(zextop5, udiv1);
2872
2873
4
  Node ext1_1 = bv::utils::mkExtract(zext1, 4, 0);
2874
4
  Node ext2_1 = bv::utils::mkExtract(d_z, 4, 0);
2875
4
  Node udiv2_1 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, ext1_1, ext2_1);
2876
4
  Node zext2_1 = bv::utils::mkConcat(bv::utils::mkZero(5), udiv2_1);
2877
2878
4
  Node ext1_2 = bv::utils::mkExtract(zext1, 2, 0);
2879
4
  Node ext2_2 = bv::utils::mkExtract(d_z, 2, 0);
2880
4
  Node udiv2_2 = d_nodeManager->mkNode(kind::BITVECTOR_UDIV, ext1_2, ext2_2);
2881
4
  Node zext2_2 = d_nodeManager->mkNode(zextop7, udiv2_2);
2882
2883
4
  Node plus = d_nodeManager->mkNode(kind::BITVECTOR_ADD, zext2_1, zext2_2);
2884
2885
2
  ASSERT_EQ(BVGauss::getMinBwExpr(plus), 6);
2886
}
2887
2888
46
TEST_F(TestPPWhiteBVGauss, get_min_bw5a)
2889
{
2890
  /* (bvadd
2891
   *   (bvadd
2892
   *     (bvadd
2893
   *       (bvadd
2894
   *         (bvadd
2895
   *           (bvadd
2896
   *             (bvadd (bvmul (_ bv86 13)
2897
   *                           ((_ zero_extend 5)
2898
   *                             ((_ extract 7 0) ((_ zero_extend 15) x))))
2899
   *                    (bvmul (_ bv41 13)
2900
   *                           ((_ zero_extend 5)
2901
   *                             ((_ extract 7 0) ((_ zero_extend 15) y)))))
2902
   *             (bvmul (_ bv37 13)
2903
   *                    ((_ zero_extend 5)
2904
   *                      ((_ extract 7 0) ((_ zero_extend 15) z)))))
2905
   *           (bvmul (_ bv170 13)
2906
   *                  ((_ zero_extend 5)
2907
   *                    ((_ extract 7 0) ((_ zero_extend 15) u)))))
2908
   *         (bvmul (_ bv112 13)
2909
   *                ((_ zero_extend 5)
2910
   *                  ((_ extract 7 0) ((_ zero_extend 15) v)))))
2911
   *       (bvmul (_ bv195 13) ((_ zero_extend 5) ((_ extract 15 8) s))))
2912
   *     (bvmul (_ bv124 13) ((_ zero_extend 5) ((_ extract 7 0) s))))
2913
   *   (bvmul (_ bv83 13)
2914
   *          ((_ zero_extend 5) ((_ extract 7 0) ((_ zero_extend 15) w)))))
2915
   */
2916
4
  Node x = bv::utils::mkVar(1);
2917
4
  Node y = bv::utils::mkVar(1);
2918
4
  Node z = bv::utils::mkVar(1);
2919
4
  Node u = bv::utils::mkVar(1);
2920
4
  Node v = bv::utils::mkVar(1);
2921
4
  Node w = bv::utils::mkVar(1);
2922
4
  Node s = bv::utils::mkVar(16);
2923
2924
  Node zextop5 =
2925
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(5));
2926
  Node zextop15 =
2927
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
2928
2929
4
  Node zext15x = d_nodeManager->mkNode(zextop15, x);
2930
4
  Node zext15y = d_nodeManager->mkNode(zextop15, y);
2931
4
  Node zext15z = d_nodeManager->mkNode(zextop15, z);
2932
4
  Node zext15u = d_nodeManager->mkNode(zextop15, u);
2933
4
  Node zext15v = d_nodeManager->mkNode(zextop15, v);
2934
4
  Node zext15w = d_nodeManager->mkNode(zextop15, w);
2935
2936
4
  Node ext7x = bv::utils::mkExtract(zext15x, 7, 0);
2937
4
  Node ext7y = bv::utils::mkExtract(zext15y, 7, 0);
2938
4
  Node ext7z = bv::utils::mkExtract(zext15z, 7, 0);
2939
4
  Node ext7u = bv::utils::mkExtract(zext15u, 7, 0);
2940
4
  Node ext7v = bv::utils::mkExtract(zext15v, 7, 0);
2941
4
  Node ext7w = bv::utils::mkExtract(zext15w, 7, 0);
2942
4
  Node ext7s = bv::utils::mkExtract(s, 7, 0);
2943
4
  Node ext15s = bv::utils::mkExtract(s, 15, 8);
2944
2945
4
  Node xx = bv::utils::mkConcat(bv::utils::mkZero(5), ext7x);
2946
4
  Node yy = bv::utils::mkConcat(bv::utils::mkZero(5), ext7y);
2947
4
  Node zz = bv::utils::mkConcat(bv::utils::mkZero(5), ext7z);
2948
4
  Node uu = bv::utils::mkConcat(bv::utils::mkZero(5), ext7u);
2949
4
  Node vv = bv::utils::mkConcat(bv::utils::mkZero(5), ext7v);
2950
4
  Node ww = bv::utils::mkConcat(bv::utils::mkZero(5), ext7w);
2951
4
  Node s7 = bv::utils::mkConcat(bv::utils::mkZero(5), ext7s);
2952
4
  Node s15 = bv::utils::mkConcat(bv::utils::mkZero(5), ext15s);
2953
2954
  Node plus1 = d_nodeManager->mkNode(
2955
      kind::BITVECTOR_ADD,
2956
8
      d_nodeManager->mkNode(
2957
4
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 86), xx),
2958
8
      d_nodeManager->mkNode(
2959
14
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 41), yy));
2960
  Node plus2 = d_nodeManager->mkNode(
2961
      kind::BITVECTOR_ADD,
2962
      plus1,
2963
8
      d_nodeManager->mkNode(
2964
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 37), zz));
2965
  Node plus3 = d_nodeManager->mkNode(
2966
      kind::BITVECTOR_ADD,
2967
      plus2,
2968
8
      d_nodeManager->mkNode(
2969
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 170), uu));
2970
  Node plus4 = d_nodeManager->mkNode(
2971
      kind::BITVECTOR_ADD,
2972
      plus3,
2973
8
      d_nodeManager->mkNode(
2974
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 112), uu));
2975
  Node plus5 = d_nodeManager->mkNode(
2976
      kind::BITVECTOR_ADD,
2977
      plus4,
2978
8
      d_nodeManager->mkNode(
2979
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 195), s15));
2980
  Node plus6 = d_nodeManager->mkNode(
2981
      kind::BITVECTOR_ADD,
2982
      plus5,
2983
8
      d_nodeManager->mkNode(
2984
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 124), s7));
2985
  Node plus7 = d_nodeManager->mkNode(
2986
      kind::BITVECTOR_ADD,
2987
      plus6,
2988
8
      d_nodeManager->mkNode(
2989
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(13, 83), ww));
2990
2991
2
  ASSERT_EQ(BVGauss::getMinBwExpr(plus7), 0);
2992
}
2993
2994
46
TEST_F(TestPPWhiteBVGauss, get_min_bw5b)
2995
{
2996
  /* (bvadd
2997
   *   (bvadd
2998
   *     (bvadd
2999
   *       (bvadd
3000
   *         (bvadd
3001
   *           (bvadd
3002
   *             (bvadd (bvmul (_ bv86 20)
3003
   *                           ((_ zero_extend 12)
3004
   *                             ((_ extract 7 0) ((_ zero_extend 15) x))))
3005
   *                    (bvmul (_ bv41 20)
3006
   *                           ((_ zero_extend 12)
3007
   *                             ((_ extract 7 0) ((_ zero_extend 15) y)))))
3008
   *             (bvmul (_ bv37 20)
3009
   *                    ((_ zero_extend 12)
3010
   *                      ((_ extract 7 0) ((_ zero_extend 15) z)))))
3011
   *           (bvmul (_ bv170 20)
3012
   *                  ((_ zero_extend 12)
3013
   *                    ((_ extract 7 0) ((_ zero_extend 15) u)))))
3014
   *         (bvmul (_ bv112 20)
3015
   *                ((_ zero_extend 12)
3016
   *                  ((_ extract 7 0) ((_ zero_extend 15) v)))))
3017
   *       (bvmul (_ bv195 20) ((_ zero_extend 12) ((_ extract 15 8) s))))
3018
   *     (bvmul (_ bv124 20) ((_ zero_extend 12) ((_ extract 7 0) s))))
3019
   *   (bvmul (_ bv83 20)
3020
   *          ((_ zero_extend 12) ((_ extract 7 0) ((_ zero_extend 15) w)))))
3021
   */
3022
4
  Node x = bv::utils::mkVar(1);
3023
4
  Node y = bv::utils::mkVar(1);
3024
4
  Node z = bv::utils::mkVar(1);
3025
4
  Node u = bv::utils::mkVar(1);
3026
4
  Node v = bv::utils::mkVar(1);
3027
4
  Node w = bv::utils::mkVar(1);
3028
4
  Node s = bv::utils::mkVar(16);
3029
3030
  Node zextop15 =
3031
4
      d_nodeManager->mkConst<BitVectorZeroExtend>(BitVectorZeroExtend(15));
3032
3033
4
  Node zext15x = d_nodeManager->mkNode(zextop15, x);
3034
4
  Node zext15y = d_nodeManager->mkNode(zextop15, y);
3035
4
  Node zext15z = d_nodeManager->mkNode(zextop15, z);
3036
4
  Node zext15u = d_nodeManager->mkNode(zextop15, u);
3037
4
  Node zext15v = d_nodeManager->mkNode(zextop15, v);
3038
4
  Node zext15w = d_nodeManager->mkNode(zextop15, w);
3039
3040
4
  Node ext7x = bv::utils::mkExtract(zext15x, 7, 0);
3041
4
  Node ext7y = bv::utils::mkExtract(zext15y, 7, 0);
3042
4
  Node ext7z = bv::utils::mkExtract(zext15z, 7, 0);
3043
4
  Node ext7u = bv::utils::mkExtract(zext15u, 7, 0);
3044
4
  Node ext7v = bv::utils::mkExtract(zext15v, 7, 0);
3045
4
  Node ext7w = bv::utils::mkExtract(zext15w, 7, 0);
3046
4
  Node ext7s = bv::utils::mkExtract(s, 7, 0);
3047
4
  Node ext15s = bv::utils::mkExtract(s, 15, 8);
3048
3049
4
  Node xx = bv::utils::mkConcat(bv::utils::mkZero(12), ext7x);
3050
4
  Node yy = bv::utils::mkConcat(bv::utils::mkZero(12), ext7y);
3051
4
  Node zz = bv::utils::mkConcat(bv::utils::mkZero(12), ext7z);
3052
4
  Node uu = bv::utils::mkConcat(bv::utils::mkZero(12), ext7u);
3053
4
  Node vv = bv::utils::mkConcat(bv::utils::mkZero(12), ext7v);
3054
4
  Node ww = bv::utils::mkConcat(bv::utils::mkZero(12), ext7w);
3055
4
  Node s7 = bv::utils::mkConcat(bv::utils::mkZero(12), ext7s);
3056
4
  Node s15 = bv::utils::mkConcat(bv::utils::mkZero(12), ext15s);
3057
3058
  Node plus1 = d_nodeManager->mkNode(
3059
      kind::BITVECTOR_ADD,
3060
8
      d_nodeManager->mkNode(
3061
4
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 86), xx),
3062
8
      d_nodeManager->mkNode(
3063
14
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 41), yy));
3064
  Node plus2 = d_nodeManager->mkNode(
3065
      kind::BITVECTOR_ADD,
3066
      plus1,
3067
8
      d_nodeManager->mkNode(
3068
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 37), zz));
3069
  Node plus3 = d_nodeManager->mkNode(
3070
      kind::BITVECTOR_ADD,
3071
      plus2,
3072
8
      d_nodeManager->mkNode(
3073
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 170), uu));
3074
  Node plus4 = d_nodeManager->mkNode(
3075
      kind::BITVECTOR_ADD,
3076
      plus3,
3077
8
      d_nodeManager->mkNode(
3078
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 112), uu));
3079
  Node plus5 = d_nodeManager->mkNode(
3080
      kind::BITVECTOR_ADD,
3081
      plus4,
3082
8
      d_nodeManager->mkNode(
3083
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 195), s15));
3084
  Node plus6 = d_nodeManager->mkNode(
3085
      kind::BITVECTOR_ADD,
3086
      plus5,
3087
8
      d_nodeManager->mkNode(
3088
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 124), s7));
3089
  Node plus7 = d_nodeManager->mkNode(
3090
      kind::BITVECTOR_ADD,
3091
      plus6,
3092
8
      d_nodeManager->mkNode(
3093
10
          kind::BITVECTOR_MULT, bv::utils::mkConst(20, 83), ww));
3094
3095
2
  ASSERT_EQ(BVGauss::getMinBwExpr(plus7), 19);
3096
2
  ASSERT_EQ(BVGauss::getMinBwExpr(Rewriter::rewrite(plus7)), 17);
3097
}
3098
}  // namespace test
3099
1478408
}  // namespace cvc5