SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
BVDirectEncoder.h
Go to the documentation of this file.
1 /*
2  * SMT-RAT - Satisfiability-Modulo-Theories Real Algebra Toolbox
3  * Copyright (C) 2012 Florian Corzilius, Ulrich Loup, Erika Abraham, Sebastian Junges
4  *
5  * This file is part of SMT-RAT.
6  *
7  * SMT-RAT is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * SMT-RAT is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with SMT-RAT. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 /**
22  * @file BVDirectEncoder.h
23  * @author Andreas Krueger <andreas.krueger@rwth-aachen.de>
24  *
25  * @version 2015-02-05
26  * Created on 2015-02-05.
27  */
28 
29 #pragma once
30 
31 #define SMTRAT_BV_INCREMENTAL_MODE
32 // define SMTRAT_BV_ENCODER_DEBUG
33 
35 #include <carl-formula/bitvector/BVConstraint.h>
36 #include <carl-formula/bitvector/BVConstraintPool.h>
37 
38 namespace smtrat
39 {
41  {
42  typedef carl::Variable Variable;
43  typedef std::vector<Variable> Variables;
44  typedef FormulaT Bit;
45  typedef std::vector<Bit> Bits;
49  typedef FormulaT Formula;
50 
51  private:
52  // Set of all propositional variables that have been introduced by the encoder
53  std::set<Variable> mIntroducedVariables;
54 
55  // Substituted fresh variables
56  // - for bitvector variables (one variable for each bitvector bit)
57  carl::FastMap<BitVec, Variables> mBitVecBits;
58  // - for bitvector terms (likewise, one variable for each bitvector bit)
59  carl::FastMap<BitVecTerm, Bits> mTermBits;
60  // - for bitvector constraints (a single variable)
61  carl::FastMap<BitVecConstr, Bit> mConstraintBits;
62 
63  // Created formulas ("encodings")
64 
65  #ifdef SMTRAT_BV_INCREMENTAL_MODE
66  // - for terms
67  carl::FastMap<BitVecTerm, FormulaSetT> mTermEncodings;
68  // - for constraints (not including the encodings for the contained terms)
69  carl::FastMap<BitVecConstr, FormulaSetT> mConstraintEncodings;
70  #endif
71  // - for terms and constraints originating from the current input formula
73 
74  // Encoding state (remember currently encoded constraint/term)
75  std::optional<BitVecConstr> mCurrentConstraint;
76  std::optional<BitVecTerm> mCurrentTerm;
77 
78  /*
79  Bit mConst0;
80  Bit mConst1;
81  */
82 
83  const Bit const0()
84  {
85  return createBit(FormulaT(carl::FormulaType::FALSE));
86  /* boolAssert(boolNot(mConst0));
87  return mConst0; */
88  }
89 
90  const Bit const1()
91  {
92  return createBit(FormulaT(carl::FormulaType::TRUE));
93  /* boolAssert(mConst1);
94  return mConst1; */
95  }
96 
97  void boolAssert(const Formula& _formula)
98  {
99  #ifdef SMTRAT_BV_INCREMENTAL_MODE
100  if(mCurrentTerm) {
101  mTermEncodings.insert(std::make_pair(*mCurrentTerm, FormulaSetT()));
102  mTermEncodings[*mCurrentTerm].insert(_formula);
103  } else if(mCurrentConstraint) {
104  mConstraintEncodings.insert(std::make_pair(*mCurrentConstraint, FormulaSetT()));
105  mConstraintEncodings[*mCurrentConstraint].insert(_formula);
106  }
107  #endif
108 
109  #ifdef SMTRAT_BV_ENCODER_DEBUG
110  std::cerr << " -> " << _formula << std::endl;
111  #endif
112  mCurrentEncodings.insert(_formula);
113  }
114 
115  Bits encodeConstant(const carl::BVValue& _value)
116  {
117  Bits out;
118  for(size_t i=0;i<_value.width();++i)
119  {
120  out.push_back(_value[i] ? const1() : const0());
121  }
122  return out;
123  }
124 
125  Bits encodeVariable(const BitVec& _variable)
126  {
127  Variables boolVariables;
128  carl::FastMap<BitVec, Variables>::iterator it = mBitVecBits.find(_variable);
129 
130  if(it == mBitVecBits.end())
131  {
132  boolVariables = createVariables(_variable.width());
133  mBitVecBits[_variable] = boolVariables;
134  }
135  else
136  {
137  boolVariables = it->second;
138  }
139 
140  return createBits(boolVariables);
141  }
142 
143  Bits encodeIte(const Bit& _condition, const Bits& _then, const Bits& _else)
144  {
145  Bits out;
146  for(std::size_t i=0;i<_then.size();++i)
147  {
148  out.push_back(createBit(boolIte(_condition, _then[i], _else[i])));
149  }
150  return out;
151  }
152 
153  Bits encodeConcat(const Bits& _first, const Bits& _second)
154  {
155  Bits concatenated(_second);
156  concatenated.insert(concatenated.end(), _first.begin(), _first.end());
157  return createBits(concatenated);
158  }
159 
160  Bits encodeExtract(const Bits& _operand, std::size_t _highest, std::size_t _lowest)
161  {
162  return createBits(Bits(&_operand[_lowest], &_operand[_highest+1]));
163  }
164 
165  Bits encodeNot(const Bits& _operand)
166  {
167  Bits out;
168  for(const Bit& bit : _operand) {
169  out.push_back(createBit(boolNot(bit)));
170  }
171  return out;
172  }
173 
174  Bits encodeNeg(const Bits& _operand)
175  {
176  // Arithmetic negation = Bitwise negation + increment
177  Bits negated = encodeNot(_operand);
178 
179  Bits carry;
180  carry.push_back(const1());
181 
182  for(size_t i=1;i<_operand.size();++i)
183  {
184  carry.push_back(createBit(boolAnd(carry[i-1], negated[i-1])));
185  }
186 
187  Bits out;
188 
189  for(size_t i=0;i<_operand.size();++i)
190  {
191  out.push_back(createBit(boolXor(carry[i], negated[i])));
192  }
193 
194  return out;
195  }
196 
197  Bits encodeAnd(const Bits& _first, const Bits& _second)
198  {
199  Bits out;
200  for(std::size_t i = 0; i < _first.size(); ++i) {
201  out.push_back(createBit(boolAnd(_first[i], _second[i])));
202  }
203  return out;
204  }
205 
206  Bits encodeOr(const Bits& _first, const Bits& _second)
207  {
208  Bits out;
209  for(std::size_t i = 0; i < _first.size(); ++i) {
210  out.push_back(createBit(boolOr(_first[i], _second[i])));
211  }
212  return out;
213  }
214 
215  Bits encodeXor(const Bits& _first, const Bits& _second)
216  {
217  Bits out;
218  for(std::size_t i = 0; i < _first.size(); ++i) {
219  out.push_back(createBit(boolXor(_first[i], _second[i])));
220  }
221  return out;
222  }
223 
224  Bits encodeNand(const Bits& _first, const Bits& _second)
225  {
226  Bits out;
227  for(std::size_t i = 0; i < _first.size(); ++i) {
228  out.push_back(createBit(boolNot(boolAnd(_first[i], _second[i]))));
229  }
230  return out;
231  }
232 
233  Bits encodeNor(const Bits& _first, const Bits& _second)
234  {
235  Bits out;
236  for(std::size_t i = 0; i < _first.size(); ++i) {
237  out.push_back(createBit(boolNot(boolOr(_first[i], _second[i]))));
238  }
239  return out;
240  }
241 
242  Bits encodeXnor(const Bits& _first, const Bits& _second)
243  {
244  Bits out;
245  for(std::size_t i = 0; i < _first.size(); ++i) {
246  out.push_back(createBit(boolIff(_first[i], _second[i])));
247  }
248  return out;
249  }
250 
251  Bits encodeAdd(const Bits& _first, const Bits& _second)
252  {
253  return encodeAdderNetwork(_first, _second, false, false);
254  }
255 
256  Bits encodeSub(const Bits& _first, const Bits& _second)
257  {
258  return encodeAdderNetwork(_first, encodeNot(_second), true);
259  }
260 
261  Bits encodeAdderNetwork(const Bits& _first, const Bits& _second, bool _carryInValue = false, bool _withCarryOut = false, bool _allowOverflow = true)
262  {
263  Bits out;
264  Bits carry;
265 
266  carry.push_back(_carryInValue ? const1() : const0());
267  std::size_t carryBitCount = _first.size() + ((_withCarryOut || ! _allowOverflow) ? 1 : 0);
268 
269  for(std::size_t i=1;i<carryBitCount;++i) {
270  carry.push_back(createBit(
271  boolOr(
272  boolAnd(_first[i-1], _second[i-1]),
273  boolAnd(
274  boolXor(_first[i-1], _second[i-1]),
275  carry[i-1]
276  )
277  )
278  ));
279  }
280 
281  for(std::size_t i=0;i<_first.size();++i) {
282  out.push_back(createBit(
283  boolXor(_first[i], boolXor(_second[i], carry[i]))
284  ));
285  }
286 
287  if(! _allowOverflow) {
288  boolAssert(boolNot(carry[carry.size()-1]));
289  }
290  if(_withCarryOut) {
291  out.push_back(carry[carry.size()-1]);
292  }
293 
294  return out;
295  }
296 
297  Bits encodeMul(const Bits& _first, const Bits& _second)
298  {
299  return encodeMultiplicationNetwork(_first, _second);
300  }
301 
302  Bits encodeMultiplicationNetwork(const Bits& _first, const Bits& _second, bool _allowOverflow = true)
303  {
304  std::vector<Bits> summands(_first.size());
305  std::vector<Bits> sums(_first.size()-1);
306 
307  for(std::size_t i=0;i<summands.size();++i) {
308  for(std::size_t j=0;j<_first.size();++j) {
309  if(j < i) {
310  summands[i].push_back(const0());
311  } else {
312  summands[i].push_back(createBit(boolAnd(_second[i], _first[j-i])));
313  }
314  }
315 
316  if(! _allowOverflow) {
317  for(std::size_t j=_first.size();j<_first.size()+i;++j) {
318  boolAssert(boolNot(boolAnd(_second[i], _first[j-i])));
319  }
320  }
321  }
322 
323  for(std::size_t i=0;i<sums.size();++i) {
324  sums[i] = encodeAdderNetwork((i == 0 ? summands[0] : sums[i-1]), summands[i+1], false, false, _allowOverflow);
325  }
326 
327  if(sums.size() > 0) {
328  return sums[sums.size()-1];
329  } else {
330  return summands[0];
331  }
332  }
333 
334  Bits encodeDivU(const Bits& _first, const Bits& _second)
335  {
336  return encodeDivisionNetwork(_first, _second, false);
337  }
338 
339  Bits encodeDivisionNetwork(const Bits& _first, const Bits& _second, bool _returnRemainder = false)
340  {
341  Bits quotient = createBits(_first.size());
342  Bits remainder = createBits(_first.size());
343 
344  Bit wellDefined = boolOr(_second);
345 
346  Bit summationCorrect = encodeEq(
347  _first,
349  encodeMultiplicationNetwork(quotient, _second, false),
350  remainder,
351  false,
352  false,
353  false
354  )
355  );
356 
357  Bit remainderLessThanDivisor = encodeUlt(remainder, _second);
358 
359  boolAssert(boolImplies(wellDefined, boolAnd(summationCorrect, remainderLessThanDivisor)));
360  if (!_returnRemainder) {
361  // bvudiv: x / 0 = 111...
362  /// TODO: Create a direct encoding of this instead of an equation to a constant.
363  Bit quotientAllOnes = encodeEq(quotient, encodeConstant(~carl::BVValue(_first.size(), 0)));
364  boolAssert(boolImplies(!wellDefined, quotientAllOnes));
365  } else {
366  // mvurem: x / 0 = x
367  Bit remainderIsFirstOp = encodeEq(remainder, _first);
368  boolAssert(boolImplies(!wellDefined, remainderIsFirstOp));
369  }
370 
371  return (_returnRemainder ? remainder : quotient);
372  }
373 
374  Bits encodeDivS(const Bits& _first, const Bits& _second)
375  {
376  /*
377  (bvsdiv s t) abbreviates
378  (let ((?msb_s ((_ extract |m-1| |m-1|) s))
379  (?msb_t ((_ extract |m-1| |m-1|) t)))
380  (ite (and (= ?msb_s #b0) (= ?msb_t #b0))
381  (bvudiv s t)
382  (ite (and (= ?msb_s #b1) (= ?msb_t #b0))
383  (bvneg (bvudiv (bvneg s) t))
384  (ite (and (= ?msb_s #b0) (= ?msb_t #b1))
385  (bvneg (bvudiv s (bvneg t)))
386  (bvudiv (bvneg s) (bvneg t))))))
387  */
388  Bit msbFirst = _first[_first.size()-1];
389  Bit msbSecond = _second[_second.size()-1];
390 
391  return encodeIte(msbFirst,
392  encodeIte(msbSecond,
393  encodeDivU(encodeNeg(_first), encodeNeg(_second)),
394  encodeNeg(encodeDivU(encodeNeg(_first), _second))),
395  encodeIte(msbSecond,
396  encodeNeg(encodeDivU(_first, encodeNeg(_second))),
397  encodeDivU(_first, _second)));
398  }
399 
400  Bits encodeModU(const Bits& _first, const Bits& _second)
401  {
402  return encodeDivisionNetwork(_first, _second, true);
403  }
404 
405  Bits encodeModS1(const Bits& _first, const Bits& _second)
406  {
407  /*
408  (bvsrem s t) abbreviates
409  (let ((?msb_s ((_ extract |m-1| |m-1|) s))
410  (?msb_t ((_ extract |m-1| |m-1|) t)))
411  (ite (and (= ?msb_s #b0) (= ?msb_t #b0))
412  (bvurem s t)
413  (ite (and (= ?msb_s #b1) (= ?msb_t #b0))
414  (bvneg (bvurem (bvneg s) t))
415  (ite (and (= ?msb_s #b0) (= ?msb_t #b1))
416  (bvurem s (bvneg t)))
417  (bvneg (bvurem (bvneg s) (bvneg t))))))
418  */
419  Bit msbFirst = _first[_first.size()-1];
420  Bit msbSecond = _second[_second.size()-1];
421 
422  return encodeIte(msbFirst,
423  encodeIte(msbSecond,
424  encodeNeg(encodeModU(encodeNeg(_first), encodeNeg(_second))),
425  encodeNeg(encodeModU(encodeNeg(_first), _second))),
426  encodeIte(msbSecond,
427  encodeModU(_first, encodeNeg(_second)),
428  encodeModU(_first, _second)));
429  }
430 
431  Bits encodeModS2(const Bits& _first, const Bits& _second)
432  {
433  /*
434  (bvsmod s t) abbreviates
435  (let ((?msb_s ((_ extract |m-1| |m-1|) s))
436  (?msb_t ((_ extract |m-1| |m-1|) t)))
437  (let ((abs_s (ite (= ?msb_s #b0) s (bvneg s)))
438  (abs_t (ite (= ?msb_t #b0) t (bvneg t))))
439  (let ((u (bvurem abs_s abs_t)))
440  (ite (= u (_ bv0 m))
441  u
442  (ite (and (= ?msb_s #b0) (= ?msb_t #b0))
443  u
444  (ite (and (= ?msb_s #b1) (= ?msb_t #b0))
445  (bvadd (bvneg u) t)
446  (ite (and (= ?msb_s #b0) (= ?msb_t #b1))
447  (bvadd u t)
448  (bvneg u))))))))
449  */
450  Bit msbFirst = _first[_first.size()-1];
451  Bit msbSecond = _second[_second.size()-1];
452 
453  Bits absFirst = encodeIte(msbFirst, encodeNeg(_first), _first);
454  Bits absSecond = encodeIte(msbSecond, encodeNeg(_second), _second);
455 
456  Bits u = encodeModU(absFirst, absSecond);
457 
458  return encodeIte(boolNot(boolOr(u)),
459  u,
460  encodeIte(msbFirst,
461  encodeIte(msbSecond,
462  encodeNeg(u),
463  encodeAdd(encodeNeg(u), _second)),
464  encodeIte(msbSecond,
465  encodeAdd(u, _second),
466  u)));
467  }
468 
469  Bits encodeComp(const Bits& _first, const Bits& _second)
470  {
471  Bits out;
472  out.push_back(encodeEq(_first, _second));
473  return out;
474  }
475 
476  Bits encodeLshift(const Bits& _first, const Bits& _second)
477  {
478  return encodeShiftNetwork(_first, _second, true);
479  }
480 
481  Bits encodeShiftNetwork(const Bits& _first, const Bits& _second, bool _left, bool _arithmetic = false)
482  {
483  std::size_t firstSize = _first.size() - 1;
484  std::size_t highestRelevantPos = 0;
485 
486  while((firstSize >>= 1) != 0)
487  ++highestRelevantPos;
488 
489  Bits lastStage(_first);
490  std::size_t currentShiftBy = 1;
491 
492  for(std::size_t stage=0;stage<=highestRelevantPos && stage<_second.size();++stage)
493  {
494  Bits currentStage;
495 
496  for(std::size_t pos=0;pos<lastStage.size();++pos)
497  {
498  Bit notShifted = lastStage[pos];
499  Bit shifted;
500 
501  if((_left && pos >= currentShiftBy) || (! _left && pos + currentShiftBy < lastStage.size()))
502  {
503  shifted = lastStage[_left ? (pos - currentShiftBy) : (pos + currentShiftBy)];
504  }
505  else
506  {
507  shifted = _arithmetic ? _first[_first.size() - 1] : const0();
508  }
509 
510  currentStage.push_back(createBit(boolIte(_second[stage], shifted, notShifted)));
511  }
512 
513  currentShiftBy *= 2;
514  lastStage = currentStage;
515  }
516 
517  if(highestRelevantPos >= _second.size() - 1)
518  {
519  return lastStage;
520  }
521  else
522  {
523  Bits overshiftBits(&_second[highestRelevantPos+1], &_second[_second.size()]);
524  Bit overshift = boolOr(overshiftBits);
525 
526  Bits out;
527 
528  for(std::size_t i=0;i<_first.size();++i)
529  {
530  out.push_back(createBit(
531  boolIte(overshift, (_arithmetic ? _first[_first.size()-1] : const0()), lastStage[i])
532  ));
533  }
534 
535  return out;
536  }
537  }
538 
539  Bits encodeRshiftLogic(const Bits& _first, const Bits& _second)
540  {
541  return encodeShiftNetwork(_first, _second, false);
542  }
543 
544  Bits encodeRshiftArith(const Bits& _first, const Bits& _second)
545  {
546  return encodeShiftNetwork(_first, _second, false, true);
547  }
548 
549  Bits encodeLrotate(const Bits& _operand, std::size_t _index)
550  {
551  Bits rotated(_operand);
552  std::rotate(rotated.begin(),
553  rotated.begin() + (Bits::difference_type)(
554  (_operand.size() -
555  (_index % _operand.size()))
556  % _operand.size()),
557  rotated.end());
558  return createBits(rotated);
559  }
560 
561  Bits encodeRrotate(const Bits& _operand, std::size_t _index)
562  {
563  Bits rotated(_operand);
564  std::rotate(rotated.begin(),
565  rotated.begin() + (Bits::difference_type)(
566  _index % _operand.size()),
567  rotated.end());
568  return createBits(rotated);
569  }
570 
571  Bits encodeExtU(const Bits& _operand, std::size_t _index)
572  {
573  Bits out = createBits(_operand);
574  for(std::size_t i=0;i<_index;++i) {
575  out.push_back(const0());
576  }
577  return out;
578  }
579 
580  Bits encodeExtS(const Bits& _operand, std::size_t _index)
581  {
582  Bits out = createBits(_operand);
583  for(std::size_t i=0;i<_index;++i) {
584  out.push_back(createBit(_operand[_operand.size()-1]));
585  }
586  return out;
587  }
588 
589  Bits encodeRepeat(const Bits& _operand, std::size_t _index)
590  {
591  Bits repeated;
592  for(std::size_t i=0;i<_index;++i)
593  {
594  repeated.insert(repeated.end(), _operand.begin(), _operand.end());
595  }
596  return createBits(repeated);
597  }
598 
599  Bits encodeTerm(const BitVecTerm& _term)
600  {
601  #ifndef SMTRAT_BV_INCREMENTAL_MODE
602  auto it = mTermBits.find(_term);
603  if(it != mTermBits.end()) {
604  return it->second;
605  }
606  #endif
607 
608  Bits subTerm1;
609  Bits subTerm2;
610  carl::BVTermType type = _term.type();
611 
612  if(carl::typeIsUnary(type) || type == carl::BVTermType::EXTRACT) {
613  subTerm1 = encodeTerm(_term.operand());
614  }
615  else if(carl::typeIsBinary(type)) {
616  subTerm1 = encodeTerm(_term.first());
617  subTerm2 = encodeTerm(_term.second());
618  }
619 
620  #ifdef SMTRAT_BV_INCREMENTAL_MODE
621  auto it = mTermEncodings.find(_term);
622  if(it != mTermEncodings.end())
623  {
624  mCurrentEncodings.insert(it->second.begin(), it->second.end());
625  return mTermBits[_term];
626  }
627  #endif
628 
629  // The term has not been encoded yet. Encode it now
630  mCurrentTerm = _term;
631  #ifdef SMTRAT_BV_ENCODER_DEBUG
632  std::cerr << "[BV] Encoding term: " << _term << std::endl;
633  #endif
634  Bits out;
635 
636  switch(type) {
637  case carl::BVTermType::CONSTANT:
638  out = encodeConstant(_term.value()); break;
639  case carl::BVTermType::VARIABLE:
640  out = encodeVariable(_term.variable()); break;
641  case carl::BVTermType::CONCAT:
642  out = encodeConcat(subTerm1, subTerm2); break;
643  case carl::BVTermType::EXTRACT:
644  out = encodeExtract(subTerm1, _term.highest(), _term.lowest()); break;
646  out = encodeNot(subTerm1); break;
647  case carl::BVTermType::NEG:
648  out = encodeNeg(subTerm1); break;
650  out = encodeAnd(subTerm1, subTerm2); break;
652  out = encodeOr(subTerm1, subTerm2); break;
654  out = encodeXor(subTerm1, subTerm2); break;
655  case carl::BVTermType::NAND:
656  out = encodeNand(subTerm1, subTerm2); break;
657  case carl::BVTermType::NOR:
658  out = encodeNor(subTerm1, subTerm2); break;
659  case carl::BVTermType::XNOR:
660  out = encodeXnor(subTerm1, subTerm2); break;
661  case carl::BVTermType::ADD:
662  out = encodeAdd(subTerm1, subTerm2); break;
663  case carl::BVTermType::SUB:
664  out = encodeSub(subTerm1, subTerm2); break;
665  case carl::BVTermType::MUL:
666  out = encodeMul(subTerm1, subTerm2); break;
667  case carl::BVTermType::DIV_U:
668  out = encodeDivU(subTerm1, subTerm2); break;
669  case carl::BVTermType::DIV_S:
670  out = encodeDivS(subTerm1, subTerm2); break;
671  case carl::BVTermType::MOD_U:
672  out = encodeModU(subTerm1, subTerm2); break;
673  case carl::BVTermType::MOD_S1:
674  out = encodeModS1(subTerm1, subTerm2); break;
675  case carl::BVTermType::MOD_S2:
676  out = encodeModS2(subTerm1, subTerm2); break;
678  out = encodeComp(subTerm1, subTerm2); break;
679  case carl::BVTermType::LSHIFT:
680  out = encodeLshift(subTerm1, subTerm2); break;
681  case carl::BVTermType::RSHIFT_LOGIC:
682  out = encodeRshiftLogic(subTerm1, subTerm2); break;
683  case carl::BVTermType::RSHIFT_ARITH:
684  out = encodeRshiftArith(subTerm1, subTerm2); break;
685  case carl::BVTermType::LROTATE:
686  out = encodeLrotate(subTerm1, _term.index()); break;
687  case carl::BVTermType::RROTATE:
688  out = encodeRrotate(subTerm1, _term.index()); break;
689  case carl::BVTermType::EXT_U:
690  out = encodeExtU(subTerm1, _term.index()); break;
691  case carl::BVTermType::EXT_S:
692  out = encodeExtS(subTerm1, _term.index()); break;
693  case carl::BVTermType::REPEAT:
694  out = encodeRepeat(subTerm1, _term.index()); break;
695  default:
696  assert(false);
697  }
698 
699  mTermBits[_term] = out;
700  mCurrentTerm = std::nullopt;
701 
702  #ifdef SMTRAT_BV_ENCODER_DEBUG
703  std::cerr << "Encoded into:";
704  for(auto bIt = out.crbegin(); bIt != out.crend(); ++bIt) {
705  std::cerr << " <" << *bIt << ">";
706  }
707  std::cerr << std::endl;
708  #endif
709 
710  return out;
711  }
712 
713  Bit encodeConstraint(const BitVecConstr& _constraint)
714  {
715  #ifndef SMTRAT_BV_INCREMENTAL_MODE
716  auto it = mConstraintBits.find(_constraint);
717  if(it != mConstraintBits.end()) {
718  return it->second;
719  }
720  #endif
721 
722  // In incremental mode,
723  // always call encodeTerm() on both subterms, even if we have
724  // already encoded _constraint. This way the mCurrentEncodings
725  // set is built correctly.
726  Bits lhs = encodeTerm(_constraint.lhs());
727  Bits rhs = encodeTerm(_constraint.rhs());
728 
729  #ifdef SMTRAT_BV_INCREMENTAL_MODE
730  auto it = mConstraintEncodings.find(_constraint);
731  if(it != mConstraintEncodings.end())
732  {
733  mCurrentEncodings.insert(it->second.begin(), it->second.end());
734  return mConstraintBits[_constraint];
735  }
736  #endif
737 
738  // The constraint has not been encoded yet. Encode it now
739  mCurrentConstraint = _constraint;
740  carl::BVCompareRelation relation = _constraint.relation();
741  Bit out;
742 
743  #ifdef SMTRAT_BV_ENCODER_DEBUG
744  std::cerr << "[BV] Encoding constraint: " << _constraint << std::endl;
745  #endif
746 
747  switch(relation)
748  {
750  out = encodeEq(lhs, rhs); break;
751  case carl::BVCompareRelation::NEQ:
752  out = encodeNeq(lhs, rhs); break;
753  case carl::BVCompareRelation::ULT:
754  out = encodeUlt(lhs, rhs); break;
755  case carl::BVCompareRelation::ULE:
756  out = encodeUle(lhs, rhs); break;
757  case carl::BVCompareRelation::UGT:
758  out = encodeUgt(lhs, rhs); break;
759  case carl::BVCompareRelation::UGE:
760  out = encodeUge(lhs, rhs); break;
761  case carl::BVCompareRelation::SLT:
762  out = encodeSlt(lhs, rhs); break;
763  case carl::BVCompareRelation::SLE:
764  out = encodeSle(lhs, rhs); break;
765  case carl::BVCompareRelation::SGT:
766  out = encodeSgt(lhs, rhs); break;
767  case carl::BVCompareRelation::SGE:
768  out = encodeSge(lhs, rhs); break;
769  default:
770  assert(false);
771  }
772 
773  mConstraintBits[_constraint] = out;
774  mCurrentConstraint = std::nullopt;
775 
776  #ifdef SMTRAT_BV_ENCODER_DEBUG
777  std::cerr << "Encoded into: <" << out << ">" << std::endl;
778  #endif
779 
780  return out;
781  }
782 
783  Bit encodeEq(const Bits& _lhs, const Bits& _rhs)
784  {
785  Bits comparisons;
786 
787  for(std::size_t i=0;i<_lhs.size();++i)
788  {
789  comparisons.push_back(boolIff(_lhs[i], _rhs[i]));
790  }
791 
792  return createBit(boolAnd(comparisons));
793  }
794 
795  Bit encodeNeq(const Bits& _lhs, const Bits& _rhs)
796  {
797  return createBit(boolNot(encodeEq(_lhs, _rhs)));
798  }
799 
800  Bit encodeUlt(const Bits& _lhs, const Bits& _rhs)
801  {
802  return createBit(boolNot(encodeUge(_lhs, _rhs)));
803  }
804 
805  Bit encodeUle(const Bits& _lhs, const Bits& _rhs)
806  {
807  Bit ult = encodeUlt(_lhs, _rhs);
808  Bit eq = encodeEq(_lhs, _rhs);
809 
810  return createBit(boolOr(eq, ult));
811  }
812 
813  Bit encodeUgt(const Bits& _lhs, const Bits& _rhs)
814  {
815  return createBit(boolNot(encodeUle(_lhs, _rhs)));
816  }
817 
818  Bit encodeUge(const Bits& _lhs, const Bits& _rhs)
819  {
820  Bits addition = encodeAdderNetwork(_lhs, encodeNot(_rhs), true, true);
821  return addition[addition.size()-1];
822  }
823 
824  Bit encodeSlt(const Bits& _lhs, const Bits& _rhs)
825  {
826  /*
827  (bvslt s t) abbreviates:
828  (or (and (= ((_ extract |m-1| |m-1|) s) #b1)
829  (= ((_ extract |m-1| |m-1|) t) #b0))
830  (and (= ((_ extract |m-1| |m-1|) s) ((_ extract |m-1| |m-1|) t))
831  (bvult s t)))
832  */
833  Bit msbLhs = _lhs[_lhs.size()-1];
834  Bit msbRhs = _rhs[_rhs.size()-1];
835  Bit ult = encodeUlt(_lhs, _rhs);
836 
837  return createBit(boolOr(
838  boolAnd(msbLhs, boolNot(msbRhs)),
839  boolAnd(boolIff(msbLhs, msbRhs), ult)
840  ));
841  }
842 
843  Bit encodeSle(const Bits& _lhs, const Bits& _rhs)
844  {
845  /*
846  (bvsle s t) abbreviates:
847  (or (and (= ((_ extract |m-1| |m-1|) s) #b1)
848  (= ((_ extract |m-1| |m-1|) t) #b0))
849  (and (= ((_ extract |m-1| |m-1|) s) ((_ extract |m-1| |m-1|) t))
850  (bvule s t)))
851  */
852  Bit msbLhs = _lhs[_lhs.size()-1];
853  Bit msbRhs = _rhs[_rhs.size()-1];
854  Bit ule = encodeUle(_lhs, _rhs);
855 
856  return createBit(boolOr(
857  boolAnd(msbLhs, boolNot(msbRhs)),
858  boolAnd(boolIff(msbLhs, msbRhs), ule)
859  ));
860  }
861 
862  Bit encodeSgt(const Bits& _lhs, const Bits& _rhs)
863  {
864  return createBit(boolNot(encodeSle(_lhs, _rhs)));
865  }
866 
867  Bit encodeSge(const Bits& _lhs, const Bits& _rhs)
868  {
869  return createBit(boolNot(encodeSlt(_lhs, _rhs)));
870  }
871 
872  Bit createBit(const FormulaT& _formula)
873  {
874  if(_formula.is_atom() || (_formula.type() == carl::FormulaType::NOT && _formula.subformula().is_atom())) {
875  return _formula;
876  }
877 
878  Bit freshBit = Bit(createVariable());
879  boolAssert(boolIff(freshBit, _formula));
880  return freshBit;
881  }
882 
883  Bits createBits(std::size_t _n)
884  {
885  return createBits(createVariables(_n));
886  }
887 
889  {
890  Variable var = carl::fresh_boolean_variable();
891  #ifndef SMTRAT_BV_ENCODER_DEBUG
892  mIntroducedVariables.insert(var);
893  #endif
894  return var;
895  }
896 
897  Variables createVariables(std::size_t _n) {
898  Variables out;
899  for(std::size_t i=0;i<_n;++i) {
900  out.push_back(createVariable());
901  }
902  return out;
903  }
904 
905  Bits createBits(const Bits& _original) {
906  /*
907  * return _original;
908  */
909  Bits out;
910  for(const Bit& bit : _original) {
911  out.push_back(createBit(bit));
912  }
913  return out;
914  }
915 
916  Bits createBits(const Variables& _variables) {
917  Bits out;
918  for(const Variable& var : _variables) {
919  out.push_back(Bit(var));
920  }
921  return out;
922  }
923 
924  Bit boolNot(const Bit& _operand) {
925  return Formula(carl::FormulaType::NOT, _operand);
926  }
927 
928  Bit boolImplies(const Bit& _first, const Bit& _second) {
929  return Formula(carl::FormulaType::IMPLIES, {_first, _second});
930  }
931 
932  Bit boolAnd(const Bit& _first, const Bit& _second) {
933  return Formula(carl::FormulaType::AND, {_first, _second});
934  }
935 
936  Bit boolAnd(const Bits& _operands) {
937  return Formula(carl::FormulaType::AND, _operands);
938  }
939 
940  Bit boolOr(const Bit& _first, const Bit& _second) {
941  return Formula(carl::FormulaType::OR, {_first, _second});
942  }
943 
944  Bit boolOr(const Bits& _operands) {
945  return Formula(carl::FormulaType::OR, _operands);
946  }
947 
948  Bit boolXor(const Bit& _first, const Bit& _second) {
949  return Formula(carl::FormulaType::XOR, {_first, _second});
950  }
951 
952  Bit boolIff(const Bit& _first, const Bit& _second) {
953  return Formula(carl::FormulaType::IFF, {_first, _second});
954  }
955 
956  Bit boolIte(const Bit& _condition, const Bit& _then, const Bit& _else) {
957  return Formula(carl::FormulaType::ITE, {_condition, _then, _else});
958  }
959 
961  {
962  if(_original.type() == carl::FormulaType::BITVECTOR)
963  {
964  Bit substitute = encodeConstraint(_original.bv_constraint());
965  return substitute;
966  }
967  return _original;
968  }
969 
970  public:
971 
972  const FormulaSetT& encode(const FormulaT& _inputFormula)
973  {
974  mCurrentEncodings.clear();
975  std::function<FormulaT(FormulaT)> encodeConstraints = std::bind(&BVDirectEncoder::encodeBVConstraints, this, std::placeholders::_1);
976  FormulaT passedFormula = carl::visit_result(_inputFormula, encodeConstraints);
977 
978  #ifdef SMTRAT_BV_ENCODER_DEBUG
979  std::cerr << "Formula encoded into: " << passedFormula << std::endl;
980  #endif
981 
982  mCurrentEncodings.insert(passedFormula);
983  return mCurrentEncodings;
984  }
985 
986  const std::set<carl::Variable>& introducedVariables() const
987  {
988  return mIntroducedVariables;
989  }
990 
991  const carl::FastMap<BitVec, Variables> bitvectorBlastings() const
992  {
993  return mBitVecBits;
994  }
995 
997  {
998  /* Bits consts = createBits(2);
999  mConst0 = consts[0];
1000  mConst1 = consts[1]; */
1001  }
1002 
1004  {}
1005 
1006  };
1007 }
#define BITVECTOR(...)
Definition: TheoryTypes.h:24
Bit boolIff(const Bit &_first, const Bit &_second)
Bits encodeRshiftLogic(const Bits &_first, const Bits &_second)
Bits encodeDivU(const Bits &_first, const Bits &_second)
Bits encodeRrotate(const Bits &_operand, std::size_t _index)
Bits createBits(const Bits &_original)
Bits encodeShiftNetwork(const Bits &_first, const Bits &_second, bool _left, bool _arithmetic=false)
FormulaT encodeBVConstraints(const FormulaT _original)
Bit boolNot(const Bit &_operand)
Bits encodeComp(const Bits &_first, const Bits &_second)
Bits encodeVariable(const BitVec &_variable)
Bits encodeExtract(const Bits &_operand, std::size_t _highest, std::size_t _lowest)
carl::BVVariable BitVec
Bit boolImplies(const Bit &_first, const Bit &_second)
Bits encodeAdd(const Bits &_first, const Bits &_second)
carl::FastMap< BitVecConstr, Bit > mConstraintBits
Bits createBits(const Variables &_variables)
Bits encodeConstant(const carl::BVValue &_value)
Bits encodeExtS(const Bits &_operand, std::size_t _index)
std::set< Variable > mIntroducedVariables
Bit encodeUle(const Bits &_lhs, const Bits &_rhs)
Bit encodeSgt(const Bits &_lhs, const Bits &_rhs)
const FormulaSetT & encode(const FormulaT &_inputFormula)
Bit encodeSle(const Bits &_lhs, const Bits &_rhs)
Bits encodeLrotate(const Bits &_operand, std::size_t _index)
std::optional< BitVecTerm > mCurrentTerm
Bit encodeSlt(const Bits &_lhs, const Bits &_rhs)
Bits encodeModU(const Bits &_first, const Bits &_second)
std::vector< Variable > Variables
Bits encodeNot(const Bits &_operand)
Bit encodeEq(const Bits &_lhs, const Bits &_rhs)
Bit encodeUlt(const Bits &_lhs, const Bits &_rhs)
Bit boolOr(const Bits &_operands)
const carl::FastMap< BitVec, Variables > bitvectorBlastings() const
Bits encodeNor(const Bits &_first, const Bits &_second)
Bit encodeConstraint(const BitVecConstr &_constraint)
const std::set< carl::Variable > & introducedVariables() const
Bits encodeOr(const Bits &_first, const Bits &_second)
Bits createBits(std::size_t _n)
Bits encodeRshiftArith(const Bits &_first, const Bits &_second)
Bits encodeAdderNetwork(const Bits &_first, const Bits &_second, bool _carryInValue=false, bool _withCarryOut=false, bool _allowOverflow=true)
Bits encodeNand(const Bits &_first, const Bits &_second)
Bit boolOr(const Bit &_first, const Bit &_second)
Bit encodeUgt(const Bits &_lhs, const Bits &_rhs)
Bit createBit(const FormulaT &_formula)
carl::FastMap< BitVec, Variables > mBitVecBits
std::vector< Bit > Bits
Bits encodeIte(const Bit &_condition, const Bits &_then, const Bits &_else)
Bits encodeXnor(const Bits &_first, const Bits &_second)
Bits encodeRepeat(const Bits &_operand, std::size_t _index)
carl::BVConstraint BitVecConstr
Bit boolXor(const Bit &_first, const Bit &_second)
std::optional< BitVecConstr > mCurrentConstraint
Bits encodeModS1(const Bits &_first, const Bits &_second)
Bits encodeTerm(const BitVecTerm &_term)
Bits encodeDivS(const Bits &_first, const Bits &_second)
Bit encodeUge(const Bits &_lhs, const Bits &_rhs)
Bits encodeDivisionNetwork(const Bits &_first, const Bits &_second, bool _returnRemainder=false)
Bit encodeNeq(const Bits &_lhs, const Bits &_rhs)
carl::FastMap< BitVecTerm, Bits > mTermBits
Bits encodeMul(const Bits &_first, const Bits &_second)
Bits encodeLshift(const Bits &_first, const Bits &_second)
Bits encodeMultiplicationNetwork(const Bits &_first, const Bits &_second, bool _allowOverflow=true)
Bits encodeConcat(const Bits &_first, const Bits &_second)
carl::FastMap< BitVecTerm, FormulaSetT > mTermEncodings
carl::FastMap< BitVecConstr, FormulaSetT > mConstraintEncodings
Bits encodeNeg(const Bits &_operand)
Bit boolAnd(const Bit &_first, const Bit &_second)
Bits encodeModS2(const Bits &_first, const Bits &_second)
Bit boolAnd(const Bits &_operands)
void boolAssert(const Formula &_formula)
Bits encodeSub(const Bits &_first, const Bits &_second)
Bit boolIte(const Bit &_condition, const Bit &_then, const Bit &_else)
Bits encodeAnd(const Bits &_first, const Bits &_second)
Bit encodeSge(const Bits &_lhs, const Bits &_rhs)
Bits encodeExtU(const Bits &_operand, std::size_t _index)
Variables createVariables(std::size_t _n)
Bits encodeXor(const Bits &_first, const Bits &_second)
int var(Lit p)
Definition: SolverTypes.h:64
bool substitute(const FormulaT &constr, const carl::Variable var, const carl::vs::Term< Poly > &term, FormulaT &result)
Definition: VSHelper.h:138
carl::BVVariable BVVariable
Definition: TheoryTypes.h:78
carl::BVConstraint BVConstraint
Typedef for bitvector constraint.
Definition: TheoryTypes.h:80
carl::BVTerm BVTerm
Typedef for bitvector term.
Definition: TheoryTypes.h:77
QuantifierType type(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:39
Class to create the formulas for axioms.
carl::FormulaSet< Poly > FormulaSetT
Definition: types.h:41
carl::Formula< Poly > FormulaT
Definition: types.h:37