Lattice land propagators completion library
Loading...
Searching...
No Matches
terms.hpp
Go to the documentation of this file.
1// Copyright 2021 Pierre Talbot
2
3#ifndef LALA_PC_TERMS_HPP
4#define LALA_PC_TERMS_HPP
5
6#include "battery/vector.hpp"
7#include "lala/universes/arith_bound.hpp"
8
9namespace lala {
10namespace pc {
11
12template <class AD, class Allocator>
13class Term;
14
15template <class AD, class Allocator>
16class Formula;
17
18template <class AD>
19class Constant {
20public:
21 using A = AD;
22 using U = typename A::local_universe;
23
24private:
25 U k;
26
27public:
28 CUDA Constant(U&& k) : k(k) {}
29 Constant(Constant<A>&& other) = default;
30
31 template <class A2, class Alloc>
32 CUDA Constant(const Constant<A2>& other, const Alloc&): k(other.k) {}
33
34 CUDA bool embed(A&, const U&) const { return false; }
35 CUDA void project(const A&, U& r) const { r.meet(k); }
36 CUDA void print(const A&) const { ::battery::print(k); }
37 template <class Env, class Allocator = typename Env::allocator_type>
38 CUDA TFormula<Allocator> deinterpret(const A&, const Env&, AType, Allocator allocator = Allocator()) const {
39 return k.template deinterpret<TFormula<Allocator>>();
40 }
41 CUDA size_t length() const { return 1; }
42
43 template <class A2>
44 friend class Constant;
45};
46
47template <class AD>
48class Variable {
49public:
50 using A = AD;
51 using U = typename A::local_universe;
52
53private:
54 AVar avar;
55
56public:
57 CUDA Variable() {}
58 CUDA Variable(AVar avar) : avar(avar) {}
59 Variable(Variable<A>&& other) = default;
60 Variable<A>& operator=(Variable<A>&& other) = default;
61
62 template <class A2, class Alloc>
63 CUDA Variable(const Variable<A2>& other, const Alloc&): avar(other.avar) {}
64
65 CUDA bool embed(A& a, const U& u) const {
66 return a.embed(avar, u);
67 }
68
69 CUDA void project(const A& a, U& r) const {
70 return a.project(avar, r);
71 }
72
73 CUDA void print(const A& a) const { printf("(%d,%d)", avar.aty(), avar.vid()); }
74
75 template <class Env, class Allocator = typename Env::allocator_type>
76 CUDA TFormula<Allocator> deinterpret(const A&, const Env& env, AType, Allocator allocator = Allocator()) const {
77 using F = TFormula<Allocator>;
78 return F::make_lvar(avar.aty(), LVar<Allocator>(env.name_of(avar), allocator));
79 }
80
81 CUDA size_t length() const { return 1; }
82
83 template <class A2>
84 friend class Variable;
85};
86
87template<class Universe>
88struct NegOp {
89 using U = Universe;
90
91 CUDA static void project(const U& a, U& r) {
92 r.project(NEG, a);
93 }
94
95 CUDA static void residual(const U& a, U& r) {
96 project(a, r); // negation is its own residual.
97 }
98
99 static constexpr bool function_symbol = false;
100 CUDA static const char* symbol() { return "-"; }
101 CUDA static Sig sig() { return NEG; }
102};
103
104template<class Universe>
105struct AbsOp {
106 using U = Universe;
107
108 CUDA static void project(const U& a, U& r) {
109 r.project(ABS, a);
110 }
111
112 CUDA static void residual(const U& a, U& r) {
113 r.meet(fjoin(a, project_fun(NEG, a)));
114 }
115
116 static constexpr bool function_symbol = true;
117 CUDA static const char* symbol() { return "abs"; }
118 CUDA static Sig sig() { return ABS; }
119};
120
121template <class AD, class UnaryOp, class Allocator>
122class Unary {
123public:
124 using allocator_type = Allocator;
125 using A = AD;
126 using U = typename A::local_universe;
128
129 template <class A2, class UnaryOp2, class Alloc2>
130 friend class Unary;
131
132private:
134 battery::unique_ptr<sub_type, allocator_type> x_term;
135
136 CUDA INLINE const sub_type& x() const {
137 return *x_term;
138 }
139
140public:
141 CUDA Unary(battery::unique_ptr<sub_type, allocator_type>&& x_term): x_term(std::move(x_term)) {}
142 CUDA Unary(this_type&& other): Unary(std::move(other.x_term)) {}
143
144 template <class A2, class UnaryOp2, class Alloc2>
145 CUDA Unary(const Unary<A2, UnaryOp2, Alloc2>& other, const allocator_type& allocator):
146 x_term(battery::allocate_unique<sub_type>(allocator, *other.x_term))
147 {}
148
149 CUDA bool embed(A& a, const U& u) const {
150 U tmp{};
151 UnaryOp::residual(u, tmp);
152 return x().embed(a, tmp);
153 }
154
155 CUDA void project(const A& a, U& r) const {
156 U tmp{};
157 x().project(a, tmp);
158 UnaryOp::project(tmp, r);
159 }
160
161 CUDA NI void print(const A& a) const {
162 printf("%s", UnaryOp::symbol());
163 if constexpr(UnaryOp::function_symbol) { printf("("); }
164 x().print(a);
165 if constexpr(UnaryOp::function_symbol) { printf(")"); }
166 }
167
168 template <class Env, class Allocator2 = typename Env::allocator_type>
169 CUDA TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
170 using F = TFormula<Allocator2>;
171 return F::make_unary(UnaryOp::sig(), x().deinterpret(a, env, apc, allocator), apc, allocator);
172 }
173
174 CUDA size_t length() const { return 1 + x().length(); }
175};
176
177template<class Universe>
178struct GroupAdd {
179 using U = Universe;
180 static constexpr bool has_absorbing_element = false;
181
182 CUDA static void project(const U& a, const U& b, U& r) {
183 r.project(ADD, a, b);
184 }
185
186 CUDA static bool is_absorbing(const U& a) {
187 return false;
188 }
189
190 CUDA static void rev_op(const U& a, const U& b, U& r) {
191 U tmp{};
192 tmp.additive_inverse(b);
193 project(a, tmp, r);
194 }
195
196 CUDA static void left_residual(const U& a, const U& b, U& r) {
197 r.project(SUB, a, b);
198 }
199
200 CUDA static void right_residual(const U& a, const U& b, U& r) {
201 left_residual(a, b, r);
202 }
203
204 static constexpr bool prefix_symbol = false;
205 CUDA static char symbol() { return '+'; }
206 CUDA static Sig sig() { return ADD; }
207};
208
209template<class Universe>
210struct GroupSub {
211 using U = Universe;
212 static constexpr bool has_absorbing_element = false;
213
214 CUDA static void project(const U& a, const U& b, U& r) {
215 return r.project(SUB, a, b);
216 }
217
218 CUDA static void left_residual(const U& a, const U& b, U& r) {
219 return r.project(ADD, a, b);
220 }
221
222 CUDA static void right_residual(const U& a, const U& b, U& r) {
223 return r.project(SUB, b, a);
224 }
225
226 static constexpr bool prefix_symbol = false;
227 CUDA static char symbol() { return '-'; }
228 CUDA static Sig sig() { return SUB; }
229};
230
231template<class Universe, Sig divsig>
232struct GroupMul {
233 using U = Universe;
234
235 CUDA static void project(const U& a, const U& b, U& r) {
236 r.project(MUL, a, b);
237 }
238
239 CUDA static bool is_absorbing(const U& a) {
240 return a == U::eq_zero();
241 }
242
243 /** \pre `is_absorbing(b)` must be `false`. */
244 CUDA static void rev_op(const U& a, const U& b, U& r) {
245 return r.project(divsig, a, b);
246 }
247
248 /** If `a` and `b` contains 0, then we cannot say anything on the inverse since 0 is absorbing and the inverse could be anything. */
249 CUDA static void left_residual(const U& a, const U& b, U& r) {
250 if(!(a >= U::eq_zero() && b >= U::eq_zero())) {
251 r.project(divsig, a, b);
252 }
253 }
254
255 CUDA static void right_residual(const U& a, const U& b, U& r) {
256 left_residual(a, b, r);
257 }
258
259 static constexpr bool prefix_symbol = false;
260 CUDA static char symbol() { return '*'; }
261 CUDA static Sig sig() { return MUL; }
262};
263
264template<class Universe, Sig divsig>
265struct GroupDiv {
266 using U = Universe;
267
268 CUDA static void project(const U& a, const U& b, U& r) {
269 return r.project(divsig, a, b);
270 }
271
272 CUDA static void left_residual(const U& a, const U& b, U& r) {
273 return r.project(MUL, a, b);
274 }
275
276 CUDA static void right_residual(const U& a, const U& b, U& r) {
277 if(!(b >= U::eq_zero())) {
278 r.project(divsig, b, a);
279 }
280 }
281
282 static constexpr bool prefix_symbol = false;
283 CUDA static char symbol() { return '/'; }
284 CUDA static Sig sig() { return divsig; }
285};
286
287template<class Universe, Sig msig>
289 static_assert(msig == MIN || msig == MAX);
290
291 using U = Universe;
292 CUDA static void project(const U& a, const U& b, U& r) {
293 return r.project(msig, a, b);
294 }
295
296 CUDA static void left_residual(const U& a, const U& b, U& r) {
297 if(fmeet(a, b).is_bot()) {
298 r.meet(a);
299 }
300 }
301
302 CUDA static void right_residual(const U& a, const U& b, U& r) {
303 left_residual(a, b, r);
304 }
305
306 static constexpr bool prefix_symbol = true;
307 CUDA static const char* symbol() { return msig == MIN ? "min" : "max"; }
308 CUDA static Sig sig() { return msig; }
309};
310
311template <class AD, class Group, class Allocator>
312class Binary {
313public:
314 using A = AD;
315 using allocator_type = Allocator;
316 using U = typename Group::U;
317 using G = Group;
319
320 template <class A2, class Group2, class Alloc2>
321 friend class Binary;
322
324 using sub_ptr = battery::unique_ptr<sub_type, allocator_type>;
325
326private:
327 sub_ptr x_term;
328 sub_ptr y_term;
329
330 CUDA INLINE const sub_type& x() const {
331 return *x_term;
332 }
333
334 CUDA INLINE const sub_type& y() const {
335 return *y_term;
336 }
337
338public:
339 CUDA Binary(sub_ptr&& x_term, sub_ptr&& y_term)
340 : x_term(std::move(x_term))
341 , y_term(std::move(y_term)) {}
342
343 CUDA Binary(this_type&& other)
344 : Binary(std::move(other.x_term), std::move(other.y_term)) {}
345
346 template <class A2, class Group2, class Alloc2>
347 CUDA Binary(const Binary<A2, Group2, Alloc2>& other, const allocator_type& allocator)
348 : x_term(battery::allocate_unique<sub_type>(allocator, *other.x_term))
349 , y_term(battery::allocate_unique<sub_type>(allocator, *other.y_term))
350 {}
351
352 /** Enforce `x <op> y <= u` where <= is the lattice order of the underlying abstract universe.
353 For instance, over the interval abstract universe, `x + y <= [2..5]` will ensure that `x + y` is eventually at least `2` and at most `5`. */
354 CUDA bool embed(A& a, const U& u) const {
355 U xt{};
356 U yt{};
357 U residual{};
358 bool has_changed = false;
359 if(!x().is(sub_type::IConstant)) {
360 y().project(a, yt);
361 G::left_residual(u, yt, residual);
362 has_changed |= x().embed(a, residual); // x <- u <residual> y
363 }
364 if(!y().is(sub_type::IConstant)) {
365 x().project(a, xt);
366 residual.join_top();
367 G::right_residual(u, xt, residual);
368 has_changed |= y().embed(a, residual); // y <- u <residual> x
369 }
370 return has_changed;
371 }
372
373 CUDA void project(const A& a, U& r) const {
374 U xt{};
375 U yt{};
376 x().project(a, xt);
377 y().project(a, yt);
378 G::project(xt, yt, r);
379 }
380
381 CUDA NI void print(const A& a) const {
382 if constexpr(G::prefix_symbol) {
383 printf("%s(", G::symbol());
384 x().print(a);
385 printf(", ");
386 x().print(a);
387 printf(")");
388 }
389 else {
390 x().print(a);
391 printf(" %c ", G::symbol());
392 y().print(a);
393 }
394 }
395
396 template <class Env, class Allocator2 = typename Env::allocator_type>
397 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
398 using F = TFormula<Allocator2>;
399 return F::make_binary(
400 x().deinterpret(a, env, apc, allocator),
401 G::sig(),
402 y().deinterpret(a, env, apc, allocator),
403 apc,
404 allocator);
405 }
406
407 CUDA size_t length() const { return 1 + x().length() + y().length(); }
408};
409
410// Nary is only valid for commutative group (e.g., addition and multiplication).
411template <class Combinator>
412class Nary {
413public:
415 using allocator_type = typename Combinator::allocator_type;
416 using A = typename Combinator::A;
417 using U = typename Combinator::U;
418 using G = typename Combinator::G;
419
420 template <class Combinator2>
421 friend class Nary;
422private:
424 battery::vector<sub_type, allocator_type> terms;
425
426 CUDA INLINE const sub_type& t(size_t i) const {
427 return terms[i];
428 }
429
430public:
431 CUDA Nary(battery::vector<sub_type, allocator_type>&& terms): terms(std::move(terms)) {}
432 CUDA Nary(this_type&& other): Nary(std::move(other.terms)) {}
433
434 template <class Combinator2>
435 CUDA Nary(const Nary<Combinator2>& other, const allocator_type& allocator)
436 : terms(other.terms, allocator)
437 {}
438
439 CUDA void project(const A& a, U& r) const {
440 U tmp{};
441 U tmp2{};
442 U accu{};
443 t(0).project(a, accu);
444 for(int i = 1; i < terms.size(); ++i) {
445 t(i).project(a, tmp);
446 G::project(accu, tmp, tmp2);
447 accu = tmp2;
448 tmp.join_top();
449 tmp2.join_top();
450 }
451 r.meet(accu);
452 }
453
454 CUDA bool embed(A& a, const U& u) const {
455 U all{};
456 U tmp{};
457 U tmp2{};
458 U residual{};
459 bool has_changed = false;
460 project(a, all);
461 if(!G::is_absorbing(all)) {
462 for(int i = 0; i < terms.size(); ++i) {
463 t(i).project(a, tmp);
464 G::rev_op(all, tmp, tmp2);
465 G::left_residual(u, tmp2, residual);
466 has_changed |= t(i).embed(a, residual);
467 tmp.join_top();
468 tmp2.join_top();
469 residual.join_top();
470 }
471 }
472 return has_changed;
473 }
474
475 CUDA NI void print(const A& a) const {
476 t(0).print(a);
477 for(int i = 1; i < terms.size(); ++i) {
478 printf(" %c ", G::symbol());
479 t(i).print(a);
480 }
481 }
482
483 template <class Env, class Allocator = typename Env::allocator_type>
484 CUDA NI TFormula<Allocator> deinterpret(const A& a, const Env& env, AType apc, Allocator allocator = Allocator()) const {
485 using F = TFormula<Allocator>;
486 typename F::Sequence seq = typename F::Sequence(allocator);
487 for(int i = 0; i < terms.size(); ++i) {
488 seq.push_back(t(i).deinterpret(a, env, apc, allocator));
489 }
490 return F::make_nary(G::sig(), std::move(seq), apc);
491 }
492
493 CUDA size_t length() const {
494 size_t len = 1;
495 for(int i = 0; i < terms.size(); ++i) {
496 len += t(i).length();
497 }
498 return len;
499 }
500};
501
502template <class AD, class Allocator>
503class Term {
504public:
505 using A = AD;
506 using U = typename A::local_universe;
507 using allocator_type = Allocator;
509 using this_ptr = battery::unique_ptr<Term<A, allocator_type>, allocator_type>;
510 using formula_ptr = battery::unique_ptr<Formula<A, allocator_type>, allocator_type>;
524
525 static constexpr size_t IVar = 0;
526 static constexpr size_t IConstant = IVar + 1;
527 static constexpr size_t IFormula = IConstant + 1;
528 static constexpr size_t INeg = IFormula + 1;
529 static constexpr size_t IAbs = INeg + 1;
530 static constexpr size_t IAdd = IAbs + 1;
531 static constexpr size_t ISub = IAdd + 1;
532 static constexpr size_t IMul = ISub + 1;
533 static constexpr size_t ITDiv = IMul + 1;
534 static constexpr size_t IFDiv = ITDiv + 1;
535 static constexpr size_t ICDiv = IFDiv + 1;
536 static constexpr size_t IEDiv = ICDiv + 1;
537 static constexpr size_t IMin = IEDiv + 1;
538 static constexpr size_t IMax = IMin + 1;
539 static constexpr size_t INaryAdd = IMax + 1;
540 static constexpr size_t INaryMul = INaryAdd + 1;
541
542 template <class A2, class Alloc2>
543 friend class Term;
544
545private:
546 using VTerm = battery::variant<
550 Neg,
551 Abs,
552 Add,
553 Sub,
554 Mul,
555 TDiv,
556 FDiv,
557 CDiv,
558 EDiv,
559 Min,
560 Max,
561 NaryAdd,
562 NaryMul
563 >;
564
565 VTerm term;
566
567 template <size_t I, class TermType, class A2, class Alloc2>
568 CUDA static VTerm create_one(const Term<A2, Alloc2>& other, const allocator_type& allocator) {
569 return VTerm::template create<I>(TermType(battery::get<I>(other.term), allocator));
570 }
571
572 template <class A2, class Alloc2>
573 CUDA NI static VTerm create(const Term<A2, Alloc2>& other, const allocator_type& allocator) {
574 switch(other.term.index()) {
575 case IVar: return create_one<IVar, Variable<A>>(other, allocator);
576 case IConstant: return create_one<IConstant, Constant<A>>(other, allocator);
577 case IFormula:
578 return VTerm::template create<IFormula>(battery::allocate_unique<Formula<A, allocator_type>>(
579 allocator, *battery::get<IFormula>(other.term)));
580 case INeg: return create_one<INeg, Neg>(other, allocator);
581 case IAbs: return create_one<IAbs, Abs>(other, allocator);
582 case IAdd: return create_one<IAdd, Add>(other, allocator);
583 case ISub: return create_one<ISub, Sub>(other, allocator);
584 case IMul: return create_one<IMul, Mul>(other, allocator);
585 case ITDiv: return create_one<ITDiv, TDiv>(other, allocator);
586 case IFDiv: return create_one<IFDiv, FDiv>(other, allocator);
587 case ICDiv: return create_one<ICDiv, CDiv>(other, allocator);
588 case IEDiv: return create_one<IEDiv, EDiv>(other, allocator);
589 case IMin: return create_one<IMin, Min>(other, allocator);
590 case IMax: return create_one<IMax, Max>(other, allocator);
591 case INaryAdd: return create_one<INaryAdd, NaryAdd>(other, allocator);
592 case INaryMul: return create_one<INaryMul, NaryMul>(other, allocator);
593 default:
594 printf("BUG: term not handled.\n");
595 assert(false);
596 return VTerm::template create<IVar>(Variable<A>());
597 }
598 }
599
600 CUDA Term(VTerm&& term): term(std::move(term)) {}
601
602 template <class F>
603 CUDA NI auto forward(F&& f) const {
604 switch(term.index()) {
605 case IVar: return f(battery::get<IVar>(term));
606 case IConstant: return f(battery::get<IConstant>(term));
607 case IFormula: return f(*battery::get<IFormula>(term));
608 case INeg: return f(battery::get<INeg>(term));
609 case IAbs: return f(battery::get<IAbs>(term));
610 case IAdd: return f(battery::get<IAdd>(term));
611 case ISub: return f(battery::get<ISub>(term));
612 case IMul: return f(battery::get<IMul>(term));
613 case ITDiv: return f(battery::get<ITDiv>(term));
614 case IFDiv: return f(battery::get<IFDiv>(term));
615 case ICDiv: return f(battery::get<ICDiv>(term));
616 case IEDiv: return f(battery::get<IEDiv>(term));
617 case IMin: return f(battery::get<IMin>(term));
618 case IMax: return f(battery::get<IMax>(term));
619 case INaryAdd: return f(battery::get<INaryAdd>(term));
620 case INaryMul: return f(battery::get<INaryMul>(term));
621 default:
622 printf("BUG: term not handled.\n");
623 assert(false);
624 return f(Variable<A>());
625 }
626 }
627
628public:
629 Term() = default;
630 Term(this_type&&) = default;
632
633 template <class A2, class Alloc2>
634 CUDA Term(const Term<A2, Alloc2>& other, const allocator_type& allocator = allocator_type())
635 : term(create(other, allocator))
636 {}
637
638 CUDA bool is(size_t kind) const {
639 return term.index() == kind;
640 }
641
642 template <size_t I, class SubTerm>
643 CUDA static this_type make(SubTerm&& sub_term) {
644 return Term(VTerm::template create<I>(std::move(sub_term)));
645 }
646
647 CUDA static this_type make_var(const AVar& avar) {
648 return make<IVar>(Variable<A>(avar));
649 }
650
651 CUDA static this_type make_constant(U&& sub_term) {
652 return make<IConstant>(Constant<A>(std::move(sub_term)));
653 }
654
655 CUDA static this_type make_formula(formula_ptr&& sub_term) {
656 return make<IFormula>(std::move(sub_term));
657 }
658
659 CUDA static this_type make_neg(this_ptr&& sub_term) {
660 return make<INeg>(Neg(std::move(sub_term)));
661 }
662
663 CUDA static this_type make_abs(this_ptr&& sub_term) {
664 return make<IAbs>(Abs(std::move(sub_term)));
665 }
666
667 CUDA static this_type make_add(this_ptr&& left, this_ptr&& right) {
668 return make<IAdd>(Add(std::move(left), std::move(right)));
669 }
670
671 CUDA static this_type make_sub(this_ptr&& left, this_ptr&& right) {
672 return make<ISub>(Sub(std::move(left), std::move(right)));
673 }
674
675 CUDA static this_type make_mul(this_ptr&& left, this_ptr&& right) {
676 return make<IMul>(Mul(std::move(left), std::move(right)));
677 }
678
679 CUDA static this_type make_tdiv(this_ptr&& left, this_ptr&& right) {
680 return make<ITDiv>(TDiv(std::move(left), std::move(right)));
681 }
682
683 CUDA static this_type make_fdiv(this_ptr&& left, this_ptr&& right) {
684 return make<IFDiv>(FDiv(std::move(left), std::move(right)));
685 }
686
687 CUDA static this_type make_cdiv(this_ptr&& left, this_ptr&& right) {
688 return make<ICDiv>(CDiv(std::move(left), std::move(right)));
689 }
690
691 CUDA static this_type make_ediv(this_ptr&& left, this_ptr&& right) {
692 return make<IEDiv>(EDiv(std::move(left), std::move(right)));
693 }
694
695 CUDA static this_type make_min(this_ptr&& left, this_ptr&& right) {
696 return make<IMin>(Min(std::move(left), std::move(right)));
697 }
698
699 CUDA static this_type make_max(this_ptr&& left, this_ptr&& right) {
700 return make<IMax>(Max(std::move(left), std::move(right)));
701 }
702
703 CUDA static this_type make_naryadd(battery::vector<this_type, allocator_type>&& sub_terms) {
704 return make<INaryAdd>(NaryAdd(std::move(sub_terms)));
705 }
706
707 CUDA static this_type make_narymul(battery::vector<this_type, allocator_type>&& sub_terms) {
708 return make<INaryMul>(NaryMul(std::move(sub_terms)));
709 }
710
711 CUDA bool embed(A& a, const U& u) const {
712 return forward([&](const auto& t) { return t.embed(a, u); });
713 }
714
715 CUDA void project(const A& a, U& r) const {
716 return forward([&](const auto& t) { t.project(a, r); });
717 }
718
719 CUDA void print(const A& a) const {
720 forward([&](const auto& t) { t.print(a); });
721 }
722
723 template <class Env, class Allocator2 = typename Env::allocator_type>
724 CUDA TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
725 return forward([&](const auto& t) { return t.deinterpret(a, env, apc, allocator); });
726 }
727
728 CUDA size_t length() const {
729 return forward([&](const auto& t) { return t.length(); });
730 }
731};
732
733} // namespace pc
734} // namespace lala
735
736#endif
Definition terms.hpp:312
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition terms.hpp:397
CUDA bool embed(A &a, const U &u) const
Definition terms.hpp:354
CUDA void project(const A &a, U &r) const
Definition terms.hpp:373
CUDA size_t length() const
Definition terms.hpp:407
CUDA Binary(const Binary< A2, Group2, Alloc2 > &other, const allocator_type &allocator)
Definition terms.hpp:347
CUDA Binary(sub_ptr &&x_term, sub_ptr &&y_term)
Definition terms.hpp:339
AD A
Definition terms.hpp:314
battery::unique_ptr< sub_type, allocator_type > sub_ptr
Definition terms.hpp:324
CUDA Binary(this_type &&other)
Definition terms.hpp:343
Allocator allocator_type
Definition terms.hpp:315
Group G
Definition terms.hpp:317
Term< A, allocator_type > sub_type
Definition terms.hpp:323
typename Group::U U
Definition terms.hpp:316
CUDA NI void print(const A &a) const
Definition terms.hpp:381
Definition terms.hpp:19
CUDA bool embed(A &, const U &) const
Definition terms.hpp:34
CUDA Constant(const Constant< A2 > &other, const Alloc &)
Definition terms.hpp:32
CUDA void project(const A &, U &r) const
Definition terms.hpp:35
CUDA TFormula< Allocator > deinterpret(const A &, const Env &, AType, Allocator allocator=Allocator()) const
Definition terms.hpp:38
CUDA size_t length() const
Definition terms.hpp:41
CUDA void print(const A &) const
Definition terms.hpp:36
Constant(Constant< A > &&other)=default
AD A
Definition terms.hpp:21
typename A::local_universe U
Definition terms.hpp:22
CUDA Constant(U &&k)
Definition terms.hpp:28
Definition terms.hpp:16
Definition terms.hpp:412
CUDA size_t length() const
Definition terms.hpp:493
CUDA Nary(this_type &&other)
Definition terms.hpp:432
CUDA Nary(const Nary< Combinator2 > &other, const allocator_type &allocator)
Definition terms.hpp:435
CUDA NI void print(const A &a) const
Definition terms.hpp:475
typename Combinator::G G
Definition terms.hpp:418
CUDA bool embed(A &a, const U &u) const
Definition terms.hpp:454
typename Combinator::A A
Definition terms.hpp:416
typename Combinator::U U
Definition terms.hpp:417
CUDA NI TFormula< Allocator > deinterpret(const A &a, const Env &env, AType apc, Allocator allocator=Allocator()) const
Definition terms.hpp:484
CUDA Nary(battery::vector< sub_type, allocator_type > &&terms)
Definition terms.hpp:431
typename Combinator::allocator_type allocator_type
Definition terms.hpp:415
CUDA void project(const A &a, U &r) const
Definition terms.hpp:439
Binary< A, GroupDiv< U, FDIV >, allocator_type > FDiv
Definition terms.hpp:517
static CUDA this_type make_constant(U &&sub_term)
Definition terms.hpp:651
battery::unique_ptr< Formula< A, allocator_type >, allocator_type > formula_ptr
Definition terms.hpp:510
static constexpr size_t IEDiv
Definition terms.hpp:536
Term()=default
Binary< A, GroupDiv< U, EDIV >, allocator_type > EDiv
Definition terms.hpp:519
static constexpr size_t IFDiv
Definition terms.hpp:534
static CUDA this_type make_abs(this_ptr &&sub_term)
Definition terms.hpp:663
CUDA TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition terms.hpp:724
Term(this_type &&)=default
static constexpr size_t INaryMul
Definition terms.hpp:540
static CUDA this_type make_max(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:699
Binary< A, GroupAdd< U >, allocator_type > Add
Definition terms.hpp:513
static constexpr size_t IMax
Definition terms.hpp:538
Nary< Mul > NaryMul
Definition terms.hpp:523
Binary< A, GroupMinMax< U, MIN >, allocator_type > Min
Definition terms.hpp:520
static constexpr size_t ISub
Definition terms.hpp:531
CUDA Term(const Term< A2, Alloc2 > &other, const allocator_type &allocator=allocator_type())
Definition terms.hpp:634
static constexpr size_t INeg
Definition terms.hpp:528
CUDA void print(const A &a) const
Definition terms.hpp:719
Binary< A, GroupMinMax< U, MAX >, allocator_type > Max
Definition terms.hpp:521
static CUDA this_type make_mul(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:675
friend class Term
Definition terms.hpp:543
static CUDA this_type make_min(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:695
CUDA bool embed(A &a, const U &u) const
Definition terms.hpp:711
static constexpr size_t ITDiv
Definition terms.hpp:533
static CUDA this_type make(SubTerm &&sub_term)
Definition terms.hpp:643
battery::unique_ptr< Term< A, allocator_type >, allocator_type > this_ptr
Definition terms.hpp:509
static CUDA this_type make_cdiv(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:687
static CUDA this_type make_neg(this_ptr &&sub_term)
Definition terms.hpp:659
static constexpr size_t INaryAdd
Definition terms.hpp:539
Binary< A, GroupSub< U >, allocator_type > Sub
Definition terms.hpp:514
static CUDA this_type make_tdiv(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:679
static constexpr size_t IMin
Definition terms.hpp:537
static CUDA this_type make_naryadd(battery::vector< this_type, allocator_type > &&sub_terms)
Definition terms.hpp:703
Binary< A, GroupMul< U, EDIV >, allocator_type > Mul
Definition terms.hpp:515
Binary< A, GroupDiv< U, CDIV >, allocator_type > CDiv
Definition terms.hpp:518
Nary< Add > NaryAdd
Definition terms.hpp:522
static CUDA this_type make_ediv(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:691
CUDA void project(const A &a, U &r) const
Definition terms.hpp:715
this_type & operator=(this_type &&)=default
static CUDA this_type make_fdiv(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:683
CUDA bool is(size_t kind) const
Definition terms.hpp:638
static CUDA this_type make_sub(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:671
static constexpr size_t ICDiv
Definition terms.hpp:535
static constexpr size_t IAdd
Definition terms.hpp:530
CUDA size_t length() const
Definition terms.hpp:728
static constexpr size_t IVar
Definition terms.hpp:525
static CUDA this_type make_formula(formula_ptr &&sub_term)
Definition terms.hpp:655
static constexpr size_t IFormula
Definition terms.hpp:527
AD A
Definition terms.hpp:505
Unary< A, NegOp< U >, allocator_type > Neg
Definition terms.hpp:511
static constexpr size_t IAbs
Definition terms.hpp:529
Unary< A, AbsOp< U >, allocator_type > Abs
Definition terms.hpp:512
static CUDA this_type make_var(const AVar &avar)
Definition terms.hpp:647
static constexpr size_t IMul
Definition terms.hpp:532
static CUDA this_type make_add(this_ptr &&left, this_ptr &&right)
Definition terms.hpp:667
static constexpr size_t IConstant
Definition terms.hpp:526
typename A::local_universe U
Definition terms.hpp:506
Allocator allocator_type
Definition terms.hpp:507
static CUDA this_type make_narymul(battery::vector< this_type, allocator_type > &&sub_terms)
Definition terms.hpp:707
Binary< A, GroupDiv< U, TDIV >, allocator_type > TDiv
Definition terms.hpp:516
Definition terms.hpp:122
CUDA Unary(this_type &&other)
Definition terms.hpp:142
typename A::local_universe U
Definition terms.hpp:126
CUDA Unary(const Unary< A2, UnaryOp2, Alloc2 > &other, const allocator_type &allocator)
Definition terms.hpp:145
CUDA bool embed(A &a, const U &u) const
Definition terms.hpp:149
CUDA NI void print(const A &a) const
Definition terms.hpp:161
Allocator allocator_type
Definition terms.hpp:124
CUDA void project(const A &a, U &r) const
Definition terms.hpp:155
CUDA Unary(battery::unique_ptr< sub_type, allocator_type > &&x_term)
Definition terms.hpp:141
AD A
Definition terms.hpp:125
CUDA size_t length() const
Definition terms.hpp:174
CUDA TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition terms.hpp:169
Definition terms.hpp:48
CUDA Variable(AVar avar)
Definition terms.hpp:58
CUDA Variable(const Variable< A2 > &other, const Alloc &)
Definition terms.hpp:63
CUDA bool embed(A &a, const U &u) const
Definition terms.hpp:65
AD A
Definition terms.hpp:50
Variable< A > & operator=(Variable< A > &&other)=default
CUDA Variable()
Definition terms.hpp:57
CUDA void project(const A &a, U &r) const
Definition terms.hpp:69
CUDA TFormula< Allocator > deinterpret(const A &, const Env &env, AType, Allocator allocator=Allocator()) const
Definition terms.hpp:76
CUDA size_t length() const
Definition terms.hpp:81
CUDA void print(const A &a) const
Definition terms.hpp:73
typename A::local_universe U
Definition terms.hpp:51
Variable(Variable< A > &&other)=default
Definition formula.hpp:8
Definition terms.hpp:105
static CUDA void project(const U &a, U &r)
Definition terms.hpp:108
static constexpr bool function_symbol
Definition terms.hpp:116
Universe U
Definition terms.hpp:106
static CUDA const char * symbol()
Definition terms.hpp:117
static CUDA Sig sig()
Definition terms.hpp:118
static CUDA void residual(const U &a, U &r)
Definition terms.hpp:112
Definition terms.hpp:178
static CUDA Sig sig()
Definition terms.hpp:206
static CUDA char symbol()
Definition terms.hpp:205
static CUDA void left_residual(const U &a, const U &b, U &r)
Definition terms.hpp:196
static CUDA void rev_op(const U &a, const U &b, U &r)
Definition terms.hpp:190
Universe U
Definition terms.hpp:179
static CUDA void project(const U &a, const U &b, U &r)
Definition terms.hpp:182
static constexpr bool has_absorbing_element
Definition terms.hpp:180
static CUDA bool is_absorbing(const U &a)
Definition terms.hpp:186
static CUDA void right_residual(const U &a, const U &b, U &r)
Definition terms.hpp:200
static constexpr bool prefix_symbol
Definition terms.hpp:204
Definition terms.hpp:265
static CUDA void project(const U &a, const U &b, U &r)
Definition terms.hpp:268
Universe U
Definition terms.hpp:266
static constexpr bool prefix_symbol
Definition terms.hpp:282
static CUDA void left_residual(const U &a, const U &b, U &r)
Definition terms.hpp:272
static CUDA char symbol()
Definition terms.hpp:283
static CUDA Sig sig()
Definition terms.hpp:284
static CUDA void right_residual(const U &a, const U &b, U &r)
Definition terms.hpp:276
Definition terms.hpp:288
static CUDA void right_residual(const U &a, const U &b, U &r)
Definition terms.hpp:302
static CUDA Sig sig()
Definition terms.hpp:308
Universe U
Definition terms.hpp:291
static CUDA const char * symbol()
Definition terms.hpp:307
static CUDA void project(const U &a, const U &b, U &r)
Definition terms.hpp:292
static constexpr bool prefix_symbol
Definition terms.hpp:306
static CUDA void left_residual(const U &a, const U &b, U &r)
Definition terms.hpp:296
Definition terms.hpp:232
Universe U
Definition terms.hpp:233
static CUDA void rev_op(const U &a, const U &b, U &r)
Definition terms.hpp:244
static CUDA bool is_absorbing(const U &a)
Definition terms.hpp:239
static CUDA void project(const U &a, const U &b, U &r)
Definition terms.hpp:235
static CUDA void right_residual(const U &a, const U &b, U &r)
Definition terms.hpp:255
static CUDA char symbol()
Definition terms.hpp:260
static CUDA void left_residual(const U &a, const U &b, U &r)
Definition terms.hpp:249
static CUDA Sig sig()
Definition terms.hpp:261
static constexpr bool prefix_symbol
Definition terms.hpp:259
Definition terms.hpp:210
static CUDA Sig sig()
Definition terms.hpp:228
static constexpr bool prefix_symbol
Definition terms.hpp:226
static CUDA void left_residual(const U &a, const U &b, U &r)
Definition terms.hpp:218
static constexpr bool has_absorbing_element
Definition terms.hpp:212
static CUDA char symbol()
Definition terms.hpp:227
static CUDA void project(const U &a, const U &b, U &r)
Definition terms.hpp:214
static CUDA void right_residual(const U &a, const U &b, U &r)
Definition terms.hpp:222
Universe U
Definition terms.hpp:211
Definition terms.hpp:88
static CUDA void project(const U &a, U &r)
Definition terms.hpp:91
static CUDA Sig sig()
Definition terms.hpp:101
static CUDA const char * symbol()
Definition terms.hpp:100
static CUDA void residual(const U &a, U &r)
Definition terms.hpp:95
static constexpr bool function_symbol
Definition terms.hpp:99
Universe U
Definition terms.hpp:89