carl  25.02
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 { bool positive = false; };
37 
38  inline bool operator==(InfinityValue lhs, InfinityValue rhs) {
39  return lhs.positive == rhs.positive;
40  }
41 
42  inline std::ostream& operator<<(std::ostream& os, const InfinityValue& iv) {
43  return os << (iv.positive ? "+" : "-") << "oo";
44  }
45 
46  template<typename Poly>
48  std::optional<MultivariateRoot<Poly>> lower = std::nullopt;
49  bool lower_strict = true;
50  std::optional<MultivariateRoot<Poly>> upper = std::nullopt;
51  bool upper_strict = true;
52  };
53 
54  template<typename Poly>
55  inline std::ostream& operator<<(std::ostream& os, const SymbolicInterval<Poly>& i) {
56  os << (i.lower_strict ? "(" : "[");
57  if (i.lower) os << i.lower;
58  else os << "-oo";
59  os << ", ";
60  if (i.upper) os << i.upper;
61  else os << "oo";
62  os << (i.upper_strict ? ")" : "]");
63  return os;
64  }
65 
66  template<typename Poly>
67  inline bool operator==(const SymbolicInterval<Poly>& lhs, const SymbolicInterval<Poly>& rhs) {
68  return (
69  lhs.lower_strict == rhs.lower_strict
70  && lhs.lower == rhs.lower
71  && lhs.upper_strict == rhs.upper_strict
72  && lhs.upper == rhs.upper
73  );
74  }
75 
76 
77  template<typename RAN>
78  struct Infinitesimal {
79  RAN value;
80  bool is_infimum; // otherwise it is a supremum
81  };
82 
83  template<typename RAN>
84  inline std::ostream& operator<<(std::ostream& os, const Infinitesimal<RAN>& d) {
85  os << "(" << (d.is_infimum ? "+ " : "- ") << d.value << " epsilon)";
86  return os;
87  }
88 
89  template<typename RAN>
90  inline bool operator==(const Infinitesimal<RAN>& lhs, const Infinitesimal<RAN>& rhs) {
91  return lhs.value == rhs.value && lhs.is_infimum == rhs.is_infimum;
92  }
93 
94 
95  /**
96  * Represent a sum type/variant over the different kinds of values that
97  * can be assigned to the different kinds of variables that exist in
98  * CARL and to use them in a more uniform way,
99  * e.g. a plain "bool", "infinity", a "carl::RealAlgebraicNumber",
100  * a (bitvector) "carl::BVValue" etc.
101  */
102  template<typename Rational, typename Poly>
103  class ModelValue {
104  template<typename R, typename P>
105  friend std::ostream& operator<<(std::ostream& os, const ModelValue<R,P>& mv);
106  template<typename R, typename P>
107  friend bool operator==(const ModelValue<R,P>& lhs, const ModelValue<R,P>& rhs);
108  template<typename R, typename P>
109  friend bool operator<(const ModelValue<R,P>& lhs, const ModelValue<R,P>& rhs);
110 
111  using RAN = typename Poly::RootType;
112  /**
113  * Base type we are deriving from.
114  */
115  using Super = std::variant<
116  bool,
117  Rational,
118  SqrtEx<Poly>,
119  RAN,
120  BVValue,
121  SortValue,
122  UFModel,
127  >;
128 
130 
131  template<typename Variant>
132  Super clone(const Variant& v) const {
133  return std::visit(overloaded {
134  [](const MultivariateRoot<Poly>& mr) {
136  },
137  [](const ModelSubstitutionPtr<Rational,Poly>& subs) { return Super(subs->clone()); },
138  [](const auto& t) { return Super(t); }
139  }, v);
140  }
141 
142  public:
143  /**
144  * Default constructor.
145  */
146  ModelValue() = default;
147 
149  : mData(clone(mv.mData))
150  {}
151  ModelValue(ModelValue&& mv) = default;
152 
153  /**
154  * Initialize the Assignment from some valid type of the underlying variant.
155  */
156  template<typename T, typename T2 = typename std::enable_if<convertible_to_variant<T, Super>::value, T>::type>
157  ModelValue(const T& _t): mData(_t) {}
158 
159  template<typename T, typename T2 = typename std::enable_if<convertible_to_variant<T, Super>::value, T>::type>
160  ModelValue(T&& _t): mData(std::move(_t)) {}
161 
162  template<typename ...Args>
163  ModelValue(const std::variant<Args...>& variant): mData(clone(variant)) {}
164 
166 
168  // Attention: Replace copy assignment with constructor + move assignment to avoid problems with self-assignment
169  mData = clone(mv.mData);
170  return *this;
171  }
172  ModelValue& operator=(ModelValue&& mv) = default;
173 
174  /**
175  * Assign some value to the underlying variant.
176  * @param t Some value.
177  * @return *this.
178  */
179  template<typename T>
180  ModelValue& operator=(const T& t) {
181  // Attention: Replace copy assignment with constructor + move assignment to avoid problems with self-assignment
182  mData = Super(t);
183  return *this;
184  }
185  template<typename ...Args>
186  ModelValue& operator=(const std::variant<Args...>& variant) {
187  // Attention: Replace copy assignment with constructor + move assignment to avoid problems with self-assignment
188  mData = clone(variant);
189  return *this;
190  }
192  mData = createSubstitution<Rational,Poly>(mr).asSubstitution();
193  return *this;
194  }
195 
196  template<typename F>
197  auto visit(F&& f) const {
198  return std::visit(f, mData);
199  }
200 
201  bool isBool() const { return std::holds_alternative<bool>(mData); }
202  bool isRational() const { return std::holds_alternative<Rational>(mData); }
203  bool isSqrtEx() const { return std::holds_alternative<SqrtEx<Poly>>(mData); }
204  bool isRAN() const { return std::holds_alternative<RAN>(mData); }
205  bool isBVValue() const { return std::holds_alternative<BVValue>(mData); }
206  bool isSortValue() const { return std::holds_alternative<SortValue>(mData); }
207  bool isUFModel() const { return std::holds_alternative<UFModel>(mData); }
208  bool isSubstitution() const { return std::holds_alternative<ModelSubstitutionPtr<Rational,Poly>>(mData); }
209  bool isPlusInfinity() const {
210  return std::holds_alternative<InfinityValue>(mData) && std::get<InfinityValue>(mData).positive;
211  }
212  bool isMinusInfinity() const {
213  return std::holds_alternative<InfinityValue>(mData) && !std::get<InfinityValue>(mData).positive;
214  }
215  bool isSymbolicInterval() const { return std::holds_alternative<SymbolicInterval<Poly>>(mData); }
216  bool isInfinitesimal() const { return std::holds_alternative<Infinitesimal<RAN>>(mData); }
217 
218  bool asBool() const { assert(isBool()); return std::get<bool>(mData); }
219  const Rational& asRational() const { assert(isRational()); return std::get<Rational>(mData); }
220  const SqrtEx<Poly>& asSqrtEx() const { assert(isSqrtEx()); return std::get<SqrtEx<Poly>>(mData); }
221  const RAN& asRAN() const { assert(isRAN()); return std::get<RAN>(mData); }
222  const BVValue& asBVValue() const { assert(isBVValue()); return std::get<BVValue>(mData); }
223  const SortValue& asSortValue() const { assert(isSortValue()); return std::get<SortValue>(mData); }
224  const UFModel& asUFModel() const { assert(isUFModel()); return std::get<UFModel>(mData); }
225  UFModel& asUFModel() { assert(isUFModel()); return std::get<UFModel>(mData); }
226  const InfinityValue& asInfinity() const { assert(isPlusInfinity() || isMinusInfinity()); return std::get<InfinityValue>(mData); }
227  const ModelSubstitutionPtr<Rational,Poly>& asSubstitution() const { assert(isSubstitution()); return std::get<ModelSubstitutionPtr<Rational,Poly>>(mData); }
228  ModelSubstitutionPtr<Rational,Poly>& asSubstitution() { assert(isSubstitution()); return std::get<ModelSubstitutionPtr<Rational,Poly>>(mData); }
229  const SymbolicInterval<Poly>& asSymbolicInterval() const { assert(isSymbolicInterval()); return std::get<SymbolicInterval<Poly>>(mData); }
230  const Infinitesimal<RAN>& asInfinitesimal() const { assert(isInfinitesimal()); return std::get<Infinitesimal<RAN>>(mData); }
231  };
232 
233  /**
234  * Check if two Assignments are equal.
235  * Two Assignments are considered equal, if both are either bool or not bool and their value is the same.
236  *
237  * If both Assignments are not bools, the check may return false although they represent the same value.
238  * If both are numbers in different representations, this comparison is only done as a "best effort".
239  *
240  * @param lhs First Assignment.
241  * @param rhs Second Assignment.
242  * @return lhs == rhs.
243  */
244  template<typename Rational, typename Poly>
246  return lhs.mData == rhs.mData;
247  }
248 
249  template<typename Rational, typename Poly>
251  return lhs.mData < rhs.mData;
252  }
253 
254  template<typename R, typename P>
255  inline std::ostream& operator<<(std::ostream& os, const ModelValue<R,P>& mv) {
256  if (mv.isBool()) { return os << mv.asBool(); }
257  if (mv.isRational()) { return os << mv.asRational(); }
258  if (mv.isSqrtEx()) { return os << mv.asSqrtEx(); }
259  if (mv.isRAN()) { return os << mv.asRAN(); }
260  if (mv.isBVValue()) { return os << mv.asBVValue(); }
261  if (mv.isSortValue()) { return os << mv.asSortValue(); }
262  if (mv.isUFModel()) { return os << mv.asUFModel(); }
263  if (mv.isSubstitution()) { return os << mv.asSubstitution(); }
264  if (mv.isPlusInfinity() || mv.isMinusInfinity()) { return os << mv.asInfinity(); }
265  if (mv.isSymbolicInterval()) { return os << mv.asSymbolicInterval(); }
266  if (mv.isInfinitesimal()) { return os << mv.asInfinitesimal(); }
267  return os << mv.mData;
268  }
269 }
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:103
ModelValue(T &&_t)
Definition: ModelValue.h:160
UFModel & asUFModel()
Definition: ModelValue.h:225
const InfinityValue & asInfinity() const
Definition: ModelValue.h:226
bool isPlusInfinity() const
Definition: ModelValue.h:209
ModelValue & operator=(ModelValue &&mv)=default
ModelValue & operator=(const MultivariateRoot< Poly > &mr)
Definition: ModelValue.h:191
const RAN & asRAN() const
Definition: ModelValue.h:221
Super clone(const Variant &v) const
Definition: ModelValue.h:132
ModelValue & operator=(const std::variant< Args... > &variant)
Definition: ModelValue.h:186
bool isUFModel() const
Definition: ModelValue.h:207
ModelValue(const std::variant< Args... > &variant)
Definition: ModelValue.h:163
const SqrtEx< Poly > & asSqrtEx() const
Definition: ModelValue.h:220
const ModelSubstitutionPtr< Rational, Poly > & asSubstitution() const
Definition: ModelValue.h:227
bool isBVValue() const
Definition: ModelValue.h:205
const BVValue & asBVValue() const
Definition: ModelValue.h:222
bool isSymbolicInterval() const
Definition: ModelValue.h:215
friend std::ostream & operator<<(std::ostream &os, const ModelValue< R, P > &mv)
Definition: ModelValue.h:255
bool isMinusInfinity() const
Definition: ModelValue.h:212
bool isBool() const
Definition: ModelValue.h:201
bool isSortValue() const
Definition: ModelValue.h:206
ModelValue(const ModelValue &mv)
Definition: ModelValue.h:148
const Infinitesimal< RAN > & asInfinitesimal() const
Definition: ModelValue.h:230
const Rational & asRational() const
Definition: ModelValue.h:219
ModelValue()=default
Default constructor.
ModelValue & operator=(const ModelValue &mv)
Definition: ModelValue.h:167
const SortValue & asSortValue() const
Definition: ModelValue.h:223
ModelValue(ModelValue &&mv)=default
bool isSqrtEx() const
Definition: ModelValue.h:203
ModelSubstitutionPtr< Rational, Poly > & asSubstitution()
Definition: ModelValue.h:228
friend bool operator==(const ModelValue< R, P > &lhs, const ModelValue< R, P > &rhs)
bool isSubstitution() const
Definition: ModelValue.h:208
bool isRational() const
Definition: ModelValue.h:202
ModelValue(const MultivariateRoot< Poly > &mr)
Definition: ModelValue.h:165
bool isInfinitesimal() const
Definition: ModelValue.h:216
const SymbolicInterval< Poly > & asSymbolicInterval() const
Definition: ModelValue.h:229
const UFModel & asUFModel() const
Definition: ModelValue.h:224
bool asBool() const
Definition: ModelValue.h:218
ModelValue & operator=(const T &t)
Assign some value to the underlying variant.
Definition: ModelValue.h:180
typename Poly::RootType RAN
Definition: ModelValue.h:111
friend bool operator<(const ModelValue< R, P > &lhs, const ModelValue< R, P > &rhs)
auto visit(F &&f) const
Definition: ModelValue.h:197
std::variant< bool, Rational, SqrtEx< Poly >, RAN, BVValue, SortValue, UFModel, InfinityValue, ModelSubstitutionPtr< Rational, Poly >, SymbolicInterval< Poly >, Infinitesimal< RAN > > Super
Base type we are deriving from.
Definition: ModelValue.h:127
bool isRAN() const
Definition: ModelValue.h:204
ModelValue(const T &_t)
Initialize the Assignment from some valid type of the underlying variant.
Definition: ModelValue.h:157
This class represents infinity or minus infinity, depending on its flag positive.
Definition: ModelValue.h:36
std::optional< MultivariateRoot< Poly > > lower
Definition: ModelValue.h:48
std::optional< MultivariateRoot< Poly > > upper
Definition: ModelValue.h:50
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