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