3#ifndef LALA_CORE_CARTESIAN_PRODUCT_HPP
4#define LALA_CORE_CARTESIAN_PRODUCT_HPP
6#include "battery/utility.hpp"
7#include "battery/vector.hpp"
8#include "battery/tuple.hpp"
9#include "battery/variant.hpp"
16class CartesianProduct;
20 CUDA
constexpr auto index_sequence_of(
const CartesianProduct<As...>&) {
21 return std::index_sequence_for<As...>{};
25 CUDA
constexpr auto index_sequence_of(
const battery::tuple<As...>&) {
26 return std::index_sequence_for<As...>{};
29 template <
class A,
class B>
30 CUDA
constexpr auto index_sequence_of(
const A& a,
const B& b) {
31 static_assert(
decltype(impl::index_sequence_of(a))::size() ==
decltype(impl::index_sequence_of(b))::size());
32 return impl::index_sequence_of(a);
36 CUDA
constexpr typename CartesianProduct<Os...>::local_type make_cp(Os... os) {
42 static constexpr bool value =
false;
46 struct is_product<CartesianProduct<As...>> {
47 static constexpr bool value =
true;
51 struct is_product<
battery::tuple<As...>> {
52 static constexpr bool value =
true;
56 inline static constexpr bool is_product_v = is_product<A>::value;
65 using type_of =
typename battery::tuple_element<i, battery::tuple<As...>>::type;
66 constexpr static size_t n = battery::tuple_size<battery::tuple<As...>>{};
67 static_assert(
n > 0,
"CartesianProduct must not be empty.");
74 using value_type = battery::tuple<
typename As::value_type...>;
77 constexpr static const bool sequential = (... && As::sequential);
79 constexpr static const bool preserve_bot = (... && As::preserve_bot);
80 constexpr static const bool preserve_top = (... && As::preserve_top);
86 constexpr static const char*
name =
"CartesianProduct";
89 battery::tuple<As...> val;
101 template<
class... Bs>
106 template <
class... Bs>
113 static_assert(
sequential,
"operator= seq (CartesianProduct).");
123 static_assert(
sequential,
"operator= seq (CartesianProduct).");
139 template<
IKind kind,
bool diagnose,
size_t i,
class F,
class Env,
class... Bs>
141 return type_of<i>::template interpret<kind, diagnose>(f, env, k.template project<i>(), diagnostics);
144 template<
IKind kind,
bool diagnose,
size_t i = 0,
class F,
class Env,
class... Bs>
145 CUDA NI
static bool interpret_all(
const F& f, CartesianProduct<Bs...>& k,
bool empty,
const Env& env, IDiagnostics& diagnostics) {
146 if constexpr(i ==
n) {
150 bool res = interpret_one<kind, diagnose, i>(f, env, k, diagnostics);
151 return interpret_all<kind, diagnose, i+1>(f, k, empty && !res, env, diagnostics);
156 template<
size_t i,
bool diagnose =
false,
class F,
class Env,
class... Bs>
158 return interpret_one<IKind::TELL, diagnose, i>(f, env, k, diagnostics);
161 template<
size_t i,
bool diagnose =
false,
class F,
class Env,
class... Bs>
163 return interpret_one<IKind::ASK, diagnose, i>(f, env, k, diagnostics);
166 template<
IKind kind,
bool diagnose =
false,
class F,
class Env,
class... Bs>
169 "No component of this Cartesian product can interpret this formula.",
170 (interpret_all<kind, diagnose>(f, k,
true, env, diagnostics))
175 template<
bool diagnose,
class F,
class Env,
class... Bs>
177 return interpret<IKind::TELL, diagnose>(f, env, k, diagnostics);
180 template<
bool diagnose,
class F,
class Env,
class... Bs>
182 return interpret<IKind::ASK, diagnose>(f, env, k, diagnostics);
186 template<
size_t... I>
187 CUDA
constexpr value_type value_(std::index_sequence<I...>)
const {
191 template<
size_t... I>
192 CUDA
constexpr local::BInc is_top_(std::index_sequence<I...>)
const {
193 return (... || project<I>().
is_top());
196 template<
size_t... I>
197 CUDA
constexpr local::BDec is_bot_(std::index_sequence<I...>)
const {
198 return (... && project<I>().
is_bot());
205 return battery::get<i>(val);
210 return battery::get<i>(val);
214 return value_(std::index_sequence_for<As...>{});
219 return is_top_(std::index_sequence_for<As...>{});
224 return is_bot_(std::index_sequence_for<As...>{});
228 template<
size_t i = 0,
class M,
class... Bs>
230 if constexpr (i <
n) {
231 project<i>().
tell(other.template project<i>(), has_changed);
232 return tell_<i+1>(other, has_changed);
239 template<
size_t i = 0,
class... Bs>
240 CUDA
constexpr this_type& tell_(
const CartesianProduct<Bs...>& other) {
241 if constexpr (i <
n) {
242 project<i>().tell(other.template project<i>());
243 return tell_<i+1>(other);
250 template<
size_t i = 0,
class M,
class... Bs>
251 CUDA
constexpr this_type& dtell_(
const CartesianProduct<Bs...>& other, BInc<M>& has_changed) {
252 if constexpr (i <
n) {
253 project<i>().dtell(other.template project<i>(), has_changed);
254 return dtell_<i+1>(other, has_changed);
261 template<
size_t i = 0,
class... Bs>
262 CUDA
constexpr this_type& dtell_(
const CartesianProduct<Bs...>& other) {
263 if constexpr (i <
n) {
264 project<i>().dtell(other.template project<i>());
265 return dtell_<i+1>(other);
272 template<
size_t i = 0>
274 if constexpr (i <
n) {
275 project<i>().dtell_bot();
276 return dtell_bot_<i+1>();
283 template<
size_t i = 0,
class... Bs>
284 CUDA
constexpr bool extract_(CartesianProduct<Bs...>& ua) {
285 if constexpr (i <
n) {
286 bool is_under = project<i>().extract(ua.template project<i>());
287 return is_under && extract_<i+1>(ua);
294 template <
size_t i = 0>
295 CUDA
constexpr void tell_top_() {
296 if constexpr(i <
n) {
297 project<i>().tell_top();
308 template <
class M,
class... Bs>
310 return tell_(other, has_changed);
313 template<
size_t i,
class Ai,
class M>
315 project<i>().
tell(a, has_changed);
319 template <
class... Bs>
324 template<
size_t i,
class Ai>
326 project<i>().
tell(a);
335 template <
class M,
class... Bs>
337 return dtell_(other, has_changed);
340 template<
size_t i,
class Ai,
class M>
342 project<i>().
dtell(a, has_changed);
346 template <
class... Bs>
348 return dtell_(other);
351 template<
size_t i,
class Ai>
353 project<i>().
dtell(a);
358 template <
class... Bs>
366 template<
Sig sig,
class A,
size_t... I>
367 CUDA
static constexpr auto fun_(
const A& a, std::index_sequence<I...>)
369 return impl::make_cp((As::template fun<sig>(a.template project<I>()))...);
372 template<
Sig sig,
class A,
class B,
size_t... I>
373 CUDA
static constexpr auto fun_(
const A& a,
const B& b, std::index_sequence<I...>)
375 return impl::make_cp((As::template fun<sig>(a.template project<I>(), b.template project<I>()))...);
378 template<
Sig sig,
class A,
class B,
size_t... I>
379 CUDA
static constexpr auto fun_left(
const A& a,
const B& b, std::index_sequence<I...>)
381 return impl::make_cp((As::template fun<sig>(a.template project<I>(), b))...);
384 template<
Sig sig,
class A,
class B,
size_t... I>
385 CUDA
static constexpr auto fun_right(
const A& a,
const B& b, std::index_sequence<I...>)
387 return impl::make_cp((As::template fun<sig>(a, b.template project<I>()))...);
392 return (... && As::is_supported_fun(sig));
396 template<
Sig sig,
class... Bs>
398 return fun_<sig>(a, impl::index_sequence_of(a));
403 template<
Sig sig,
class... As2,
class... Bs>
405 return fun_<sig>(a, b, impl::index_sequence_of(a, b));
408 template<
Sig sig,
class... As2,
class B>
410 return fun_left<sig>(a, b, impl::index_sequence_of(a));
413 template<
Sig sig,
class A,
class... Bs>
415 return fun_right<sig>(a, b, impl::index_sequence_of(b));
419 template<
size_t i,
class Env,
class Allocator =
typename Env::allocator_type>
423 if constexpr(i <
n) {
424 auto f = project<i>().deinterpret(x, env);
428 return deinterpret_<i+1, Env>(x, seq, env);
431 if(seq.size() == 1) {
432 return std::move(seq[0]);
445 using allocator_t =
typename Env::allocator_type;
447 return deinterpret_<0, Env>(x, seq, env);
451 template<
size_t i = 0>
452 CUDA NI
void print_()
const {
453 if constexpr(i <
n) {
454 project<i>().print();
455 if constexpr(i <
n - 1) {
469template<
size_t i,
class... As>
470CUDA
constexpr const typename CartesianProduct<As...>::template type_of<i>&
472 return cp.template project<i>();
475template<
size_t i,
class... As>
476CUDA
constexpr typename CartesianProduct<As...>::template type_of<i>&
478 return cp.template project<i>();
483 template<
class A,
class B,
size_t... I>
484 CUDA
constexpr auto join_(
const A& a,
const B& b, std::index_sequence<I...>)
486 return make_cp(
join(project<I>(a), project<I>(b))...);
489 template<
class A,
class B,
size_t... I>
490 CUDA
constexpr auto meet_(
const A& a,
const B& b, std::index_sequence<I...>)
492 return make_cp(
meet(project<I>(a), project<I>(b))...);
495 template<
class A,
class B,
size_t... I>
496 CUDA
constexpr bool eq_(
const A& a,
const B& b, std::index_sequence<I...>)
498 return (... && (project<I>(a) == project<I>(b)));
501 template<
class A,
class B,
size_t... I>
502 CUDA
constexpr bool neq_(
const A& a,
const B& b, std::index_sequence<I...>)
504 return (... || (project<I>(a) != project<I>(b)));
507 template<
class A,
class B,
size_t... I>
508 CUDA
constexpr bool leq_(
const A& a,
const B& b, std::index_sequence<I...>)
510 return (... && (project<I>(a) <= project<I>(b)));
513 template<
class A,
class B,
size_t... I>
514 CUDA
constexpr bool lt_(
const A& a,
const B& b, std::index_sequence<I...>)
516 return leq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
519 template<
class A,
class B,
size_t... I>
520 CUDA
constexpr bool geq_(
const A& a,
const B& b, std::index_sequence<I...>)
522 return (... && (project<I>(a) >= project<I>(b)));
525 template<
class A,
class B,
size_t... I>
526 CUDA
constexpr bool gt_(
const A& a,
const B& b, std::index_sequence<I...>)
528 return geq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
533template<
class... As,
class... Bs>
536 return impl::join_(a, b, impl::index_sequence_of(a, b));
540template<
class... As,
class... Bs>
543 return impl::meet_(a, b, impl::index_sequence_of(a, b));
547template<
class... As,
class... Bs>
548CUDA
constexpr bool operator<=(
const CartesianProduct<As...>& a,
const CartesianProduct<Bs...>& b)
550 return impl::leq_(a, b, impl::index_sequence_of(a, b));
553template<
class... As,
class... Bs>
556 return impl::lt_(a, b, impl::index_sequence_of(a, b));
559template<
class... As,
class... Bs>
560CUDA
constexpr bool operator>=(
const CartesianProduct<As...>& a,
const CartesianProduct<Bs...>& b)
562 return impl::geq_(a, b, impl::index_sequence_of(a, b));
565template<
class... As,
class... Bs>
568 return impl::gt_(a, b, impl::index_sequence_of(a, b));
571template<
class... As,
class... Bs>
574 return impl::eq_(a, b, impl::index_sequence_of(a, b));
577template<
class... As,
class... Bs>
578CUDA
constexpr bool operator!=(
const CartesianProduct<As...>& a,
const CartesianProduct<Bs...>& b)
580 return impl::neq_(a, b, impl::index_sequence_of(a, b));
584 template<
size_t i = 0,
class... As>
585 void std_print(std::ostream &s,
const CartesianProduct<As...> &cp) {
586 if constexpr(i < CartesianProduct<As...>::n) {
588 if constexpr(i < CartesianProduct<As...>::n - 1) {
590 std_print<i+1>(s, cp);
596template<
class A,
class... As>
601 impl::std_print<0>(s, cp);
Definition cartesian_product.hpp:62
CartesianProduct< As... > this_type
Definition cartesian_product.hpp:68
CUDA constexpr this_type & operator=(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:107
CUDA constexpr this_type & dtell(const Ai &a)
Definition cartesian_product.hpp:352
CUDA constexpr this_type & dtell(const CartesianProduct< Bs... > &other, BInc< M > &has_changed)
Definition cartesian_product.hpp:336
constexpr CartesianProduct()=default
static CUDA bool interpret_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:181
static constexpr const bool complemented
Definition cartesian_product.hpp:85
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
static CUDA bool interpret_one_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:162
CUDA constexpr type_of< i > & project()
Definition cartesian_product.hpp:204
static CUDA bool interpret_one_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:157
CUDA constexpr this_type & tell(const Ai &a, BInc< M > &has_changed)
Definition cartesian_product.hpp:314
CUDA constexpr value_type value() const
Definition cartesian_product.hpp:213
static constexpr const bool is_totally_ordered
Definition cartesian_product.hpp:78
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
static CUDA bool interpret_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:176
static constexpr const bool preserve_join
Definition cartesian_product.hpp:81
CUDA constexpr this_type & tell_top()
Definition cartesian_product.hpp:303
CUDA void print() const
Definition cartesian_product.hpp:463
static constexpr const bool sequential
Definition cartesian_product.hpp:77
typename battery::tuple_element< i, battery::tuple< As... > >::type type_of
Definition cartesian_product.hpp:65
static constexpr const char * name
Definition cartesian_product.hpp:86
CUDA constexpr this_type & dtell(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:347
CUDA constexpr this_type & operator=(const this_type &other)
Definition cartesian_product.hpp:117
static constexpr size_t n
Definition cartesian_product.hpp:66
static CUDA constexpr auto fun(const CartesianProduct< Bs... > &a)
Definition cartesian_product.hpp:397
CUDA constexpr this_type & dtell(const Ai &a, BInc< M > &has_changed)
Definition cartesian_product.hpp:341
static constexpr const bool preserve_bot
Definition cartesian_product.hpp:79
static constexpr const bool preserve_meet
Definition cartesian_product.hpp:82
CUDA constexpr this_type & tell(const Ai &a)
Definition cartesian_product.hpp:325
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
CUDA constexpr this_type & tell(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:320
CUDA constexpr const type_of< i > & project() const
Definition cartesian_product.hpp:209
static CUDA constexpr local_type top()
Definition cartesian_product.hpp:133
typename type_of< 0 >::memory_type memory_type
Definition cartesian_product.hpp:70
CUDA constexpr CartesianProduct(const As &... as)
Definition cartesian_product.hpp:94
CUDA constexpr CartesianProduct(typename As::value_type... vs)
Definition cartesian_product.hpp:96
CartesianProduct< typename As::local_type... > local_type
Definition cartesian_product.hpp:69
static constexpr const bool preserve_concrete_covers
Definition cartesian_product.hpp:84
CUDA static NI bool interpret(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:167
static CUDA constexpr auto fun(const CartesianProduct< As2... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:404
static constexpr const bool preserve_top
Definition cartesian_product.hpp:80
CUDA constexpr CartesianProduct(CartesianProduct< Bs... > &&other)
Definition cartesian_product.hpp:102
static CUDA constexpr local_type bot()
Definition cartesian_product.hpp:128
static CUDA constexpr auto fun(const A &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:414
static CUDA constexpr auto fun(const CartesianProduct< As2... > &a, const B &b)
Definition cartesian_product.hpp:409
CUDA TFormula< typename Env::allocator_type > deinterpret(AVar x, const Env &env) const
Definition cartesian_product.hpp:444
static constexpr const bool is_abstract_universe
Definition cartesian_product.hpp:76
static CUDA constexpr bool is_supported_fun(Sig sig)
Definition cartesian_product.hpp:391
CUDA constexpr CartesianProduct(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:99
CUDA constexpr CartesianProduct(As &&... as)
Definition cartesian_product.hpp:95
Definition diagnostics.hpp:19
Definition primitive_upset.hpp:118
CUDA constexpr this_type & tell(const this_type2< M1 > &other, BInc< M2 > &has_changed)
Definition primitive_upset.hpp:239
#define CALL_WITH_ERROR_CONTEXT(MSG, CALL)
Definition diagnostics.hpp:180
::lala::BInc< battery::local_memory > BInc
Definition primitive_upset.hpp:85
::lala::BDec< battery::local_memory > BDec
Definition primitive_upset.hpp:86
Definition abstract_deps.hpp:14
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition cartesian_product.hpp:597
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:572
@ AND
Unary arithmetic function symbols.
Definition ast.hpp:114
CUDA constexpr auto join(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:534
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 constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:566
IKind
Definition ast.hpp:28
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:471