Lattice Land Core Library
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 
13 namespace lala {
14 
15 template<class... As>
16 class CartesianProduct;
17 
18 namespace 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.
60 Concretization function: \f$ \gamma((a_1, \ldots, a_n)) = \bigcap_{i \leq n} \gamma_i(a_i) \f$. */
61 template<class... As>
63 public:
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.");
68  using this_type = CartesianProduct<As...>;
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 
87 private:
88  battery::tuple<As...> val;
89 
90 public:
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;
98  constexpr CartesianProduct(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 
127 private:
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 
145 public:
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 
175 private:
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 
191 public:
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 
219 private:
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 
271 public:
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 
308 private:
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 
333 public:
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 
361 private:
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 
385 public:
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 
392 private:
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 
404 public:
405  CUDA void print() const {
406  print_();
407  }
408 };
409 
410 /// Similar to `cp.template project<i>()`, just to avoid the ".template" syntax.
411 template<size_t i, class... As>
412 CUDA constexpr const typename CartesianProduct<As...>::template type_of<i>&
414  return cp.template project<i>();
415 }
416 
417 template<size_t i, class... As>
418 CUDA constexpr typename CartesianProduct<As...>::template type_of<i>&
420  return cp.template project<i>();
421 }
422 
423 // Lattice operators
424 namespace 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$ */
463 template<class... As, class... Bs>
464 CUDA 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$ */
470 template<class... As, class... Bs>
471 CUDA 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$. */
477 template<class... As, class... Bs>
478 CUDA 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 
484 template<class... As, class... Bs>
485 CUDA 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 
491 template<class... As, class... Bs>
492 CUDA constexpr bool operator>=(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
493 {
494  return b <= a;
495 }
496 
497 template<class... As, class... Bs>
498 CUDA constexpr bool operator>(const CartesianProduct<As...>& a, const CartesianProduct<Bs...>& b)
499 {
500  return b < a;
501 }
502 
503 template<class... As, class... Bs>
504 CUDA 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 
510 template<class... As, class... Bs>
511 CUDA 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 
517 namespace 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 
530 template<class A, class... As>
531 std::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
constexpr CUDA bool join(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:277
CUDA TFormula< Allocator > deinterpret(AVar x, const Env &env, const Allocator &allocator=Allocator()) const
Definition: cartesian_product.hpp:387
constexpr static const bool preserve_join
Definition: cartesian_product.hpp:81
constexpr static size_t n
Definition: cartesian_product.hpp:66
constexpr CUDA value_type value() const
Definition: cartesian_product.hpp:203
constexpr static const bool sequential
Definition: cartesian_product.hpp:77
constexpr CartesianProduct()=default
static CUDA bool interpret_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:171
constexpr CUDA bool meet(const Ai &a)
Definition: cartesian_product.hpp:296
constexpr CUDA CartesianProduct(CartesianProduct< Bs... > &&other)
Definition: cartesian_product.hpp:104
constexpr CUDA auto project(Sig fun, const A &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:357
constexpr CUDA CartesianProduct(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:101
static CUDA bool interpret_one_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:152
constexpr CUDA this_type & operator=(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:109
constexpr CUDA void meet_bot()
Definition: cartesian_product.hpp:286
constexpr static const bool is_abstract_universe
Definition: cartesian_product.hpp:76
constexpr static const bool preserve_top
Definition: cartesian_product.hpp:80
static CUDA bool interpret_one_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:147
static constexpr CUDA local_type bot()
Definition: cartesian_product.hpp:118
constexpr CUDA bool join(const Ai &a)
Definition: cartesian_product.hpp:282
static CUDA bool interpret_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:166
CUDA void print() const
Definition: cartesian_product.hpp:405
constexpr static const bool preserve_meet
Definition: cartesian_product.hpp:82
constexpr CUDA const type_of< i > & project() const
Definition: cartesian_product.hpp:199
constexpr static const bool is_totally_ordered
Definition: cartesian_product.hpp:78
constexpr CUDA void join_top()
Definition: cartesian_product.hpp:272
constexpr static const bool preserve_bot
Definition: cartesian_product.hpp:79
constexpr static const bool preserve_concrete_covers
Definition: cartesian_product.hpp:84
constexpr CUDA local::B is_top() const
Definition: cartesian_product.hpp:208
constexpr CUDA type_of< i > & project()
Definition: cartesian_product.hpp:194
static constexpr CUDA local_type top()
Definition: cartesian_product.hpp:123
constexpr CUDA void project(Sig fun, const CartesianProduct< As2... > &a, const B &b)
Definition: cartesian_product.hpp:352
constexpr CartesianProduct(const CartesianProduct< As... > &)=default
constexpr CUDA CartesianProduct(const As &... as)
Definition: cartesian_product.hpp:93
battery::tuple< typename As::value_type... > value_type
Definition: cartesian_product.hpp:74
constexpr CUDA local::B is_bot() const
Definition: cartesian_product.hpp:215
constexpr static const char * name
Definition: cartesian_product.hpp:85
constexpr this_type & operator=(const this_type &)=default
typename type_of< 0 >::memory_type memory_type
Definition: cartesian_product.hpp:70
constexpr CUDA void project(Sig fun, const CartesianProduct< As2... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:347
CartesianProduct< typename As::local_type... > local_type
Definition: cartesian_product.hpp:69
static constexpr CUDA bool is_trivial_fun(Sig fun)
Definition: cartesian_product.hpp:334
constexpr CUDA CartesianProduct(typename As::value_type... vs)
Definition: cartesian_product.hpp:95
constexpr CUDA bool meet(const CartesianProduct< Bs... > &other)
Definition: cartesian_product.hpp:291
CUDA static NI bool interpret(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition: cartesian_product.hpp:157
constexpr CUDA bool extract(CartesianProduct< Bs... > &ua) const
Definition: cartesian_product.hpp:302
constexpr static const bool injective_concretization
Definition: cartesian_product.hpp:83
constexpr CartesianProduct(CartesianProduct< As... > &&)=default
constexpr CUDA CartesianProduct(As &&... as)
Definition: cartesian_product.hpp:94
constexpr this_type & operator=(this_type &&)=default
constexpr CUDA void project(Sig fun, const CartesianProduct< Bs... > &a)
Definition: cartesian_product.hpp:340
typename battery::tuple_element< i, battery::tuple< As... > >::type type_of
Definition: cartesian_product.hpp:65
Definition: diagnostics.hpp:19
Definition: ast.hpp:247
battery::vector< this_type, Allocator > Sequence
Definition: ast.hpp:251
CUDA static NI this_type make_nary(Sig sig, Sequence children, AType atype=UNTYPED, bool flatten=true)
Definition: ast.hpp:440
#define CALL_WITH_ERROR_CONTEXT(MSG, CALL)
Definition: diagnostics.hpp:180
Definition: ast.hpp:223
::lala::B<::battery::local_memory > B
Definition: b.hpp:12
Definition: abstract_deps.hpp:14
constexpr CUDA const CartesianProduct< As... >::template type_of< i > & project(const CartesianProduct< As... > &cp)
Similar to cp.template project<i>(), just to avoid the ".template" syntax.
Definition: cartesian_product.hpp:413
constexpr CUDA bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:504
Sig
Definition: ast.hpp:94
@ AND
Unary arithmetic function symbols.
Definition: ast.hpp:114
constexpr CUDA auto fjoin(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:464
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition: cartesian_product.hpp:531
IKind
Definition: ast.hpp:28
constexpr CUDA bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:485
constexpr CUDA auto fmeet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:471
constexpr CUDA bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition: cartesian_product.hpp:498