3#ifndef LALA_CORE_AST_HPP 
    4#define LALA_CORE_AST_HPP 
    6#include "battery/utility.hpp" 
    7#include "battery/vector.hpp" 
    8#include "battery/string.hpp" 
    9#include "battery/tuple.hpp" 
   10#include "battery/variant.hpp" 
   11#include "battery/shared_ptr.hpp" 
   12#include "battery/unique_ptr.hpp" 
   24template<
class Allocator>
 
   25using LVar = battery::string<Allocator>;
 
   41  CUDA 
constexpr AVar(): value(-1) {}
 
   47    return value == other.value;
 
 
   49  CUDA 
constexpr bool operator!=(
const AVar& other)
 const {
 
   50    return value != other.value;
 
   53  CUDA 
constexpr AVar(
AType atype, 
int var_id): value((var_id << 8) | atype) {
 
   56    assert(atype < (1 << 8));
 
   57    assert(var_id < (1 << 23));
 
 
   59  CUDA 
constexpr AVar(
AType atype, 
size_t var_id): 
AVar(atype, static_cast<int>(var_id)) {}
 
   65  CUDA 
constexpr int aty()
 const {
 
   66    return is_untyped() ? -1 : (value & ((1 << 8) - 1));
 
 
   69  CUDA 
constexpr int vid()
 const {
 
 
   74    value = (
vid() << 8) | 
aty;
 
 
 
  100  SIN, 
COS, 
TAN, 
ASIN, 
ACOS, 
ATAN, 
SINH, 
COSH, 
TANH, 
ASINH, 
ACOSH, 
ATANH, 
 
 
  123    case NEG: 
return "-";
 
  124    case ABS: 
return "abs";
 
  125    case ADD: 
return "+";
 
  126    case SUB: 
return "-";
 
  127    case MUL: 
return "*";
 
  128    case DIV: 
return "/";
 
  129    case TDIV: 
return "tdiv";
 
  130    case FDIV: 
return "fdiv";
 
  131    case CDIV: 
return "cdiv";
 
  132    case EDIV: 
return "ediv";
 
  133    case MOD: 
return "%%";
 
  134    case TMOD: 
return "tmod";
 
  135    case FMOD: 
return "fmod";
 
  136    case CMOD: 
return "cmod";
 
  137    case EMOD: 
return "emod";
 
  138    case POW: 
return "^";
 
  139    case SQRT: 
return "sqrt";
 
  140    case EXP: 
return "exp";
 
  141    case LN: 
return "ln";
 
  142    case NROOT: 
return "nroot";
 
  143    case LOG: 
return "log";
 
  144    case SIN: 
return "sin";
 
  145    case COS: 
return "cos";
 
  146    case TAN: 
return "tan";
 
  147    case ASIN: 
return "asin";
 
  148    case ACOS: 
return "acos";
 
  149    case ATAN: 
return "atan";
 
  150    case SINH: 
return "sinh";
 
  151    case COSH: 
return "cosh";
 
  152    case TANH: 
return "tanh";
 
  153    case ASINH: 
return "asinh";
 
  154    case ACOSH: 
return "acosh";
 
  155    case ATANH: 
return "atanh";
 
  156    case MIN: 
return "min";
 
  157    case MAX: 
return "max";
 
  158    case UNION: 
return "\u222A";
 
  163    case IN: 
return "\u2208";
 
  164    case SUBSET: 
return "\u2282";
 
  166    case SUPSET: 
return "\u2283";
 
  168    case CARD: 
return "card";
 
  169    case HULL: 
return "hull";
 
  170    case CONVEX: 
return "convex";
 
  172    case NEQ: 
return "\u2260";
 
  173    case LEQ: 
return "\u2264";
 
  174    case GEQ: 
return "\u2265";
 
  177    case AND: 
return "\u2227";
 
  178    case OR: 
return "\u2228";
 
  179    case IMPLY: 
return "\u21D2";
 
  180    case EQUIV: 
return "\u21D4";
 
  181    case NOT: 
return "\u00AC";
 
  182    case XOR: 
return "\u2295";
 
  183    case ITE: 
return "ite";
 
  188      return "<bug! unknown sig>";
 
 
  194      case NEG: 
return "neg";
 
  195      case ADD: 
return "add";
 
  196      case SUB: 
return "sub";
 
  197      case MUL: 
return "mul";
 
  198      case DIV: 
return "div";
 
  199      case MOD: 
return "mod";
 
  200      case POW: 
return "pow";
 
  201      case UNION: 
return "union";
 
  205      case IN: 
return "in";
 
  206      case SUBSET: 
return "subset";
 
  208      case SUPSET: 
return "supset";
 
  210      case EQ: 
return "eq";
 
  211      case NEQ: 
return "neq";
 
  212      case LEQ: 
return "leq";
 
  213      case GEQ: 
return "geq";
 
  214      case LT: 
return "lt";
 
  215      case GT: 
return "gt";
 
  216      case AND: 
return "and";
 
  217      case OR: 
return "or";
 
  218      case IMPLY: 
return "imply";
 
  219      case EQUIV: 
return "equiv";
 
  220      case NOT: 
return "not";
 
  221      case XOR: 
return "xor";
 
 
  253    return sig == 
LEQ || sig == 
GEQ || sig == 
EQ || sig == 
NEQ || sig == 
GT || sig == 
LT;
 
 
  262        sig == 
EQ || sig == 
NEQ || sig == 
LEQ || sig == 
GEQ || sig == 
LT || sig == 
GT;
 
 
  289template<
class Allocator, 
class ExtendedSig = battery::
string<Allocator>>
 
  294  using Sequence = battery::vector<this_type, Allocator>;
 
  305    battery::tuple<Sig, Sequence>,  
 
  306    battery::tuple<ExtendedSig, Sequence>  
 
  310  static constexpr size_t B = 0;
 
  313  static constexpr size_t Z = 
B + 1;
 
  316  static constexpr size_t R = 
Z + 1;
 
  319  static constexpr size_t S = 
R + 1;
 
  322  static constexpr size_t V = 
S + 1;
 
  325  static constexpr size_t LV = 
V + 1;
 
  328  static constexpr size_t E = 
LV + 1;
 
  331  static constexpr size_t Seq = 
E + 1;
 
  349  template <
class Alloc2, 
class ExtendedSig2>
 
  352  template <
class Alloc2, 
class ExtendedSig2>
 
  354    : type_(other.type_), formula(
Formula::template create<
B>(true))
 
  356    switch(other.formula.index()) {
 
  357      case B: formula = Formula::template create<B>(other.
b()); 
break;
 
  358      case Z: formula = Formula::template create<Z>(other.
z()); 
break;
 
  359      case R: formula = Formula::template create<R>(other.
r()); 
break;
 
  360      case S: formula = Formula::template create<S>(
LogicSet(other.
s(), allocator));
 
  362      case V: formula = Formula::template create<V>(other.
v()); 
break;
 
  363      case LV: formula = Formula::template create<LV>(
LVar<Allocator>(other.
lv(), allocator)); 
break;
 
  364      case E: formula = Formula::template create<E>(
 
  367          battery::get<1>(other.
exists())));
 
  370        formula = Formula::template create<Seq>(
 
  376        formula = Formula::template create<ESeq>(
 
  378            ExtendedSig(other.
esig(), allocator),
 
  381      default: printf(
"print: formula not handled.\n"); assert(
false); 
break;
 
 
  386    ::battery::swap(type_, other.type_);
 
  387    ::battery::swap(formula, other.formula);
 
 
  414  CUDA NI std::optional<Sort<allocator_type>> 
sort()
 const {
 
  416    switch(formula.index()) {
 
  417      case B: 
return sort_t(sort_t::Bool);
 
  418      case Z: 
return sort_t(sort_t::Int);
 
  419      case R: 
return sort_t(sort_t::Real);
 
  424        for(
int i = 0; i < 
s().size(); ++i) {
 
  425          auto subsort = battery::get<0>(
s()[i]).sort();
 
  426          if(!subsort.has_value()) {
 
  427            subsort = battery::get<1>(
s()[i]).sort();
 
  429          if(subsort.has_value()) {
 
  430            return sort_t(sort_t::Set, std::move(*subsort) , 
s().get_allocator());
 
  435      case E: 
return battery::get<1>(
exists());
 
 
  444    return this_type(atype, Formula::template create<B>(
b));
 
 
  448    return this_type(atype, Formula::template create<Z>(i));
 
 
  454    return this_type(atype, Formula::template create<R>(battery::make_tuple(lb, ub)));
 
 
  458    return this_type(atype, Formula::template create<R>(
r));
 
 
  462    return this_type(atype, Formula::template create<S>(std::move(set)));
 
 
  475    return this_type(ty, Formula::template create<LV>(std::move(lvar)));
 
 
  479    return this_type(ty, Formula::template create<E>(battery::make_tuple(std::move(lvar), std::move(ctype))));
 
 
  487      for(
size_t i = 0; i < children.size(); ++i) {
 
  488        if(children[i].
is(
Seq) && children[i].
sig() == 
sig && children[i].
type() == atype) {
 
  489          for(
size_t j = 0; j < children[i].seq().size(); ++j) {
 
  490            seq.push_back(std::move(children[i].
seq(j)));
 
  494          seq.push_back(std::move(children[i]));
 
  497      return this_type(atype, Formula::template create<Seq>(battery::make_tuple(
sig, std::move(
seq))));
 
  500      return this_type(atype, Formula::template create<Seq>(battery::make_tuple(
sig, std::move(children))));
 
 
  523    return this_type(atype, Formula::template create<ESeq>(battery::make_tuple(std::move(
esig), std::move(children))));
 
 
  527    return formula.index();
 
 
  530  CUDA 
bool is(
size_t kind)
 const {
 
  531    return formula.index() == kind;
 
 
  535    return (
is(
B) && 
b()) || (
is(
Z) && 
z() != 0);
 
 
  539    return (
is(
B) && !
b()) || (
is(
Z) && 
z() == 0);
 
 
  544    return (
is(
B) ? (
b() ? 1 : 0) : 
z());
 
 
  556    return is(
Seq) && 
seq().size() == 1;
 
 
  560    return is(
Seq) && 
seq().size() == 2;
 
 
  564    return battery::get<B>(formula);
 
 
  568    return battery::get<Z>(formula);
 
 
  572    return battery::get<R>(formula);
 
 
  576    return battery::get<S>(formula);
 
 
  580    return battery::get<V>(formula);
 
 
  584    return battery::get<LV>(formula);
 
 
  588    return battery::get<E>(formula);
 
 
  592    return battery::get<0>(battery::get<Seq>(formula));
 
 
  597      return ::lala::is_logical(
sig());
 
 
  604      return ::lala::is_predicate(
sig());
 
 
  617  CUDA 
const ExtendedSig& 
esig()
 const {
 
  618    return battery::get<0>(battery::get<ESeq>(formula));
 
 
  622    return battery::get<1>(battery::get<Seq>(formula));
 
 
  630    return battery::get<1>(battery::get<ESeq>(formula));
 
 
  638    return battery::get<B>(formula);
 
 
  642    return battery::get<Z>(formula);
 
 
  646    return battery::get<R>(formula);
 
 
  650    return battery::get<S>(formula);
 
 
  654    return battery::get<V>(formula);
 
 
  658    return battery::get<0>(battery::get<Seq>(formula));
 
 
  662    return battery::get<0>(battery::get<ESeq>(formula));
 
 
  666    return battery::get<1>(battery::get<Seq>(formula));
 
 
  674    return battery::get<1>(battery::get<ESeq>(formula));
 
 
  696  CUDA NI 
void inplace_map_(Fun fun, 
const this_type& parent) {
 
  697    switch(formula.index()) {
 
  699        for(
int i = 0; i < 
seq().size(); ++i) {
 
  700          seq(i).inplace_map_(fun, *
this);
 
  705        for(
int i = 0; i < 
eseq().size(); ++i) {
 
  706          eseq(i).inplace_map_(fun, *
this);
 
  722    return inplace_map_(fun, *
this);
 
 
  730    return std::move(copy);
 
 
  735  CUDA NI 
void print_sequence(
bool print_atype, 
bool top_level = 
false)
 const {
 
  736    const auto& op = battery::get<0>(battery::get<n>(formula));
 
  737    const auto& children = battery::get<1>(battery::get<n>(formula));
 
  738    if(children.size() == 0) {
 
  742    if constexpr(n == 
Seq) {
 
  743      if(children.size() == 1) {
 
  745        children[0].print_impl(print_atype);
 
  750    bool isprefix = 
true;
 
  751    if constexpr(n == 
Seq) {
 
  758    for(
int i = 0; i < children.size(); ++i) {
 
  759      children[i].print_impl(print_atype);
 
  760      if(i < children.size() - 1) {
 
  770      if constexpr(n == 
Seq) {
 
  771        if(op == 
AND && top_level && i != children.size() - 1) {
 
  780  CUDA NI 
void print_impl(
bool print_atype = 
true, 
bool top_level = 
false)
 const {
 
  784    switch(formula.index()) {
 
  786        printf(
"%s", 
b() ? 
"true" : 
"false");
 
  792        const auto& r_lb = battery::get<0>(
r());
 
  793        const auto& r_ub = battery::get<1>(
r());
 
  795          printf(
"%.50lf", r_lb);
 
  798          printf(
"[%.50lf..%.50lf]", r_lb, r_ub);
 
  804        for(
int i = 0; i < 
s().size(); ++i) {
 
  805          const auto& lb = battery::get<0>(
s()[i]);
 
  806          const auto& ub = battery::get<1>(
s()[i]);
 
  808            lb.print(print_atype);
 
  812            lb.print(print_atype);
 
  814            ub.print(print_atype);
 
  817          if(i < 
s().size() - 1) {
 
  824        printf(
"var(%d, %d)", 
v().vid(), 
v().aty());
 
  830        if(print_atype) { printf(
"("); }
 
  833        battery::get<0>(e).print();
 
  835        battery::get<1>(e).print();
 
  836        if(print_atype) { printf(
")"); }
 
  839      case Seq: print_sequence<Seq>(print_atype, top_level); 
break;
 
  840      case ESeq: print_sequence<ESeq>(print_atype, top_level); 
break;
 
  841      default: printf(
"%% print: formula not handled.\n"); assert(
false); 
break;
 
  844      printf(
":%d", type_);
 
  849  CUDA 
void print(
bool print_atype = 
false)
 const {
 
  850    print_impl(print_atype, 
true);
 
 
 
  854template<
typename Allocator, 
typename ExtendedSig>
 
  859template<
typename Allocator, 
typename ExtendedSig>
 
  860CUDA 
bool operator!=(
const TFormula<Allocator, ExtendedSig>& lhs, 
const TFormula<Allocator, ExtendedSig>& rhs) {
 
  861  return !(lhs == rhs);
 
CUDA constexpr int vid() const
Definition ast.hpp:69
 
CUDA constexpr int aty() const
Definition ast.hpp:65
 
CUDA constexpr AVar(AType atype, size_t var_id)
Definition ast.hpp:59
 
CUDA constexpr void type_as(AType aty)
Definition ast.hpp:73
 
constexpr AVar(const AVar &)=default
 
CUDA constexpr bool operator==(const AVar &other) const
Definition ast.hpp:46
 
constexpr AVar & operator=(const AVar &)=default
 
CUDA constexpr AVar(AType atype, int var_id)
Definition ast.hpp:53
 
constexpr AVar & operator=(AVar &&)=default
 
CUDA constexpr AVar()
Definition ast.hpp:41
 
CUDA constexpr bool is_untyped() const
Definition ast.hpp:61
 
constexpr AVar(AVar &&)=default
 
CUDA NI void print(const lala::Sig &sig)
Definition ast.hpp:268
 
Definition abstract_deps.hpp:14
 
CUDA NI constexpr bool is_commutative(Sig sig)
Definition ast.hpp:247
 
battery::tuple< double, double > logic_real
Definition sort.hpp:119
 
CUDA NI const char * string_of_sig_txt(Sig sig)
Definition ast.hpp:192
 
bool logic_bool
Definition sort.hpp:109
 
long long int logic_int
Definition sort.hpp:114
 
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:504
 
CUDA NI bool is_arithmetic_comparison(const F &f)
Definition algorithm.hpp:360
 
CUDA NI constexpr bool is_associative(Sig sig)
Definition ast.hpp:242
 
CUDA NI constexpr bool is_z_division(Sig sig)
Definition ast.hpp:230
 
@ HULL
Unary function performing the convex hull of a set, e.g., .
Definition ast.hpp:110
 
@ XOR
Logical connector.
Definition ast.hpp:114
 
@ SIN
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ ITE
If-then-else.
Definition ast.hpp:115
 
@ NEQ
Equality relations.
Definition ast.hpp:112
 
@ SYMMETRIC_DIFFERENCE
Unary arithmetic function symbols.
Definition ast.hpp:106
 
@ LEQ
Unary arithmetic function symbols.
Definition ast.hpp:113
 
@ NOT
Unary arithmetic function symbols.
Definition ast.hpp:114
 
@ ACOS
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ IMPLY
Unary arithmetic function symbols.
Definition ast.hpp:114
 
@ TANH
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ TMOD
Truncated division, present in most programming languages, is defined as , i.e., it rounds towards ze...
Definition ast.hpp:102
 
@ ATAN
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ ASIN
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ CARD
Cardinality function from set to integer.
Definition ast.hpp:109
 
@ SUPSETEQ
Set inclusion predicates.
Definition ast.hpp:107
 
@ MOD
Division and modulus over continuous domains (e.g., floating-point numbers and rational).
Definition ast.hpp:101
 
@ DIFFERENCE
Unary arithmetic function symbols.
Definition ast.hpp:106
 
@ ATANH
Trigonometric unary function symbols.
Definition ast.hpp:100
 
@ CONVEX
Unary predicate, requiring .
Definition ast.hpp:111
 
@ UNION
Unary arithmetic function symbols.
Definition ast.hpp:106
 
@ OR
Unary arithmetic function symbols.
Definition ast.hpp:114
 
@ EQ
Unary arithmetic function symbols.
Definition ast.hpp:112
 
@ ACOSH
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ NROOT
Unary arithmetic function symbols.
Definition ast.hpp:99
 
@ GEQ
Unary arithmetic function symbols.
Definition ast.hpp:113
 
@ ADD
Unary arithmetic function symbols.
Definition ast.hpp:97
 
@ IN
Set membership predicate.
Definition ast.hpp:108
 
@ COS
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ POW
Unary arithmetic function symbols.
Definition ast.hpp:97
 
@ MIN
Unary arithmetic function symbols.
Definition ast.hpp:97
 
@ INTERSECTION
Unary arithmetic function symbols.
Definition ast.hpp:106
 
@ LN
Square root, natural exponential and natural logarithm function symbols.
Definition ast.hpp:98
 
@ SINH
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ EDIV
Unary arithmetic function symbols.
Definition ast.hpp:105
 
@ DIV
Unary arithmetic function symbols.
Definition ast.hpp:101
 
@ GT
Arithmetic comparison predicates. When applied to set, it corresponds to the lexicographic ordering o...
Definition ast.hpp:113
 
@ FMOD
Floor division (Knuth D. (1972). The Art of Computer Programming, Vol 1, Fundamental Algorithms),...
Definition ast.hpp:103
 
@ MAX
Binary arithmetic function symbols.
Definition ast.hpp:97
 
@ SQRT
Unary arithmetic function symbols.
Definition ast.hpp:98
 
@ LT
Unary arithmetic function symbols.
Definition ast.hpp:113
 
@ TDIV
Unary arithmetic function symbols.
Definition ast.hpp:102
 
@ FDIV
Unary arithmetic function symbols.
Definition ast.hpp:103
 
@ EXP
Unary arithmetic function symbols.
Definition ast.hpp:98
 
@ COMPLEMENT
Set functions.
Definition ast.hpp:106
 
@ TAN
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ SUBSETEQ
Unary arithmetic function symbols.
Definition ast.hpp:107
 
@ AND
Unary arithmetic function symbols.
Definition ast.hpp:114
 
@ MAXIMIZE
Unary "meta-predicate" indicating that its argument must be maximized, according to the increasing or...
Definition ast.hpp:116
 
@ SUBSET
Unary arithmetic function symbols.
Definition ast.hpp:107
 
@ MINIMIZE
Same as MAXIMIZE, but for minimization.
Definition ast.hpp:117
 
@ EQUIV
Unary arithmetic function symbols.
Definition ast.hpp:114
 
@ ABS
Unary arithmetic function symbols.
Definition ast.hpp:96
 
@ ASINH
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ SUB
Unary arithmetic function symbols.
Definition ast.hpp:97
 
@ SUPSET
Unary arithmetic function symbols.
Definition ast.hpp:107
 
@ COSH
Unary arithmetic function symbols.
Definition ast.hpp:100
 
@ MUL
Unary arithmetic function symbols.
Definition ast.hpp:97
 
@ CMOD
Ceil division is defined as . Modulus is defined as .
Definition ast.hpp:104
 
@ LOG
nth root and logarithm to base (both binary function symbols).
Definition ast.hpp:99
 
@ CDIV
Unary arithmetic function symbols.
Definition ast.hpp:104
 
@ NEG
Unary arithmetic function symbols.
Definition ast.hpp:96
 
@ EMOD
Euclidean division (Boute T. R. (1992). The Euclidean definition of the functions div and mod)....
Definition ast.hpp:105
 
battery::vector< battery::tuple< F, F >, typename F::allocator_type > logic_set
Definition sort.hpp:127
 
int AType
Definition sort.hpp:18
 
CUDA NI constexpr bool is_prefix(Sig sig)
Definition ast.hpp:226
 
CUDA NI constexpr bool is_predicate(Sig sig)
Definition ast.hpp:260
 
CUDA NI const char * string_of_sig(Sig sig)
Definition ast.hpp:121
 
CUDA NI constexpr bool is_division(Sig sig)
Definition ast.hpp:234
 
IKind
Definition ast.hpp:28
 
battery::string< Allocator > LVar
Definition ast.hpp:25
 
CUDA NI constexpr bool is_logical(Sig sig)
Definition ast.hpp:256
 
CUDA NI constexpr bool is_modulo(Sig sig)
Definition ast.hpp:238
 
#define UNTYPED
Definition sort.hpp:21