Lattice Land Core Library
Loading...
Searching...
No Matches
cartesian_product.hpp
Go to the documentation of this file.
1// Copyright 2021 Pierre Talbot
2
3#ifndef LALA_CORE_CARTESIAN_PRODUCT_HPP
4#define LALA_CORE_CARTESIAN_PRODUCT_HPP
5
6#include "battery/utility.hpp"
7#include "battery/vector.hpp"
8#include "battery/tuple.hpp"
9#include "battery/variant.hpp"
10#include "logic/logic.hpp"
12
13namespace lala {
14
15template<class... As>
16class CartesianProduct;
17
18namespace impl {
19 template<class... As>
20 CUDA constexpr auto index_sequence_of(const CartesianProduct<As...>&) {
21 return std::index_sequence_for<As...>{};
22 }
23
24 template<class... As>
25 CUDA constexpr auto index_sequence_of(const battery::tuple<As...>&) {
26 return std::index_sequence_for<As...>{};
27 }
28
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);
33 }
34
35 template<class... Os>
36 CUDA constexpr typename CartesianProduct<Os...>::local_type make_cp(Os... os) {
37 return typename CartesianProduct<Os...>::local_type(os...);
38 }
39
40 template<class A>
41 struct is_product {
42 static constexpr bool value = false;
43 };
44
45 template<class... As>
46 struct is_product<CartesianProduct<As...>> {
47 static constexpr bool value = true;
48 };
49
50 template<class... As>
51 struct is_product<battery::tuple<As...>> {
52 static constexpr bool value = true;
53 };
54
55 template<class A>
56 inline static constexpr bool is_product_v = is_product<A>::value;
57}
58
59/** The Cartesian product abstract domain is a _domain transformer_ combining several abstract domains.
60Concretization function: \f$ \gamma((a_1, \ldots, a_n)) = \bigcap_{i \leq n} \gamma_i(a_i) \f$. */
61template<class... As>
63public:
64 template<size_t i>
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.");
69 using local_type = CartesianProduct<typename As::local_type...>;
71
72 template<class...Bs> friend class CartesianProduct;
73
74 using value_type = battery::tuple<typename As::value_type...>;
75
76 constexpr static const bool is_abstract_universe = true;
77 constexpr static const bool sequential = (... && As::sequential);
78 constexpr static const bool is_totally_ordered = false;
79 constexpr static const bool preserve_bot = (... && As::preserve_bot);
80 constexpr static const bool preserve_top = (... && As::preserve_top);
81 constexpr static const bool preserve_join = false; // false in general, not sure if there are conditions the underlying universes could satisfy to make this true.
82 constexpr static const bool preserve_meet = (... && As::preserve_meet);
83 constexpr static const bool injective_concretization = (... && As::injective_concretization);
84 constexpr static const bool preserve_concrete_covers = (... && As::preserve_concrete_covers);
85 constexpr static const char* name = "CartesianProduct";
86
87private:
88 battery::tuple<As...> val;
89
90public:
91 /** Initialize a Cartesian product to top using default constructors. */
92 constexpr CartesianProduct() = default;
93 CUDA constexpr CartesianProduct(const As&... as): val(battery::make_tuple(as...)) {}
94 CUDA constexpr CartesianProduct(As&&... as): val(battery::make_tuple(std::forward<As>(as)...)) {}
95 CUDA constexpr CartesianProduct(typename As::value_type... vs): val(battery::make_tuple(As(vs)...)) {}
96
97 constexpr CartesianProduct(const CartesianProduct<As...>&) = default;
99
100 template<class... Bs>
101 CUDA constexpr CartesianProduct(const CartesianProduct<Bs...>& other): val(other.val) {}
102
103 template<class... Bs>
104 CUDA constexpr CartesianProduct(CartesianProduct<Bs...>&& other): val(std::move(other.val)) {}
105
106 /** The assignment operator can only be used in a sequential context.
107 * It is monotone but not extensive. */
108 template <class... Bs>
109 CUDA constexpr this_type& operator=(const CartesianProduct<Bs...>& other) {
110 val = other.val;
111 return *this;
112 }
113
114 constexpr this_type& operator=(const this_type&) = default;
115 constexpr this_type& operator=(this_type&&) = default;
116
117 /** Cartesian product initialized to \f$ (\bot_1, \ldots, \bot_n) \f$. */
118 CUDA static constexpr local_type bot() {
119 return local_type(As::bot()...);
120 }
121
122 /** Cartesian product initialized to \f$ (\top_1, \ldots, \top_n) \f$. */
123 CUDA static constexpr local_type top() {
124 return local_type(As::top()...);
125 }
126
127private:
128 /** Interpret the formula in the component `i`. */
129 template<IKind kind, bool diagnose, size_t i, class F, class Env, class... Bs>
130 CUDA NI static bool interpret_one(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
131 return type_of<i>::template interpret<kind, diagnose>(f, env, k.template project<i>(), diagnostics);
132 }
133
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) {
137 return !empty;
138 }
139 else {
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);
142 }
143 }
144
145public:
146 template<size_t i, bool diagnose = false, class F, class Env, class... Bs>
147 CUDA static bool interpret_one_tell(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
148 return interpret_one<IKind::TELL, diagnose, i>(f, env, k, diagnostics);
149 }
150
151 template<size_t i, bool diagnose = false, class F, class Env, class... Bs>
152 CUDA static bool interpret_one_ask(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
153 return interpret_one<IKind::ASK, diagnose, i>(f, env, k, diagnostics);
154 }
155
156 template<IKind kind, bool diagnose = false, class F, class Env, class... Bs>
157 CUDA NI static bool interpret(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
159 "No component of this Cartesian product can interpret this formula.",
160 (interpret_all<kind, diagnose>(f, k, true, env, diagnostics))
161 );
162 }
163
164 /** Interpret the formula `f` in all sub-universes in which `f` is interpretable. */
165 template<bool diagnose, class F, class Env, class... Bs>
166 CUDA static bool interpret_tell(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
167 return interpret<IKind::TELL, diagnose>(f, env, k, diagnostics);
168 }
169
170 template<bool diagnose, class F, class Env, class... Bs>
171 CUDA static bool interpret_ask(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
172 return interpret<IKind::ASK, diagnose>(f, env, k, diagnostics);
173 }
174
175private:
176 template<size_t... I>
177 CUDA constexpr value_type value_(std::index_sequence<I...>) const {
178 return value_type(project<I>().value()...);
179 }
180
181 template<size_t... I>
182 CUDA constexpr local::B is_top_(std::index_sequence<I...>) const {
183 return (... && project<I>().is_top());
184 }
185
186 template<size_t... I>
187 CUDA constexpr local::B is_bot_(std::index_sequence<I...>) const {
188 return (... || project<I>().is_bot());
189 }
190
191public:
192 /** You must use the lattice interface (tell methods) to modify the projected type, if you use assignment you violate the PCCP model. */
193 template<size_t i>
194 CUDA constexpr type_of<i>& project() {
195 return battery::get<i>(val);
196 }
197
198 template<size_t i>
199 CUDA constexpr const type_of<i>& project() const {
200 return battery::get<i>(val);
201 }
202
203 CUDA constexpr value_type value() const {
204 return value_(std::index_sequence_for<As...>{});
205 }
206 /** \return `true` if \f$ \forall{j},~\gamma(a_j) = U \f$ with U the universe of discourse of \f$ a_j \f$, `false` otherwise.
207 * @parallel @order-preserving @increasing */
208 CUDA constexpr local::B is_top() const {
209 return is_top_(std::index_sequence_for<As...>{});
210 }
211
212 /** \return `true` if \f$ \exists{j},~\gamma(a_j) = \{\} \f$, `false` otherwise.
213 * @parallel @order-preserving @decreasing
214 */
215 CUDA constexpr local::B is_bot() const {
216 return is_bot_(std::index_sequence_for<As...>{});
217 }
218
219private:
220 template<size_t i = 0, class... Bs>
221 CUDA constexpr bool join_(const CartesianProduct<Bs...>& other) {
222 if constexpr (i < n) {
223 bool has_changed = project<i>().join(other.template project<i>());
224 has_changed |= join_<i+1>(other);
225 return has_changed;
226 }
227 else {
228 return false;
229 }
230 }
231
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);
237 return has_changed;
238 }
239 else {
240 return false;
241 }
242 }
243
244 template<size_t i = 0>
245 CUDA constexpr void meet_bot_() {
246 if constexpr (i < n) {
247 project<i>().meet_bot();
248 meet_bot_<i+1>();
249 }
250 }
251
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);
257 }
258 else {
259 return true;
260 }
261 }
262
263 template <size_t i = 0>
264 CUDA constexpr void join_top_() {
265 if constexpr(i < n) {
266 project<i>().join_top();
267 join_top_<i+1>();
268 }
269 }
270
271public:
272 CUDA constexpr void join_top() {
273 join_top_();
274 }
275
276 template <class... Bs>
277 CUDA constexpr bool join(const CartesianProduct<Bs...>& other) {
278 return join_(other);
279 }
280
281 template<size_t i, class Ai>
282 CUDA constexpr bool join(const Ai& a) {
283 return project<i>().join(a);
284 }
285
286 CUDA constexpr void meet_bot() {
287 meet_bot_();
288 }
289
290 template <class... Bs>
291 CUDA constexpr bool meet(const CartesianProduct<Bs...>& other) {
292 return meet_(other);
293 }
294
295 template<size_t i, class Ai>
296 CUDA constexpr bool meet(const Ai& a) {
297 return project<i>().meet(a);
298 }
299
300 /** For correctness, the parameter `ua` must be stored in a local memory. */
301 template <class... Bs>
302 CUDA constexpr bool extract(CartesianProduct<Bs...>& ua) const {
303 return extract_(ua);
304 }
305
306// Implementation of the logical signature.
307
308private:
309 template<class A, size_t... I>
310 CUDA constexpr void project(Sig fun, const A& a, std::index_sequence<I...>)
311 {
312 (project<I>().project(fun, a.template project<I>()),...);
313 }
314
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...>)
317 {
318 (project<I>().project(fun, a.template project<I>(), b.template project<I>()),...);
319 }
320
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...>)
323 {
324 (project<I>().project(fun, a.template project<I>(), b),...);
325 }
326
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...>)
329 {
330 (project<I>().project(fun, a, b.template project<I>()),...);
331 }
332
333public:
334 CUDA static constexpr bool is_trivial_fun(Sig fun) {
335 return (... && As::is_trivial_fun(fun));
336 }
337
338 /** Given a product \f$ (x_1, \ldots, x_n) \f$, join in-place \f$ (fun(x_1), \ldots, fun(x_n)) \f$. */
339 template<class... Bs>
340 CUDA constexpr void project(Sig fun, const CartesianProduct<Bs...>& a) {
341 project(fun, a, impl::index_sequence_of(a));
342 }
343
344 /** Given two product \f$ (x_1, \ldots, x_n) \f$ and \f$ (y_1, \ldots, y_n) \f$, join in-place \f$ (fun(x_1, y_1), \ldots, fun(x_n, y_n)) \f$.
345 If either the left or right operand is not a product, join in-place \f$ (fun(x_1, c), \ldots, fun(x_n, c)) \f$ or \f$ (fun(c, y_1), \ldots, fun(c, y_n)) \f$. */
346 template<class... As2, class... Bs>
347 CUDA constexpr void project(Sig fun, const CartesianProduct<As2...>& a, const CartesianProduct<Bs...>& b) {
348 project(fun, a, b, impl::index_sequence_of(a, b));
349 }
350
351 template<class... As2, class B>
352 CUDA constexpr void project(Sig fun, const CartesianProduct<As2...>& a, const B& b) {
353 project_left(fun, a, b, impl::index_sequence_of(a));
354 }
355
356 template<class A, class... Bs>
357 CUDA constexpr auto project(Sig fun, const A& a, const CartesianProduct<Bs...>& b) {
358 project_right(fun, a, b, impl::index_sequence_of(b));
359 }
360
361private:
362 template<size_t i, class Env, class Allocator = typename Env::allocator_type>
363 CUDA NI TFormula<Allocator> deinterpret_(AVar x,
364 typename TFormula<Allocator>::Sequence& seq, const Env& env, const Allocator& allocator) const
365 {
366 if constexpr(i < n) {
367 auto f = project<i>().deinterpret(x, env, allocator);
368 if(!f.is_true()) {
369 seq.push_back(project<i>().deinterpret(x, env, allocator));
370 }
371 return deinterpret_<i+1, Env>(x, seq, env, allocator);
372 }
373 else {
374 if(seq.size() == 1) {
375 return std::move(seq[0]);
376 }
377 else {
379 AND,
380 std::move(seq));
381 }
382 }
383 }
384
385public:
386 template<class Env, class Allocator = typename Env::allocator_type>
387 CUDA TFormula<Allocator> deinterpret(AVar x, const Env& env, const Allocator& allocator = Allocator()) const {
388 typename TFormula<Allocator>::Sequence seq(allocator);
389 return deinterpret_<0, Env>(x, seq, env, allocator);
390 }
391
392private:
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) {
398 printf("\n");
399 print_<i+1>();
400 }
401 }
402 }
403
404public:
405 CUDA void print() const {
406 print_();
407 }
408};
409
410/// Similar to `cp.template project<i>()`, just to avoid the ".template" syntax.
411template<size_t i, class... As>
412CUDA constexpr const typename CartesianProduct<As...>::template type_of<i>&
414 return cp.template project<i>();
415}
416
417template<size_t i, class... As>
418CUDA constexpr typename CartesianProduct<As...>::template type_of<i>&
420 return cp.template project<i>();
421}
422
423// Lattice operators
424namespace impl {
425 template<class A, class B, size_t... I>
426 CUDA constexpr auto fjoin_(const A& a, const B& b, std::index_sequence<I...>)
427 {
428 return make_cp(fjoin(project<I>(a), project<I>(b))...);
429 }
430
431 template<class A, class B, size_t... I>
432 CUDA constexpr auto fmeet_(const A& a, const B& b, std::index_sequence<I...>)
433 {
434 return make_cp(fmeet(project<I>(a), project<I>(b))...);
435 }
436
437 template<class A, class B, size_t... I>
438 CUDA constexpr bool eq_(const A& a, const B& b, std::index_sequence<I...>)
439 {
440 return (... && (project<I>(a) == project<I>(b)));
441 }
442
443 template<class A, class B, size_t... I>
444 CUDA constexpr bool neq_(const A& a, const B& b, std::index_sequence<I...>)
445 {
446 return (... || (project<I>(a) != project<I>(b)));
447 }
448
449 template<class A, class B, size_t... I>
450 CUDA constexpr bool leq_(const A& a, const B& b, std::index_sequence<I...>)
451 {
452 return (... && (project<I>(a) <= project<I>(b)));
453 }
454
455 template<class A, class B, size_t... I>
456 CUDA constexpr bool lt_(const A& a, const B& b, std::index_sequence<I...>)
457 {
458 return leq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
459 }
460}
461
462/** \f$ (a_1, \ldots, a_n) \sqcup (b_1, \ldots, b_n) = (a_1 \sqcup_1 b_1, \ldots, a_n \sqcup_n b_n) \f$ */
463template<class... As, class... Bs>
464CUDA constexpr auto fjoin(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
465{
466 return impl::fjoin_(a, b, impl::index_sequence_of(a, b));
467}
468
469/** \f$ (a_1, \ldots, a_n) \sqcap (b_1, \ldots, b_n) = (a_1 \sqcap_1 b_1, \ldots, a_n \sqcap_n b_n) \f$ */
470template<class... As, class... Bs>
471CUDA constexpr auto fmeet(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
472{
473 return impl::fmeet_(a, b, impl::index_sequence_of(a, b));
474}
475
476/** \f$ (a_1, \ldots, a_n) \leq (b_1, \ldots, b_n) \f$ holds when \f$ \forall{i \leq n},~a_i \leq_i b_i \f$. */
477template<class... As, class... Bs>
478CUDA constexpr bool operator<=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
479{
480 if(a.is_bot()) { return true; }
481 return impl::leq_(a, b, impl::index_sequence_of(a, b));
482}
483
484template<class... As, class... Bs>
485CUDA constexpr bool operator<(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
486{
487 if(a.is_bot()) { return !b.is_bot(); }
488 return impl::lt_(a, b, impl::index_sequence_of(a, b));
489}
490
491template<class... As, class... Bs>
492CUDA constexpr bool operator>=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
493{
494 return b <= a;
495}
496
497template<class... As, class... Bs>
498CUDA constexpr bool operator>(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
499{
500 return b < a;
501}
502
503template<class... As, class... Bs>
504CUDA constexpr bool operator==(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
505{
506 if(a.is_bot() && b.is_bot()) { return true; }
507 return impl::eq_(a, b, impl::index_sequence_of(a, b));
508}
509
510template<class... As, class... Bs>
511CUDA constexpr bool operator!=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
512{
513 if(a.is_bot() != b.is_bot()) { return true; }
514 return impl::neq_(a, b, impl::index_sequence_of(a, b));
515}
516
517namespace impl {
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) {
521 s << project<i>(cp);
522 if constexpr(i < CartesianProduct<As...>::n - 1) {
523 s << ", ";
524 std_print<i+1>(s, cp);
525 }
526 }
527 }
528}
529
530template<class A, class... As>
531std::ostream& operator<<(std::ostream &s, const CartesianProduct<A, As...> &cp) {
532// There is a weird compilation bug with `template<class... As>` where the compiler tries to instantiate << with an empty sequence of templates.
533// Forcing at least one template solves the problem.
534 s << "(";
535 impl::std_print<0>(s, cp);
536 s << ")";
537 return s;
538}
539
540} // namespace lala
541
542#endif
Definition ast.hpp:38
Definition b.hpp:10
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
Definition ast.hpp:286
battery::vector< this_type, Allocator > Sequence
Definition ast.hpp:290
CUDA static NI this_type make_nary(Sig sig, Sequence children, AType atype=UNTYPED, bool flatten=true)
Definition ast.hpp:479
#define CALL_WITH_ERROR_CONTEXT(MSG, CALL)
Definition diagnostics.hpp:180
Definition ast.hpp:262
::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
Sig
Definition ast.hpp:94
@ 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