carl  24.04
Computer ARithmetic Library
Term.tpp
Go to the documentation of this file.
1 /**
2  * @file Term.tpp
3  * @ingroup MultiRP
4  * @author Sebastian Junges
5  */
6 #pragma once
7 
8 #include <carl-arith/numbers/numbers.h>
9 #include "Term.h"
10 #include "functions/GCD_Monomial.h"
11 
12 namespace carl
13 {
14 
15 template<typename Coefficient>
16 Term<Coefficient>::Term(const Coefficient& c) :
17  mCoeff(c)
18 {
19  assert(this->is_consistent());
20 }
21 template<typename Coefficient>
22 Term<Coefficient>::Term(Variable v) :
23  mCoeff(carl::constant_one<Coefficient>().get()), mMonomial(createMonomial(v, uint(1)))
24 {
25  assert(this->is_consistent());
26 }
27 
28 template<typename Coefficient>
29 Term<Coefficient>::Term(Monomial::Arg m) :
30  mCoeff(carl::constant_one<Coefficient>().get()), mMonomial(std::move(m))
31 {
32  assert(this->is_consistent());
33 }
34 
35 template<typename Coefficient>
36 Term<Coefficient>::Term(Monomial::Arg&& m) :
37  mCoeff(carl::constant_one<Coefficient>().get()), mMonomial(std::move(m))
38 {
39  assert(this->is_consistent());
40 }
41 
42 template<typename Coefficient>
43 Term<Coefficient>::Term(const Coefficient& c, Monomial::Arg m) :
44  mCoeff(c), mMonomial(std::move(m))
45 {
46  assert(this->is_consistent());
47 }
48 
49 template<typename Coefficient>
50 Term<Coefficient>::Term(Coefficient&& c, Monomial::Arg&& m) :
51  mCoeff(std::move(c)), mMonomial(std::move(m))
52 {
53  assert(this->is_consistent());
54 }
55 
56 template<typename Coefficient>
57 Term<Coefficient>::Term(const Coefficient& c, Variable v, uint e):
58  mCoeff(c),
59  mMonomial(createMonomial(v,e))
60 {
61  assert(this->is_consistent());
62 }
63 
64 template<typename Coefficient>
65 Term<Coefficient> Term<Coefficient>::divide(const Coefficient& c) const
66 {
67  assert(!carl::is_zero(c));
68  return Term(mCoeff / c, mMonomial);
69 }
70 
71 template<typename Coefficient>
72 bool Term<Coefficient>::divide(const Coefficient& c, Term& res) const
73 {
74  assert(!carl::is_zero(c));
75  res.mCoeff = mCoeff / c;
76  res.mMonomial = mMonomial;
77  return true;
78 }
79 
80 template<typename Coefficient>
81 bool Term<Coefficient>::divide(Variable v, Term& res) const
82 {
83  if(mMonomial) {
84  if(mMonomial->divide(v, res.mMonomial)) {
85  res.mCoeff = mCoeff;
86  return true;
87  }
88  }
89  return false;
90 }
91 
92 template<typename Coefficient>
93 bool Term<Coefficient>::divide(const Monomial::Arg& m, Term& res) const
94 {
95  if (mMonomial) {
96  if (mMonomial->divide(m, res.mMonomial)) {
97  res.mCoeff = mCoeff;
98  return true;
99  }
100  return false;
101  }
102  res = *this;
103  return true;
104 }
105 
106 template<typename Coefficient>
107 bool Term<Coefficient>::divide(const Term& t, Term& res) const
108 {
109  assert(!carl::is_zero(t.mCoeff));
110  if (mMonomial) {
111  if (t.mMonomial) {
112  if (mMonomial->divide(t.mMonomial, res.mMonomial)) {
113  res.mCoeff = mCoeff / t.mCoeff;
114  return true;
115  }
116  return false;
117  }
118  res.mMonomial = mMonomial;
119  res.mCoeff = mCoeff / t.mCoeff;
120  return true;
121  }
122  if (t.mMonomial) return false;
123  res.mMonomial = nullptr;
124  res.mCoeff = mCoeff / t.mCoeff;
125  return true;
126 }
127 
128 template<typename Coefficient>
129 Term<Coefficient> Term<Coefficient>::calcLcmAndDivideBy(const Monomial::Arg& m) const
130 {
131  assert(carl::is_one(coeff()));
132  Monomial::Arg tmp = Monomial::calcLcmAndDivideBy(monomial(), m);
133  if(tmp == nullptr)
134  {
135  return Term(carl::constant_one<Coefficient>().get());
136  }
137  else
138  {
139  return Term(carl::constant_one<Coefficient>().get(), tmp);
140  }
141 
142 
143 }
144 
145 template<typename Coefficient>
146 bool Term<Coefficient>::sqrt(Term<Coefficient>& res) const {
147  Coefficient resCoeff;
148  if (!carl::sqrt_exact(this->coeff(), resCoeff)) return false;
149  if (this->monomial() == nullptr) {
150  res = Term(resCoeff);
151  return true;
152  }
153  Monomial::Arg resMonomial = this->monomial()->sqrt();
154  if (resMonomial == nullptr) return false;
155  res = Term(resCoeff, resMonomial);
156  return true;
157 }
158 
159 template<typename Coefficient>
160 template<typename C, EnableIf<is_field_type<C>>>
161 bool Term<Coefficient>::divisible(const Term& t) const {
162  if (this->monomial() == nullptr) return t.monomial() == nullptr;
163  if (t.monomial() == nullptr) return true;
164  return this->monomial()->divisible(t.monomial());
165 }
166 
167 template<typename Coefficient>
168 template<typename C, DisableIf<is_field_type<C>>>
169 bool Term<Coefficient>::divisible(const Term& t) const {
170  if (carl::remainder(this->coeff(), t.coeff()) != Coefficient(0)) return false;
171  if (this->monomial() == nullptr) return t.monomial() == nullptr;
172  if (t.monomial() == nullptr) return true;
173  return this->monomial()->divisible(t.monomial());
174 }
175 
176 template<typename Coeff>
177 bool operator==(const Term<Coeff>& lhs, const Term<Coeff>& rhs) {
178  if (lhs.coeff() != rhs.coeff()) return false;
179  return lhs.monomial() == rhs.monomial();
180 }
181 template<typename Coeff>
182 bool operator==(const Term<Coeff>& lhs, const Monomial::Arg& rhs) {
183  if (lhs.monomial() != rhs) return false;
184  return carl::is_one(lhs.coeff());
185 }
186 template<typename Coeff>
187 bool operator==(const Term<Coeff>& lhs, Variable rhs) {
188  if (lhs.monomial() != rhs) return false;
189  return carl::is_one(lhs.coeff());
190 }
191 template<typename Coeff>
192 bool operator==(const Term<Coeff>& lhs, const Coeff& rhs) {
193  return !lhs.monomial() && lhs.coeff() == rhs;
194 }
195 
196 template<typename Coeff>
197 bool operator<(const Term<Coeff>& lhs, const Term<Coeff>& rhs) {
198  if (lhs.monomial() == rhs.monomial()) return lhs.coeff() < rhs.coeff();
199  return lhs.monomial() < rhs.monomial();
200 }
201 
202 template<typename Coeff>
203 bool operator<(const Term<Coeff>& lhs, const Monomial::Arg& rhs) {
204  if (lhs.monomial() == rhs) return lhs.coeff() < carl::constant_one<Coeff>().get();
205  return lhs.monomial() < rhs;
206 }
207 
208 template<typename Coeff>
209 bool operator<(const Term<Coeff>& lhs, Variable rhs) {
210  if (lhs.monomial() == rhs) return lhs.coeff() < carl::constant_one<Coeff>().get();
211  return lhs.monomial() < rhs;
212 }
213 
214 template<typename Coeff>
215 bool operator<(const Term<Coeff>& lhs, const Coeff& rhs) {
216  if (lhs.monomial() == nullptr) return lhs.coeff() < rhs;
217  return false;
218 }
219 
220 template<typename Coeff>
221 bool operator<(const Monomial::Arg& lhs, const Term<Coeff>& rhs) {
222  if (lhs == rhs.monomial()) return carl::constant_one<Coeff>().get() < rhs.coeff();
223  return lhs < rhs.monomial();
224 }
225 
226 template<typename Coeff>
227 bool operator<(Variable lhs, const Term<Coeff>& rhs) {
228  if (lhs == rhs.monomial()) return carl::constant_one<Coeff>().get() < rhs.coeff();
229  return lhs < rhs.monomial();
230 }
231 
232 template<typename Coeff>
233 bool operator<(const Coeff& lhs, const Term<Coeff>& rhs) {
234  if (rhs.monomial() == nullptr) return lhs < rhs.coeff();
235  return true;
236 }
237 
238 template<typename Coeff>
239 const Term<Coeff> operator/(const Term<Coeff>& lhs, uint rhs)
240 {
241  return Term<Coeff>(lhs.coeff()/carl::from_int<Coeff>(rhs), lhs.monomial());
242 }
243 
244 template<typename Coeff>
245 std::ostream& operator<<(std::ostream& os, const Term<Coeff>& rhs) {
246  if (rhs.monomial()) {
247  if (!carl::is_one(rhs.coeff())) {
248  os << rhs.coeff() << "*";
249  }
250  os << rhs.monomial();
251  } else {
252  os << rhs.coeff();
253  }
254  return os;
255 }
256 
257 template<typename Coeff>
258 std::ostream& operator<<(std::ostream& os, const std::shared_ptr<const Term<Coeff>>& rhs)
259 {
260  if (rhs) return os << *rhs;
261  else return os << "nullptr";
262 }
263 
264 template<typename Coefficient>
265 bool Term<Coefficient>::is_consistent() const {
266  if (this->mMonomial) {
267  assert(!this->mMonomial->is_constant());
268  }
269  return true;
270 }
271 
272 }