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);
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) {
411template<
size_t i,
class... As>
412CUDA
constexpr const typename CartesianProduct<As...>::template type_of<i>&
414 return cp.template project<i>();
417template<
size_t i,
class... As>
418CUDA
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...>{});
463template<
class... As,
class... Bs>
466 return impl::fjoin_(a, b, impl::index_sequence_of(a, b));
470template<
class... As,
class... Bs>
473 return impl::fmeet_(a, b, impl::index_sequence_of(a, b));
477template<
class... As,
class... Bs>
478CUDA
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));
484template<
class... As,
class... Bs>
488 return impl::lt_(a, b, impl::index_sequence_of(a, b));
491template<
class... As,
class... Bs>
492CUDA
constexpr bool operator>=(
const CartesianProduct<As...>& a,
const CartesianProduct<Bs...>& b)
497template<
class... As,
class... Bs>
503template<
class... As,
class... Bs>
507 return impl::eq_(a, b, impl::index_sequence_of(a, b));
510template<
class... As,
class... Bs>
511CUDA
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) {
520 if constexpr(i < CartesianProduct<As...>::n) {
522 if constexpr(i < CartesianProduct<As...>::n - 1) {
524 std_print<i+1>(s, cp);
530template<
class A,
class... As>
535 impl::std_print<0>(s, cp);
Definition cartesian_product.hpp:62
CUDA constexpr this_type & operator=(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:109
CUDA constexpr bool join(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:277
CUDA constexpr void project(Sig fun, const CartesianProduct< As2... > &a, const B &b)
Definition cartesian_product.hpp:352
constexpr CartesianProduct()=default
CUDA constexpr void project(Sig fun, const CartesianProduct< As2... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:347
static CUDA bool interpret_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:171
static CUDA constexpr bool is_trivial_fun(Sig fun)
Definition cartesian_product.hpp:334
CUDA constexpr bool join(const Ai &a)
Definition cartesian_product.hpp:282
CUDA TFormula< Allocator > deinterpret(AVar x, const Env &env, const Allocator &allocator=Allocator()) const
Definition cartesian_product.hpp:387
CUDA constexpr bool extract(CartesianProduct< Bs... > &ua) const
Definition cartesian_product.hpp:302
CUDA constexpr local::B is_bot() const
Definition cartesian_product.hpp:215
CUDA constexpr local::B is_top() const
Definition cartesian_product.hpp:208
static CUDA bool interpret_one_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:152
CUDA constexpr type_of< i > & project()
Definition cartesian_product.hpp:194
static CUDA bool interpret_one_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:147
constexpr this_type & operator=(const this_type &)=default
CUDA constexpr value_type value() const
Definition cartesian_product.hpp:203
static constexpr const bool is_totally_ordered
Definition cartesian_product.hpp:78
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:166
static constexpr const bool preserve_join
Definition cartesian_product.hpp:81
CUDA void print() const
Definition cartesian_product.hpp:405
CUDA constexpr bool meet(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:291
CUDA constexpr void meet_bot()
Definition cartesian_product.hpp:286
static constexpr const bool sequential
Definition cartesian_product.hpp:77
static constexpr const char * name
Definition cartesian_product.hpp:85
CUDA constexpr void project(Sig fun, const CartesianProduct< Bs... > &a)
Definition cartesian_product.hpp:340
constexpr this_type & operator=(this_type &&)=default
static constexpr size_t n
Definition cartesian_product.hpp:66
CUDA constexpr void join_top()
Definition cartesian_product.hpp:272
constexpr CartesianProduct(const CartesianProduct< As... > &)=default
static constexpr const bool preserve_bot
Definition cartesian_product.hpp:79
static constexpr const bool preserve_meet
Definition cartesian_product.hpp:82
battery::tuple< typename As::value_type... > value_type
Definition cartesian_product.hpp:74
CUDA constexpr const type_of< i > & project() const
Definition cartesian_product.hpp:199
static CUDA constexpr local_type top()
Definition cartesian_product.hpp:123
typename type_of< 0 >::memory_type memory_type
Definition cartesian_product.hpp:70
CUDA constexpr CartesianProduct(const As &... as)
Definition cartesian_product.hpp:93
CUDA constexpr CartesianProduct(typename As::value_type... vs)
Definition cartesian_product.hpp:95
CartesianProduct< typename As::local_type... > local_type
Definition cartesian_product.hpp:69
CUDA constexpr bool meet(const Ai &a)
Definition cartesian_product.hpp:296
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:157
constexpr CartesianProduct(CartesianProduct< As... > &&)=default
static constexpr const bool preserve_top
Definition cartesian_product.hpp:80
CUDA constexpr CartesianProduct(CartesianProduct< Bs... > &&other)
Definition cartesian_product.hpp:104
static CUDA constexpr local_type bot()
Definition cartesian_product.hpp:118
CUDA constexpr auto project(Sig fun, const A &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:357
typename battery::tuple_element< i, battery::tuple< As... > >::type type_of
Definition cartesian_product.hpp:65
static constexpr const bool is_abstract_universe
Definition cartesian_product.hpp:76
CUDA constexpr CartesianProduct(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:101
CUDA constexpr CartesianProduct(As &&... as)
Definition cartesian_product.hpp:94
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
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition cartesian_product.hpp:531
CUDA constexpr auto fjoin(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:464
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:504
@ AND
Unary arithmetic function symbols.
Definition ast.hpp:114
CUDA constexpr bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:485
CUDA constexpr auto fmeet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:471
CUDA constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:498
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:413