carl  24.04
Computer ARithmetic Library
BVTermPool.cpp
Go to the documentation of this file.
1 /*
2  * File: BVTermPool.cpp
3  * Author: Andreas Krueger <andreas.krueger@rwth-aachen.de>
4  */
5 
6 #include "BVTermPool.h"
7 #include "BVTermContent.h"
8 
9 namespace carl
10 {
12  mpInvalid(add(new Term))
13  {
14  }
15 
17  {
18  return this->mpInvalid;
19  }
20 
22  {
23  return this->add(new Term(_type, std::move(_value)));
24  }
25 
27  {
28  return this->add(new Term(_type, _variable));
29  }
30 
31  BVTermPool::ConstTermPtr BVTermPool::create(BVTermType _type, const BVTerm& _operand, std::size_t _index)
32  {
33  if (_operand.is_constant()) {
34  switch (_type) {
35  case BVTermType::NOT: {
36  return create(BVTermType::CONSTANT, ~_operand.value());
37  }
38  case BVTermType::NEG: {
39  return create(BVTermType::CONSTANT, -_operand.value());
40  }
41  case BVTermType::LROTATE: {
42  return create(BVTermType::CONSTANT, _operand.value().rotateLeft(_index));
43  }
44  case BVTermType::RROTATE: {
45  return create(BVTermType::CONSTANT, _operand.value().rotateRight(_index));
46  }
47  case BVTermType::REPEAT: {
48  return create(BVTermType::CONSTANT, _operand.value().repeat(_index));
49  }
50  case BVTermType::EXT_U: {
51  return create(BVTermType::CONSTANT, _operand.value().extendUnsignedBy(_index));
52  }
53  case BVTermType::EXT_S: {
54  return create(BVTermType::CONSTANT, _operand.value().extendSignedBy(_index));
55  }
56  default:
57  CARL_LOG_WARN("carl.bitvector", "No simplification for " << _type << " BVTerm.");
58  }
59  }
60  return this->add(new Term(_type, _operand, _index));
61  }
62 
63  BVTermPool::ConstTermPtr BVTermPool::create(BVTermType _type, const BVTerm& _first, const BVTerm& _second)
64  {
65  // Catch expressions leading to an "undefined" result (i.e., division by zero)
66  // As of SMT-LIB 2.6, this is defined as #b111...
67  if (_second.is_constant() && _second.value().is_zero()) {
68  switch (_type) {
69  case BVTermType::DIV_U:
70  return create(BVTermType::CONSTANT, ~BVValue(_first.width(), 0));
71  case BVTermType::DIV_S:
72  if (_first.is_constant()) {
73  if (_first.value().is_zero()) {
74  // Zero -> 1
75  return create(BVTermType::CONSTANT, BVValue(_first.width(), 1));
76  } else if (_first.value()[_first.width()-1]) {
77  // Negative -> 1
78  return create(BVTermType::CONSTANT, BVValue(_first.width(), 1));
79  } else {
80  // Positive -> _first
81  return _first.mpContent;
82  }
83  }
84  break;
85  case BVTermType::MOD_S1:
86  case BVTermType::MOD_S2:
87  case BVTermType::MOD_U:
88  return _first.mpContent;
89  default:
90  break;
91  }
92  }
93 
94  // Evaluate term if both terms arguments are constant
95  if (_first.is_constant() && _second.is_constant()) {
96  switch (_type) {
97  case BVTermType::CONCAT: {
98  return create(BVTermType::CONSTANT, _first.value().concat(_second.value()));
99  }
100  case BVTermType::AND: {
101  return create(BVTermType::CONSTANT, _first.value() & _second.value());
102  }
103  case BVTermType::OR: {
104  return create(BVTermType::CONSTANT, _first.value() | _second.value());
105  }
106  case BVTermType::XOR: {
107  return create(BVTermType::CONSTANT, _first.value() ^ _second.value());
108  }
109  case BVTermType::NAND: {
110  return create(BVTermType::CONSTANT, ~(_first.value() & _second.value()));
111  }
112  case BVTermType::NOR: {
113  return create(BVTermType::CONSTANT, ~(_first.value() | _second.value()));
114  }
115  case BVTermType::XNOR: {
116  return create(BVTermType::CONSTANT, ~(_first.value() ^ _second.value()));
117  }
118  case BVTermType::ADD: {
119  return create(BVTermType::CONSTANT, _first.value() + _second.value());
120  }
121  case BVTermType::SUB: {
122  return create(BVTermType::CONSTANT, _first.value() - _second.value());
123  }
124  case BVTermType::MUL: {
125  return create(BVTermType::CONSTANT, _first.value() * _second.value());
126  }
127  case BVTermType::DIV_U: {
128  return create(BVTermType::CONSTANT, _first.value() / _second.value());
129  }
130  case BVTermType::DIV_S: {
131  return create(BVTermType::CONSTANT, _first.value().divideSigned(_second.value()));
132  }
133  case BVTermType::MOD_U: {
134  return create(BVTermType::CONSTANT, _first.value() % _second.value());
135  }
136  case BVTermType::MOD_S1: {
137  return create(BVTermType::CONSTANT, _first.value().remSigned(_second.value()));
138  }
139  case BVTermType::MOD_S2: {
140  return create(BVTermType::CONSTANT, _first.value().modSigned(_second.value()));
141  }
142  case BVTermType::EQ: {
143  assert(_first.width() == _second.width());
144  unsigned val = (_first.value() == _second.value()) ? 1 : 0;
145  return create(BVTermType::CONSTANT, BVValue(1, val));
146  }
147  case BVTermType::LSHIFT: {
148  return create(BVTermType::CONSTANT, _first.value() << _second.value());
149  }
151  return create(BVTermType::CONSTANT, _first.value() >> _second.value());
152  }
154  return create(BVTermType::CONSTANT, _first.value().rightShiftArithmetic(_second.value()));
155  }
156  default:
157  CARL_LOG_WARN("carl.bitvector", "No simplification for " << _type << " BVTerm.");
158  }
159  }
160 
161  return this->add(new Term(_type, _first, _second));
162  }
163 
164  BVTermPool::ConstTermPtr BVTermPool::create(BVTermType _type, const BVTerm& _operand, std::size_t _highest, std::size_t _lowest)
165  {
166  if(_operand.is_constant()) {
167  if(_type == BVTermType::EXTRACT) {
168  return create(BVTermType::CONSTANT, _operand.value().extract(_highest, _lowest));
169  } else {
170  CARL_LOG_WARN("carl.bitvector", "No simplification for " << _type << " BVTerm.");
171  }
172  }
173  return this->add(new Term(_type, _operand, _highest, _lowest));
174  }
175 
176  void BVTermPool::assignId(TermPtr _term, std::size_t _id)
177  {
178  _term->mId = _id;
179  }
180 }
181 
182 #define BV_TERM_POOL BVTermPool::getInstance()
#define CARL_LOG_WARN(channel, msg)
Definition: carl-logging.h:41
carl is the main namespace for the library.
BVTermType
Definition: BVTermType.h:10
std::size_t width() const
Definition: BVTerm.cpp:43
bool is_constant() const
Definition: BVTerm.h:51
const BVTermContent * mpContent
Definition: BVTerm.h:30
const BVValue & value() const
Definition: BVTerm.cpp:91
BVTermContent Term
Definition: BVTermPool.h:18
ConstTermPtr mpInvalid
Definition: BVTermPool.h:23
ConstTermPtr create()
Definition: BVTermPool.cpp:16
void assignId(TermPtr _term, std::size_t _id) override
Assigns a unique id to the generated element.
Definition: BVTermPool.cpp:176
BVValue modSigned(const BVValue &_other) const
Definition: BVValue.cpp:90
BVValue extract(std::size_t _highest, std::size_t _lowest) const
Definition: BVValue.cpp:114
BVValue concat(const BVValue &_other) const
Definition: BVValue.cpp:46
BVValue repeat(std::size_t _n) const
Definition: BVValue.h:96
BVValue rotateLeft(std::size_t _n) const
Definition: BVValue.h:82
BVValue rotateRight(std::size_t _n) const
Definition: BVValue.h:92
BVValue extendSignedBy(std::size_t _n) const
Definition: BVValue.h:112
BVValue extendUnsignedBy(std::size_t _n) const
Definition: BVValue.h:106
BVValue rightShiftArithmetic(const BVValue &_other) const
Definition: BVValue.h:136
bool is_zero() const
Definition: BVValue.h:78
BVValue divideSigned(const BVValue &_other) const
Definition: BVValue.cpp:56
BVValue remSigned(const BVValue &_other) const
Definition: BVValue.cpp:73
Represent a BitVector-Variable.
Definition: BVVariable.h:13
ConstElementPtr add(ElementPtr _element)
Adds the given element to the pool, if it does not yet occur in there.
Definition: Pool.h:113