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 = (... && As::preserve_join);
82 constexpr static const bool preserve_meet = false; // false in general, not sure if there are conditions the underlying universes could satisfy to make this true.
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 bool complemented = false;
86 constexpr static const char* name = "CartesianProduct";
87
88private:
89 battery::tuple<As...> val;
90
91public:
92 /** Initialize a Cartesian product to bottom using default constructors. */
93 constexpr CartesianProduct() = default;
94 CUDA constexpr CartesianProduct(const As&... as): val(battery::make_tuple(as...)) {}
95 CUDA constexpr CartesianProduct(As&&... as): val(battery::make_tuple(std::forward<As>(as)...)) {}
96 CUDA constexpr CartesianProduct(typename As::value_type... vs): val(battery::make_tuple(As(vs)...)) {}
97
98 template<class... Bs>
99 CUDA constexpr CartesianProduct(const CartesianProduct<Bs...>& other): val(other.val) {}
100
101 template<class... Bs>
102 CUDA constexpr CartesianProduct(CartesianProduct<Bs...>&& other): val(std::move(other.val)) {}
103
104 /** The assignment operator can only be used in a sequential context.
105 * It is monotone but not extensive. */
106 template <class... Bs>
107 CUDA constexpr this_type& operator=(const CartesianProduct<Bs...>& other) {
108 if constexpr(sequential) {
109 val = other.val;
110 return *this;
111 }
112 else {
113 static_assert(sequential, "operator= seq (CartesianProduct).");
114 }
115 }
116
117 CUDA constexpr this_type& operator=(const this_type& other) {
118 if constexpr(sequential) {
119 val = other.val;
120 return *this;
121 }
122 else {
123 static_assert(sequential, "operator= seq (CartesianProduct).");
124 }
125 }
126
127 /** Cartesian product initialized to \f$ (\bot_1, \ldots, \bot_n) \f$. */
128 CUDA static constexpr local_type bot() {
129 return local_type(As::bot()...);
130 }
131
132 /** Cartesian product initialized to \f$ (\top_1, \ldots, \top_n) \f$. */
133 CUDA static constexpr local_type top() {
134 return local_type(As::top()...);
135 }
136
137private:
138 /** Interpret the formula in the component `i`. */
139 template<IKind kind, bool diagnose, size_t i, class F, class Env, class... Bs>
140 CUDA NI static bool interpret_one(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
141 return type_of<i>::template interpret<kind, diagnose>(f, env, k.template project<i>(), diagnostics);
142 }
143
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) {
147 return !empty;
148 }
149 else {
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);
152 }
153 }
154
155public:
156 template<size_t i, bool diagnose = false, class F, class Env, class... Bs>
157 CUDA static bool interpret_one_tell(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
158 return interpret_one<IKind::TELL, diagnose, i>(f, env, k, diagnostics);
159 }
160
161 template<size_t i, bool diagnose = false, class F, class Env, class... Bs>
162 CUDA static bool interpret_one_ask(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
163 return interpret_one<IKind::ASK, diagnose, i>(f, env, k, diagnostics);
164 }
165
166 template<IKind kind, bool diagnose = false, class F, class Env, class... Bs>
167 CUDA NI static bool interpret(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
169 "No component of this Cartesian product can interpret this formula.",
170 (interpret_all<kind, diagnose>(f, k, true, env, diagnostics))
171 );
172 }
173
174 /** Interpret the formula `f` in all sub-universes in which `f` is interpretable. */
175 template<bool diagnose, class F, class Env, class... Bs>
176 CUDA static bool interpret_tell(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
177 return interpret<IKind::TELL, diagnose>(f, env, k, diagnostics);
178 }
179
180 template<bool diagnose, class F, class Env, class... Bs>
181 CUDA static bool interpret_ask(const F& f, const Env& env, CartesianProduct<Bs...>& k, IDiagnostics& diagnostics) {
182 return interpret<IKind::ASK, diagnose>(f, env, k, diagnostics);
183 }
184
185private:
186 template<size_t... I>
187 CUDA constexpr value_type value_(std::index_sequence<I...>) const {
188 return value_type(project<I>().value()...);
189 }
190
191 template<size_t... I>
192 CUDA constexpr local::BInc is_top_(std::index_sequence<I...>) const {
193 return (... || project<I>().is_top());
194 }
195
196 template<size_t... I>
197 CUDA constexpr local::BDec is_bot_(std::index_sequence<I...>) const {
198 return (... && project<I>().is_bot());
199 }
200
201public:
202 /** You must use the lattice interface (tell methods) to modify the projected type, if you use assignment you violate the PCCP model. */
203 template<size_t i>
204 CUDA constexpr type_of<i>& project() {
205 return battery::get<i>(val);
206 }
207
208 template<size_t i>
209 CUDA constexpr const type_of<i>& project() const {
210 return battery::get<i>(val);
211 }
212
213 CUDA constexpr value_type value() const {
214 return value_(std::index_sequence_for<As...>{});
215 }
216
217 /** `true` if \f$ \exists{j \geq i},~\gamma(a_j) = \top^\flat \f$, `false` otherwise. */
218 CUDA constexpr local::BInc is_top() const {
219 return is_top_(std::index_sequence_for<As...>{});
220 }
221
222 /** `true` if \f$ \forall{j \geq i},~\gamma(a_j) = \bot^\flat \f$, `false` otherwise. */
223 CUDA constexpr local::BDec is_bot() const {
224 return is_bot_(std::index_sequence_for<As...>{});
225 }
226
227private:
228 template<size_t i = 0, class M, class... Bs>
229 CUDA constexpr this_type& tell_(const CartesianProduct<Bs...>& other, BInc<M>& has_changed) {
230 if constexpr (i < n) {
231 project<i>().tell(other.template project<i>(), has_changed);
232 return tell_<i+1>(other, has_changed);
233 }
234 else {
235 return *this;
236 }
237 }
238
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);
244 }
245 else {
246 return *this;
247 }
248 }
249
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);
255 }
256 else {
257 return *this;
258 }
259 }
260
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);
266 }
267 else {
268 return *this;
269 }
270 }
271
272 template<size_t i = 0>
273 CUDA constexpr this_type& dtell_bot_() {
274 if constexpr (i < n) {
275 project<i>().dtell_bot();
276 return dtell_bot_<i+1>();
277 }
278 else {
279 return *this;
280 }
281 }
282
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);
288 }
289 else {
290 return true;
291 }
292 }
293
294 template <size_t i = 0>
295 CUDA constexpr void tell_top_() {
296 if constexpr(i < n) {
297 project<i>().tell_top();
298 tell_top_<i+1>();
299 }
300 }
301
302public:
303 CUDA constexpr this_type& tell_top() {
304 tell_top_();
305 return *this;
306 }
307
308 template <class M, class... Bs>
309 CUDA constexpr this_type& tell(const CartesianProduct<Bs...>& other, BInc<M>& has_changed) {
310 return tell_(other, has_changed);
311 }
312
313 template<size_t i, class Ai, class M>
314 CUDA constexpr this_type& tell(const Ai& a, BInc<M>& has_changed) {
315 project<i>().tell(a, has_changed);
316 return *this;
317 }
318
319 template <class... Bs>
320 CUDA constexpr this_type& tell(const CartesianProduct<Bs...>& other) {
321 return tell_(other);
322 }
323
324 template<size_t i, class Ai>
325 CUDA constexpr this_type& tell(const Ai& a) {
326 project<i>().tell(a);
327 return *this;
328 }
329
330 CUDA constexpr this_type& dtell_bot() {
331 dtell_bot_();
332 return *this;
333 }
334
335 template <class M, class... Bs>
336 CUDA constexpr this_type& dtell(const CartesianProduct<Bs...>& other, BInc<M>& has_changed) {
337 return dtell_(other, has_changed);
338 }
339
340 template<size_t i, class Ai, class M>
341 CUDA constexpr this_type& dtell(const Ai& a, BInc<M>& has_changed) {
342 project<i>().dtell(a, has_changed);
343 return *this;
344 }
345
346 template <class... Bs>
347 CUDA constexpr this_type& dtell(const CartesianProduct<Bs...>& other) {
348 return dtell_(other);
349 }
350
351 template<size_t i, class Ai>
352 CUDA constexpr this_type& dtell(const Ai& a) {
353 project<i>().dtell(a);
354 return *this;
355 }
356
357 /** For correctness, the parameter `ua` must be stored in a local memory. */
358 template <class... Bs>
359 CUDA constexpr bool extract(CartesianProduct<Bs...>& ua) const {
360 return extract_(ua);
361 }
362
363// Implementation of the logical signature.
364
365private:
366 template<Sig sig, class A, size_t... I>
367 CUDA static constexpr auto fun_(const A& a, std::index_sequence<I...>)
368 {
369 return impl::make_cp((As::template fun<sig>(a.template project<I>()))...);
370 }
371
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...>)
374 {
375 return impl::make_cp((As::template fun<sig>(a.template project<I>(), b.template project<I>()))...);
376 }
377
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...>)
380 {
381 return impl::make_cp((As::template fun<sig>(a.template project<I>(), b))...);
382 }
383
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...>)
386 {
387 return impl::make_cp((As::template fun<sig>(a, b.template project<I>()))...);
388 }
389
390public:
391 CUDA static constexpr bool is_supported_fun(Sig sig) {
392 return (... && As::is_supported_fun(sig));
393 }
394
395 /** Given a product \f$ (x_1, \ldots, x_n) \f$, returns \f$ (f(x_1), \ldots, f(x_n)) \f$. */
396 template<Sig sig, class... Bs>
397 CUDA static constexpr auto fun(const CartesianProduct<Bs...>& a) {
398 return fun_<sig>(a, impl::index_sequence_of(a));
399 }
400
401 /** Given two product \f$ (x_1, \ldots, x_n) \f$ and \f$ (y_1, \ldots, y_n) \f$, returns \f$ (f(x_1, y_1), \ldots, f(x_n, y_n)) \f$.
402 If either the left or right operand is not a product, returns \f$ (f(x_1, c), \ldots, f(x_n, c)) \f$ or \f$ (f(c, y_1), \ldots, f(c, y_n)) \f$. */
403 template<Sig sig, class... As2, class... Bs>
404 CUDA static constexpr auto fun(const CartesianProduct<As2...>& a, const CartesianProduct<Bs...>& b) {
405 return fun_<sig>(a, b, impl::index_sequence_of(a, b));
406 }
407
408 template<Sig sig, class... As2, class B>
409 CUDA static constexpr auto fun(const CartesianProduct<As2...>& a, const B& b) {
410 return fun_left<sig>(a, b, impl::index_sequence_of(a));
411 }
412
413 template<Sig sig, class A, class... Bs>
414 CUDA static constexpr auto fun(const A& a, const CartesianProduct<Bs...>& b) {
415 return fun_right<sig>(a, b, impl::index_sequence_of(b));
416 }
417
418private:
419 template<size_t i, class Env, class Allocator = typename Env::allocator_type>
420 CUDA NI TFormula<Allocator> deinterpret_(AVar x,
421 typename TFormula<Allocator>::Sequence& seq, const Env& env) const
422 {
423 if constexpr(i < n) {
424 auto f = project<i>().deinterpret(x, env);
425 if(!f.is_true()) {
426 seq.push_back(project<i>().deinterpret(x, env));
427 }
428 return deinterpret_<i+1, Env>(x, seq, env);
429 }
430 else {
431 if(seq.size() == 1) {
432 return std::move(seq[0]);
433 }
434 else {
436 AND,
437 std::move(seq));
438 }
439 }
440 }
441
442public:
443 template<class Env>
445 using allocator_t = typename Env::allocator_type;
446 typename TFormula<allocator_t>::Sequence seq(env.get_allocator());
447 return deinterpret_<0, Env>(x, seq, env);
448 }
449
450private:
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) {
456 printf("\n");
457 print_<i+1>();
458 }
459 }
460 }
461
462public:
463 CUDA void print() const {
464 print_();
465 }
466};
467
468/// Similar to `cp.template project<i>()`, just to avoid the ".template" syntax.
469template<size_t i, class... As>
470CUDA constexpr const typename CartesianProduct<As...>::template type_of<i>&
472 return cp.template project<i>();
473}
474
475template<size_t i, class... As>
476CUDA constexpr typename CartesianProduct<As...>::template type_of<i>&
478 return cp.template project<i>();
479}
480
481// Lattice operators
482namespace impl {
483 template<class A, class B, size_t... I>
484 CUDA constexpr auto join_(const A& a, const B& b, std::index_sequence<I...>)
485 {
486 return make_cp(join(project<I>(a), project<I>(b))...);
487 }
488
489 template<class A, class B, size_t... I>
490 CUDA constexpr auto meet_(const A& a, const B& b, std::index_sequence<I...>)
491 {
492 return make_cp(meet(project<I>(a), project<I>(b))...);
493 }
494
495 template<class A, class B, size_t... I>
496 CUDA constexpr bool eq_(const A& a, const B& b, std::index_sequence<I...>)
497 {
498 return (... && (project<I>(a) == project<I>(b)));
499 }
500
501 template<class A, class B, size_t... I>
502 CUDA constexpr bool neq_(const A& a, const B& b, std::index_sequence<I...>)
503 {
504 return (... || (project<I>(a) != project<I>(b)));
505 }
506
507 template<class A, class B, size_t... I>
508 CUDA constexpr bool leq_(const A& a, const B& b, std::index_sequence<I...>)
509 {
510 return (... && (project<I>(a) <= project<I>(b)));
511 }
512
513 template<class A, class B, size_t... I>
514 CUDA constexpr bool lt_(const A& a, const B& b, std::index_sequence<I...>)
515 {
516 return leq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
517 }
518
519 template<class A, class B, size_t... I>
520 CUDA constexpr bool geq_(const A& a, const B& b, std::index_sequence<I...>)
521 {
522 return (... && (project<I>(a) >= project<I>(b)));
523 }
524
525 template<class A, class B, size_t... I>
526 CUDA constexpr bool gt_(const A& a, const B& b, std::index_sequence<I...>)
527 {
528 return geq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
529 }
530}
531
532/** \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$ */
533template<class... As, class... Bs>
534CUDA constexpr auto join(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
535{
536 return impl::join_(a, b, impl::index_sequence_of(a, b));
537}
538
539/** \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$ */
540template<class... As, class... Bs>
541CUDA constexpr auto meet(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
542{
543 return impl::meet_(a, b, impl::index_sequence_of(a, b));
544}
545
546/** \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$. */
547template<class... As, class... Bs>
548CUDA constexpr bool operator<=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
549{
550 return impl::leq_(a, b, impl::index_sequence_of(a, b));
551}
552
553template<class... As, class... Bs>
554CUDA constexpr bool operator<(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
555{
556 return impl::lt_(a, b, impl::index_sequence_of(a, b));
557}
558
559template<class... As, class... Bs>
560CUDA constexpr bool operator>=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
561{
562 return impl::geq_(a, b, impl::index_sequence_of(a, b));
563}
564
565template<class... As, class... Bs>
566CUDA constexpr bool operator>(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
567{
568 return impl::gt_(a, b, impl::index_sequence_of(a, b));
569}
570
571template<class... As, class... Bs>
572CUDA constexpr bool operator==(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
573{
574 return impl::eq_(a, b, impl::index_sequence_of(a, b));
575}
576
577template<class... As, class... Bs>
578CUDA constexpr bool operator!=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
579{
580 return impl::neq_(a, b, impl::index_sequence_of(a, b));
581}
582
583namespace impl {
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) {
587 s << project<i>(cp);
588 if constexpr(i < CartesianProduct<As...>::n - 1) {
589 s << ", ";
590 std_print<i+1>(s, cp);
591 }
592 }
593 }
594}
595
596template<class A, class... As>
597std::ostream& operator<<(std::ostream &s, const CartesianProduct<A, As...> &cp) {
598// There is a weird compilation bug with `template<class... As>` where the compiler tries to instantiate << with an empty sequence of templates.
599// Forcing at least one template solves the problem.
600 s << "(";
601 impl::std_print<0>(s, cp);
602 s << ")";
603 return s;
604}
605
606} // namespace lala
607
608#endif
Definition ast.hpp:38
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
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::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
Sig
Definition ast.hpp:94
@ 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