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"
16 class 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);
85 constexpr
static const char*
name =
"CartesianProduct";
88 battery::tuple<As...> val;
100 template<
class... Bs>
103 template<
class... Bs>
108 template <
class... Bs>
129 template<
IKind kind,
bool diagnose,
size_t i,
class F,
class Env,
class... Bs>
131 return type_of<i>::template interpret<kind, diagnose>(f, env, k.template project<i>(), diagnostics);
134 template<
IKind kind,
bool diagnose,
size_t i = 0,
class F,
class Env,
class... Bs>
135 CUDA NI
static bool interpret_all(
const F& f, CartesianProduct<Bs...>& k,
bool empty,
const Env& env, IDiagnostics& diagnostics) {
136 if constexpr(i ==
n) {
140 bool res = interpret_one<kind, diagnose, i>(f, env, k, diagnostics);
141 return interpret_all<kind, diagnose, i+1>(f, k, empty && !res, env, diagnostics);
146 template<
size_t i,
bool diagnose =
false,
class F,
class Env,
class... Bs>
148 return interpret_one<IKind::TELL, diagnose, i>(f, env, k, diagnostics);
151 template<
size_t i,
bool diagnose =
false,
class F,
class Env,
class... Bs>
153 return interpret_one<IKind::ASK, diagnose, i>(f, env, k, diagnostics);
156 template<
IKind kind,
bool diagnose =
false,
class F,
class Env,
class... Bs>
159 "No component of this Cartesian product can interpret this formula.",
160 (interpret_all<kind, diagnose>(f, k,
true, env, diagnostics))
165 template<
bool diagnose,
class F,
class Env,
class... Bs>
167 return interpret<IKind::TELL, diagnose>(f, env, k, diagnostics);
170 template<
bool diagnose,
class F,
class Env,
class... Bs>
172 return interpret<IKind::ASK, diagnose>(f, env, k, diagnostics);
176 template<
size_t... I>
177 CUDA constexpr
value_type value_(std::index_sequence<I...>)
const {
181 template<
size_t... I>
182 CUDA constexpr
local::B is_top_(std::index_sequence<I...>)
const {
183 return (... && project<I>().
is_top());
186 template<
size_t... I>
187 CUDA constexpr
local::B is_bot_(std::index_sequence<I...>)
const {
188 return (... || project<I>().
is_bot());
195 return battery::get<i>(val);
200 return battery::get<i>(val);
204 return value_(std::index_sequence_for<As...>{});
209 return is_top_(std::index_sequence_for<As...>{});
216 return is_bot_(std::index_sequence_for<As...>{});
220 template<
size_t i = 0,
class... Bs>
222 if constexpr (i <
n) {
223 bool has_changed = project<i>().join(other.template project<i>());
224 has_changed |= join_<i+1>(other);
232 template<
size_t i = 0,
class... Bs>
233 CUDA constexpr
bool meet_(
const CartesianProduct<Bs...>& other) {
234 if constexpr (i <
n) {
235 bool has_changed = project<i>().meet(other.template project<i>());
236 has_changed |= meet_<i+1>(other);
244 template<
size_t i = 0>
245 CUDA constexpr
void meet_bot_() {
246 if constexpr (i <
n) {
247 project<i>().meet_bot();
252 template<
size_t i = 0,
class... Bs>
253 CUDA constexpr
bool extract_(CartesianProduct<Bs...>& ua) {
254 if constexpr (i <
n) {
255 bool is_under = project<i>().extract(ua.template project<i>());
256 return is_under && extract_<i+1>(ua);
263 template <
size_t i = 0>
264 CUDA constexpr
void join_top_() {
265 if constexpr(i <
n) {
266 project<i>().join_top();
276 template <
class... Bs>
281 template<
size_t i,
class Ai>
282 CUDA constexpr
bool join(
const Ai& a) {
283 return project<i>().join(a);
290 template <
class... Bs>
295 template<
size_t i,
class Ai>
296 CUDA constexpr
bool meet(
const Ai& a) {
297 return project<i>().meet(a);
301 template <
class... Bs>
309 template<
class A,
size_t... I>
310 CUDA constexpr
void project(
Sig fun,
const A& a, std::index_sequence<I...>)
312 (project<I>().project(fun, a.template project<I>()),...);
315 template<
class A,
class B,
size_t... I>
316 CUDA constexpr
void project(
Sig fun,
const A& a,
const B& b, std::index_sequence<I...>)
318 (project<I>().project(fun, a.template project<I>(), b.template project<I>()),...);
321 template<
class A,
class B,
size_t... I>
322 CUDA constexpr
void project_left(
Sig fun,
const A& a,
const B& b, std::index_sequence<I...>)
324 (project<I>().project(fun, a.template project<I>(), b),...);
327 template<
class A,
class B,
size_t... I>
328 CUDA constexpr
void project_right(
Sig fun,
const A& a,
const B& b, std::index_sequence<I...>)
330 (project<I>().project(fun, a, b.template project<I>()),...);
335 return (... && As::is_trivial_fun(fun));
339 template<
class... Bs>
341 project(fun, a, impl::index_sequence_of(a));
346 template<
class... As2,
class... Bs>
348 project(fun, a, b, impl::index_sequence_of(a, b));
351 template<
class... As2,
class B>
353 project_left(fun, a, b, impl::index_sequence_of(a));
356 template<
class A,
class... Bs>
358 project_right(fun, a, b, impl::index_sequence_of(b));
362 template<
size_t i,
class Env,
class Allocator =
typename Env::allocator_type>
366 if constexpr(i <
n) {
367 auto f = project<i>().deinterpret(x, env, allocator);
369 seq.push_back(project<i>().
deinterpret(x, env, allocator));
371 return deinterpret_<i+1, Env>(x, seq, env, allocator);
374 if(seq.size() == 1) {
375 return std::move(seq[0]);
386 template<
class Env,
class Allocator =
typename Env::allocator_type>
389 return deinterpret_<0, Env>(x, seq, env, allocator);
393 template<
size_t i = 0>
394 CUDA NI
void print_()
const {
395 if constexpr(i <
n) {
396 project<i>().print();
397 if constexpr(i <
n - 1) {
411 template<
size_t i,
class... As>
412 CUDA constexpr
const typename CartesianProduct<As...>::template type_of<i>&
414 return cp.template project<i>();
417 template<
size_t i,
class... As>
418 CUDA constexpr
typename CartesianProduct<As...>::template type_of<i>&
420 return cp.template project<i>();
425 template<
class A,
class B,
size_t... I>
426 CUDA constexpr
auto fjoin_(
const A& a,
const B& b, std::index_sequence<I...>)
428 return make_cp(
fjoin(project<I>(a), project<I>(b))...);
431 template<
class A,
class B,
size_t... I>
432 CUDA constexpr
auto fmeet_(
const A& a,
const B& b, std::index_sequence<I...>)
434 return make_cp(
fmeet(project<I>(a), project<I>(b))...);
437 template<
class A,
class B,
size_t... I>
438 CUDA constexpr
bool eq_(
const A& a,
const B& b, std::index_sequence<I...>)
440 return (... && (project<I>(a) == project<I>(b)));
443 template<
class A,
class B,
size_t... I>
444 CUDA constexpr
bool neq_(
const A& a,
const B& b, std::index_sequence<I...>)
446 return (... || (project<I>(a) != project<I>(b)));
449 template<
class A,
class B,
size_t... I>
450 CUDA constexpr
bool leq_(
const A& a,
const B& b, std::index_sequence<I...>)
452 return (... && (project<I>(a) <= project<I>(b)));
455 template<
class A,
class B,
size_t... I>
456 CUDA constexpr
bool lt_(
const A& a,
const B& b, std::index_sequence<I...>)
458 return leq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
463 template<
class... As,
class... Bs>
466 return impl::fjoin_(a, b, impl::index_sequence_of(a, b));
470 template<
class... As,
class... Bs>
473 return impl::fmeet_(a, b, impl::index_sequence_of(a, b));
477 template<
class... As,
class... Bs>
478 CUDA constexpr
bool operator<=(
const CartesianProduct<As...>& a,
const CartesianProduct<Bs...>& b)
480 if(a.is_bot()) {
return true; }
481 return impl::leq_(a, b, impl::index_sequence_of(a, b));
484 template<
class... As,
class... Bs>
488 return impl::lt_(a, b, impl::index_sequence_of(a, b));
491 template<
class... As,
class... Bs>
492 CUDA constexpr
bool operator>=(
const CartesianProduct<As...>& a,
const CartesianProduct<Bs...>& b)
497 template<
class... As,
class... Bs>
503 template<
class... As,
class... Bs>
507 return impl::eq_(a, b, impl::index_sequence_of(a, b));
510 template<
class... As,
class... Bs>
511 CUDA constexpr
bool operator!=(
const CartesianProduct<As...>& a,
const CartesianProduct<Bs...>& b)
513 if(a.is_bot() != b.is_bot()) {
return true; }
514 return impl::neq_(a, b, impl::index_sequence_of(a, b));
518 template<
size_t i = 0,
class... As>
519 void std_print(std::ostream &s,
const CartesianProduct<As...> &cp) {
524 std_print<i+1>(s, cp);
530 template<
class A,
class... As>
535 impl::std_print<0>(s, cp);
Definition: cartesian_product.hpp:62
constexpr CUDA bool join(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:277
CUDA TFormula< Allocator > deinterpret(AVar x, const Env &env, const Allocator &allocator=Allocator()) const
Definition: cartesian_product.hpp:387
constexpr static const bool preserve_join
Definition: cartesian_product.hpp:81
constexpr static size_t n
Definition: cartesian_product.hpp:66
constexpr CUDA value_type value() const
Definition: cartesian_product.hpp:203
constexpr static const bool sequential
Definition: cartesian_product.hpp:77
constexpr CartesianProduct()=default
static CUDA bool interpret_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:171
constexpr CUDA bool meet(const Ai &a)
Definition: cartesian_product.hpp:296
constexpr CUDA CartesianProduct(CartesianProduct< Bs... > &&other)
Definition: cartesian_product.hpp:104
constexpr CUDA auto project(Sig fun, const A &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:357
constexpr CUDA CartesianProduct(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:101
static CUDA bool interpret_one_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:152
constexpr CUDA this_type & operator=(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:109
constexpr CUDA void meet_bot()
Definition: cartesian_product.hpp:286
constexpr static const bool is_abstract_universe
Definition: cartesian_product.hpp:76
constexpr static const bool preserve_top
Definition: cartesian_product.hpp:80
static CUDA bool interpret_one_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:147
static constexpr CUDA local_type bot()
Definition: cartesian_product.hpp:118
constexpr CUDA bool join(const Ai &a)
Definition: cartesian_product.hpp:282
static CUDA bool interpret_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:166
CUDA void print() const
Definition: cartesian_product.hpp:405
constexpr static const bool preserve_meet
Definition: cartesian_product.hpp:82
constexpr CUDA const type_of< i > & project() const
Definition: cartesian_product.hpp:199
constexpr static const bool is_totally_ordered
Definition: cartesian_product.hpp:78
constexpr CUDA void join_top()
Definition: cartesian_product.hpp:272
constexpr static const bool preserve_bot
Definition: cartesian_product.hpp:79
constexpr static const bool preserve_concrete_covers
Definition: cartesian_product.hpp:84
constexpr CUDA local::B is_top() const
Definition: cartesian_product.hpp:208
constexpr CUDA type_of< i > & project()
Definition: cartesian_product.hpp:194
static constexpr CUDA local_type top()
Definition: cartesian_product.hpp:123
constexpr CUDA void project(Sig fun, const CartesianProduct< As2... > &a, const B &b)
Definition: cartesian_product.hpp:352
constexpr CartesianProduct(const CartesianProduct< As... > &)=default
constexpr CUDA CartesianProduct(const As &... as)
Definition: cartesian_product.hpp:93
battery::tuple< typename As::value_type... > value_type
Definition: cartesian_product.hpp:74
constexpr CUDA local::B is_bot() const
Definition: cartesian_product.hpp:215
constexpr static const char * name
Definition: cartesian_product.hpp:85
constexpr this_type & operator=(const this_type &)=default
typename type_of< 0 >::memory_type memory_type
Definition: cartesian_product.hpp:70
constexpr CUDA void project(Sig fun, const CartesianProduct< As2... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:347
CartesianProduct< typename As::local_type... > local_type
Definition: cartesian_product.hpp:69
static constexpr CUDA bool is_trivial_fun(Sig fun)
Definition: cartesian_product.hpp:334
constexpr CUDA CartesianProduct(typename As::value_type... vs)
Definition: cartesian_product.hpp:95
constexpr CUDA bool meet(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:291
CUDA static NI bool interpret(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:157
constexpr CUDA bool extract(CartesianProduct< Bs... > &ua) const
Definition: cartesian_product.hpp:302
constexpr static const bool injective_concretization
Definition: cartesian_product.hpp:83
constexpr CartesianProduct(CartesianProduct< As... > &&)=default
constexpr CUDA CartesianProduct(As &&... as)
Definition: cartesian_product.hpp:94
constexpr this_type & operator=(this_type &&)=default
constexpr CUDA void project(Sig fun, const CartesianProduct< Bs... > &a)
Definition: cartesian_product.hpp:340
typename battery::tuple_element< i, battery::tuple< As... > >::type type_of
Definition: cartesian_product.hpp:65
Definition: diagnostics.hpp:19
#define CALL_WITH_ERROR_CONTEXT(MSG, CALL)
Definition: diagnostics.hpp:180
::lala::B<::battery::local_memory > B
Definition: b.hpp:12
Definition: abstract_deps.hpp:14
constexpr CUDA 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:413
constexpr CUDA bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:504
Sig
Definition: ast.hpp:94
@ AND
Unary arithmetic function symbols.
Definition: ast.hpp:114
constexpr CUDA auto fjoin(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:464
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition: cartesian_product.hpp:531
IKind
Definition: ast.hpp:28
constexpr CUDA bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:485
constexpr CUDA auto fmeet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:471
constexpr CUDA bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:498