GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bitblast/bitblast_strategies_template.h Lines: 364 455 80.0 %
Date: 2021-08-01 Branches: 699 2412 29.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Liana Hadarean, Aina Niemetz, Tim King
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
 * Implementation of bitblasting functions for various operators.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__BV__BITBLAST__BITBLAST_STRATEGIES_TEMPLATE_H
19
#define CVC5__THEORY__BV__BITBLAST__BITBLAST_STRATEGIES_TEMPLATE_H
20
21
#include <cmath>
22
#include <ostream>
23
24
#include "expr/node.h"
25
#include "theory/bv/bitblast/bitblast_utils.h"
26
#include "theory/bv/theory_bv_utils.h"
27
#include "theory/rewriter.h"
28
#include "util/bitvector.h"
29
30
namespace cvc5 {
31
32
namespace theory {
33
namespace bv {
34
35
/**
36
 * Default Atom Bitblasting strategies:
37
 *
38
 * @param node the atom to be bitblasted
39
 * @param bb the bitblaster
40
 */
41
42
template <class T>
43
T UndefinedAtomBBStrategy(TNode node, TBitblaster<T>* bb) {
44
  Debug("bitvector") << "TheoryBV::Bitblaster Undefined bitblasting strategy for kind: "
45
                     << node.getKind() << "\n";
46
  Unreachable();
47
}
48
49
50
template <class T>
51
36777
T DefaultEqBB(TNode node, TBitblaster<T>* bb) {
52
36777
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
53
54
36777
  Assert(node.getKind() == kind::EQUAL);
55
73554
  std::vector<T> lhs, rhs;
56
36777
  bb->bbTerm(node[0], lhs);
57
36777
  bb->bbTerm(node[1], rhs);
58
59
36777
  Assert(lhs.size() == rhs.size());
60
61
73554
  std::vector<T> bits_eq;
62
452979
  for (unsigned i = 0; i < lhs.size(); i++) {
63
832404
    T bit_eq = mkIff(lhs[i], rhs[i]);
64
416202
    bits_eq.push_back(bit_eq);
65
  }
66
36777
  T bv_eq = mkAnd(bits_eq);
67
73554
  return bv_eq;
68
}
69
70
template <class T>
71
T AdderUltBB(TNode node, TBitblaster<T>* bb) {
72
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
73
  Assert(node.getKind() == kind::BITVECTOR_ULT);
74
  std::vector<T> a, b;
75
  bb->bbTerm(node[0], a);
76
  bb->bbTerm(node[1], b);
77
  Assert(a.size() == b.size());
78
79
  // a < b <=> ~ (add(a, ~b, 1).carry_out)
80
  std::vector<T> not_b;
81
  negateBits(b, not_b);
82
  T carry = mkTrue<T>();
83
84
  for (unsigned i = 0 ; i < a.size(); ++i) {
85
    carry = mkOr( mkAnd(a[i], not_b[i]),
86
                  mkAnd( mkXor(a[i], not_b[i]),
87
                         carry));
88
  }
89
  return mkNot(carry);
90
}
91
92
93
template <class T>
94
6397
T DefaultUltBB(TNode node, TBitblaster<T>* bb) {
95
6397
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
96
6397
  Assert(node.getKind() == kind::BITVECTOR_ULT);
97
12794
  std::vector<T> a, b;
98
6397
  bb->bbTerm(node[0], a);
99
6397
  bb->bbTerm(node[1], b);
100
6397
  Assert(a.size() == b.size());
101
102
  // construct bitwise comparison
103
6397
  T res = uLessThanBB(a, b, false);
104
12794
  return res;
105
}
106
107
template <class T>
108
T DefaultUleBB(TNode node, TBitblaster<T>* bb){
109
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
110
  Assert(node.getKind() == kind::BITVECTOR_ULE);
111
  std::vector<T> a, b;
112
113
  bb->bbTerm(node[0], a);
114
  bb->bbTerm(node[1], b);
115
  Assert(a.size() == b.size());
116
  // construct bitwise comparison
117
  T res = uLessThanBB(a, b, true);
118
  return res;
119
}
120
121
template <class T>
122
T DefaultUgtBB(TNode node, TBitblaster<T>* bb){
123
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
124
  // should be rewritten
125
  Unimplemented();
126
}
127
template <class T>
128
T DefaultUgeBB(TNode node, TBitblaster<T>* bb){
129
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
130
  // should be rewritten
131
  Unimplemented();
132
}
133
134
template <class T>
135
6599
T DefaultSltBB(TNode node, TBitblaster<T>* bb){
136
6599
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
137
138
13198
  std::vector<T> a, b;
139
6599
  bb->bbTerm(node[0], a);
140
6599
  bb->bbTerm(node[1], b);
141
6599
  Assert(a.size() == b.size());
142
143
6599
  T res = sLessThanBB(a, b, false);
144
13198
  return res;
145
}
146
147
template <class T>
148
T DefaultSleBB(TNode node, TBitblaster<T>* bb){
149
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
150
151
  std::vector<T> a, b;
152
  bb->bbTerm(node[0], a);
153
  bb->bbTerm(node[1], b);
154
  Assert(a.size() == b.size());
155
156
  T res = sLessThanBB(a, b, true);
157
  return res;
158
}
159
160
template <class T>
161
T DefaultSgtBB(TNode node, TBitblaster<T>* bb){
162
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
163
  // should be rewritten
164
  Unimplemented();
165
}
166
167
template <class T>
168
T DefaultSgeBB(TNode node, TBitblaster<T>* bb){
169
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
170
  // should be rewritten
171
  Unimplemented();
172
}
173
174
175
/// Term bitblasting strategies
176
177
/**
178
 * Default Term Bitblasting strategies
179
 *
180
 * @param node the term to be bitblasted
181
 * @param bits [output parameter] bits representing the new term
182
 * @param bb the bitblaster in which the clauses are added
183
 */
184
template <class T>
185
void UndefinedTermBBStrategy(TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
186
  Debug("bitvector") << "theory::bv:: Undefined bitblasting strategy for kind: "
187
                     << node.getKind() << "\n";
188
  Unreachable();
189
}
190
191
template <class T>
192
19904
void DefaultVarBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
193
19904
  Assert(bits.size() == 0);
194
19904
  bb->makeVariable(node, bits);
195
196
19904
  if(Debug.isOn("bitvector-bb")) {
197
    Debug("bitvector-bb") << "theory::bv::DefaultVarBB bitblasting  " << node << "\n";
198
    Debug("bitvector-bb") << "                           with bits  " << toString(bits);
199
  }
200
19904
}
201
202
template <class T>
203
14687
void DefaultConstBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
204
14687
  Debug("bitvector-bb") << "theory::bv::DefaultConstBB bitblasting " << node << "\n";
205
14687
  Assert(node.getKind() == kind::CONST_BITVECTOR);
206
14687
  Assert(bits.size() == 0);
207
208
177396
  for (unsigned i = 0; i < utils::getSize(node); ++i) {
209
325418
    Integer bit = node.getConst<BitVector>().extract(i, i).getValue();
210
162709
    if(bit == Integer(0)){
211
109884
      bits.push_back(mkFalse<T>());
212
    } else {
213
52825
      Assert(bit == Integer(1));
214
52825
      bits.push_back(mkTrue<T>());
215
    }
216
  }
217
14687
  if(Debug.isOn("bitvector-bb")) {
218
    Debug("bitvector-bb") << "with  bits: " << toString(bits) << "\n";
219
  }
220
14687
}
221
222
223
template <class T>
224
4998
void DefaultNotBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
225
4998
  Debug("bitvector-bb") << "theory::bv::DefaultNotBB bitblasting " << node << "\n";
226
4998
  Assert(node.getKind() == kind::BITVECTOR_NOT);
227
4998
  Assert(bits.size() == 0);
228
9996
  std::vector<T> bv;
229
4998
  bb->bbTerm(node[0], bv);
230
4998
  negateBits(bv, bits);
231
4998
}
232
233
template <class T>
234
9094
void DefaultConcatBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
235
9094
  Debug("bitvector-bb") << "theory::bv::DefaultConcatBB bitblasting " << node << "\n";
236
9094
  Assert(bits.size() == 0);
237
238
9094
  Assert(node.getKind() == kind::BITVECTOR_CONCAT);
239
33498
  for (int i = node.getNumChildren() -1 ; i >= 0; --i ) {
240
48808
    TNode current = node[i];
241
48808
    std::vector<T> current_bits;
242
24404
    bb->bbTerm(current, current_bits);
243
244
149865
    for(unsigned j = 0; j < utils::getSize(current); ++j) {
245
125461
      bits.push_back(current_bits[j]);
246
    }
247
  }
248
9094
  Assert(bits.size() == utils::getSize(node));
249
9094
  if(Debug.isOn("bitvector-bb")) {
250
    Debug("bitvector-bb") << "with  bits: " << toString(bits) << "\n";
251
  }
252
9094
}
253
254
template <class T>
255
4252
void DefaultAndBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
256
4252
  Debug("bitvector-bb") << "theory::bv::DefaultAndBB bitblasting " << node << "\n";
257
258
4252
  Assert(node.getKind() == kind::BITVECTOR_AND && bits.size() == 0);
259
260
4252
  bb->bbTerm(node[0], bits);
261
8504
  std::vector<T> current;
262
11554
  for(unsigned j = 1; j < node.getNumChildren(); ++j) {
263
7302
    bb->bbTerm(node[j], current);
264
23183
    for (unsigned i = 0; i < utils::getSize(node); ++i) {
265
15881
      bits[i] = mkAnd(bits[i], current[i]);
266
    }
267
7302
    current.clear();
268
  }
269
4252
  Assert(bits.size() == utils::getSize(node));
270
4252
}
271
272
template <class T>
273
5760
void DefaultOrBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
274
5760
  Debug("bitvector-bb") << "theory::bv::DefaultOrBB bitblasting " << node << "\n";
275
276
5760
  Assert(node.getKind() == kind::BITVECTOR_OR && bits.size() == 0);
277
278
5760
  bb->bbTerm(node[0], bits);
279
11520
  std::vector<T> current;
280
52782
  for(unsigned j = 1; j < node.getNumChildren(); ++j) {
281
47022
    bb->bbTerm(node[j], current);
282
97654
    for (unsigned i = 0; i < utils::getSize(node); ++i) {
283
50632
      bits[i] = mkOr(bits[i], current[i]);
284
    }
285
47022
    current.clear();
286
  }
287
5760
  Assert(bits.size() == utils::getSize(node));
288
5760
}
289
290
template <class T>
291
519
void DefaultXorBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
292
519
  Debug("bitvector-bb") << "theory::bv::DefaultXorBB bitblasting " << node << "\n";
293
294
519
  Assert(node.getKind() == kind::BITVECTOR_XOR && bits.size() == 0);
295
296
519
  bb->bbTerm(node[0], bits);
297
1038
  std::vector<T> current;
298
1045
  for(unsigned j = 1; j < node.getNumChildren(); ++j) {
299
526
    bb->bbTerm(node[j], current);
300
2865
    for (unsigned i = 0; i < utils::getSize(node); ++i) {
301
2339
      bits[i] = mkXor(bits[i], current[i]);
302
    }
303
526
    current.clear();
304
  }
305
519
  Assert(bits.size() == utils::getSize(node));
306
519
}
307
308
template <class T>
309
void DefaultXnorBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
310
  Debug("bitvector-bb") << "theory::bv::DefaultXnorBB bitblasting " << node << "\n";
311
312
  Assert(node.getNumChildren() == 2 && node.getKind() == kind::BITVECTOR_XNOR
313
         && bits.size() == 0);
314
  std::vector<T> lhs, rhs;
315
  bb->bbTerm(node[0], lhs);
316
  bb->bbTerm(node[1], rhs);
317
  Assert(lhs.size() == rhs.size());
318
319
  for (unsigned i = 0; i < lhs.size(); ++i) {
320
    bits.push_back(mkIff(lhs[i], rhs[i]));
321
  }
322
}
323
324
325
template <class T>
326
void DefaultNandBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
327
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
328
                     << node.getKind() << "\n";
329
  Unimplemented();
330
}
331
template <class T>
332
void DefaultNorBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
333
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
334
                     << node.getKind() << "\n";
335
  Unimplemented();
336
}
337
template <class T>
338
6734
void DefaultCompBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
339
6734
  Debug("bitvector") << "theory::bv:: DefaultCompBB bitblasting "<< node << "\n";
340
341
6734
  Assert(utils::getSize(node) == 1 && bits.size() == 0
342
         && node.getKind() == kind::BITVECTOR_COMP);
343
13468
  std::vector<T> a, b;
344
6734
  bb->bbTerm(node[0], a);
345
6734
  bb->bbTerm(node[1], b);
346
347
13468
  std::vector<T> bit_eqs;
348
74613
  for (unsigned i = 0; i < a.size(); ++i) {
349
135758
    T eq = mkIff(a[i], b[i]);
350
67879
    bit_eqs.push_back(eq);
351
  }
352
13468
  T a_eq_b = mkAnd(bit_eqs);
353
6734
  bits.push_back(a_eq_b);
354
6734
}
355
356
template <class T>
357
1211
void DefaultMultBB (TNode node, std::vector<T>& res, TBitblaster<T>* bb) {
358
1211
  Debug("bitvector") << "theory::bv:: DefaultMultBB bitblasting "<< node << "\n";
359
1211
  Assert(res.size() == 0 && node.getKind() == kind::BITVECTOR_MULT);
360
361
  // if (node.getNumChildren() == 2) {
362
  //   std::vector<T> a;
363
  //   std::vector<T> b;
364
  //   bb->bbTerm(node[0], a);
365
  //   bb->bbTerm(node[1], b);
366
  //   unsigned bw = utils::getSize(node);
367
  //   unsigned thresh = bw % 2 ? bw/2 : bw/2 - 1;
368
  //   bool no_overflow = true;
369
  //   for (unsigned i = thresh; i < bw; ++i) {
370
  //     if (a[i] != mkFalse<T> || b[i] != mkFalse<T> ) {
371
  //       no_overflow = false;
372
  //     }
373
  //   }
374
  //   if (no_overflow) {
375
  //     shiftAddMultiplier();
376
  //     return;
377
  //   }
378
379
  // }
380
381
2422
  std::vector<T> newres;
382
1211
  bb->bbTerm(node[0], res);
383
2462
  for(unsigned i = 1; i < node.getNumChildren(); ++i) {
384
2502
    std::vector<T> current;
385
1251
    bb->bbTerm(node[i], current);
386
1251
    newres.clear();
387
    // constructs a simple shift and add multiplier building the result
388
    // in res
389
1251
    shiftAddMultiplier(res, current, newres);
390
1251
    res = newres;
391
  }
392
1211
  if(Debug.isOn("bitvector-bb")) {
393
    Debug("bitvector-bb") << "with bits: " << toString(res)  << "\n";
394
  }
395
1211
}
396
397
template <class T>
398
2897
void DefaultAddBB(TNode node, std::vector<T>& res, TBitblaster<T>* bb)
399
{
400
2897
  Debug("bitvector-bb") << "theory::bv::DefaultAddBB bitblasting " << node
401
                        << "\n";
402
2897
  Assert(node.getKind() == kind::BITVECTOR_ADD && res.size() == 0);
403
404
2897
  bb->bbTerm(node[0], res);
405
406
5794
  std::vector<T> newres;
407
408
5956
  for(unsigned i = 1; i < node.getNumChildren(); ++i) {
409
6118
    std::vector<T> current;
410
3059
    bb->bbTerm(node[i], current);
411
3059
    newres.clear();
412
3059
    rippleCarryAdder(res, current, newres, mkFalse<T>());
413
3059
    res = newres;
414
  }
415
416
2897
  Assert(res.size() == utils::getSize(node));
417
2897
}
418
419
template <class T>
420
void DefaultSubBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
421
  Debug("bitvector-bb") << "theory::bv::DefaultSubBB bitblasting " << node << "\n";
422
  Assert(node.getKind() == kind::BITVECTOR_SUB && node.getNumChildren() == 2
423
         && bits.size() == 0);
424
425
  std::vector<T> a, b;
426
  bb->bbTerm(node[0], a);
427
  bb->bbTerm(node[1], b);
428
  Assert(a.size() == b.size() && utils::getSize(node) == a.size());
429
430
  // bvsub a b = adder(a, ~b, 1)
431
  std::vector<T> not_b;
432
  negateBits(b, not_b);
433
  rippleCarryAdder(a, not_b, bits, mkTrue<T>());
434
}
435
436
template <class T>
437
1509
void DefaultNegBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
438
1509
  Debug("bitvector-bb") << "theory::bv::DefaultNegBB bitblasting " << node << "\n";
439
1509
  Assert(node.getKind() == kind::BITVECTOR_NEG);
440
441
3018
  std::vector<T> a;
442
1509
  bb->bbTerm(node[0], a);
443
1509
  Assert(utils::getSize(node) == a.size());
444
445
  // -a = add(~a, 0, 1).
446
3018
  std::vector<T> not_a;
447
1509
  negateBits(a, not_a);
448
3018
  std::vector<T> zero;
449
1509
  makeZero(zero, utils::getSize(node));
450
451
1509
  rippleCarryAdder(not_a, zero, bits, mkTrue<T>());
452
1509
}
453
454
template <class T>
455
4883
void uDivModRec(const std::vector<T>& a, const std::vector<T>& b, std::vector<T>& q, std::vector<T>& r, unsigned rec_width) {
456
4883
  Assert(q.size() == 0 && r.size() == 0);
457
458
4883
  if(rec_width == 0 || isZero(a)) {
459
685
    makeZero(q, a.size());
460
685
    makeZero(r, a.size());
461
685
    return;
462
  }
463
464
8396
  std::vector<T> q1, r1;
465
8396
  std::vector<T> a1 = a;
466
4198
  rshift(a1, 1);
467
468
4198
  uDivModRec(a1, b, q1, r1, rec_width - 1);
469
  // shift the quotient and remainder (i.e. multiply by two) and add 1 to remainder if a is odd
470
4198
  lshift(q1, 1);
471
4198
  lshift(r1, 1);
472
473
474
8396
  T is_odd = mkIff(a[0], mkTrue<T>());
475
8396
  T one_if_odd = mkIte(is_odd, mkTrue<T>(), mkFalse<T>());
476
477
8396
  std::vector<T> zero;
478
4198
  makeZero(zero, b.size());
479
480
8396
  std::vector<T> r1_shift_add;
481
  // account for a being odd
482
4198
  rippleCarryAdder(r1, zero, r1_shift_add, one_if_odd);
483
  // now check if the remainder is greater than b
484
8396
  std::vector<T> not_b;
485
4198
  negateBits(b, not_b);
486
8396
  std::vector<T> r_minus_b;
487
8396
  T co1;
488
  // use adder because we need r_minus_b anyway
489
4198
  co1 = rippleCarryAdder(r1_shift_add, not_b, r_minus_b, mkTrue<T>());
490
  // sign is true if r1 < b
491
8396
  T sign = mkNot(co1);
492
493
4198
  q1[0] = mkIte(sign, q1[0], mkTrue<T>());
494
495
  // would be nice to have a high level ITE instead of bitwise
496
54837
  for(unsigned i = 0; i < a.size(); ++i) {
497
50639
    r1_shift_add[i] = mkIte(sign, r1_shift_add[i], r_minus_b[i]);
498
  }
499
500
  // check if a < b
501
502
8396
  std::vector<T> a_minus_b;
503
8396
  T co2 = rippleCarryAdder(a, not_b, a_minus_b, mkTrue<T>());
504
  // Node a_lt_b = a_minus_b.back();
505
8396
  T a_lt_b = mkNot(co2);
506
507
54837
  for(unsigned i = 0; i < a.size(); ++i) {
508
101278
    T qval = mkIte(a_lt_b, mkFalse<T>(), q1[i]);
509
101278
    T rval = mkIte(a_lt_b, a[i], r1_shift_add[i]);
510
50639
    q.push_back(qval);
511
50639
    r.push_back(rval);
512
  }
513
514
}
515
516
template <class T>
517
380
void DefaultUdivBB(TNode node, std::vector<T>& q, TBitblaster<T>* bb)
518
{
519
380
  Debug("bitvector-bb") << "theory::bv::DefaultUdivBB bitblasting " << node
520
                        << "\n";
521
380
  Assert(node.getKind() == kind::BITVECTOR_UDIV && q.size() == 0);
522
523
760
  std::vector<T> a, b;
524
380
  bb->bbTerm(node[0], a);
525
380
  bb->bbTerm(node[1], b);
526
527
760
  std::vector<T> r;
528
380
  uDivModRec(a, b, q, r, utils::getSize(node));
529
  // adding a special case for division by 0
530
760
  std::vector<T> iszero;
531
3043
  for (unsigned i = 0; i < b.size(); ++i)
532
  {
533
2663
    iszero.push_back(mkIff(b[i], mkFalse<T>()));
534
  }
535
760
  T b_is_0 = mkAnd(iszero);
536
537
3043
  for (unsigned i = 0; i < q.size(); ++i)
538
  {
539
2663
    q[i] = mkIte(b_is_0, mkTrue<T>(), q[i]);  // a udiv 0 is 11..11
540
2663
    r[i] = mkIte(b_is_0, a[i], r[i]);         // a urem 0 is a
541
  }
542
543
  // cache the remainder in case we need it later
544
760
  Node remainder = Rewriter::rewrite(
545
      NodeManager::currentNM()->mkNode(kind::BITVECTOR_UREM, node[0], node[1]));
546
380
  bb->storeBBTerm(remainder, r);
547
380
}
548
549
template <class T>
550
305
void DefaultUremBB(TNode node, std::vector<T>& rem, TBitblaster<T>* bb)
551
{
552
305
  Debug("bitvector-bb") << "theory::bv::DefaultUremBB bitblasting " << node
553
                        << "\n";
554
305
  Assert(node.getKind() == kind::BITVECTOR_UREM && rem.size() == 0);
555
556
610
  std::vector<T> a, b;
557
305
  bb->bbTerm(node[0], a);
558
305
  bb->bbTerm(node[1], b);
559
560
610
  std::vector<T> q;
561
305
  uDivModRec(a, b, q, rem, utils::getSize(node));
562
  // adding a special case for division by 0
563
610
  std::vector<T> iszero;
564
2463
  for (unsigned i = 0; i < b.size(); ++i)
565
  {
566
2158
    iszero.push_back(mkIff(b[i], mkFalse<T>()));
567
  }
568
610
  T b_is_0 = mkAnd(iszero);
569
570
2463
  for (unsigned i = 0; i < q.size(); ++i)
571
  {
572
2158
    q[i] = mkIte(b_is_0, mkTrue<T>(), q[i]);  // a udiv 0 is 11..11
573
2158
    rem[i] = mkIte(b_is_0, a[i], rem[i]);     // a urem 0 is a
574
  }
575
576
  // cache the quotient in case we need it later
577
610
  Node quotient = Rewriter::rewrite(
578
      NodeManager::currentNM()->mkNode(kind::BITVECTOR_UDIV, node[0], node[1]));
579
305
  bb->storeBBTerm(quotient, q);
580
305
}
581
582
template <class T>
583
void DefaultSdivBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
584
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
585
                     << node.getKind() << "\n";
586
  Unimplemented();
587
}
588
template <class T>
589
void DefaultSremBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
590
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
591
                     << node.getKind() << "\n";
592
  Unimplemented();
593
}
594
template <class T>
595
void DefaultSmodBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
596
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
597
                     << node.getKind() << "\n";
598
  Unimplemented();
599
}
600
601
template <class T>
602
704
void DefaultShlBB(TNode node, std::vector<T>& res, TBitblaster<T>* bb)
603
{
604
704
  Debug("bitvector-bb") << "theory::bv::DefaultShlBB bitblasting " << node
605
                        << "\n";
606
704
  Assert(node.getKind() == kind::BITVECTOR_SHL && res.size() == 0);
607
1408
  std::vector<T> a, b;
608
704
  bb->bbTerm(node[0], a);
609
704
  bb->bbTerm(node[1], b);
610
611
  // check for b < log2(n)
612
704
  unsigned size = utils::getSize(node);
613
704
  unsigned log2_size = std::ceil(log2((double)size));
614
1408
  Node a_size = utils::mkConst(size, size);
615
616
1408
  std::vector<T> a_size_bits;
617
704
  DefaultConstBB(a_size, a_size_bits, bb);
618
1408
  T b_ult_a_size = uLessThanBB(b, a_size_bits, false);
619
620
1408
  std::vector<T> prev_res;
621
704
  res = a;
622
  // we only need to look at the bits bellow log2_a_size
623
2360
  for (unsigned s = 0; s < log2_size; ++s)
624
  {
625
    // barrel shift stage: at each stage you can either shift by 2^s bits
626
    // or leave the previous stage untouched
627
1656
    prev_res = res;
628
1656
    unsigned threshold = pow(2, s);
629
17924
    for (unsigned i = 0; i < a.size(); ++i)
630
    {
631
16268
      if (i < threshold)
632
      {
633
        // if b[s] is true then we must have shifted by at least 2^b bits so
634
        // all bits bellow 2^s will be 0, otherwise just use previous shift
635
        // value
636
4711
        res[i] = mkIte(b[s], mkFalse<T>(), prev_res[i]);
637
      }
638
      else
639
      {
640
        // if b[s]= 0, use previous value, otherwise shift by threshold  bits
641
11557
        Assert(i >= threshold);
642
11557
        res[i] = mkIte(b[s], prev_res[i - threshold], prev_res[i]);
643
      }
644
    }
645
  }
646
704
  prev_res = res;
647
5402
  for (unsigned i = 0; i < b.size(); ++i)
648
  {
649
    // this is fine  because b_ult_a_size has been bit-blasted
650
4698
    res[i] = mkIte(b_ult_a_size, prev_res[i], mkFalse<T>());
651
  }
652
653
704
  if (Debug.isOn("bitvector-bb"))
654
  {
655
    Debug("bitvector-bb") << "with bits: " << toString(res) << "\n";
656
  }
657
704
}
658
659
template <class T>
660
798
void DefaultLshrBB(TNode node, std::vector<T>& res, TBitblaster<T>* bb)
661
{
662
798
  Debug("bitvector-bb") << "theory::bv::DefaultLshrBB bitblasting " << node
663
                        << "\n";
664
798
  Assert(node.getKind() == kind::BITVECTOR_LSHR && res.size() == 0);
665
1596
  std::vector<T> a, b;
666
798
  bb->bbTerm(node[0], a);
667
798
  bb->bbTerm(node[1], b);
668
669
  // check for b < log2(n)
670
798
  unsigned size = utils::getSize(node);
671
798
  unsigned log2_size = std::ceil(log2((double)size));
672
1596
  Node a_size = utils::mkConst(size, size);
673
674
1596
  std::vector<T> a_size_bits;
675
798
  DefaultConstBB(a_size, a_size_bits, bb);
676
1596
  T b_ult_a_size = uLessThanBB(b, a_size_bits, false);
677
678
798
  res = a;
679
1596
  std::vector<T> prev_res;
680
681
2735
  for (unsigned s = 0; s < log2_size; ++s)
682
  {
683
    // barrel shift stage: at each stage you can either shift by 2^s bits
684
    // or leave the previous stage untouched
685
1937
    prev_res = res;
686
1937
    int threshold = pow(2, s);
687
22483
    for (unsigned i = 0; i < a.size(); ++i)
688
    {
689
20546
      if (i + threshold >= a.size())
690
      {
691
        // if b[s] is true then we must have shifted by at least 2^b bits so
692
        // all bits above 2^s will be 0, otherwise just use previous shift value
693
5347
        res[i] = mkIte(b[s], mkFalse<T>(), prev_res[i]);
694
      }
695
      else
696
      {
697
        // if b[s]= 0, use previous value, otherwise shift by threshold  bits
698
15199
        Assert(i + threshold < a.size());
699
15199
        res[i] = mkIte(mkNot(b[s]), prev_res[i], prev_res[i + threshold]);
700
      }
701
    }
702
  }
703
704
798
  prev_res = res;
705
6725
  for (unsigned i = 0; i < b.size(); ++i)
706
  {
707
    // this is fine  because b_ult_a_size has been bit-blasted
708
5927
    res[i] = mkIte(b_ult_a_size, prev_res[i], mkFalse<T>());
709
  }
710
711
798
  if (Debug.isOn("bitvector-bb"))
712
  {
713
    Debug("bitvector-bb") << "with bits: " << toString(res) << "\n";
714
  }
715
798
}
716
717
template <class T>
718
621
void DefaultAshrBB(TNode node, std::vector<T>& res, TBitblaster<T>* bb)
719
{
720
621
  Debug("bitvector-bb") << "theory::bv::DefaultAshrBB bitblasting " << node
721
                        << "\n";
722
621
  Assert(node.getKind() == kind::BITVECTOR_ASHR && res.size() == 0);
723
1242
  std::vector<T> a, b;
724
621
  bb->bbTerm(node[0], a);
725
621
  bb->bbTerm(node[1], b);
726
727
  //   check for b < n
728
621
  unsigned size = utils::getSize(node);
729
621
  unsigned log2_size = std::ceil(log2((double)size));
730
1242
  Node a_size = utils::mkConst(size, size);
731
732
1242
  std::vector<T> a_size_bits;
733
621
  DefaultConstBB(a_size, a_size_bits, bb);
734
1242
  T b_ult_a_size = uLessThanBB(b, a_size_bits, false);
735
736
621
  res = a;
737
1242
  T sign_bit = a.back();
738
1242
  std::vector<T> prev_res;
739
740
1891
  for (unsigned s = 0; s < log2_size; ++s)
741
  {
742
    // barrel shift stage: at each stage you can either shift by 2^s bits
743
    // or leave the previous stage untouched
744
1270
    prev_res = res;
745
1270
    int threshold = pow(2, s);
746
10509
    for (unsigned i = 0; i < a.size(); ++i)
747
    {
748
9239
      if (i + threshold >= a.size())
749
      {
750
        // if b[s] is true then we must have shifted by at least 2^b bits so
751
        // all bits above 2^s will be the sign bit, otherwise just use previous
752
        // shift value
753
2863
        res[i] = mkIte(b[s], sign_bit, prev_res[i]);
754
      }
755
      else
756
      {
757
        // if b[s]= 0, use previous value, otherwise shift by threshold  bits
758
6376
        Assert(i + threshold < a.size());
759
6376
        res[i] = mkIte(mkNot(b[s]), prev_res[i], prev_res[i + threshold]);
760
      }
761
    }
762
  }
763
764
621
  prev_res = res;
765
3831
  for (unsigned i = 0; i < b.size(); ++i)
766
  {
767
    // this is fine  because b_ult_a_size has been bit-blasted
768
3210
    res[i] = mkIte(b_ult_a_size, prev_res[i], sign_bit);
769
  }
770
771
621
  if (Debug.isOn("bitvector-bb"))
772
  {
773
    Debug("bitvector-bb") << "with bits: " << toString(res) << "\n";
774
  }
775
621
}
776
777
template <class T>
778
578
void DefaultUltbvBB (TNode node, std::vector<T>& res, TBitblaster<T>* bb) {
779
578
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
780
578
  Assert(node.getKind() == kind::BITVECTOR_ULTBV);
781
1156
  std::vector<T> a, b;
782
578
  bb->bbTerm(node[0], a);
783
578
  bb->bbTerm(node[1], b);
784
578
  Assert(a.size() == b.size());
785
786
  // construct bitwise comparison
787
578
  res.push_back(uLessThanBB(a, b, false));
788
578
}
789
790
template <class T>
791
1163
void DefaultSltbvBB (TNode node, std::vector<T>& res, TBitblaster<T>* bb) {
792
1163
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
793
1163
  Assert(node.getKind() == kind::BITVECTOR_SLTBV);
794
2326
  std::vector<T> a, b;
795
1163
  bb->bbTerm(node[0], a);
796
1163
  bb->bbTerm(node[1], b);
797
1163
  Assert(a.size() == b.size());
798
799
  // construct bitwise comparison
800
1163
  res.push_back(sLessThanBB(a, b, false));
801
1163
}
802
803
template <class T>
804
3506
void DefaultIteBB (TNode node, std::vector<T>& res, TBitblaster<T>* bb) {
805
3506
  Debug("bitvector-bb") << "Bitblasting node " << node  << "\n";
806
3506
  Assert(node.getKind() == kind::BITVECTOR_ITE);
807
7012
  std::vector<T> cond, thenpart, elsepart;
808
3506
  bb->bbTerm(node[0], cond);
809
3506
  bb->bbTerm(node[1], thenpart);
810
3506
  bb->bbTerm(node[2], elsepart);
811
812
3506
  Assert(cond.size() == 1);
813
3506
  Assert(thenpart.size() == elsepart.size());
814
815
58531
  for (unsigned i = 0; i < thenpart.size(); ++i) {
816
    // (~cond OR thenpart) AND (cond OR elsepart)
817
55025
    res.push_back(mkAnd(mkOr(mkNot(cond[0]),thenpart[i]),mkOr(cond[0],elsepart[i])));
818
  }
819
3506
}
820
821
template <class T>
822
9040
void DefaultExtractBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
823
9040
  Assert(node.getKind() == kind::BITVECTOR_EXTRACT);
824
9040
  Assert(bits.size() == 0);
825
826
18080
  std::vector<T> base_bits;
827
9040
  bb->bbTerm(node[0], base_bits);
828
9040
  unsigned high = utils::getExtractHigh(node);
829
9040
  unsigned low  = utils::getExtractLow(node);
830
831
70874
  for (unsigned i = low; i <= high; ++i) {
832
61834
    bits.push_back(base_bits[i]);
833
  }
834
9040
  Assert(bits.size() == high - low + 1);
835
836
9040
  if(Debug.isOn("bitvector-bb")) {
837
    Debug("bitvector-bb") << "theory::bv::DefaultExtractBB bitblasting " << node << "\n";
838
    Debug("bitvector-bb") << "                               with bits " << toString(bits);
839
  }
840
9040
}
841
842
843
template <class T>
844
void DefaultRepeatBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
845
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
846
                     << node.getKind() << "\n";
847
  // this should be rewritten
848
  Unimplemented();
849
}
850
851
template <class T>
852
void DefaultZeroExtendBB (TNode node, std::vector<T>& res_bits, TBitblaster<T>* bb) {
853
854
  Debug("bitvector-bb") << "theory::bv::DefaultZeroExtendBB bitblasting " << node  << "\n";
855
856
  // this should be rewritten
857
  Unimplemented();
858
859
}
860
861
template <class T>
862
4118
void DefaultSignExtendBB (TNode node, std::vector<T>& res_bits, TBitblaster<T>* bb) {
863
4118
  Debug("bitvector-bb") << "theory::bv::DefaultSignExtendBB bitblasting " << node  << "\n";
864
865
4118
  Assert(node.getKind() == kind::BITVECTOR_SIGN_EXTEND && res_bits.size() == 0);
866
867
8236
  std::vector<T> bits;
868
4118
  bb->bbTerm(node[0], bits);
869
870
8236
  T sign_bit = bits.back();
871
4118
  unsigned amount =
872
8236
      node.getOperator().getConst<BitVectorSignExtend>().d_signExtendAmount;
873
874
15630
  for (unsigned i = 0; i < bits.size(); ++i ) {
875
11512
    res_bits.push_back(bits[i]);
876
  }
877
878
23386
  for (unsigned i = 0 ; i < amount ; ++i ) {
879
19268
    res_bits.push_back(sign_bit);
880
  }
881
882
4118
  Assert(res_bits.size() == amount + bits.size());
883
4118
}
884
885
template <class T>
886
void DefaultRotateRightBB (TNode node, std::vector<T>& res, TBitblaster<T>* bb) {
887
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
888
                     << node.getKind() << "\n";
889
890
  Unimplemented();
891
}
892
893
template <class T>
894
void DefaultRotateLeftBB (TNode node, std::vector<T>& bits, TBitblaster<T>* bb) {
895
  Debug("bitvector") << "theory::bv:: Unimplemented kind "
896
                     << node.getKind() << "\n";
897
  Unimplemented();
898
}
899
900
901
}
902
}
903
}  // namespace cvc5
904
905
#endif