3#ifndef LALA_CORE_CARTESIAN_PRODUCT_HPP 
    4#define LALA_CORE_CARTESIAN_PRODUCT_HPP 
    6#include "battery/utility.hpp" 
    7#include "battery/vector.hpp" 
    8#include "battery/tuple.hpp" 
    9#include "battery/variant.hpp" 
   16class CartesianProduct;
 
   20  CUDA 
constexpr auto index_sequence_of(
const CartesianProduct<As...>&) {
 
   21    return std::index_sequence_for<As...>{};
 
   25  CUDA 
constexpr auto index_sequence_of(
const battery::tuple<As...>&) {
 
   26    return std::index_sequence_for<As...>{};
 
   29  template <
class A, 
class B>
 
   30  CUDA 
constexpr auto index_sequence_of(
const A& a, 
const B& b) {
 
   31    static_assert(
decltype(impl::index_sequence_of(a))::size() == 
decltype(impl::index_sequence_of(b))::size());
 
   32    return impl::index_sequence_of(a);
 
   36  CUDA 
constexpr typename CartesianProduct<Os...>::local_type make_cp(Os... os) {
 
   42    static constexpr bool value = 
false;
 
   46  struct is_product<CartesianProduct<As...>> {
 
   47    static constexpr bool value = 
true;
 
   51  struct is_product<
battery::tuple<As...>> {
 
   52    static constexpr bool value = 
true;
 
   56  inline static constexpr bool is_product_v = is_product<A>::value;
 
   65  using type_of = 
typename battery::tuple_element<i, battery::tuple<As...>>::type;
 
   66  constexpr static size_t n = battery::tuple_size<battery::tuple<As...>>{};
 
   67  static_assert(
n > 0, 
"CartesianProduct must not be empty.");
 
   74  using value_type = battery::tuple<
typename As::value_type...>;
 
   77  constexpr static const bool sequential = (... && As::sequential);
 
   79  constexpr static const bool preserve_bot = (... && As::preserve_bot);
 
   80  constexpr static const bool preserve_top = (... && As::preserve_top);
 
   85  constexpr static const char* 
name = 
"CartesianProduct";
 
   88  battery::tuple<As...> val;
 
  100  template<
class... Bs>
 
  103  template<
class... Bs>
 
  108  template <
class... Bs>
 
  129  template<
IKind kind, 
bool diagnose, 
size_t i, 
class F, 
class Env, 
class... Bs>
 
  131    return type_of<i>::template interpret<kind, diagnose>(f, env, k.template project<i>(), diagnostics);
 
  134  template<
IKind kind, 
bool diagnose, 
size_t i = 0, 
class F, 
class Env, 
class... Bs>
 
  135  CUDA NI 
static bool interpret_all(
const F& f, CartesianProduct<Bs...>& k, 
bool empty, 
const Env& env, IDiagnostics& diagnostics) {
 
  136    if constexpr(i == 
n) {
 
  140      bool res = interpret_one<kind, diagnose, i>(f, env, k, diagnostics);
 
  141      return interpret_all<kind, diagnose, i+1>(f, k, empty && !res, env, diagnostics);
 
  146  template<
size_t i, 
bool diagnose = 
false, 
class F, 
class Env, 
class... Bs>
 
  148    return interpret_one<IKind::TELL, diagnose, i>(f, env, k, diagnostics);
 
 
  151  template<
size_t i, 
bool diagnose = 
false, 
class F, 
class Env, 
class... Bs>
 
  153    return interpret_one<IKind::ASK, diagnose, i>(f, env, k, diagnostics);
 
 
  156  template<
IKind kind, 
bool diagnose = 
false, 
class F, 
class Env, 
class... Bs>
 
  159      "No component of this Cartesian product can interpret this formula.",
 
  160      (interpret_all<kind, diagnose>(f, k, 
true, env, diagnostics))
 
 
  165  template<
bool diagnose, 
class F, 
class Env, 
class... Bs>
 
  167    return interpret<IKind::TELL, diagnose>(f, env, k, diagnostics);
 
 
  170  template<
bool diagnose, 
class F, 
class Env, 
class... Bs>
 
  172    return interpret<IKind::ASK, diagnose>(f, env, k, diagnostics);
 
 
  176  template<
size_t... I>
 
  177  CUDA 
constexpr value_type value_(std::index_sequence<I...>)
 const {
 
  181  template<
size_t... I>
 
  182  CUDA 
constexpr local::B is_top_(std::index_sequence<I...>)
 const {
 
  183    return (... && project<I>().
is_top());
 
  186  template<
size_t... I>
 
  187  CUDA 
constexpr local::B is_bot_(std::index_sequence<I...>)
 const {
 
  188    return (... || project<I>().
is_bot());
 
  195    return battery::get<i>(val);
 
 
  200    return battery::get<i>(val);
 
 
  204    return value_(std::index_sequence_for<As...>{});
 
 
  209    return is_top_(std::index_sequence_for<As...>{});
 
 
  216    return is_bot_(std::index_sequence_for<As...>{});
 
 
  220  template<
size_t i = 0, 
class... Bs>
 
  222    if constexpr (i < 
n) {
 
  223      bool has_changed = project<i>().join(other.template project<i>());
 
  224      has_changed |= join_<i+1>(other);
 
  232  template<
size_t i = 0, 
class... Bs>
 
  233  CUDA 
constexpr bool meet_(
const CartesianProduct<Bs...>& other) {
 
  234    if constexpr (i < 
n) {
 
  235      bool has_changed = project<i>().meet(other.template project<i>());
 
  236      has_changed |= meet_<i+1>(other);
 
  244  template<
size_t i = 0>
 
  245  CUDA 
constexpr void meet_bot_() {
 
  246    if constexpr (i < 
n) {
 
  247      project<i>().meet_bot();
 
  252  template<
size_t i = 0, 
class... Bs>
 
  253  CUDA 
constexpr bool extract_(CartesianProduct<Bs...>& ua) {
 
  254    if constexpr (i < 
n) {
 
  255      bool is_under = project<i>().extract(ua.template project<i>());
 
  256      return is_under && extract_<i+1>(ua);
 
  263  template <
size_t i = 0>
 
  264  CUDA 
constexpr void join_top_() {
 
  265    if constexpr(i < 
n) {
 
  266      project<i>().join_top();
 
  276  template <
class... Bs>
 
  281  template<
size_t i, 
class Ai>
 
  282  CUDA 
constexpr bool join(
const Ai& a) {
 
  283    return project<i>().join(a);
 
 
  290  template <
class... Bs>
 
  295  template<
size_t i, 
class Ai>
 
  296  CUDA 
constexpr bool meet(
const Ai& a) {
 
  297    return project<i>().meet(a);
 
 
  301  template <
class... Bs>
 
  309  template<
class A, 
size_t... I>
 
  310  CUDA 
constexpr void project(
Sig fun, 
const A& a, std::index_sequence<I...>)
 
  312    (project<I>().project(fun, a.template project<I>()),...);
 
  315  template<
class A, 
class B, 
size_t... I>
 
  316  CUDA 
constexpr void project(
Sig fun, 
const A& a, 
const B& b, std::index_sequence<I...>)
 
  318    (project<I>().project(fun, a.template project<I>(), b.template project<I>()),...);
 
  321  template<
class A, 
class B, 
size_t... I>
 
  322  CUDA 
constexpr void project_left(
Sig fun, 
const A& a, 
const B& b, std::index_sequence<I...>)
 
  324    (project<I>().project(fun, a.template project<I>(), b),...);
 
  327  template<
class A, 
class B, 
size_t... I>
 
  328  CUDA 
constexpr void project_right(
Sig fun, 
const A& a, 
const B& b, std::index_sequence<I...>)
 
  330    (project<I>().project(fun, a, b.template project<I>()),...);
 
  335    return (... && As::is_trivial_fun(fun));
 
 
  339  template<
class... Bs>
 
  341    project(fun, a, impl::index_sequence_of(a));
 
 
  346  template<
class... As2, 
class... Bs>
 
  348    project(fun, a, b, impl::index_sequence_of(a, b));
 
 
  351  template<
class... As2, 
class B>
 
  353    project_left(fun, a, b, impl::index_sequence_of(a));
 
 
  356  template<
class A, 
class... Bs>
 
  358    project_right(fun, a, b, impl::index_sequence_of(b));
 
 
  362  template<
size_t i, 
class Env, 
class Allocator = 
typename Env::allocator_type>
 
  366    if constexpr(i < 
n) {
 
  367      auto f = project<i>().deinterpret(x, env, allocator);
 
  369        seq.push_back(project<i>().
deinterpret(x, env, allocator));
 
  371      return deinterpret_<i+1, Env>(x, seq, env, allocator);
 
  374      if(seq.size() == 1) {
 
  375        return std::move(seq[0]);
 
  386  template<
class Env, 
class Allocator = 
typename Env::allocator_type>
 
  389    return deinterpret_<0, Env>(x, seq, env, allocator);
 
 
  393  template<
size_t i = 0>
 
  394  CUDA NI 
void print_()
 const {
 
  395    if constexpr(i < 
n) {
 
  396      project<i>().print();
 
  397      if constexpr(i < 
n - 1) {
 
 
  411template<
size_t i, 
class... As>
 
  412CUDA 
constexpr const typename CartesianProduct<As...>::template type_of<i>&
 
  414  return cp.template project<i>();
 
 
  417template<
size_t i, 
class... As>
 
  418CUDA 
constexpr typename CartesianProduct<As...>::template type_of<i>&
 
  420  return cp.template project<i>();
 
 
  425  template<
class A, 
class B, 
size_t... I>
 
  426  CUDA 
constexpr auto fjoin_(
const A& a, 
const B& b, std::index_sequence<I...>)
 
  428    return make_cp(
fjoin(project<I>(a), project<I>(b))...);
 
  431  template<
class A, 
class B, 
size_t... I>
 
  432  CUDA 
constexpr auto fmeet_(
const A& a, 
const B& b, std::index_sequence<I...>)
 
  434    return make_cp(
fmeet(project<I>(a), project<I>(b))...);
 
  437  template<
class A, 
class B, 
size_t... I>
 
  438  CUDA 
constexpr bool eq_(
const A& a, 
const B& b, std::index_sequence<I...>)
 
  440    return (... && (project<I>(a) == project<I>(b)));
 
  443  template<
class A, 
class B, 
size_t... I>
 
  444  CUDA 
constexpr bool neq_(
const A& a, 
const B& b, std::index_sequence<I...>)
 
  446    return (... || (project<I>(a) != project<I>(b)));
 
  449  template<
class A, 
class B, 
size_t... I>
 
  450  CUDA 
constexpr bool leq_(
const A& a, 
const B& b, std::index_sequence<I...>)
 
  452    return (... && (project<I>(a) <= project<I>(b)));
 
  455  template<
class A, 
class B, 
size_t... I>
 
  456  CUDA 
constexpr bool lt_(
const A& a, 
const B& b, std::index_sequence<I...>)
 
  458    return leq_(a, b, std::index_sequence<I...>{}) && neq_(a, b, std::index_sequence<I...>{});
 
  463template<
class... As, 
class... Bs>
 
  466  return impl::fjoin_(a, b, impl::index_sequence_of(a, b));
 
 
  470template<
class... As, 
class... Bs>
 
  473  return impl::fmeet_(a, b, impl::index_sequence_of(a, b));
 
 
  477template<
class... As, 
class... Bs>
 
  478CUDA 
constexpr bool operator<=(
const CartesianProduct<As...>& a, 
const CartesianProduct<Bs...>& b)
 
  480  if(a.is_bot()) { 
return true; }
 
  481  return impl::leq_(a, b, impl::index_sequence_of(a, b));
 
  484template<
class... As, 
class... Bs>
 
  488  return impl::lt_(a, b, impl::index_sequence_of(a, b));
 
 
  491template<
class... As, 
class... Bs>
 
  492CUDA 
constexpr bool operator>=(
const CartesianProduct<As...>& a, 
const CartesianProduct<Bs...>& b)
 
  497template<
class... As, 
class... Bs>
 
  503template<
class... As, 
class... Bs>
 
  507  return impl::eq_(a, b, impl::index_sequence_of(a, b));
 
 
  510template<
class... As, 
class... Bs>
 
  511CUDA 
constexpr bool operator!=(
const CartesianProduct<As...>& a, 
const CartesianProduct<Bs...>& b)
 
  513  if(a.is_bot() != b.is_bot()) { 
return true; }
 
  514  return impl::neq_(a, b, impl::index_sequence_of(a, b));
 
  518  template<
size_t i = 0, 
class... As>
 
  519  void std_print(std::ostream &s, 
const CartesianProduct<As...> &cp) {
 
  520    if constexpr(i < CartesianProduct<As...>::n) {
 
  522      if constexpr(i < CartesianProduct<As...>::n - 1) {
 
  524        std_print<i+1>(s, cp);
 
  530template<
class A, 
class... As>
 
  535  impl::std_print<0>(s, cp);
 
 
Definition cartesian_product.hpp:62
 
CUDA constexpr this_type & operator=(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:109
 
CUDA constexpr bool join(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:277
 
CUDA constexpr void project(Sig fun, const CartesianProduct< As2... > &a, const B &b)
Definition cartesian_product.hpp:352
 
constexpr CartesianProduct()=default
 
CUDA constexpr void project(Sig fun, const CartesianProduct< As2... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:347
 
static CUDA bool interpret_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:171
 
static CUDA constexpr bool is_trivial_fun(Sig fun)
Definition cartesian_product.hpp:334
 
CUDA constexpr bool join(const Ai &a)
Definition cartesian_product.hpp:282
 
CUDA TFormula< Allocator > deinterpret(AVar x, const Env &env, const Allocator &allocator=Allocator()) const
Definition cartesian_product.hpp:387
 
CUDA constexpr bool extract(CartesianProduct< Bs... > &ua) const
Definition cartesian_product.hpp:302
 
CUDA constexpr local::B is_bot() const
Definition cartesian_product.hpp:215
 
CUDA constexpr local::B is_top() const
Definition cartesian_product.hpp:208
 
static CUDA bool interpret_one_ask(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:152
 
CUDA constexpr type_of< i > & project()
Definition cartesian_product.hpp:194
 
static CUDA bool interpret_one_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:147
 
constexpr this_type & operator=(const this_type &)=default
 
CUDA constexpr value_type value() const
Definition cartesian_product.hpp:203
 
static constexpr const bool is_totally_ordered
Definition cartesian_product.hpp:78
 
static constexpr const bool injective_concretization
Definition cartesian_product.hpp:83
 
static CUDA bool interpret_tell(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:166
 
static constexpr const bool preserve_join
Definition cartesian_product.hpp:81
 
CUDA void print() const
Definition cartesian_product.hpp:405
 
CUDA constexpr bool meet(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:291
 
CUDA constexpr void meet_bot()
Definition cartesian_product.hpp:286
 
static constexpr const bool sequential
Definition cartesian_product.hpp:77
 
static constexpr const char * name
Definition cartesian_product.hpp:85
 
CUDA constexpr void project(Sig fun, const CartesianProduct< Bs... > &a)
Definition cartesian_product.hpp:340
 
constexpr this_type & operator=(this_type &&)=default
 
static constexpr size_t n
Definition cartesian_product.hpp:66
 
CUDA constexpr void join_top()
Definition cartesian_product.hpp:272
 
constexpr CartesianProduct(const CartesianProduct< As... > &)=default
 
static constexpr const bool preserve_bot
Definition cartesian_product.hpp:79
 
static constexpr const bool preserve_meet
Definition cartesian_product.hpp:82
 
battery::tuple< typename As::value_type... > value_type
Definition cartesian_product.hpp:74
 
CUDA constexpr const type_of< i > & project() const
Definition cartesian_product.hpp:199
 
static CUDA constexpr local_type top()
Definition cartesian_product.hpp:123
 
typename type_of< 0 >::memory_type memory_type
Definition cartesian_product.hpp:70
 
CUDA constexpr CartesianProduct(const As &... as)
Definition cartesian_product.hpp:93
 
CUDA constexpr CartesianProduct(typename As::value_type... vs)
Definition cartesian_product.hpp:95
 
CartesianProduct< typename As::local_type... > local_type
Definition cartesian_product.hpp:69
 
CUDA constexpr bool meet(const Ai &a)
Definition cartesian_product.hpp:296
 
static constexpr const bool preserve_concrete_covers
Definition cartesian_product.hpp:84
 
CUDA static NI bool interpret(const F &f, const Env &env, CartesianProduct< Bs... > &k, IDiagnostics &diagnostics)
Definition cartesian_product.hpp:157
 
constexpr CartesianProduct(CartesianProduct< As... > &&)=default
 
static constexpr const bool preserve_top
Definition cartesian_product.hpp:80
 
CUDA constexpr CartesianProduct(CartesianProduct< Bs... > &&other)
Definition cartesian_product.hpp:104
 
static CUDA constexpr local_type bot()
Definition cartesian_product.hpp:118
 
CUDA constexpr auto project(Sig fun, const A &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:357
 
typename battery::tuple_element< i, battery::tuple< As... > >::type type_of
Definition cartesian_product.hpp:65
 
static constexpr const bool is_abstract_universe
Definition cartesian_product.hpp:76
 
CUDA constexpr CartesianProduct(const CartesianProduct< Bs... > &other)
Definition cartesian_product.hpp:101
 
CUDA constexpr CartesianProduct(As &&... as)
Definition cartesian_product.hpp:94
 
Definition diagnostics.hpp:19
 
#define CALL_WITH_ERROR_CONTEXT(MSG, CALL)
Definition diagnostics.hpp:181
 
::lala::B<::battery::local_memory > B
Definition b.hpp:12
 
Definition abstract_deps.hpp:14
 
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition cartesian_product.hpp:531
 
CUDA constexpr auto fjoin(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:464
 
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:504
 
@ AND
Unary arithmetic function symbols.
Definition ast.hpp:114
 
CUDA constexpr bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:485
 
CUDA constexpr auto fmeet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:471
 
CUDA constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:498
 
IKind
Definition ast.hpp:28
 
CUDA constexpr const CartesianProduct< As... >::template type_of< i > & project(const CartesianProduct< As... > &cp)
Similar to cp.template project<i>(), just to avoid the ".template" syntax.
Definition cartesian_product.hpp:413