3#ifndef LALA_PC_TERMS_HPP
4#define LALA_PC_TERMS_HPP
6#include "battery/vector.hpp"
7#include "lala/universes/arith_bound.hpp"
12template <
class AD,
class Allocator>
15template <
class AD,
class Allocator>
22 using U =
typename A::local_universe;
31 template <
class A2,
class Alloc>
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 {
41 CUDA
size_t length()
const {
return 1; }
51 using U =
typename A::local_universe;
62 template <
class A2,
class Alloc>
66 return a.embed(avar, u);
70 return a.project(avar, r);
73 CUDA
void print(
const A& a)
const { printf(
"(%d,%d)", avar.aty(), avar.vid()); }
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));
81 CUDA
size_t length()
const {
return 1; }
87template<
class Universe>
100 CUDA
static const char*
symbol() {
return "-"; }
101 CUDA
static Sig
sig() {
return NEG; }
104template<
class Universe>
113 r.meet(fjoin(a, project_fun(NEG, a)));
117 CUDA
static const char*
symbol() {
return "abs"; }
118 CUDA
static Sig
sig() {
return ABS; }
121template <
class AD,
class UnaryOp,
class Allocator>
126 using U =
typename A::local_universe;
129 template <
class A2,
class UnaryOp2,
class Alloc2>
134 battery::unique_ptr<sub_type, allocator_type> x_term;
136 CUDA INLINE
const sub_type& x()
const {
141 CUDA
Unary(battery::unique_ptr<sub_type, allocator_type>&& x_term): x_term(std::move(x_term)) {}
144 template <
class A2,
class UnaryOp2,
class Alloc2>
146 x_term(battery::allocate_unique<
sub_type>(allocator, *other.x_term))
151 UnaryOp::residual(u, tmp);
152 return x().
embed(a, tmp);
158 UnaryOp::project(tmp, r);
162 printf(
"%s", UnaryOp::symbol());
163 if constexpr(UnaryOp::function_symbol) { printf(
"("); }
165 if constexpr(UnaryOp::function_symbol) { printf(
")"); }
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);
177template<
class Universe>
183 r.project(ADD, a, b);
192 tmp.additive_inverse(b);
197 r.project(SUB, a, b);
205 CUDA
static char symbol() {
return '+'; }
206 CUDA
static Sig
sig() {
return ADD; }
209template<
class Universe>
215 return r.project(SUB, a, b);
219 return r.project(ADD, a, b);
223 return r.project(SUB, b, a);
227 CUDA
static char symbol() {
return '-'; }
228 CUDA
static Sig
sig() {
return SUB; }
231template<
class Universe, Sig divsig>
236 r.project(MUL, a, b);
240 return a == U::eq_zero();
245 return r.project(divsig, a, b);
250 if(!(a >= U::eq_zero() && b >= U::eq_zero())) {
251 r.project(divsig, a, b);
260 CUDA
static char symbol() {
return '*'; }
261 CUDA
static Sig
sig() {
return MUL; }
264template<
class Universe, Sig divsig>
269 return r.project(divsig, a, b);
273 return r.project(MUL, a, b);
277 if(!(b >= U::eq_zero())) {
278 r.project(divsig, b, a);
283 CUDA
static char symbol() {
return '/'; }
284 CUDA
static Sig
sig() {
return divsig; }
287template<
class Universe, Sig msig>
289 static_assert(msig == MIN || msig == MAX);
293 return r.project(msig, a, b);
297 if(fmeet(a, b).is_bot()) {
307 CUDA
static const char*
symbol() {
return msig == MIN ?
"min" :
"max"; }
308 CUDA
static Sig
sig() {
return msig; }
311template <
class AD,
class Group,
class Allocator>
316 using U =
typename Group::U;
320 template <
class A2,
class Group2,
class Alloc2>
324 using sub_ptr = battery::unique_ptr<sub_type, allocator_type>;
330 CUDA INLINE
const sub_type& x()
const {
334 CUDA INLINE
const sub_type& y()
const {
340 : x_term(std::move(x_term))
341 , y_term(std::move(y_term)) {}
344 :
Binary(std::move(other.x_term), std::move(other.y_term)) {}
346 template <
class A2,
class Group2,
class Alloc2>
348 : x_term(battery::allocate_unique<
sub_type>(allocator, *other.x_term))
349 , y_term(battery::allocate_unique<
sub_type>(allocator, *other.y_term))
358 bool has_changed =
false;
361 G::left_residual(u, yt, residual);
362 has_changed |= x().
embed(a, residual);
367 G::right_residual(u, xt, residual);
368 has_changed |= y().
embed(a, residual);
378 G::project(xt, yt, r);
382 if constexpr(G::prefix_symbol) {
383 printf(
"%s(", G::symbol());
391 printf(
" %c ", G::symbol());
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(
411template <
class Combinator>
416 using A =
typename Combinator::A;
417 using U =
typename Combinator::U;
418 using G =
typename Combinator::G;
420 template <
class Combinator2>
424 battery::vector<sub_type, allocator_type> terms;
426 CUDA INLINE
const sub_type& t(
size_t i)
const {
431 CUDA
Nary(battery::vector<sub_type, allocator_type>&& terms): terms(std::move(terms)) {}
434 template <
class Combinator2>
436 : terms(other.terms, allocator)
444 for(
int i = 1; i < terms.size(); ++i) {
446 G::project(accu, tmp, tmp2);
459 bool has_changed =
false;
461 if(!G::is_absorbing(all)) {
462 for(
int i = 0; i < terms.size(); ++i) {
464 G::rev_op(all, tmp, tmp2);
465 G::left_residual(u, tmp2, residual);
466 has_changed |= t(i).
embed(a, residual);
477 for(
int i = 1; i < terms.size(); ++i) {
478 printf(
" %c ", G::symbol());
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));
490 return F::make_nary(G::sig(), std::move(seq), apc);
495 for(
int i = 0; i < terms.size(); ++i) {
502template <
class AD,
class Allocator>
506 using U =
typename A::local_universe;
525 static constexpr size_t IVar = 0;
542 template <
class A2,
class Alloc2>
546 using VTerm = battery::variant<
567 template <
size_t I,
class TermType,
class A2,
class Alloc2>
569 return VTerm::template create<I>(TermType(battery::get<I>(other.term), allocator));
572 template <
class A2,
class Alloc2>
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);
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);
594 printf(
"BUG: term not handled.\n");
596 return VTerm::template create<IVar>(
Variable<A>());
600 CUDA
Term(VTerm&& term): term(std::move(term)) {}
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));
622 printf(
"BUG: term not handled.\n");
624 return f(Variable<A>());
633 template <
class A2,
class Alloc2>
635 : term(create(other, allocator))
638 CUDA
bool is(
size_t kind)
const {
639 return term.index() == kind;
642 template <
size_t I,
class SubTerm>
644 return Term(VTerm::template create<I>(std::move(sub_term)));
712 return forward([&](
const auto& t) {
return t.embed(a, u); });
716 return forward([&](
const auto& t) { t.project(a, r); });
720 forward([&](
const auto& t) { t.print(a); });
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); });
729 return forward([&](
const auto& t) {
return t.length(); });
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
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
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
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
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
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
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
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
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
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
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
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
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