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