3#ifndef LALA_CORE_INTERVAL_HPP
4#define LALA_CORE_INTERVAL_HPP
14template<
class L,
class K>
18 template <
class LB,
class UB>
23 template <
class U>
constexpr const typename Interval<U>::LB& lb(
const Interval<U>& itv) {
return itv.lb(); }
24 template <
class L>
constexpr const L& lb(
const L& other) {
return other; }
25 template <
class U>
constexpr const typename Interval<U>::UB& ub(
const Interval<U>& itv) {
return itv.ub(); }
26 template <
class L>
constexpr const L& ub(
const L& other) {
return other; }
35 using UB =
typename LB::dual_type;
56 constexpr static const char*
name =
"Interval";
59 using LB2 =
typename LB::local_type;
60 using UB2 =
typename UB::local_type;
62 CUDA
constexpr Interval(
const CP& cp): cp(cp) {}
69 CUDA
constexpr Interval(
const typename U::value_type& x): cp(x, x) {}
104 template<
class A,
class B>
107 typename A::template flat_type<battery::local_memory>(a.
lb()),
108 typename B::template flat_type<battery::local_memory>(b.
lb()));
110 typename A::template flat_type<battery::local_memory>(a.
ub()),
111 typename B::template flat_type<battery::local_memory>(b.
ub()));
116 lb().project(fun,
typename A::template flat_type<battery::local_memory>(a.lb()));
117 ub().project(fun,
typename A::template flat_type<battery::local_memory>(a.ub()));
124 template<
bool diagnose = false,
class F,
class Env,
class U2>
126 if constexpr(LB::preserve_concrete_covers && LB::is_arithmetic) {
128 auto sort = f.sort();
129 if(sort.has_value() && sort->is_bool()) {
130 k.
meet(
local_type(LB::geq_k(LB::pre_universe::zero()), UB::leq_k(UB::pre_universe::one())));
142 template<
bool diagnose = false,
class F,
class Env,
class U2>
145 if(f.is_binary() && f.sig() ==
NEQ) {
148 else if(f.is_binary() && f.sig() ==
EQ) {
150 "When interpreting equality, the underlying bounds LB and UB failed to agree on the same value.",
153 itv.
lb() == itv.
ub()),
156 else if(f.is_binary() && f.sig() ==
IN && f.seq(0).is_variable()
157 && f.seq(1).is(F::S) && f.seq(1).s().size() == 1)
159 const auto&
lb = battery::get<0>(f.seq(1).s()[0]);
160 const auto&
ub = battery::get<1>(f.seq(1).s()[0]);
163 "Failed to interpret the decomposition of set membership `x in {[v..v]}` into equality `x == v`.",
167 "Failed to interpret the decomposition of set membership `x in {[l..u]}` into `x >= l /\\ x <= u`.",
176 template<IKind kind,
bool diagnose = false,
class F,
class Env,
class U2>
209 return cp.
join(other.cp);
228 return cp.
meet(other.cp);
236 template<
class Env,
class Allocator =
typename Env::allocator_type>
240 return F::make_false();
248 logical_set[0] = battery::make_tuple(std::move(logical_lb), std::move(logical_ub));
249 F set = F::make_set(std::move(logical_set));
250 F var = F::make_avar(x);
251 return F::make_binary(var,
IN, std::move(set),
UNTYPED, allocator);
261 if(logical_lb.is(F::R)) {
263 battery::get<1>(logical_lb.r()) = battery::get<0>(logical_ub.r());
299 nx.meet_lb(LB2::geq_k(LB2::pre_universe::zero()));
330 CUDA
constexpr static bounds_sign sign(
const Interval<A>& a) {
331 if(a.lb() >= LB2::geq_k(LB2::pre_universe::zero())) {
332 if(a.ub() > UB2::leq_k(UB2::pre_universe::zero())) {
340 if(a.ub() >= UB2::leq_k(UB2::pre_universe::zero())) {
360 using PLB =
typename LB::pre_universe;
361 using PUB =
typename UB::pre_universe;
362 using value_t =
typename PUB::value_type;
364 value_t x1 = PUB::project(fun, a.lb().value(), b.lb().value());
365 value_t x2 = PUB::project(fun, a.lb().value(), b.ub().value());
366 value_t x3 = PUB::project(fun, a.ub().value(), b.lb().value());
367 value_t x4 = PUB::project(fun, a.ub().value(), b.ub().value());
368 meet_lb(
LB(PLB::join(PLB::join(x1, x2), PLB::join(x3, x4))));
369 meet_ub(
UB(PUB::join(PUB::join(x1, x2), PUB::join(x3, x4))));
372 value_t x1 = PLB::project(fun, a.lb().value(), b.lb().value());
373 value_t x2 = PLB::project(fun, a.lb().value(), b.ub().value());
374 value_t x3 = PLB::project(fun, a.ub().value(), b.lb().value());
375 value_t x4 = PLB::project(fun, a.ub().value(), b.ub().value());
376 meet_lb(
LB(PLB::join(PLB::join(x1, x2), PLB::join(x3, x4))));
378 x1 = PUB::project(fun, a.lb().value(), b.lb().value());
379 x2 = PUB::project(fun, a.lb().value(), b.ub().value());
380 x3 = PUB::project(fun, a.ub().value(), b.lb().value());
381 x4 = PUB::project(fun, a.ub().value(), b.ub().value());
382 meet_ub(
UB(PUB::join(PUB::join(x1, x2), PUB::join(x3, x4))));
389 piecewise_monotone_fun(
MUL, a, b);
394 constexpr auto zero = LB2::pre_universe::zero();
395 using flat_type = LB2::local_flat_type;
396 constexpr auto fzero = flat_type::eq_k(zero);
401 piecewise_monotone_fun(divfun, a,
403 (b.
ub().value() == zero) ? UB2(-1) : b.
ub()));
406 flat_type al(a.
lb());
407 flat_type au(a.
ub());
408 flat_type bl(b.
lb());
409 flat_type bu(b.
ub());
412 if(bl <= fzero && bu >= fzero) {
413 if(bl == fzero && bu == fzero) {
meet_bot();
return; }
414 if(al == fzero && au == fzero) {
meet_lb(LB2::geq_k(zero));
meet_ub(UB2::leq_k(zero));
return; }
415 if(bl == fzero) {
lb().project(divfun, al, bu);
return; }
416 ub().project(divfun, al, bl);
420 piecewise_monotone_fun(divfun, a, b);
428 flat_fun(modfun, a, b);
440 return LB2::is_trivial_fun(fun) && UB2::is_trivial_fun(fun)
445 if(LB2::is_order_preserving_fun(fun) && UB2::is_order_preserving_fun(fun)) {
448 else if constexpr(LB::is_arithmetic) {
449 if (fun ==
SUB) {
sub(x, y); }
450 else if (fun ==
MUL) {
mul(x, y); }
453 else if (fun ==
POW) {
pow(x, y); }
458 static_assert(LB::is_totally_ordered && LB::is_arithmetic,
459 "Width is only defined for totally ordered arithmetic intervals.");
467 static_assert(LB::is_totally_ordered && LB::is_arithmetic,
468 "Median function is only defined for totally ordered arithmetic intervals.");
472 auto u =
ub().value();
473 return local_type(l + battery::fdiv((u - l), 2), l + battery::cdiv((u - l), 2));
479template<
class L,
class K>
482 if(a.
is_bot()) {
return b; }
483 if(b.
is_bot()) {
return a; }
487template<
class L,
class K>
493template<
class L,
class K>
494CUDA
constexpr bool operator<=(
const Interval<L>& a,
const Interval<K>& b)
496 return a.is_bot() || a.as_product() <= b.as_product();
499template<
class L,
class K>
505template<
class L,
class K>
506CUDA
constexpr bool operator>=(
const Interval<L>& a,
const Interval<K>& b)
511template<
class L,
class K>
517template<
class L,
class K>
523template<
class L,
class K>
524CUDA
constexpr bool operator!=(
const Interval<L>& a,
const Interval<K>& b)
526 return a.as_product() != b.as_product() && !(a.is_bot() && b.is_bot());
531 return s <<
"[" << itv.
lb() <<
".." << itv.
ub() <<
"]";
Definition cartesian_product.hpp:62
CUDA constexpr bool join(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:276
CUDA TFormula< Allocator > deinterpret(AVar x, const Env &env, const Allocator &allocator=Allocator()) const
Definition cartesian_product.hpp:386
CUDA constexpr bool extract(CartesianProduct< Bs... > &ua) const
Definition cartesian_product.hpp:301
CUDA constexpr local::B is_bot() const
Definition cartesian_product.hpp:214
CUDA constexpr local::B is_top() const
Definition cartesian_product.hpp:207
CUDA constexpr type_of< i > & project()
Definition cartesian_product.hpp:193
CUDA constexpr value_type value() const
Definition cartesian_product.hpp:202
static constexpr const bool injective_concretization
Definition cartesian_product.hpp:83
CUDA constexpr bool meet(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:290
CUDA constexpr void meet_bot()
Definition cartesian_product.hpp:285
static constexpr const bool sequential
Definition cartesian_product.hpp:77
CUDA constexpr void join_top()
Definition cartesian_product.hpp:271
battery::tuple< typename As::value_type... > value_type
Definition cartesian_product.hpp:74
static CUDA constexpr local_type top()
Definition cartesian_product.hpp:122
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 constexpr const bool preserve_top
Definition cartesian_product.hpp:80
static CUDA constexpr local_type bot()
Definition cartesian_product.hpp:117
Definition diagnostics.hpp:19
Definition interval.hpp:32
CUDA constexpr this_type & operator=(const this_type &other)
Definition interval.hpp:86
CUDA constexpr bool meet(const Interval< A > &other)
Definition interval.hpp:227
typename LB::dual_type UB
Definition interval.hpp:35
typename CP::value_type value_type
Definition interval.hpp:39
CUDA static NI bool interpret(const F &f, const Env &env, Interval< U2 > &k, IDiagnostics &diagnostics)
Definition interval.hpp:177
CUDA constexpr bool meet_ub(const A &ub)
Definition interval.hpp:222
CUDA static constexpr local_type eq_one()
Definition interval.hpp:94
CUDA static constexpr local_type bot()
Definition interval.hpp:96
CUDA constexpr void mul(const local_type &a, const local_type &b)
Definition interval.hpp:387
static constexpr const bool sequential
Definition interval.hpp:46
CUDA constexpr bool extract(Interval< A > &ua) const
Definition interval.hpp:232
CUDA static constexpr local_type reverse(const Interval< L > &x)
Definition interval.hpp:287
CUDA constexpr Interval()
Definition interval.hpp:67
CUDA constexpr void mod(Sig modfun, const local_type &a, const local_type &b)
Definition interval.hpp:425
CUDA constexpr UB & ub()
Definition interval.hpp:188
static constexpr const bool is_arithmetic
Definition interval.hpp:55
static constexpr const bool injective_concretization
Definition interval.hpp:52
static constexpr const bool preserve_concrete_covers
Definition interval.hpp:53
CUDA constexpr local::B is_bot() const
Definition interval.hpp:98
CUDA constexpr void div(Sig divfun, const local_type &a, const local_type &b)
Definition interval.hpp:393
static CUDA constexpr bool is_trivial_fun(Sig fun)
Definition interval.hpp:439
CUDA constexpr void project(Sig fun, const local_type &x)
Definition interval.hpp:304
CUDA constexpr bool join_ub(const A &ub)
Definition interval.hpp:203
typename CP::memory_type memory_type
Definition interval.hpp:40
CUDA constexpr void additive_inverse(const this_type &x)
Definition interval.hpp:282
CUDA constexpr bool join(const Interval< A > &other)
Definition interval.hpp:208
static constexpr const bool is_totally_ordered
Definition interval.hpp:47
U LB
Definition interval.hpp:34
static constexpr const char * name
Definition interval.hpp:56
CUDA static constexpr local_type eq_zero()
Definition interval.hpp:92
static constexpr const bool preserve_top
Definition interval.hpp:48
static constexpr const bool preserve_join
Definition interval.hpp:51
CUDA constexpr Interval(const typename U::value_type &x)
Definition interval.hpp:69
CUDA constexpr const UB & ub() const
Definition interval.hpp:191
CUDA constexpr void pow(const local_type &a, const local_type &b)
Definition interval.hpp:432
CUDA NI void print() const
Definition interval.hpp:271
CUDA TFormula< Allocator > deinterpret(AVar x, const Env &env, const Allocator &allocator=Allocator()) const
Definition interval.hpp:237
static constexpr const bool preserve_meet
Definition interval.hpp:50
Interval< typename LB::local_type > local_type
Definition interval.hpp:37
CUDA constexpr Interval(const LB &lb, const UB &ub)
Definition interval.hpp:70
CUDA static constexpr local_type top()
Definition interval.hpp:97
CUDA constexpr void meet_bot()
Definition interval.hpp:212
CUDA constexpr void add(const local_type &x, const local_type &y)
Definition interval.hpp:311
CUDA constexpr void join_top()
Definition interval.hpp:193
CUDA constexpr void abs(const local_type &x)
Definition interval.hpp:296
static constexpr const bool is_abstract_universe
Definition interval.hpp:45
CUDA constexpr void project(Sig fun, const local_type &x, const local_type &y)
Definition interval.hpp:444
CUDA static NI bool interpret_ask(const F &f, const Env &env, Interval< U2 > &k, IDiagnostics &diagnostics)
Definition interval.hpp:143
CUDA constexpr local_type width() const
Definition interval.hpp:457
static constexpr const bool complemented
Definition interval.hpp:54
CUDA constexpr local_type median() const
Definition interval.hpp:466
CUDA constexpr value_type value() const
Definition interval.hpp:101
friend class Interval
Definition interval.hpp:43
CUDA constexpr void sub(const local_type &x, const local_type &y)
Definition interval.hpp:315
CUDA constexpr bool join_lb(const A &lb)
Definition interval.hpp:198
CUDA constexpr local::B is_top() const
Definition interval.hpp:99
CUDA NI F deinterpret() const
Definition interval.hpp:259
CUDA constexpr LB & lb()
Definition interval.hpp:187
CUDA constexpr Interval(const Interval< A > &other)
Definition interval.hpp:73
CUDA constexpr Interval(Interval< A > &&other)
Definition interval.hpp:76
CUDA constexpr void neg(const local_type &x)
Definition interval.hpp:291
CUDA constexpr this_type & operator=(const Interval< A > &other)
Definition interval.hpp:81
CUDA constexpr bool meet_lb(const A &lb)
Definition interval.hpp:217
CUDA static NI bool interpret_tell(const F &f, const Env &env, Interval< U2 > &k, IDiagnostics &diagnostics)
Definition interval.hpp:125
CUDA constexpr const CP & as_product() const
Definition interval.hpp:100
CUDA constexpr const LB & lb() const
Definition interval.hpp:190
static constexpr const bool preserve_bot
Definition interval.hpp:49
#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:530
battery::vector< battery::tuple< F, F >, typename F::allocator_type > logic_set
Definition sort.hpp:127
CUDA constexpr LDual dual(const L &x)
Definition arith_bound.hpp:110
CUDA constexpr auto fjoin(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:463
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:503
@ NEQ
Equality relations.
Definition ast.hpp:112
@ 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
@ 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
@ NEG
Unary arithmetic function symbols.
Definition ast.hpp:96
CUDA Sig leq_of_constant(const TFormula< Allocator > &f)
Definition algorithm.hpp:60
CUDA constexpr bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:484
CUDA NI constexpr bool is_division(Sig sig)
Definition ast.hpp:196
CUDA constexpr auto fmeet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:470
CUDA constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:497
CUDA constexpr auto meet(const Interval< L > &, const Interval< K > &)
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
CUDA constexpr const CartesianProduct< As... >::template type_of< i > & project(const CartesianProduct< As... > &cp)
Similar to cp.template project<i>(), just to avoid the ".template" syntax.
Definition cartesian_product.hpp:412
#define UNTYPED
Definition sort.hpp:21