logic.cpp
1 #include <symengine/logic.h>
2 
3 namespace SymEngine
4 {
5 
6 RCP<const Boolean> Boolean::logical_not() const
7 {
8  return make_rcp<const Not>(this->rcp_from_this_cast<const Boolean>());
9 }
10 
11 BooleanAtom::BooleanAtom(bool b)
12  : b_{b} {SYMENGINE_ASSIGN_TYPEID()}
13 
14  hash_t BooleanAtom::__hash__() const
15 {
16  hash_t seed = SYMENGINE_BOOLEAN_ATOM;
17  if (b_)
18  ++seed;
19  return seed;
20 }
21 bool BooleanAtom::get_val() const
22 {
23  return b_;
24 }
25 
26 vec_basic BooleanAtom::get_args() const
27 {
28  return {};
29 }
30 
31 bool BooleanAtom::__eq__(const Basic &o) const
32 {
33  return is_a<BooleanAtom>(o)
34  and get_val() == down_cast<const BooleanAtom &>(o).get_val();
35 }
36 
37 int BooleanAtom::compare(const Basic &o) const
38 {
39  SYMENGINE_ASSERT(is_a<BooleanAtom>(o))
40  bool ob = down_cast<const BooleanAtom &>(o).get_val();
41  if (get_val()) {
42  return (ob) ? 0 : 1;
43  } else {
44  return (ob) ? -1 : 0;
45  }
46 }
47 
48 RCP<const Boolean> BooleanAtom::logical_not() const
49 {
50  return boolean(not this->get_val());
51 }
52 
53 RCP<const BooleanAtom> boolTrue = make_rcp<BooleanAtom>(true);
54 RCP<const BooleanAtom> boolFalse = make_rcp<BooleanAtom>(false);
55 
56 Contains::Contains(const RCP<const Basic> &expr, const RCP<const Set> &set)
57  : expr_{expr}, set_{set} {SYMENGINE_ASSIGN_TYPEID()}
58 
59  hash_t Contains::__hash__() const
60 {
61  hash_t seed = SYMENGINE_CONTAINS;
62  hash_combine<Basic>(seed, *expr_);
63  hash_combine<Basic>(seed, *set_);
64  return seed;
65 }
66 
67 RCP<const Basic> Contains::get_expr() const
68 {
69  return expr_;
70 }
71 
72 RCP<const Set> Contains::get_set() const
73 {
74  return set_;
75 }
76 
78 {
79  vec_basic v;
80  v.push_back(expr_);
81  v.push_back(set_);
82  return v;
83 }
84 
85 bool Contains::__eq__(const Basic &o) const
86 {
87  return is_a<Contains>(o)
88  and unified_eq(get_expr(), down_cast<const Contains &>(o).get_expr())
89  and unified_eq(get_set(), down_cast<const Contains &>(o).get_set());
90 }
91 
92 int Contains::compare(const Basic &o) const
93 {
94  SYMENGINE_ASSERT(is_a<Contains>(o))
95  const Contains &c = down_cast<const Contains &>(o);
96  int cmp = unified_compare(get_expr(), c.get_expr());
97  if (cmp != 0)
98  return cmp;
99  return unified_compare(get_set(), c.get_set());
100 }
101 
102 RCP<const Basic> Contains::create(const RCP<const Basic> &lhs,
103  const RCP<const Set> &rhs) const
104 {
105  return contains(lhs, rhs);
106 }
107 
108 RCP<const Boolean> contains(const RCP<const Basic> &expr,
109  const RCP<const Set> &set)
110 {
111  if (is_a_Number(*expr) or is_a_Set(*expr)) {
112  return set->contains(expr);
113  } else {
114  return make_rcp<Contains>(expr, set);
115  }
116 }
117 
119  : vec_(vec){SYMENGINE_ASSIGN_TYPEID()}
120 
121  hash_t Piecewise::__hash__() const
122 {
123  hash_t seed = this->get_type_code();
124  for (auto &p : vec_) {
125  hash_combine<Basic>(seed, *p.first);
126  hash_combine<Basic>(seed, *p.second);
127  }
128  return seed;
129 }
130 
131 const PiecewiseVec &Piecewise::get_vec() const
132 {
133  return vec_;
134 }
135 
137 {
138  vec_basic v;
139  for (auto &p : vec_) {
140  v.push_back(p.first);
141  v.push_back(p.second);
142  }
143  return v;
144 }
145 
146 bool Piecewise::__eq__(const Basic &o) const
147 {
148  return is_a<Piecewise>(o)
149  and unified_eq(get_vec(), down_cast<const Piecewise &>(o).get_vec());
150 }
151 
152 int Piecewise::compare(const Basic &o) const
153 {
154  SYMENGINE_ASSERT(is_same_type(*this, o))
155  RCP<const Piecewise> t = o.rcp_from_this_cast<Piecewise>();
156  return unified_compare(get_vec(), t->get_vec());
157 }
158 
159 And::And(const set_boolean &s) : container_{s}
160 {
161  SYMENGINE_ASSIGN_TYPEID()
162  SYMENGINE_ASSERT(is_canonical(s));
163 }
164 
165 hash_t And::__hash__() const
166 {
167  hash_t seed = SYMENGINE_AND;
168  for (const auto &a : container_)
169  hash_combine<Basic>(seed, *a);
170  return seed;
171 }
172 
174 {
175  vec_basic v(container_.begin(), container_.end());
176  return v;
177 }
178 
179 bool And::__eq__(const Basic &o) const
180 {
181  return is_a<And>(o)
182  and unified_eq(container_,
183  down_cast<const And &>(o).get_container());
184 }
185 
186 int And::compare(const Basic &o) const
187 {
188  SYMENGINE_ASSERT(is_a<And>(o))
189  return unified_compare(container_,
190  down_cast<const And &>(o).get_container());
191 }
192 
193 bool And::is_canonical(const set_boolean &container_)
194 {
195  if (container_.size() >= 2) {
196  for (auto &a : container_) {
197  if (is_a<BooleanAtom>(*a) or is_a<And>(*a))
198  return false;
199  if (container_.find(SymEngine::logical_not(a)) != container_.end())
200  return false;
201  }
202  return true;
203  }
204  return false;
205 }
206 
207 const set_boolean &And::get_container() const
208 {
209  return container_;
210 }
211 
212 RCP<const Basic> And::create(const set_boolean &a) const
213 {
214  return logical_and(a);
215 }
216 
217 RCP<const Boolean> And::logical_not() const
218 {
219  auto container = this->get_container();
220  set_boolean cont;
221  for (auto &a : container) {
222  cont.insert(SymEngine::logical_not(a));
223  }
224  return make_rcp<const Or>(cont);
225 }
226 
227 Or::Or(const set_boolean &s) : container_{s}
228 {
229  SYMENGINE_ASSIGN_TYPEID()
230  SYMENGINE_ASSERT(is_canonical(s));
231 }
232 
233 hash_t Or::__hash__() const
234 {
235  hash_t seed = SYMENGINE_OR;
236  for (const auto &a : container_)
237  hash_combine<Basic>(seed, *a);
238  return seed;
239 }
240 
242 {
243  vec_basic v(container_.begin(), container_.end());
244  return v;
245 }
246 
247 bool Or::__eq__(const Basic &o) const
248 {
249  return is_a<Or>(o)
250  and unified_eq(container_, down_cast<const Or &>(o).get_container());
251 }
252 
253 int Or::compare(const Basic &o) const
254 {
255  SYMENGINE_ASSERT(is_a<Or>(o))
256  return unified_compare(container_,
257  down_cast<const Or &>(o).get_container());
258 }
259 
260 bool Or::is_canonical(const set_boolean &container_)
261 {
262  if (container_.size() >= 2) {
263  for (auto &a : container_) {
264  if (is_a<BooleanAtom>(*a) or is_a<Or>(*a))
265  return false;
266  if (container_.find(SymEngine::logical_not(a)) != container_.end())
267  return false;
268  }
269  return true;
270  }
271  return false;
272 }
273 
274 const set_boolean &Or::get_container() const
275 {
276  return container_;
277 }
278 
279 RCP<const Boolean> Or::logical_not() const
280 {
281  auto container = this->get_container();
282  set_boolean cont;
283  for (auto &a : container) {
284  cont.insert(SymEngine::logical_not(a));
285  }
286  return make_rcp<const And>(cont);
287 }
288 
289 Not::Not(const RCP<const Boolean> &in) : arg_{in}
290 {
291  SYMENGINE_ASSIGN_TYPEID()
292  SYMENGINE_ASSERT(is_canonical(in));
293 }
294 
295 hash_t Not::__hash__() const
296 {
297  hash_t seed = SYMENGINE_NOT;
298  hash_combine<Basic>(seed, *arg_);
299  return seed;
300 }
301 
303 {
304  vec_basic v;
305  v.push_back(arg_);
306  return v;
307 }
308 
309 bool Not::__eq__(const Basic &o) const
310 {
311  return is_a<Not>(o) and eq(*arg_, *down_cast<const Not &>(o).get_arg());
312 }
313 
314 int Not::compare(const Basic &o) const
315 {
316  SYMENGINE_ASSERT(is_a<Not>(o))
317  return arg_->__cmp__(*down_cast<const Not &>(o).get_arg());
318 }
319 
320 bool Not::is_canonical(const RCP<const Boolean> &in)
321 {
322  if (is_a<BooleanAtom>(*in) or is_a<Not>(*in))
323  return false;
324  return true;
325 }
326 
327 RCP<const Boolean> Not::get_arg() const
328 {
329  return arg_;
330 }
331 
332 RCP<const Boolean> Not::logical_not() const
333 {
334  return this->get_arg();
335 }
336 
337 Xor::Xor(const vec_boolean &s) : container_{s}
338 {
339  SYMENGINE_ASSIGN_TYPEID()
340  SYMENGINE_ASSERT(is_canonical(s));
341 }
342 
343 hash_t Xor::__hash__() const
344 {
345  hash_t seed = SYMENGINE_XOR;
346  for (const auto &a : container_)
347  hash_combine<Basic>(seed, *a);
348  return seed;
349 }
350 
352 {
353  vec_basic v(container_.begin(), container_.end());
354  return v;
355 }
356 
357 bool Xor::__eq__(const Basic &o) const
358 {
359  return is_a<Xor>(o)
360  and unified_eq(container_,
361  down_cast<const Xor &>(o).get_container());
362 }
363 
364 int Xor::compare(const Basic &o) const
365 {
366  SYMENGINE_ASSERT(is_a<Xor>(o))
367  return unified_compare(container_,
368  down_cast<const Xor &>(o).get_container());
369 }
370 
371 bool Xor::is_canonical(const vec_boolean &container_)
372 {
373  if (container_.size() >= 2) {
374  set_boolean args;
375  for (auto &a : container_) {
376  if (is_a<BooleanAtom>(*a) or is_a<Xor>(*a)) {
377  return false;
378  }
379  if (args.find(a) != args.end()) {
380  return false;
381  }
382  if (args.find(SymEngine::logical_not(a)) != args.end()) {
383  return false;
384  }
385  args.insert(a);
386  }
387  return true;
388  }
389  return false;
390 }
391 
392 const vec_boolean &Xor::get_container() const
393 {
394  return container_;
395 }
396 
397 const vec_boolean get_vec_from_set(const set_boolean &s)
398 {
399  vec_boolean v(s.begin(), s.end());
400  return v;
401 }
402 
403 template <typename caller>
404 RCP<const Boolean> and_or(const set_boolean &s, const bool &op_x_notx)
405 {
406  set_boolean args;
407  for (auto &a : s) {
408  if (is_a<BooleanAtom>(*a)) {
409  auto val = down_cast<const BooleanAtom &>(*a).get_val();
410  if (val == op_x_notx)
411  return boolean(op_x_notx);
412  else
413  continue;
414  }
415  if (is_a<caller>(*a)) {
416  const caller &to_insert = down_cast<const caller &>(*a);
417  auto container = to_insert.get_container();
418  args.insert(container.begin(), container.end());
419  continue;
420  }
421  args.insert(a);
422  }
423  for (auto &a : args) {
424  if (args.find(logical_not(a)) != args.end())
425  return boolean(op_x_notx);
426  }
427  if (not op_x_notx) {
428  for (auto it = args.begin(); it != args.end(); it++) {
429  if (is_a<Contains>(**it)
430  and is_a<Symbol>(*down_cast<const Contains &>(**it).get_expr())
431  and is_a<FiniteSet>(
432  *down_cast<const Contains &>(**it).get_set())) {
433  auto sym = down_cast<const Contains &>(**it).get_expr();
434  // iterate through args and check for the condition that
435  // defines the domain of sym.
436  // Simplify if that set is a FiniteSet.
437  set_basic present;
438  auto fset = down_cast<const FiniteSet &>(
439  *down_cast<const Contains &>(**it).get_set())
440  .get_container();
441  // If there exists atleast one number/constant, then only we can
442  // simplify.
443  bool check = false;
444  for (const auto &elem : fset) {
445  if (is_a_Number(*elem) or is_a<Constant>(*elem)) {
446  check = true;
447  break;
448  }
449  }
450  if (!check)
451  break;
452  auto restCont = args;
453  restCont.erase(*it);
454  auto restCond = logical_and(restCont);
455  map_basic_basic d;
456  bool symexists = false;
457  for (const auto &fselement : fset) {
458  d[sym] = fselement;
459  auto contain = restCond->subs(d);
460  if (eq(*contain, *boolean(true))) {
461  present.insert(fselement);
462  } else if (not eq(*contain, *boolean(false))) {
463  present.insert(fselement);
464  symexists = true;
465  }
466  d.clear();
467  }
468  if (not symexists) {
469  // if there are no symbols, then this reduces to a
470  // Contains(sym,finiteset())
471  return finiteset(present)->contains(sym);
472  } else if (present.size() != fset.size()) {
473  restCond = logical_and(
474  {finiteset(present)->contains(sym), restCond});
475  return restCond;
476  } else {
477  // if present is same as fset, then return object of type
478  // `And`.
479  break;
480  }
481  }
482  }
483  }
484  if (args.size() == 1)
485  return *(args.begin());
486  else if (args.size() == 0)
487  return boolean(not op_x_notx);
488  return make_rcp<const caller>(args);
489 }
490 
491 RCP<const Boolean> logical_not(const RCP<const Boolean> &s)
492 {
493  return s->logical_not();
494 }
495 
496 RCP<const Boolean> logical_xor(const vec_boolean &s)
497 {
498  set_boolean args;
499  int nots = 0;
500  for (auto &a : s) {
501  if (is_a<BooleanAtom>(*a)) {
502  auto val = down_cast<const BooleanAtom &>(*a).get_val();
503  if (val == true) {
504  nots++;
505  }
506  continue;
507  } else if (is_a<Xor>(*a)) {
508  auto container = down_cast<const Xor &>(*a).get_container();
509  for (auto &aa : container) {
510  if (args.find(aa) != args.end()) {
511  args.erase(aa);
512  } else {
513  auto pos = args.find(logical_not(aa));
514  if (pos != args.end()) {
515  args.erase(pos);
516  nots++;
517  } else {
518  args.insert(aa);
519  }
520  }
521  }
522  continue;
523  }
524  if (args.find(a) != args.end()) {
525  args.erase(a);
526  } else {
527  auto pos = args.find(logical_not(a));
528  if (pos != args.end()) {
529  args.erase(pos);
530  nots++;
531  } else {
532  args.insert(a);
533  }
534  }
535  }
536 
537  if (nots % 2 == 0) {
538  if (args.size() == 0) {
539  return boolFalse;
540  } else if (args.size() == 1) {
541  return *args.begin();
542  } else {
543  return make_rcp<const Xor>(get_vec_from_set(args));
544  }
545  } else {
546  if (args.size() == 0) {
547  return boolTrue;
548  } else if (args.size() == 1) {
549  return logical_not(*args.begin());
550  } else {
551  return make_rcp<const Not>(
552  make_rcp<const Xor>(get_vec_from_set(args)));
553  }
554  }
555 }
556 
557 Relational::Relational(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
558  : TwoArgBasic<Boolean>(lhs, rhs)
559 {
560 }
561 
562 inline bool Relational::is_canonical(const RCP<const Basic> &lhs,
563  const RCP<const Basic> &rhs) const
564 {
565  if (eq(*lhs, *rhs))
566  return false;
567  if (is_a_Number(*lhs) and is_a_Number(*rhs))
568  return false;
569  if (is_a<BooleanAtom>(*lhs) and is_a<BooleanAtom>(*rhs))
570  return false;
571  return true;
572 }
573 
574 Equality::Equality(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
575  : Relational(lhs, rhs)
576 {
577  SYMENGINE_ASSIGN_TYPEID();
578  SYMENGINE_ASSERT(is_canonical(lhs, rhs));
579 }
580 
581 RCP<const Basic> Equality::create(const RCP<const Basic> &lhs,
582  const RCP<const Basic> &rhs) const
583 {
584  return Eq(lhs, rhs);
585 }
586 
587 RCP<const Boolean> Equality::logical_not() const
588 {
589  return make_rcp<const Unequality>(get_arg1(), get_arg2());
590 }
591 
592 RCP<const Boolean> Eq(const RCP<const Basic> &lhs)
593 {
594  return Eq(lhs, zero);
595 }
596 
597 RCP<const Boolean> Eq(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
598 {
599  if (is_a<NaN>(*lhs) or is_a<NaN>(*rhs))
600  return boolean(false);
601  bool b = eq(*lhs, *rhs);
602  if (b) {
603  return boolean(true);
604  } else {
605  if ((is_a_Number(*lhs) and is_a_Number(*rhs))
606  or (is_a<BooleanAtom>(*lhs) and is_a<BooleanAtom>(*rhs)))
607  return boolean(false);
608  if (lhs->__cmp__(*rhs) == 1)
609  return make_rcp<const Equality>(rhs, lhs);
610  return make_rcp<Equality>(lhs, rhs);
611  }
612 }
613 
614 Unequality::Unequality(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
615  : Relational(lhs, rhs)
616 {
617  SYMENGINE_ASSIGN_TYPEID();
618  SYMENGINE_ASSERT(is_canonical(lhs, rhs));
619 }
620 
621 RCP<const Basic> Unequality::create(const RCP<const Basic> &lhs,
622  const RCP<const Basic> &rhs) const
623 {
624  return Ne(lhs, rhs);
625 }
626 
627 RCP<const Boolean> Unequality::logical_not() const
628 {
629  return make_rcp<const Equality>(get_arg1(), get_arg2());
630 }
631 
632 RCP<const Boolean> Ne(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
633 {
634  RCP<const Basic> r = Eq(lhs, rhs);
635  if (is_a<BooleanAtom>(*r)) {
636  return logical_not(rcp_static_cast<const BooleanAtom>(r));
637  }
638  if (lhs->__cmp__(*rhs) == 1)
639  return make_rcp<const Unequality>(rhs, lhs);
640  return make_rcp<Unequality>(lhs, rhs);
641 }
642 
643 LessThan::LessThan(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
644  : Relational(lhs, rhs)
645 {
646  SYMENGINE_ASSIGN_TYPEID();
647  SYMENGINE_ASSERT(is_canonical(lhs, rhs));
648 }
649 
650 RCP<const Basic> LessThan::create(const RCP<const Basic> &lhs,
651  const RCP<const Basic> &rhs) const
652 {
653  return Le(lhs, rhs);
654 }
655 
656 RCP<const Boolean> LessThan::logical_not() const
657 {
658  return make_rcp<const StrictLessThan>(get_arg2(), get_arg1());
659 }
660 
661 RCP<const Boolean> Le(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
662 {
663  if (is_a_Complex(*lhs) or is_a_Complex(*rhs))
664  throw SymEngineException("Invalid comparison of complex numbers.");
665  if (is_a<NaN>(*lhs) or is_a<NaN>(*rhs))
666  throw SymEngineException("Invalid NaN comparison.");
667  if (eq(*lhs, *ComplexInf) or eq(*rhs, *ComplexInf))
668  throw SymEngineException("Invalid comparison of complex zoo.");
669  if (is_a<BooleanAtom>(*lhs) or is_a<BooleanAtom>(*rhs))
670  throw SymEngineException("Invalid comparison of Boolean objects.");
671  if (eq(*lhs, *rhs))
672  return boolean(true);
673  if (is_a_Number(*lhs) and is_a_Number(*rhs)) {
674  RCP<const Number> s = down_cast<const Number &>(*lhs).sub(
675  down_cast<const Number &>(*rhs));
676  if (s->is_negative())
677  return boolean(true);
678  return boolean(false);
679  }
680  return make_rcp<const LessThan>(lhs, rhs);
681 }
682 
683 RCP<const Boolean> Ge(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
684 {
685  return Le(rhs, lhs);
686 }
687 
688 StrictLessThan::StrictLessThan(const RCP<const Basic> &lhs,
689  const RCP<const Basic> &rhs)
690  : Relational(lhs, rhs)
691 {
692  SYMENGINE_ASSIGN_TYPEID();
693  SYMENGINE_ASSERT(is_canonical(lhs, rhs));
694 }
695 
696 RCP<const Basic> StrictLessThan::create(const RCP<const Basic> &lhs,
697  const RCP<const Basic> &rhs) const
698 {
699  return Lt(lhs, rhs);
700 }
701 
702 RCP<const Boolean> StrictLessThan::logical_not() const
703 {
704  return make_rcp<const LessThan>(get_arg2(), get_arg1());
705 }
706 
707 RCP<const Boolean> Lt(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
708 {
709  if (is_a_Complex(*lhs) or is_a_Complex(*rhs))
710  throw SymEngineException("Invalid comparison of complex numbers.");
711  if (is_a<NaN>(*lhs) or is_a<NaN>(*rhs))
712  throw SymEngineException("Invalid NaN comparison.");
713  if (eq(*lhs, *ComplexInf) or eq(*rhs, *ComplexInf))
714  throw SymEngineException("Invalid comparison of complex zoo.");
715  if (is_a<BooleanAtom>(*lhs) or is_a<BooleanAtom>(*rhs))
716  throw SymEngineException("Invalid comparison of Boolean objects.");
717  if (eq(*lhs, *rhs))
718  return boolean(false);
719  if (is_a_Number(*lhs) and is_a_Number(*rhs)) {
720  RCP<const Number> s = down_cast<const Number &>(*lhs).sub(
721  down_cast<const Number &>(*rhs));
722  if (s->is_negative())
723  return boolean(true);
724  return boolean(false);
725  }
726  return make_rcp<const StrictLessThan>(lhs, rhs);
727 }
728 
729 RCP<const Boolean> Gt(const RCP<const Basic> &lhs, const RCP<const Basic> &rhs)
730 {
731  return Lt(rhs, lhs);
732 }
733 
734 RCP<const Boolean> logical_and(const set_boolean &s)
735 {
736  return and_or<And>(s, false);
737 }
738 
739 RCP<const Boolean> logical_nand(const set_boolean &s)
740 {
741  RCP<const Boolean> a = logical_and(s);
742  return logical_not(a);
743 }
744 
745 RCP<const Boolean> logical_or(const set_boolean &s)
746 {
747  return and_or<Or>(s, true);
748 }
749 
750 RCP<const Boolean> logical_nor(const set_boolean &s)
751 {
752  return logical_not(and_or<Or>(s, true));
753 }
754 
755 RCP<const Boolean> logical_xnor(const vec_boolean &s)
756 {
757  return logical_not(logical_xor(s));
758 }
759 } // namespace SymEngine
virtual vec_basic get_args() const
Returns the list of arguments.
Definition: logic.cpp:173
virtual int compare(const Basic &o) const
Structural equality comparator.
Definition: logic.cpp:186
virtual bool __eq__(const Basic &o) const
Test equality.
Definition: logic.cpp:179
hash_t __hash__() const
Definition: logic.cpp:165
The lowest unit of symbolic representation.
Definition: basic.h:95
virtual vec_basic get_args() const
Returns the list of arguments.
Definition: logic.cpp:77
virtual int compare(const Basic &o) const
Structural equality comparator.
Definition: logic.cpp:92
hash_t __hash__() const
Definition: logic.cpp:59
virtual bool __eq__(const Basic &o) const
Test equality.
Definition: logic.cpp:85
RCP< const T2 > rcp_from_this_cast() const
Get RCP<T2> pointer to self (it will cast the pointer to T2)
virtual RCP< const Basic > create(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs) const
Method to construct classes with canonicalization.
Definition: logic.cpp:581
virtual bool __eq__(const Basic &o) const
Test equality.
Definition: logic.cpp:309
hash_t __hash__() const
Definition: logic.cpp:295
virtual int compare(const Basic &o) const
Structural equality comparator.
Definition: logic.cpp:314
virtual vec_basic get_args() const
Returns the list of arguments.
Definition: logic.cpp:302
hash_t __hash__() const
Definition: logic.cpp:233
virtual bool __eq__(const Basic &o) const
Test equality.
Definition: logic.cpp:247
virtual vec_basic get_args() const
Returns the list of arguments.
Definition: logic.cpp:241
virtual int compare(const Basic &o) const
Structural equality comparator.
Definition: logic.cpp:253
Piecewise(PiecewiseVec &&vec)
Constructor.
Definition: logic.cpp:118
virtual int compare(const Basic &o) const
Structural equality comparator.
Definition: logic.cpp:152
hash_t __hash__() const
Definition: logic.cpp:121
virtual bool __eq__(const Basic &o) const
Test equality.
Definition: logic.cpp:146
virtual vec_basic get_args() const
Returns the list of arguments.
Definition: logic.cpp:136
Relational(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs)
Constructor.
Definition: logic.cpp:557
virtual bool is_canonical(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs) const
Definition: logic.cpp:562
RCP< const Basic > get_arg1() const
Definition: functions.h:91
RCP< const Basic > get_arg2() const
Definition: functions.h:96
virtual int compare(const Basic &o) const
Definition: logic.cpp:364
virtual vec_basic get_args() const
Returns the list of arguments.
Definition: logic.cpp:351
virtual bool __eq__(const Basic &o) const
Test equality.
Definition: logic.cpp:357
T end(T... args)
T erase(T... args)
T find(T... args)
T insert(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
bool is_a_Number(const Basic &b)
Definition: number.h:130
RCP< const Boolean > Ge(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs)
Convenience function returning LessThan object.
Definition: logic.cpp:683
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
RCP< const Boolean > Lt(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs)
Returns the canonicalized StrictLessThan object from the arguments.
Definition: logic.cpp:707
RCP< const Boolean > Le(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs)
Returns the canonicalized LessThan object from the arguments.
Definition: logic.cpp:661
bool is_same_type(const Basic &a, const Basic &b)
Returns true if a and b are exactly the same type T.
Definition: basic-inl.h:47
RCP< const Boolean > Eq(const RCP< const Basic > &lhs)
Returns the canonicalized Equality object from a single argument.
Definition: logic.cpp:592
RCP< const Set > finiteset(const set_basic &container)
Definition: sets.h:502
int unified_compare(const T &a, const T &b)
Definition: dict.h:205
bool is_a_Complex(const Basic &b)
Definition: complex.h:24
RCP< const Boolean > Gt(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs)
Convenience function returning StrictLessThan object.
Definition: logic.cpp:729
RCP< const Boolean > Ne(const RCP< const Basic > &lhs, const RCP< const Basic > &rhs)
Returns the canonicalized Unequality object from the arguments.
Definition: logic.cpp:632
T push_back(T... args)
T size(T... args)