GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/bitblast/bitblast_strategies_template.h Lines: 359 450 79.8 %
Date: 2021-09-15 Branches: 678 2432 27.9 %

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