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 template<class... Bs>
98 CUDA constexpr CartesianProduct(const CartesianProduct<Bs...>& other): val(other.val) {}
99
100 template<class... Bs>
101 CUDA constexpr CartesianProduct(CartesianProduct<Bs...>&& other): val(std::move(other.val)) {}
102
103 /** The assignment operator can only be used in a sequential context.
104 * It is monotone but not extensive. */
105 template <class... Bs>
106 CUDA constexpr this_type& operator=(const CartesianProduct<Bs...>& other) {
107 val = other.val;
108 return *this;
109 }
110
111 CUDA constexpr this_type& operator=(const this_type& other) {
112 val = other.val;
113 return *this;
114 }
115
116 /** Cartesian product initialized to \f$ (\bot_1, \ldots, \bot_n) \f$. */
117 CUDA static constexpr local_type bot() {
118 return local_type(As::bot()...);
119 }
120
121 /** Cartesian product initialized to \f$ (\top_1, \ldots, \top_n) \f$. */
122 CUDA static constexpr local_type top() {
123 return local_type(As::top()...);
124 }
125
126private:
127 /** Interpret the formula in the component `i`. */
128 template<IKind kind, bool diagnose, size_t i, class F, class Env, class... Bs>
129 CUDA NI static bool interpret_one(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
130 return type_of<i>::template interpret<kind, diagnose>(f, env, k.template project<i>(), diagnostics);
131 }
132
133 template<IKind kind, bool diagnose, size_t i = 0, class F, class Env, class... Bs>
134 CUDA NI static bool interpret_all(const F& f, CartesianProduct<Bs...>& k, bool empty, const Env& env, IDiagnostics& diagnostics) {
135 if constexpr(i == n) {
136 return !empty;
137 }
138 else {
139 bool res = interpret_one<kind, diagnose, i>(f, env, k, diagnostics);
140 return interpret_all<kind, diagnose, i+1>(f, k, empty && !res, env, diagnostics);
141 }
142 }
143
144public:
145 template<size_t i, bool diagnose = false, class F, class Env, class... Bs>
146 CUDA static bool interpret_one_tell(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
147 return interpret_one<IKind::TELL, diagnose, i>(f, env, k, diagnostics);
148 }
149
150 template<size_t i, bool diagnose = false, class F, class Env, class... Bs>
151 CUDA static bool interpret_one_ask(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
152 return interpret_one<IKind::ASK, diagnose, i>(f, env, k, diagnostics);
153 }
154
155 template<IKind kind, bool diagnose = false, class F, class Env, class... Bs>
156 CUDA NI static bool interpret(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
158 "No component of this Cartesian product can interpret this formula.",
159 (interpret_all<kind, diagnose>(f, k, true, env, diagnostics))
160 );
161 }
162
163 /** Interpret the formula `f` in all sub-universes in which `f` is interpretable. */
164 template<bool diagnose, class F, class Env, class... Bs>
165 CUDA static bool interpret_tell(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
166 return interpret<IKind::TELL, diagnose>(f, env, k, diagnostics);
167 }
168
169 template<bool diagnose, class F, class Env, class... Bs>
170 CUDA static bool interpret_ask(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
171 return interpret<IKind::ASK, diagnose>(f, env, k, diagnostics);
172 }
173
174private:
175 template<size_t... I>
176 CUDA constexpr value_type value_(std::index_sequence<I...>) const {
177 return value_type(project<I>().value()...);
178 }
179
180 template<size_t... I>
181 CUDA constexpr local::B is_top_(std::index_sequence<I...>) const {
182 return (... && project<I>().is_top());
183 }
184
185 template<size_t... I>
186 CUDA constexpr local::B is_bot_(std::index_sequence<I...>) const {
187 return (... || project<I>().is_bot());
188 }
189
190public:
191 /** You must use the lattice interface (tell methods) to modify the projected type, if you use assignment you violate the PCCP model. */
192 template<size_t i>
193 CUDA constexpr type_of<i>& project() {
194 return battery::get<i>(val);
195 }
196
197 template<size_t i>
198 CUDA constexpr const type_of<i>& project() const {
199 return battery::get<i>(val);
200 }
201
202 CUDA constexpr value_type value() const {
203 return value_(std::index_sequence_for<As...>{});
204 }
205 /** \return `true` if \f$ \forall{j},~\gamma(a_j) = U \f$ with U the universe of discourse of \f$ a_j \f$, `false` otherwise.
206 * @parallel @order-preserving @increasing */
207 CUDA constexpr local::B is_top() const {
208 return is_top_(std::index_sequence_for<As...>{});
209 }
210
211 /** \return `true` if \f$ \exists{j},~\gamma(a_j) = \{\} \f$, `false` otherwise.
212 * @parallel @order-preserving @decreasing
213 */
214 CUDA constexpr local::B is_bot() const {
215 return is_bot_(std::index_sequence_for<As...>{});
216 }
217
218private:
219 template<size_t i = 0, class... Bs>
220 CUDA constexpr bool join_(const CartesianProduct<Bs...>& other) {
221 if constexpr (i < n) {
222 bool has_changed = project<i>().join(other.template project<i>());
223 has_changed |= join_<i+1>(other);
224 return has_changed;
225 }
226 else {
227 return false;
228 }
229 }
230
231 template<size_t i = 0, class... Bs>
232 CUDA constexpr bool meet_(const CartesianProduct<Bs...>& other) {
233 if constexpr (i < n) {
234 bool has_changed = project<i>().meet(other.template project<i>());
235 has_changed |= meet_<i+1>(other);
236 return has_changed;
237 }
238 else {
239 return false;
240 }
241 }
242
243 template<size_t i = 0>
244 CUDA constexpr void meet_bot_() {
245 if constexpr (i < n) {
246 project<i>().meet_bot();
247 meet_bot_<i+1>();
248 }
249 }
250
251 template<size_t i = 0, class... Bs>
252 CUDA constexpr bool extract_(CartesianProduct<Bs...>& ua) {
253 if constexpr (i < n) {
254 bool is_under = project<i>().extract(ua.template project<i>());
255 return is_under && extract_<i+1>(ua);
256 }
257 else {
258 return true;
259 }
260 }
261
262 template <size_t i = 0>
263 CUDA constexpr void join_top_() {
264 if constexpr(i < n) {
265 project<i>().join_top();
266 join_top_<i+1>();
267 }
268 }
269
270public:
271 CUDA constexpr void join_top() {
272 join_top_();
273 }
274
275 template <class... Bs>
276 CUDA constexpr bool join(const CartesianProduct<Bs...>& other) {
277 return join_(other);
278 }
279
280 template<size_t i, class Ai>
281 CUDA constexpr bool join(const Ai& a) {
282 return project<i>().join(a);
283 }
284
285 CUDA constexpr void meet_bot() {
286 meet_bot_();
287 }
288
289 template <class... Bs>
290 CUDA constexpr bool meet(const CartesianProduct<Bs...>& other) {
291 return meet_(other);
292 }
293
294 template<size_t i, class Ai>
295 CUDA constexpr bool meet(const Ai& a) {
296 return project<i>().meet(a);
297 }
298
299 /** For correctness, the parameter `ua` must be stored in a local memory. */
300 template <class... Bs>
301 CUDA constexpr bool extract(CartesianProduct<Bs...>& ua) const {
302 return extract_(ua);
303 }
304
305// Implementation of the logical signature.
306
307private:
308 template<class A, size_t... I>
309 CUDA constexpr void project(Sig fun, const A& a, std::index_sequence<I...>)
310 {
311 (project<I>().project(fun, a.template project<I>()),...);
312 }
313
314 template<class A, class B, size_t... I>
315 CUDA constexpr void project(Sig fun, const A& a, const B& b, std::index_sequence<I...>)
316 {
317 (project<I>().project(fun, a.template project<I>(), b.template project<I>()),...);
318 }
319
320 template<class A, class B, size_t... I>
321 CUDA constexpr void project_left(Sig fun, const A& a, const B& b, std::index_sequence<I...>)
322 {
323 (project<I>().project(fun, a.template project<I>(), b),...);
324 }
325
326 template<class A, class B, size_t... I>
327 CUDA constexpr void project_right(Sig fun, const A& a, const B& b, std::index_sequence<I...>)
328 {
329 (project<I>().project(fun, a, b.template project<I>()),...);
330 }
331
332public:
333 CUDA static constexpr bool is_trivial_fun(Sig fun) {
334 return (... && As::is_trivial_fun(fun));
335 }
336
337 /** Given a product \f$ (x_1, \ldots, x_n) \f$, join in-place \f$ (fun(x_1), \ldots, fun(x_n)) \f$. */
338 template<class... Bs>
339 CUDA constexpr void project(Sig fun, const CartesianProduct<Bs...>& a) {
340 project(fun, a, impl::index_sequence_of(a));
341 }
342
343 /** 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$.
344 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$. */
345 template<class... As2, class... Bs>
346 CUDA constexpr void project(Sig fun, const CartesianProduct<As2...>& a, const CartesianProduct<Bs...>& b) {
347 project(fun, a, b, impl::index_sequence_of(a, b));
348 }
349
350 template<class... As2, class B>
351 CUDA constexpr void project(Sig fun, const CartesianProduct<As2...>& a, const B& b) {
352 project_left(fun, a, b, impl::index_sequence_of(a));
353 }
354
355 template<class A, class... Bs>
356 CUDA constexpr auto project(Sig fun, const A& a, const CartesianProduct<Bs...>& b) {
357 project_right(fun, a, b, impl::index_sequence_of(b));
358 }
359
360private:
361 template<size_t i, class Env, class Allocator = typename Env::allocator_type>
362 CUDA NI TFormula<Allocator> deinterpret_(AVar x,
363 typename TFormula<Allocator>::Sequence& seq, const Env& env, const Allocator& allocator) const
364 {
365 if constexpr(i < n) {
366 auto f = project<i>().deinterpret(x, env, allocator);
367 if(!f.is_true()) {
368 seq.push_back(project<i>().deinterpret(x, env, allocator));
369 }
370 return deinterpret_<i+1, Env>(x, seq, env, allocator);
371 }
372 else {
373 if(seq.size() == 1) {
374 return std::move(seq[0]);
375 }
376 else {
378 AND,
379 std::move(seq));
380 }
381 }
382 }
383
384public:
385 template<class Env, class Allocator = typename Env::allocator_type>
386 CUDA TFormula<Allocator> deinterpret(AVar x, const Env& env, const Allocator& allocator = Allocator()) const {
387 typename TFormula<Allocator>::Sequence seq(allocator);
388 return deinterpret_<0, Env>(x, seq, env, allocator);
389 }
390
391private:
392 template<size_t i = 0>
393 CUDA NI void print_() const {
394 if constexpr(i < n) {
395 project<i>().print();
396 if constexpr(i < n - 1) {
397 printf("\n");
398 print_<i+1>();
399 }
400 }
401 }
402
403public:
404 CUDA void print() const {
405 print_();
406 }
407};
408
409/// Similar to `cp.template project<i>()`, just to avoid the ".template" syntax.
410template<size_t i, class... As>
411CUDA constexpr const typename CartesianProduct<As...>::template type_of<i>&
413 return cp.template project<i>();
414}
415
416template<size_t i, class... As>
417CUDA constexpr typename CartesianProduct<As...>::template type_of<i>&
419 return cp.template project<i>();
420}
421
422// Lattice operators
423namespace impl {
424 template<class A, class B, size_t... I>
425 CUDA constexpr auto fjoin_(const A& a, const B& b, std::index_sequence<I...>)
426 {
427 return make_cp(fjoin(project<I>(a), project<I>(b))...);
428 }
429
430 template<class A, class B, size_t... I>
431 CUDA constexpr auto fmeet_(const A& a, const B& b, std::index_sequence<I...>)
432 {
433 return make_cp(fmeet(project<I>(a), project<I>(b))...);
434 }
435
436 template<class A, class B, size_t... I>
437 CUDA constexpr bool eq_(const A& a, const B& b, std::index_sequence<I...>)
438 {
439 return (... && (project<I>(a) == project<I>(b)));
440 }
441
442 template<class A, class B, size_t... I>
443 CUDA constexpr bool neq_(const A& a, const B& b, std::index_sequence<I...>)
444 {
445 return (... || (project<I>(a) != project<I>(b)));
446 }
447
448 template<class A, class B, size_t... I>
449 CUDA constexpr bool leq_(const A& a, const B& b, std::index_sequence<I...>)
450 {
451 return (... && (project<I>(a) <= project<I>(b)));
452 }
453
454 template<class A, class B, size_t... I>
455 CUDA constexpr bool lt_(const A& a, const B& b, std::index_sequence<I...>)
456 {
457 return leq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
458 }
459}
460
461/** \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$ */
462template<class... As, class... Bs>
463CUDA constexpr auto fjoin(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
464{
465 return impl::fjoin_(a, b, impl::index_sequence_of(a, b));
466}
467
468/** \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$ */
469template<class... As, class... Bs>
470CUDA constexpr auto fmeet(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
471{
472 return impl::fmeet_(a, b, impl::index_sequence_of(a, b));
473}
474
475/** \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$. */
476template<class... As, class... Bs>
477CUDA constexpr bool operator<=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
478{
479 if(a.is_bot()) { return true; }
480 return impl::leq_(a, b, impl::index_sequence_of(a, b));
481}
482
483template<class... As, class... Bs>
484CUDA constexpr bool operator<(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
485{
486 if(a.is_bot()) { return !b.is_bot(); }
487 return impl::lt_(a, b, impl::index_sequence_of(a, b));
488}
489
490template<class... As, class... Bs>
491CUDA constexpr bool operator>=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
492{
493 return b <= a;
494}
495
496template<class... As, class... Bs>
497CUDA constexpr bool operator>(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
498{
499 return b < a;
500}
501
502template<class... As, class... Bs>
503CUDA constexpr bool operator==(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
504{
505 if(a.is_bot() && b.is_bot()) { return true; }
506 return impl::eq_(a, b, impl::index_sequence_of(a, b));
507}
508
509template<class... As, class... Bs>
510CUDA constexpr bool operator!=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
511{
512 if(a.is_bot() != b.is_bot()) { return true; }
513 return impl::neq_(a, b, impl::index_sequence_of(a, b));
514}
515
516namespace impl {
517 template<size_t i = 0, class... As>
518 void std_print(std::ostream &s, const CartesianProduct<As...> &cp) {
519 if constexpr(i < CartesianProduct<As...>::n) {
520 s << project<i>(cp);
521 if constexpr(i < CartesianProduct<As...>::n - 1) {
522 s << ", ";
523 std_print<i+1>(s, cp);
524 }
525 }
526 }
527}
528
529template<class A, class... As>
530std::ostream& operator<<(std::ostream &s, const CartesianProduct<A, As...> &cp) {
531// There is a weird compilation bug with `template<class... As>` where the compiler tries to instantiate << with an empty sequence of templates.
532// Forcing at least one template solves the problem.
533 s << "(";
534 impl::std_print<0>(s, cp);
535 s << ")";
536 return s;
537}
538
539} // namespace lala
540
541#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:106
CUDA constexpr bool join(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:276
CUDA constexpr void project(Sig fun, const CartesianProduct< As2... > &a, const B &b)
Definition cartesian_product.hpp:351
constexpr CartesianProduct()=default
CUDA constexpr void project(Sig fun, const CartesianProduct< As2... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:346
static CUDA bool interpret_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:170
friend class CartesianProduct
Definition cartesian_product.hpp:72
static CUDA constexpr bool is_trivial_fun(Sig fun)
Definition cartesian_product.hpp:333
CUDA constexpr bool join(const Ai &a)
Definition cartesian_product.hpp:281
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
static CUDA bool interpret_one_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:151
CUDA constexpr type_of< i > & project()
Definition cartesian_product.hpp:193
static CUDA bool interpret_one_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:146
CUDA constexpr value_type value() const
Definition cartesian_product.hpp:202
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:165
static constexpr const bool preserve_join
Definition cartesian_product.hpp:81
CUDA void print() const
Definition cartesian_product.hpp:404
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
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:85
CUDA constexpr void project(Sig fun, const CartesianProduct< Bs... > &a)
Definition cartesian_product.hpp:339
CUDA constexpr this_type & operator=(const this_type &other)
Definition cartesian_product.hpp:111
static constexpr size_t n
Definition cartesian_product.hpp:66
CUDA constexpr void join_top()
Definition cartesian_product.hpp:271
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:198
static CUDA constexpr local_type top()
Definition cartesian_product.hpp:122
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:295
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:156
static constexpr const bool preserve_top
Definition cartesian_product.hpp:80
CUDA constexpr CartesianProduct(CartesianProduct< Bs... > &&other)
Definition cartesian_product.hpp:101
static CUDA constexpr local_type bot()
Definition cartesian_product.hpp:117
CUDA constexpr auto project(Sig fun, const A &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:356
static constexpr const bool is_abstract_universe
Definition cartesian_product.hpp:76
CUDA constexpr CartesianProduct(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:98
CUDA constexpr CartesianProduct(As &&... as)
Definition cartesian_product.hpp:94
Definition diagnostics.hpp:19
Definition ast.hpp:234
battery::vector< this_type, Allocator > Sequence
Definition ast.hpp:238
CUDA static NI this_type make_nary(Sig sig, Sequence children, AType atype=UNTYPED, bool flatten=true)
Definition ast.hpp:427
#define CALL_WITH_ERROR_CONTEXT(MSG, CALL)
Definition diagnostics.hpp:180
Definition ast.hpp:210
::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:530
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
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:484
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
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:412