3#ifndef LALA_CORE_INTERVAL_HPP
4#define LALA_CORE_INTERVAL_HPP
15 template <
class LB,
class UB>
20 template <
class U>
constexpr const typename Interval<U>::LB& lb(
const Interval<U>& itv) {
return itv.lb(); }
21 template <
class L>
constexpr const L& lb(
const L& other) {
return other; }
22 template <
class U>
constexpr const typename Interval<U>::UB& ub(
const Interval<U>& itv) {
return itv.ub(); }
23 template <
class L>
constexpr const L& ub(
const L& other) {
return other; }
32 using UB =
typename LB::dual_type;
52 constexpr static const char*
name =
"Interval";
55 using LB2 =
typename LB::local_type;
56 using UB2 =
typename UB::local_type;
58 CUDA
constexpr Interval(
const CP& cp): cp(cp) {}
65 CUDA
constexpr Interval(
const typename U::value_type& x): cp(x, x) {}
100 template<Sig sig,
class A,
class B>
103 LB2::template fun<sig>(
104 typename A::template flat_type<battery::local_memory>(a.
lb()),
105 typename B::template flat_type<battery::local_memory>(b.
lb())),
106 UB2::template fun<sig>(
107 typename A::template flat_type<battery::local_memory>(a.
ub()),
108 typename B::template flat_type<battery::local_memory>(b.
ub())));
111 template<Sig sig,
class A>
112 CUDA
constexpr static local_type flat_fun(
const Interval<A>& a) {
114 LB2::template fun<sig>(
typename A::template flat_type<battery::local_memory>(a.lb())),
115 UB2::template fun<sig>(
typename A::template flat_type<battery::local_memory>(a.ub())));
122 template<
bool diagnose = false,
class F,
class Env,
class U2>
124 if constexpr(LB::preserve_concrete_covers && LB::is_arithmetic) {
126 auto sort = f.sort();
127 if(sort.has_value() && sort->is_bool()) {
128 k.
tell(
local_type(LB::geq_k(LB::pre_universe::zero()), UB::leq_k(UB::pre_universe::one())));
133 return CP::template interpret_tell<diagnose>(f, env, k.cp, diagnostics);
140 template<
bool diagnose = false,
class F,
class Env,
class U2>
143 if(f.is_binary() && f.sig() ==
NEQ) {
144 return LB::template interpret_ask<diagnose>(f, env, k.
lb(), diagnostics);
146 else if(f.is_binary() && f.sig() ==
EQ) {
148 "When interpreting equality, the underlying bounds LB and UB failed to agree on the same value.",
149 (LB::template interpret_tell<diagnose>(f, env, itv.
lb(), diagnostics) &&
150 UB::template interpret_tell<diagnose>(f, env, itv.
ub(), diagnostics) &&
151 itv.
lb() == itv.
ub()),
154 else if(f.is_binary() && f.sig() ==
IN && f.seq(0).is_variable()
155 && f.seq(1).is(F::S) && f.seq(1).s().size() == 1)
157 const auto&
lb = battery::get<0>(f.seq(1).s()[0]);
158 const auto&
ub = battery::get<1>(f.seq(1).s()[0]);
161 "Failed to interpret the decomposition of set membership `x in {[v..v]}` into equality `x == v`.",
162 (interpret_ask<diagnose>(F::make_binary(f.seq(0),
EQ,
lb), env, k, diagnostics)));
165 "Failed to interpret the decomposition of set membership `x in {[l..u]}` into `x >= l /\\ x <= u`.",
166 (LB::template interpret_ask<diagnose>(F::make_binary(f.seq(0),
geq_of_constant(
lb),
lb), env, itv.
lb(), diagnostics) &&
167 UB::template interpret_ask<diagnose>(F::make_binary(f.seq(0),
leq_of_constant(
ub),
ub), env, itv.
ub(), diagnostics)),
171 return CP::template interpret_ask<diagnose>(f, env, k.cp, diagnostics);
174 template<IKind kind,
bool diagnose = false,
class F,
class Env,
class U2>
177 return interpret_ask<diagnose>(f, env, k, diagnostics);
180 return interpret_tell<diagnose>(f, env, k, diagnostics);
185 CUDA
constexpr LB&
lb() {
return project<0>(cp); }
186 CUDA
constexpr UB&
ub() {
return project<1>(cp); }
188 CUDA
constexpr const LB&
lb()
const {
return project<0>(cp); }
189 CUDA
constexpr const UB&
ub()
const {
return project<1>(cp); }
196 template<
class A,
class M>
198 cp.template tell<0>(
lb, has_changed);
202 template<
class A,
class M>
204 cp.template tell<1>(
ub, has_changed);
210 cp.template tell<0>(
lb);
216 cp.template tell<1>(
ub);
220 template<
class A,
class M>
222 cp.
tell(other.cp, has_changed);
237 template<
class A,
class M>
239 cp.template dtell<0>(
lb, has_changed);
243 template<
class A,
class M>
245 cp.template dtell<1>(
ub, has_changed);
251 cp.template dtell<0>(
lb);
257 cp.template dtell<1>(
ub);
261 template<
class A,
class M>
263 cp.
dtell(other.cp, has_changed);
284 F logical_lb =
lb().template deinterpret<F>();
285 F logical_ub =
ub().template deinterpret<F>();
287 logical_set[0] = battery::make_tuple(std::move(logical_lb), std::move(logical_ub));
288 F set = F::make_set(std::move(logical_set));
289 F var = F::make_avar(x);
290 return F::make_binary(var,
IN, std::move(set),
UNTYPED, env.get_allocator());
299 F logical_lb =
lb().template deinterpret<F>();
300 if(logical_lb.is(F::R)) {
301 F logical_ub =
ub().template deinterpret<F>();
302 battery::get<1>(logical_lb.r()) = battery::get<0>(logical_ub.r());
333 default:
return false;
341 static_assert(LB::is_supported_fun(
NEG) && UB::is_supported_fun(
NEG),
342 "Negation of interval bounds are required to compute the additive inverse.");
343 return flat_fun<NEG>(x);
354 return reverse(flat_fun<NEG>(x));
363 LB2::geq_k(LB2::pre_universe::zero()),
364 meet(dual<UB2>(LB2::template fun<ABS>(
typename L::template flat_type<battery::local_memory>(x.
lb()))), x.
ub()));
365 case NN:
return neg(x);
366 case PN:
return local_type(x.
lb(),
meet(UB2::leq_k(UB2::pre_universe::zero()), x.
ub()));
372 template<Sig sig,
class L>
374 static_assert(sig ==
NEG || sig ==
ABS,
"Unsupported unary function.");
384 template<
class L,
class K>
386 return flat_fun<ADD>(x, y);
389 template<
class L,
class K>
403 CUDA
constexpr static bounds_sign sign(
const Interval<A>& a) {
404 if(a.lb() >= LB2::geq_k(LB2::pre_universe::zero())) {
405 if(a.ub() > UB2::leq_k(UB2::pre_universe::zero())) {
413 if(a.ub() >= UB2::leq_k(UB2::pre_universe::zero())) {
422 template<
class A,
class B>
423 CUDA
constexpr static local_type mul2(
const Interval<A>& a,
const Interval<B>& b) {
424 return flat_fun<MUL>(a, b);
427 template<Sig sig,
class R,
class A,
class B>
428 CUDA
constexpr static R flat_fun2(
const A& a,
const B& b) {
429 return R::template fun<sig>(
430 typename A::template flat_type<battery::local_memory>(a),
431 typename B::template flat_type<battery::local_memory>(b));
435 template<
class L,
class K>
443 case PP:
return mul2(a, b);
444 case NP:
return mul2(a.ub2(), b);
445 case NN:
return mul2(
reverse(a), b);
447 if(b.as_product().is_top()) {
return top(); }
448 else {
return mul2(a.lb2(), b); }
452 case PP:
return mul2(a, b.ub2());
455 meet(flat_fun2<MUL, LB2>(a.lb(), b.ub()), flat_fun2<MUL, LB2>(a.ub(), b.lb())),
456 meet(flat_fun2<MUL, UB2>(a.lb(), b.lb()), flat_fun2<MUL, UB2>(a.ub(), b.ub())));
457 case NN:
return mul2(
reverse(a), b.lb2());
459 if(b.as_product().is_top()) {
return top(); }
464 case PP:
return mul2(a,
reverse(b));
465 case NP:
return mul2(a.lb2(),
reverse(b));
468 if(b.as_product().is_top()) {
return top(); }
469 else {
return mul2(a.ub2(),
reverse(b)); }
472 if(a.as_product().is_top()) {
return top(); }
475 case PP:
return mul2(a, b.lb2());
477 case NN:
return mul2(
reverse(a), b.ub2());
479 if(b.as_product().is_top()) {
return top(); }
482 join(flat_fun2<MUL, LB2>(a.lb(), b.lb()), flat_fun2<MUL, LB2>(a.ub(), b.ub())),
483 join(flat_fun2<MUL, UB2>(a.lb(), b.ub()), flat_fun2<MUL, UB2>(a.ub(), b.lb())));
494 template<Sig divsig,
class AL,
class AU,
class BL,
class BU>
495 CUDA
constexpr static local_type div2(
const AL& al,
const AU& au,
const BL& bl,
const BU& bu) {
496 return local_type(LB2::template guarded_div<divsig>(al, bl),
497 UB2::template guarded_div<divsig>(au, bu));
501 template<Sig divsig,
class L,
class K>
506 if(a.is_top() || b.is_top()) {
return top(); }
508 constexpr auto leq_zero = UB_K::leq_k(UB_K::pre_universe::zero());
512 if(b.ub() >= leq_zero) {
return top(); }
514 case PP:
return div2<divsig>(a.lb(), a.ub(), b.ub(), b.lb());
515 case NP:
return div2<divsig>(a.lb(), a.ub(), b.lb(), b.lb());
516 case NN:
return div2<divsig>(a.lb(), a.ub(), b.lb(), b.ub());
518 if(a.as_product().is_top()) {
return top(); }
519 else {
return div2<divsig>(a.lb(), a.ub(), b.ub(), b.ub()); }
522 if(a.is_top()) {
return top(); }
524 if constexpr(L::preserve_concrete_covers && K::preserve_concrete_covers) {
526 case PP:
return div2<divsig>(a.ub(), a.ub(), b.lb(), b.ub());
528 meet(LB2::template guarded_div<divsig>(a.lb(), b.ub()), LB2::template guarded_div<divsig>(a.ub(), b.lb())),
529 meet(UB2::template guarded_div<divsig>(a.lb(), b.lb()), UB2::template guarded_div<divsig>(a.ub(), b.ub())));
530 case NN:
return div2<divsig>(a.lb(), a.lb(), b.ub(), b.lb());
531 case PN:
return (a.as_product().is_top()) ?
top() :
eq_zero();
540 case PP:
return div2<divsig>(a.ub(), a.lb(), b.ub(), b.lb());
541 case NP:
return div2<divsig>(a.ub(), a.lb(), b.ub(), b.ub());
542 case NN:
return div2<divsig>(a.ub(), a.lb(), b.lb(), b.ub());
544 if(a.as_product().is_top()) {
return top(); }
545 else {
return div2<divsig>(a.ub(), a.lb(), b.lb(), b.lb()); }
548 if(b.as_product().is_top()) {
return top(); }
549 if constexpr(L::preserve_concrete_covers && K::preserve_concrete_covers) {
551 case PP:
return div2<divsig>(a.lb(), a.lb(), b.ub(), b.lb());
553 case NN:
return div2<divsig>(a.ub(), a.ub(), b.ub(), b.lb());
555 if(a.as_product().is_top()) {
return top(); }
558 join(LB2::template guarded_div<divsig>(a.lb(), b.ub()), LB2::template guarded_div<divsig>(a.ub(), b.lb())),
559 join(UB2::template guarded_div<divsig>(a.lb(), b.lb()), UB2::template guarded_div<divsig>(a.ub(), b.ub())));
571 template<Sig modsig,
class L,
class K>
575 if(a.is_top() || b.is_top()) {
return top(); }
576 if(a.lb() == dual<LB2>(a.ub()) && b.lb() == dual<LB2>(b.ub())) {
577 return flat_fun<modsig>(a, b);
584 template<
class L,
class K>
588 if(a.is_top() || b.is_top()) {
return top(); }
589 if(a.lb() == dual<LB2>(a.ub()) && b.lb() == dual<LB2>(b.ub())) {
590 return flat_fun<POW>(a, b);
597 template<Sig sig,
class L,
class K>
599 if constexpr(sig ==
ADD) {
return add(x, y); }
600 else if constexpr(sig ==
SUB) {
return sub(x, y); }
601 else if constexpr(sig ==
MUL) {
return mul(x, y); }
602 else if constexpr(
is_division(sig)) {
return div<sig>(x, y); }
603 else if constexpr(
is_modulo(sig)) {
return mod<sig>(x, y); }
604 else if constexpr(sig ==
POW) {
return pow(x, y); }
606 else {
static_assert(
608 "Unsupported binary function.");
613 static_assert(LB::is_totally_ordered && LB::is_arithmetic,
614 "Width is only defined for totally ordered arithmetic intervals.");
615 return sub(ub2(), lb2());
620 static_assert(LB::is_totally_ordered && LB::is_arithmetic,
621 "Median function is only defined for totally ordered arithmetic intervals.");
622 auto x =
sub(ub2(), lb2());
630template<
class L,
class K>
636template<
class L,
class K>
639 if(a.
is_top()) {
return b; }
640 if(b.
is_top()) {
return a; }
644template<
class L,
class K>
645CUDA
constexpr bool operator<=(
const Interval<L>& a,
const Interval<K>& b)
647 return b.is_top() || a.as_product() <= b.as_product();
650template<
class L,
class K>
656template<
class L,
class K>
657CUDA
constexpr bool operator>=(
const Interval<L>& a,
const Interval<K>& b)
662template<
class L,
class K>
668template<
class L,
class K>
674template<
class L,
class K>
675CUDA
constexpr bool operator!=(
const Interval<L>& a,
const Interval<K>& b)
677 return a.as_product() != b.as_product() && !(a.is_top() && b.is_top());
682 return s <<
"[" << itv.
lb() <<
".." << itv.
ub() <<
"]";
CUDA constexpr this_type & dtell(const CartesianProduct< Bs... > &other, BInc< M > &has_changed)
Definition cartesian_product.hpp:336
CUDA constexpr bool extract(CartesianProduct< Bs... > &ua) const
Definition cartesian_product.hpp:359
CUDA constexpr local::BDec is_bot() const
Definition cartesian_product.hpp:223
CUDA constexpr value_type value() const
Definition cartesian_product.hpp:213
CUDA constexpr local::BInc is_top() const
Definition cartesian_product.hpp:218
CUDA constexpr this_type & dtell_bot()
Definition cartesian_product.hpp:330
static constexpr const bool injective_concretization
Definition cartesian_product.hpp:83
CUDA constexpr this_type & tell_top()
Definition cartesian_product.hpp:303
static constexpr const bool sequential
Definition cartesian_product.hpp:77
static constexpr const bool preserve_bot
Definition cartesian_product.hpp:79
CUDA constexpr this_type & tell(const CartesianProduct< Bs... > &other, BInc< M > &has_changed)
Definition cartesian_product.hpp:309
battery::tuple< typename As::value_type... > value_type
Definition cartesian_product.hpp:74
static CUDA constexpr local_type top()
Definition cartesian_product.hpp:133
typename type_of< 0 >::memory_type memory_type
Definition cartesian_product.hpp:70
static constexpr const bool preserve_concrete_covers
Definition cartesian_product.hpp:84
static CUDA constexpr local_type bot()
Definition cartesian_product.hpp:128
CUDA TFormula< typename Env::allocator_type > deinterpret(AVar x, const Env &env) const
Definition cartesian_product.hpp:444
static CUDA constexpr bool is_supported_fun(Sig sig)
Definition cartesian_product.hpp:391
Definition diagnostics.hpp:19
Definition interval.hpp:29
CUDA constexpr this_type & operator=(const this_type &other)
Definition interval.hpp:82
CUDA static constexpr local_type additive_inverse(const this_type &x)
Definition interval.hpp:340
CUDA constexpr this_type & dtell_lb(const A &lb, BInc< M > &has_changed)
Definition interval.hpp:238
typename LB::dual_type UB
Definition interval.hpp:32
typename CP::value_type value_type
Definition interval.hpp:36
CUDA static NI bool interpret(const F &f, const Env &env, Interval< U2 > &k, IDiagnostics &diagnostics)
Definition interval.hpp:175
CUDA static constexpr local_type eq_one()
Definition interval.hpp:90
CUDA static constexpr local_type bot()
Definition interval.hpp:92
CUDA static constexpr local_type abs(const Interval< L > &x)
Definition interval.hpp:359
CUDA NI static constexpr bool is_supported_fun(Sig sig)
Definition interval.hpp:315
static constexpr const bool sequential
Definition interval.hpp:43
CUDA constexpr bool extract(Interval< A > &ua) const
Definition interval.hpp:274
CUDA static constexpr local_type reverse(const Interval< L > &x)
Definition interval.hpp:348
CUDA constexpr Interval()
Definition interval.hpp:63
CUDA constexpr UB & ub()
Definition interval.hpp:186
CUDA constexpr this_type & tell(const Interval< A > &other)
Definition interval.hpp:227
static constexpr const bool injective_concretization
Definition interval.hpp:49
CUDA static constexpr local_type mod(const Interval< L > &l, const Interval< K > &k)
Definition interval.hpp:572
static constexpr const bool preserve_concrete_covers
Definition interval.hpp:50
CUDA constexpr this_type & dtell_bot()
Definition interval.hpp:232
CUDA constexpr this_type & dtell_lb(const A &lb)
Definition interval.hpp:250
CUDA constexpr this_type & tell_lb(const A &lb, BInc< M > &has_changed)
Definition interval.hpp:197
CUDA static constexpr local_type neg(const Interval< L > &x)
Definition interval.hpp:353
typename CP::memory_type memory_type
Definition interval.hpp:37
CUDA static constexpr local_type fun(const Interval< L > &x)
Definition interval.hpp:373
static constexpr const bool is_totally_ordered
Definition interval.hpp:44
U LB
Definition interval.hpp:31
static constexpr const char * name
Definition interval.hpp:52
CUDA static constexpr local_type eq_zero()
Definition interval.hpp:88
static constexpr const bool preserve_top
Definition interval.hpp:46
CUDA constexpr this_type & dtell(const Interval< A > &other, BInc< M > &has_changed)
Definition interval.hpp:262
static constexpr const bool preserve_join
Definition interval.hpp:47
CUDA constexpr Interval(const typename U::value_type &x)
Definition interval.hpp:65
CUDA constexpr const UB & ub() const
Definition interval.hpp:189
CUDA constexpr this_type & dtell_ub(const A &ub, BInc< M > &has_changed)
Definition interval.hpp:244
CUDA constexpr this_type & tell_lb(const A &lb)
Definition interval.hpp:209
CUDA constexpr this_type & dtell_ub(const A &ub)
Definition interval.hpp:256
CUDA constexpr this_type & tell_top()
Definition interval.hpp:191
CUDA NI void print() const
Definition interval.hpp:307
static constexpr const bool preserve_meet
Definition interval.hpp:48
Interval< typename LB::local_type > local_type
Definition interval.hpp:34
CUDA constexpr Interval(const LB &lb, const UB &ub)
Definition interval.hpp:66
CUDA static constexpr local_type mul(const Interval< L > &l, const Interval< K > &k)
Definition interval.hpp:436
CUDA static constexpr local_type top()
Definition interval.hpp:93
CUDA static constexpr local_type add(const Interval< L > &x, const Interval< K > &y)
Definition interval.hpp:385
static constexpr const bool is_abstract_universe
Definition interval.hpp:42
CUDA constexpr local::BInc is_top() const
Definition interval.hpp:94
CUDA static constexpr local_type div(const Interval< L > &l, const Interval< K > &k)
Definition interval.hpp:502
CUDA static NI bool interpret_ask(const F &f, const Env &env, Interval< U2 > &k, IDiagnostics &diagnostics)
Definition interval.hpp:141
CUDA constexpr local_type width() const
Definition interval.hpp:612
static constexpr const bool complemented
Definition interval.hpp:51
CUDA constexpr local_type median() const
Definition interval.hpp:619
CUDA constexpr value_type value() const
Definition interval.hpp:97
CUDA static constexpr local_type pow(const Interval< L > &l, const Interval< K > &k)
Definition interval.hpp:585
friend class Interval
Definition interval.hpp:40
CUDA constexpr local::BDec is_bot() const
Definition interval.hpp:95
CUDA static constexpr local_type fun(const Interval< L > &x, const Interval< K > &y)
Definition interval.hpp:598
CUDA NI F deinterpret() const
Definition interval.hpp:298
CUDA TFormula< typename Env::allocator_type > deinterpret(AVar x, const Env &env) const
Definition interval.hpp:279
CUDA static constexpr local_type sub(const Interval< L > &x, const Interval< K > &y)
Definition interval.hpp:390
CUDA constexpr LB & lb()
Definition interval.hpp:185
CUDA constexpr Interval(const Interval< A > &other)
Definition interval.hpp:69
CUDA constexpr Interval(Interval< A > &&other)
Definition interval.hpp:72
CUDA constexpr this_type & tell_ub(const A &ub, BInc< M > &has_changed)
Definition interval.hpp:203
CUDA constexpr this_type & tell(const Interval< A > &other, BInc< M > &has_changed)
Definition interval.hpp:221
CUDA constexpr this_type & tell_ub(const A &ub)
Definition interval.hpp:215
CUDA constexpr this_type & operator=(const Interval< A > &other)
Definition interval.hpp:77
CUDA constexpr this_type & dtell(const Interval< A > &other)
Definition interval.hpp:268
CUDA static NI bool interpret_tell(const F &f, const Env &env, Interval< U2 > &k, IDiagnostics &diagnostics)
Definition interval.hpp:123
CUDA constexpr const CP & as_product() const
Definition interval.hpp:96
CUDA constexpr const LB & lb() const
Definition interval.hpp:188
static constexpr const bool preserve_bot
Definition interval.hpp:45
Definition primitive_upset.hpp:118
#define CALL_WITH_ERROR_CONTEXT(MSG, CALL)
Definition diagnostics.hpp:180
#define CALL_WITH_ERROR_CONTEXT_WITH_MERGE(MSG, CALL, MERGE)
Definition diagnostics.hpp:167
Definition abstract_deps.hpp:14
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition cartesian_product.hpp:597
battery::vector< battery::tuple< F, F >, typename F::allocator_type > logic_set
Definition sort.hpp:127
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:572
@ NEQ
Equality relations.
Definition ast.hpp:112
@ TMOD
Truncated division, present in most programming languages, is defined as , i.e., it rounds towards ze...
Definition ast.hpp:102
@ EQ
Unary arithmetic function symbols.
Definition ast.hpp:112
@ ADD
Unary arithmetic function symbols.
Definition ast.hpp:97
@ IN
Set membership predicate.
Definition ast.hpp:108
@ POW
Unary arithmetic function symbols.
Definition ast.hpp:97
@ MIN
Unary arithmetic function symbols.
Definition ast.hpp:97
@ EDIV
Unary arithmetic function symbols.
Definition ast.hpp:105
@ FMOD
Floor division (Knuth D. (1972). The Art of Computer Programming, Vol 1, Fundamental Algorithms),...
Definition ast.hpp:103
@ MAX
Binary arithmetic function symbols.
Definition ast.hpp:97
@ TDIV
Unary arithmetic function symbols.
Definition ast.hpp:102
@ FDIV
Unary arithmetic function symbols.
Definition ast.hpp:103
@ ABS
Unary arithmetic function symbols.
Definition ast.hpp:96
@ SUB
Unary arithmetic function symbols.
Definition ast.hpp:97
@ MUL
Unary arithmetic function symbols.
Definition ast.hpp:97
@ CMOD
Ceil division is defined as . Modulus is defined as .
Definition ast.hpp:104
@ CDIV
Unary arithmetic function symbols.
Definition ast.hpp:104
@ NEG
Unary arithmetic function symbols.
Definition ast.hpp:96
@ EMOD
Euclidean division (Boute T. R. (1992). The Euclidean definition of the functions div and mod)....
Definition ast.hpp:105
CUDA constexpr auto join(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:534
CUDA Sig leq_of_constant(const TFormula< Allocator > &f)
Definition algorithm.hpp:60
CUDA constexpr auto meet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:541
CUDA constexpr bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:554
CUDA NI constexpr bool is_division(Sig sig)
Definition ast.hpp:196
CUDA constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:566
CUDA Sig geq_of_constant(const TFormula< Allocator > &f)
Definition algorithm.hpp:53
CUDA NI constexpr bool is_modulo(Sig sig)
Definition ast.hpp:200
#define UNTYPED
Definition sort.hpp:21