GCC Code Coverage Report
Directory: . Exec Total Coverage
File: test/unit/preprocessing/pass_bv_gauss_white.cpp Lines: 1281 1316 97.3 %
Date: 2021-09-07 Branches: 4785 11225 42.6 %

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