carl  24.04
Computer ARithmetic Library
ran_thom.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "ThomEncoding.h"
4 #include "../common/Operations.h""
5 
6 
7 #include <memory>
8 
9 namespace carl {
10 
11 // TODO adapt to new interface
12 
13 template<typename Number>
14 struct RealAlgebraicNumberThom {
15  template<typename Num>
16  friend bool operator==(const RealAlgebraicNumberThom<Num>& lhs, const RealAlgebraicNumberThom<Num>& rhs);
17  template<typename Num>
18  friend bool operator<(const RealAlgebraicNumberThom<Num>& lhs, const RealAlgebraicNumberThom<Num>& rhs);
19 private:
20  struct Content {
21  ThomEncoding<Number> te;
22 
23  Content(const ThomEncoding<Number>& t):
24  te(t)
25  {}
26  };
27  std::shared_ptr<Content> mContent;
28 public:
29  RealAlgebraicNumberThom(const ThomEncoding<Number>& te):
30  mContent(std::make_shared<Content>(te))
31  {}
32 
33  auto& thom_encoding() {
34  return mContent->te;
35  }
36  const auto& thom_encoding() const {
37  return mContent->te;
38  }
39 
40  const auto& polynomial() const {
41  return thom_encoding().polynomial();
42  }
43  const auto& main_var() const {
44  return thom_encoding().main_var();
45  }
46  auto sign_condition() const {
47  return thom_encoding().signCondition();
48  }
49  const auto& point() const {
50  return thom_encoding().point();
51  }
52 
53  std::size_t bitsize() const {
54  return thom_encoding().dimension();
55  }
56 
57  std::size_t dimension() const {
58  return thom_encoding().dimension();
59  }
60 
61  bool is_integral() const {
62  return thom_encoding().is_integral();
63  }
64  bool is_zero() const {
65  return thom_encoding().is_zero();
66  }
67  bool contained_in(const Interval<Number>& i) const {
68  return thom_encoding().containedIn(i);
69  }
70 
71  Number integer_below() const {
72  return thom_encoding().integer_below();
73  }
74  Sign sgn() const {
75  return thom_encoding().sgn();
76  }
77  Sign sgn(const UnivariatePolynomial<Number>& p) const {
78  return thom_encoding().sgn(p);
79  }
80 };
81 
82 template<typename Number>
83 Number branching_point(const RealAlgebraicNumberThom<Number>& n) {
84  return n.thom_encoding().get_number();
85 }
86 
87 template<typename Number>
88 Number evaluate(const MultivariatePolynomial<Number>& p, std::map<Variable, RealAlgebraicNumberThom<Number>>& m) {
89  //using Polynomial = MultivariatePolynomial<Number>;
90 
91  CARL_LOG_INFO("carl.ran.thom",
92  "\n****************************\n"
93  << "Thom evaluate\n"
94  << "****************************\n"
95  << "p = " << p << "\n"
96  << "m = " << m << "\n"
97  << "****************************\n");
98  for(const auto& entry : m) {
99  assert(entry.first == entry.second.thom_encoding().main_var());
100  }
101  assert(m.size() > 0);
102 
103  std::map<Variable, RealAlgebraicNumberThom<Number>>& m_prime(m);
104  auto it = m_prime.begin();
105  while(it != m_prime.end()) {
106  if(!p.has(it->first)) {
107  CARL_LOG_TRACE("carl.thom.evaluation", "removing " << it->first);
108  it = m_prime.erase(it);
109  } else {
110  it++;
111  }
112  }
113 
114  std::map<Variable, ThomEncoding<Number>> mTE;
115  for(const auto& entry : m_prime) {
116  mTE.insert(std::make_pair(entry.first, entry.second.thom_encoding()));
117  }
118 
119  CARL_LOG_ASSERT("carl.thom.evaluation", variables(p).size() == mTE.size(), "p = " << p << ", mTE = " << mTE);
120 
121  if(mTE.size() == 1) {
122  int sgn = int(mTE.begin()->second.signOnPolynomial(p));
123  CARL_LOG_TRACE("carl.thom.evaluation", "sign of evaluated polynomial is " << sgn);
124  return Number(sgn);
125  }
126 
127  CARL_LOG_TRACE("carl.thom.evaluation", "mTE = " << mTE);
128 
129  ThomEncoding<Number> point = ThomEncoding<Number>::analyzeTEMap(mTE);
130  int sgn = int(point.signOnPolynomial(p));
131  CARL_LOG_TRACE("carl.thom.", "sign of evaluated polynomial is " << sgn);
132  return Number(sgn);
133 
134 }
135 
136 template<typename Number, typename Poly>
137 bool evaluate(const BasicConstraint<Poly>& c, std::map<Variable, RealAlgebraicNumberThom<Number>>& m) {
138  auto res = evaluate(c.lhs(), m);
139  return evaluate(res, c.relation());
140 }
141 
142 template<typename Number>
143 RealAlgebraicNumberThom<Number> abs(const RealAlgebraicNumberThom<Number>& n) {
144  assert(false);
145  return n;
146 }
147 
148 template<typename Number>
149 RealAlgebraicNumberThom<Number> sample_above(const RealAlgebraicNumberThom<Number>& n) {
150  return n.thom_encoding() + Number(1);
151 }
152 template<typename Number>
153 RealAlgebraicNumberThom<Number> sample_below(const RealAlgebraicNumberThom<Number>& n) {
154  return n.thom_encoding() + Number(-1);
155 }
156 template<typename Number>
157 RealAlgebraicNumberThom<Number> sample_between(const RealAlgebraicNumberThom<Number>& lower, const RealAlgebraicNumberThom<Number>& upper) {
158  return ThomEncoding<Number>::intermediatePoint(lower.thom_encoding(), upper.thom_encoding());
159 }
160 template<typename Number>
161 Number sample_between(const RealAlgebraicNumberThom<Number>& lower, const Number& upper) {
162  return ThomEncoding<Number>::intermediatePoint(lower.thom_encoding(), upper);
163 }
164 template<typename Number>
165 Number sample_between(const Number& lower, const RealAlgebraicNumberThom<Number>& upper) {
166  return ThomEncoding<Number>::intermediatePoint(lower, upper.thom_encoding());
167 }
168 
169 template<typename Number>
170 Number floor(const RealAlgebraicNumberThom<Number>& n) {
171  return carl::floor(get_interval(n).lower());
172 }
173 template<typename Number>
174 Number ceil(const RealAlgebraicNumberThom<Number>& n) {
175  return carl::ceil(get_interval(n).upper());
176 }
177 
178 template<typename Number>
179 bool operator==(const RealAlgebraicNumberThom<Number>& lhs, const RealAlgebraicNumberThom<Number>& rhs) {
180  if (lhs.mContent.get() == rhs.mContent.get()) return true;
181  return lhs.thom_encoding() == rhs.thom_encoding();
182 }
183 
184 template<typename Number>
185 bool operator==(const RealAlgebraicNumberThom<Number>& lhs, const Number& rhs) {
186  return lhs.thom_encoding() == rhs;
187 }
188 
189 template<typename Number>
190 bool operator==(const Number& lhs, const RealAlgebraicNumberThom<Number>& rhs) {
191  return lhs == rhs.thom_encoding();
192 }
193 
194 template<typename Number>
195 bool operator<(const RealAlgebraicNumberThom<Number>& lhs, const RealAlgebraicNumberThom<Number>& rhs) {
196  if (lhs.mContent.get() == rhs.mContent.get()) return false;
197  return lhs.thom_encoding() < rhs.thom_encoding();
198 }
199 
200 template<typename Number>
201 bool operator<(const RealAlgebraicNumberThom<Number>& lhs, const Number& rhs) {
202  return lhs.thom_encoding() == rhs;
203 }
204 
205 template<typename Number>
206 bool operator<(const Number& lhs, const RealAlgebraicNumberThom<Number>& rhs) {
207  return lhs == rhs.thom_encoding();
208 }
209 
210 template<typename Num>
211 std::ostream& operator<<(std::ostream& os, const RealAlgebraicNumberThom<Num>& rhs) {
212  os << "(TE " << rhs.polynomial() << " in " << rhs.main_var() << ", " << rhs.sign_condition();
213  if (rhs.dimension() > 1) {
214  os << " OVER " << rhs.point();
215  }
216  os << ")";
217  return os;
218 }
219 
220 template<typename Number>
221 struct is_ran_type<RealAlgebraicNumberThom<Number>> {
222  static const bool value = true;
223 };
224 
225 }
226 
227 
228 namespace std {
229 template<typename Number>
230 struct hash<carl::RealAlgebraicNumberThom<Number>> {
231  std::size_t operator()(const carl::RealAlgebraicNumberThom<Number>& n) const {
232  return carl::hash_all(n.integer_below());
233  }
234 };
235 }
carl is the main namespace for the library.