4 * @author Sebastian Junges
8 #include <carl-arith/numbers/numbers.h>
10 #include "functions/GCD_Monomial.h"
15 template<typename Coefficient>
16 Term<Coefficient>::Term(const Coefficient& c) :
19 assert(this->is_consistent());
21 template<typename Coefficient>
22 Term<Coefficient>::Term(Variable v) :
23 mCoeff(carl::constant_one<Coefficient>().get()), mMonomial(createMonomial(v, uint(1)))
25 assert(this->is_consistent());
28 template<typename Coefficient>
29 Term<Coefficient>::Term(Monomial::Arg m) :
30 mCoeff(carl::constant_one<Coefficient>().get()), mMonomial(std::move(m))
32 assert(this->is_consistent());
35 template<typename Coefficient>
36 Term<Coefficient>::Term(Monomial::Arg&& m) :
37 mCoeff(carl::constant_one<Coefficient>().get()), mMonomial(std::move(m))
39 assert(this->is_consistent());
42 template<typename Coefficient>
43 Term<Coefficient>::Term(const Coefficient& c, Monomial::Arg m) :
44 mCoeff(c), mMonomial(std::move(m))
46 assert(this->is_consistent());
49 template<typename Coefficient>
50 Term<Coefficient>::Term(Coefficient&& c, Monomial::Arg&& m) :
51 mCoeff(std::move(c)), mMonomial(std::move(m))
53 assert(this->is_consistent());
56 template<typename Coefficient>
57 Term<Coefficient>::Term(const Coefficient& c, Variable v, uint e):
59 mMonomial(createMonomial(v,e))
61 assert(this->is_consistent());
64 template<typename Coefficient>
65 Term<Coefficient> Term<Coefficient>::divide(const Coefficient& c) const
67 assert(!carl::is_zero(c));
68 return Term(mCoeff / c, mMonomial);
71 template<typename Coefficient>
72 bool Term<Coefficient>::divide(const Coefficient& c, Term& res) const
74 assert(!carl::is_zero(c));
75 res.mCoeff = mCoeff / c;
76 res.mMonomial = mMonomial;
80 template<typename Coefficient>
81 bool Term<Coefficient>::divide(Variable v, Term& res) const
84 if(mMonomial->divide(v, res.mMonomial)) {
92 template<typename Coefficient>
93 bool Term<Coefficient>::divide(const Monomial::Arg& m, Term& res) const
96 if (mMonomial->divide(m, res.mMonomial)) {
106 template<typename Coefficient>
107 bool Term<Coefficient>::divide(const Term& t, Term& res) const
109 assert(!carl::is_zero(t.mCoeff));
112 if (mMonomial->divide(t.mMonomial, res.mMonomial)) {
113 res.mCoeff = mCoeff / t.mCoeff;
118 res.mMonomial = mMonomial;
119 res.mCoeff = mCoeff / t.mCoeff;
122 if (t.mMonomial) return false;
123 res.mMonomial = nullptr;
124 res.mCoeff = mCoeff / t.mCoeff;
128 template<typename Coefficient>
129 Term<Coefficient> Term<Coefficient>::calcLcmAndDivideBy(const Monomial::Arg& m) const
131 assert(carl::is_one(coeff()));
132 Monomial::Arg tmp = Monomial::calcLcmAndDivideBy(monomial(), m);
135 return Term(carl::constant_one<Coefficient>().get());
139 return Term(carl::constant_one<Coefficient>().get(), tmp);
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);
153 Monomial::Arg resMonomial = this->monomial()->sqrt();
154 if (resMonomial == nullptr) return false;
155 res = Term(resCoeff, resMonomial);
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());
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());
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();
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());
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());
191 template<typename Coeff>
192 bool operator==(const Term<Coeff>& lhs, const Coeff& rhs) {
193 return !lhs.monomial() && lhs.coeff() == rhs;
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();
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;
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;
214 template<typename Coeff>
215 bool operator<(const Term<Coeff>& lhs, const Coeff& rhs) {
216 if (lhs.monomial() == nullptr) return lhs.coeff() < rhs;
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();
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();
232 template<typename Coeff>
233 bool operator<(const Coeff& lhs, const Term<Coeff>& rhs) {
234 if (rhs.monomial() == nullptr) return lhs < rhs.coeff();
238 template<typename Coeff>
239 const Term<Coeff> operator/(const Term<Coeff>& lhs, uint rhs)
241 return Term<Coeff>(lhs.coeff()/carl::from_int<Coeff>(rhs), lhs.monomial());
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() << "*";
250 os << rhs.monomial();
257 template<typename Coeff>
258 std::ostream& operator<<(std::ostream& os, const std::shared_ptr<const Term<Coeff>>& rhs)
260 if (rhs) return os << *rhs;
261 else return os << "nullptr";
264 template<typename Coefficient>
265 bool Term<Coefficient>::is_consistent() const {
266 if (this->mMonomial) {
267 assert(!this->mMonomial->is_constant());