carl  24.04
Computer ARithmetic Library
ModelValue.h
Go to the documentation of this file.
1 #pragma once
2 
3 
7 #include <carl-arith/ran/ran.h>
8 #include <carl-arith/vs/SqrtEx.h>
11 
12 #include <memory>
13 #include <variant>
14 
15 namespace carl
16 {
17  template<typename Rational, typename Poly>
18  class ModelValue;
19  template<typename Rational, typename Poly>
20  class ModelSubstitution;
21  template<typename Rational, typename Poly>
22  class ModelMVRootSubstitution;
23  template<typename Rational, typename Poly>
24  using ModelSubstitutionPtr = std::unique_ptr<ModelSubstitution<Rational,Poly>>;
25  template<typename Rational, typename Poly, typename Substitution, typename... Args>
26  inline ModelValue<Rational,Poly> createSubstitution(Args&&... args);
27  template<typename Rational, typename Poly, typename Substitution, typename... Args>
29  template<typename Rational, typename Poly>
31 
32  /**
33  * This class represents infinity or minus infinity, depending on its flag positive.
34  * The default is minus infinity.
35  */
36  struct InfinityValue {
37  bool positive = false;
38  };
39 
40  inline bool operator==(InfinityValue lhs, InfinityValue rhs) {
41  return lhs.positive == rhs.positive;
42  }
43 
44  inline std::ostream& operator<<(std::ostream& os, const InfinityValue& iv) {
45  return os << (iv.positive ? "+" : "-") << "infinity";
46  }
47 
48  /**
49  * Represent a sum type/variant over the different kinds of values that
50  * can be assigned to the different kinds of variables that exist in
51  * CARL and to use them in a more uniform way,
52  * e.g. a plain "bool", "infinity", a "carl::RealAlgebraicNumber",
53  * a (bitvector) "carl::BVValue" etc.
54  */
55  template<typename Rational, typename Poly>
56  class ModelValue {
57  template<typename R, typename P>
58  friend std::ostream& operator<<(std::ostream& os, const ModelValue<R,P>& mv);
59  template<typename R, typename P>
60  friend bool operator==(const ModelValue<R,P>& lhs, const ModelValue<R,P>& rhs);
61  template<typename R, typename P>
62  friend bool operator<(const ModelValue<R,P>& lhs, const ModelValue<R,P>& rhs);
63  /**
64  * Base type we are deriving from.
65  */
66  using Super = std::variant<bool, Rational, SqrtEx<Poly>, typename Poly::RootType, BVValue, SortValue, UFModel, InfinityValue, ModelSubstitutionPtr<Rational,Poly>>;
67 
69 
70  template<typename Variant>
71  Super clone(const Variant& v) const {
72  return std::visit(overloaded {
73  [](const MultivariateRoot<Poly>& mr) {
75  },
76  [](const ModelSubstitutionPtr<Rational,Poly>& subs) { return Super(subs->clone()); },
77  [](const auto& t) { return Super(t); }
78  }, v);
79  }
80 
81  public:
82  /**
83  * Default constructor.
84  */
85  ModelValue() = default;
86 
88  : mData(clone(mv.mData))
89  {}
90  ModelValue(ModelValue&& mv) = default;
91 
92  /**
93  * Initialize the Assignment from some valid type of the underlying variant.
94  */
95  template<typename T, typename T2 = typename std::enable_if<convertible_to_variant<T, Super>::value, T>::type>
96  ModelValue(const T& _t): mData(_t) {}
97 
98  template<typename T, typename T2 = typename std::enable_if<convertible_to_variant<T, Super>::value, T>::type>
99  ModelValue(T&& _t): mData(std::move(_t)) {}
100 
101  template<typename ...Args>
102  ModelValue(const std::variant<Args...>& variant): mData(clone(variant)) {}
103 
105 
107  // Attention: Replace copy assignment with constructor + move assignment to avoid problems with self-assignment
108  mData = clone(mv.mData);
109  return *this;
110  }
111  ModelValue& operator=(ModelValue&& mv) = default;
112 
113  /**
114  * Assign some value to the underlying variant.
115  * @param t Some value.
116  * @return *this.
117  */
118  template<typename T>
119  ModelValue& operator=(const T& t) {
120  // Attention: Replace copy assignment with constructor + move assignment to avoid problems with self-assignment
121  mData = Super(t);
122  return *this;
123  }
124  template<typename ...Args>
125  ModelValue& operator=(const std::variant<Args...>& variant) {
126  // Attention: Replace copy assignment with constructor + move assignment to avoid problems with self-assignment
127  mData = clone(variant);
128  return *this;
129  }
131  mData = createSubstitution<Rational,Poly>(mr).asSubstitution();
132  return *this;
133  }
134 
135  template<typename F>
136  auto visit(F&& f) const {
137  return std::visit(f, mData);
138  }
139 
140  /**
141  * @return true, if the stored value is a bool.
142  */
143  bool isBool() const {
144  return std::holds_alternative<bool>(mData);
145  }
146 
147  /**
148  * @return true, if the stored value is a rational.
149  */
150  bool isRational() const {
151  return std::holds_alternative<Rational>(mData);
152  }
153 
154  /**
155  * @return true, if the stored value is a square root expression.
156  */
157  bool isSqrtEx() const {
158  return std::holds_alternative<SqrtEx<Poly>>(mData);
159  }
160 
161  /**
162  * @return true, if the stored value is a real algebraic number.
163  */
164  bool isRAN() const {
165  return std::holds_alternative<typename Poly::RootType>(mData);
166  }
167 
168  /**
169  * @return true, if the stored value is a bitvector literal.
170  */
171  bool isBVValue() const {
172  return std::holds_alternative<BVValue>(mData);
173  }
174 
175  /**
176  * @return true, if the stored value is a sort value.
177  */
178  bool isSortValue() const {
179  return std::holds_alternative<SortValue>(mData);
180  }
181 
182  /**
183  * @return true, if the stored value is a uninterpreted function model.
184  */
185  bool isUFModel() const {
186  return std::holds_alternative<UFModel>(mData);
187  }
188 
189  /**
190  * @return true, if the stored value is +infinity.
191  */
192  bool isPlusInfinity() const {
193  return std::holds_alternative<InfinityValue>(mData) && std::get<InfinityValue>(mData).positive;
194  }
195  /**
196  * @return true, if the stored value is -infinity.
197  */
198  bool isMinusInfinity() const {
199  return std::holds_alternative<InfinityValue>(mData) && !std::get<InfinityValue>(mData).positive;
200  }
201 
202  bool isSubstitution() const {
203  return std::holds_alternative<ModelSubstitutionPtr<Rational,Poly>>(mData);
204  }
205 
206  /**
207  * @return The stored value as a bool.
208  */
209  bool asBool() const {
210  assert(isBool());
211  return std::get<bool>(mData);
212  }
213 
214  /**
215  * @return The stored value as a rational.
216  */
217  const Rational& asRational() const {
218  assert(isRational());
219  return std::get<Rational>(mData);
220  }
221 
222  /**
223  * @return The stored value as a square root expression.
224  */
225  const SqrtEx<Poly>& asSqrtEx() const {
226  assert(isSqrtEx());
227  return std::get<SqrtEx<Poly>>(mData);
228  }
229 
230  /**
231  * @return The stored value as a real algebraic number.
232  */
233  const typename Poly::RootType& asRAN() const {
234  assert(isRAN());
235  return std::get<typename Poly::RootType>(mData);
236  }
237 
238  /**
239  * @return The stored value as a real algebraic number.
240  */
241  const carl::BVValue& asBVValue() const {
242  assert(isBVValue());
243  return std::get<carl::BVValue>(mData);
244  }
245 
246  /**
247  * @return The stored value as a sort value.
248  */
249  const SortValue& asSortValue() const {
250  assert(isSortValue());
251  return std::get<SortValue>(mData);
252  }
253 
254  /**
255  * @return The stored value as a uninterpreted function model.
256  */
257  const UFModel& asUFModel() const {
258  assert(isUFModel());
259  return std::get<UFModel>(mData);
260  }
262  assert(isUFModel());
263  return std::get<UFModel>(mData);
264  }
265  /**
266  * @return The stored value as a infinity value.
267  */
268  const InfinityValue& asInfinity() const {
269  assert(isPlusInfinity() || isMinusInfinity());
270  return std::get<InfinityValue>(mData);
271  }
272 
274  assert(isSubstitution());
275  return std::get<ModelSubstitutionPtr<Rational,Poly>>(mData);
276  }
278  assert(isSubstitution());
279  return std::get<ModelSubstitutionPtr<Rational,Poly>>(mData);
280  }
281  };
282 
283  /**
284  * Check if two Assignments are equal.
285  * Two Assignments are considered equal, if both are either bool or not bool and their value is the same.
286  *
287  * If both Assignments are not bools, the check may return false although they represent the same value.
288  * If both are numbers in different representations, this comparison is only done as a "best effort".
289  *
290  * @param lhs First Assignment.
291  * @param rhs Second Assignment.
292  * @return lhs == rhs.
293  */
294  template<typename Rational, typename Poly>
296  return lhs.mData == rhs.mData;
297  }
298 
299  template<typename Rational, typename Poly>
301  return lhs.mData < rhs.mData;
302  }
303 
304  template<typename R, typename P>
305  inline std::ostream& operator<<(std::ostream& os, const ModelValue<R,P>& mv) {
306  return os << mv.mData;
307  }
308 }
Represent a dynamic root, also known as a "root expression".
Represent a real algebraic number (RAN) in one of several ways:
mpq_class Rational
Definition: HornerTest.cpp:12
carl is the main namespace for the library.
bool operator<(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
ModelValue< Rational, Poly > createSubstitution(Args &&... args)
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
void visit(const Formula< Pol > &formula, Visitor func)
Recursively calls func on every subformula.
Definition: Visit.h:12
bool operator==(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
ModelSubstitutionPtr< Rational, Poly > createSubstitutionPtr(Args &&... args)
std::unique_ptr< ModelSubstitution< Rational, Poly > > ModelSubstitutionPtr
Definition: ModelValue.h:24
Represent a sum type/variant over the different kinds of values that can be assigned to the different...
Definition: ModelValue.h:56
ModelValue(T &&_t)
Definition: ModelValue.h:99
UFModel & asUFModel()
Definition: ModelValue.h:261
const InfinityValue & asInfinity() const
Definition: ModelValue.h:268
bool isPlusInfinity() const
Definition: ModelValue.h:192
std::variant< bool, Rational, SqrtEx< Poly >, typename Poly::RootType, BVValue, SortValue, UFModel, InfinityValue, ModelSubstitutionPtr< Rational, Poly > > Super
Base type we are deriving from.
Definition: ModelValue.h:66
ModelValue & operator=(ModelValue &&mv)=default
const Poly::RootType & asRAN() const
Definition: ModelValue.h:233
ModelValue & operator=(const MultivariateRoot< Poly > &mr)
Definition: ModelValue.h:130
Super clone(const Variant &v) const
Definition: ModelValue.h:71
ModelValue & operator=(const std::variant< Args... > &variant)
Definition: ModelValue.h:125
bool isUFModel() const
Definition: ModelValue.h:185
ModelValue(const std::variant< Args... > &variant)
Definition: ModelValue.h:102
const SqrtEx< Poly > & asSqrtEx() const
Definition: ModelValue.h:225
const ModelSubstitutionPtr< Rational, Poly > & asSubstitution() const
Definition: ModelValue.h:273
bool isBVValue() const
Definition: ModelValue.h:171
friend std::ostream & operator<<(std::ostream &os, const ModelValue< R, P > &mv)
Definition: ModelValue.h:305
bool isMinusInfinity() const
Definition: ModelValue.h:198
bool isBool() const
Definition: ModelValue.h:143
bool isSortValue() const
Definition: ModelValue.h:178
ModelValue(const ModelValue &mv)
Definition: ModelValue.h:87
const Rational & asRational() const
Definition: ModelValue.h:217
ModelValue()=default
Default constructor.
ModelValue & operator=(const ModelValue &mv)
Definition: ModelValue.h:106
const SortValue & asSortValue() const
Definition: ModelValue.h:249
ModelValue(ModelValue &&mv)=default
bool isSqrtEx() const
Definition: ModelValue.h:157
const carl::BVValue & asBVValue() const
Definition: ModelValue.h:241
ModelSubstitutionPtr< Rational, Poly > & asSubstitution()
Definition: ModelValue.h:277
friend bool operator==(const ModelValue< R, P > &lhs, const ModelValue< R, P > &rhs)
bool isSubstitution() const
Definition: ModelValue.h:202
bool isRational() const
Definition: ModelValue.h:150
ModelValue(const MultivariateRoot< Poly > &mr)
Definition: ModelValue.h:104
const UFModel & asUFModel() const
Definition: ModelValue.h:257
bool asBool() const
Definition: ModelValue.h:209
ModelValue & operator=(const T &t)
Assign some value to the underlying variant.
Definition: ModelValue.h:119
friend bool operator<(const ModelValue< R, P > &lhs, const ModelValue< R, P > &rhs)
auto visit(F &&f) const
Definition: ModelValue.h:136
bool isRAN() const
Definition: ModelValue.h:164
ModelValue(const T &_t)
Initialize the Assignment from some valid type of the underlying variant.
Definition: ModelValue.h:96
This class represents infinity or minus infinity, depending on its flag positive.
Definition: ModelValue.h:36
Implements a sort value, being a value of the uninterpreted domain specified by this sort.
Definition: SortValue.h:22
Implements a sort value, being a value of the uninterpreted domain specified by this sort.
Definition: UFModel.h:24