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>";
210 return sig ==
LEQ || sig ==
GEQ || sig ==
EQ || sig ==
NEQ || sig ==
GT || sig ==
LT;
219 sig ==
EQ || sig ==
NEQ || sig ==
LEQ || sig ==
GEQ || sig ==
LT || sig ==
GT;
246template<
class Allocator,
class ExtendedSig = battery::
string<Allocator>>
251 using Sequence = battery::vector<this_type, Allocator>;
262 battery::tuple<Sig, Sequence>,
263 battery::tuple<ExtendedSig, Sequence>
267 static constexpr size_t B = 0;
270 static constexpr size_t Z =
B + 1;
273 static constexpr size_t R =
Z + 1;
276 static constexpr size_t S =
R + 1;
279 static constexpr size_t V =
S + 1;
282 static constexpr size_t LV =
V + 1;
285 static constexpr size_t E =
LV + 1;
288 static constexpr size_t Seq =
E + 1;
306 template <
class Alloc2,
class ExtendedSig2>
309 template <
class Alloc2,
class ExtendedSig2>
311 : type_(other.type_), formula(
Formula::template create<
B>(true))
313 switch(other.formula.index()) {
314 case B: formula = Formula::template create<B>(other.b()); break;
315 case Z: formula = Formula::template create<Z>(other.z()); break;
316 case R: formula = Formula::template create<R>(other.r()); break;
317 case S: formula = Formula::template create<S>(LogicSet(other.s(), allocator));
319 case V: formula = Formula::template create<V>(other.v()); break;
320 case LV: formula = Formula::template create<LV>(LVar<Allocator>(other.lv(), allocator)); break;
321 case E: formula = Formula::template create<E>(
323 LVar<Allocator>(battery::get<0>(other.exists()), allocator),
324 battery::get<1>(other.exists())));
327 formula = Formula::template create<Seq>(
330 Sequence(other.seq(), allocator)));
333 formula = Formula::template create<ESeq>(
335 ExtendedSig(other.esig(), allocator),
336 Sequence(other.eseq(), allocator)));
338 default: printf(
"print: formula not handled.\n"); assert(false); break;
343 ::battery::swap(type_, other.type_);
344 ::battery::swap(formula, other.formula);
371 CUDA NI std::optional<Sort<allocator_type>>
sort()
const {
373 switch(formula.index()) {
374 case B:
return sort_t(sort_t::Bool);
375 case Z:
return sort_t(sort_t::Int);
376 case R:
return sort_t(sort_t::Real);
381 for(
int i = 0; i <
s().size(); ++i) {
382 auto subsort = battery::get<0>(
s()[i]).sort();
383 if(!subsort.has_value()) {
384 subsort = battery::get<1>(
s()[i]).sort();
386 if(subsort.has_value()) {
387 return sort_t(sort_t::Set, std::move(*subsort) ,
s().get_allocator());
392 case E:
return battery::get<1>(
exists());
401 return this_type(atype, Formula::template create<B>(
b));
405 return this_type(atype, Formula::template create<Z>(i));
411 return this_type(atype, Formula::template create<R>(battery::make_tuple(lb, ub)));
415 return this_type(atype, Formula::template create<R>(
r));
419 return this_type(atype, Formula::template create<S>(std::move(set)));
432 return this_type(ty, Formula::template create<LV>(std::move(lvar)));
436 return this_type(ty, Formula::template create<E>(battery::make_tuple(std::move(lvar), std::move(ctype))));
444 for(
size_t i = 0; i < children.size(); ++i) {
445 if(children[i].
is(
Seq) && children[i].
sig() ==
sig && children[i].
type() == atype) {
446 for(
size_t j = 0; j < children[i].seq().size(); ++j) {
447 seq.push_back(std::move(children[i].
seq(j)));
451 seq.push_back(std::move(children[i]));
454 return this_type(atype, Formula::template create<Seq>(battery::make_tuple(
sig, std::move(
seq))));
457 return this_type(atype, Formula::template create<Seq>(battery::make_tuple(
sig, std::move(children))));
480 return this_type(atype, Formula::template create<ESeq>(battery::make_tuple(std::move(
esig), std::move(children))));
484 return formula.index();
487 CUDA
bool is(
size_t kind)
const {
488 return formula.index() == kind;
492 return (
is(
B) &&
b()) || (
is(
Z) &&
z() != 0);
496 return (
is(
B) && !
b()) || (
is(
Z) &&
z() == 0);
501 return (
is(
B) ? (
b() ? 1 : 0) :
z());
513 return is(
Seq) &&
seq().size() == 1;
517 return is(
Seq) &&
seq().size() == 2;
521 return battery::get<B>(formula);
525 return battery::get<Z>(formula);
529 return battery::get<R>(formula);
533 return battery::get<S>(formula);
537 return battery::get<V>(formula);
541 return battery::get<LV>(formula);
545 return battery::get<E>(formula);
549 return battery::get<0>(battery::get<Seq>(formula));
554 return ::lala::is_logical(
sig());
561 return ::lala::is_predicate(
sig());
574 CUDA
const ExtendedSig&
esig()
const {
575 return battery::get<0>(battery::get<ESeq>(formula));
579 return battery::get<1>(battery::get<Seq>(formula));
587 return battery::get<1>(battery::get<ESeq>(formula));
595 return battery::get<B>(formula);
599 return battery::get<Z>(formula);
603 return battery::get<R>(formula);
607 return battery::get<S>(formula);
611 return battery::get<V>(formula);
615 return battery::get<0>(battery::get<Seq>(formula));
619 return battery::get<0>(battery::get<ESeq>(formula));
623 return battery::get<1>(battery::get<Seq>(formula));
631 return battery::get<1>(battery::get<ESeq>(formula));
653 CUDA NI
void inplace_map_(Fun fun,
const this_type& parent) {
654 switch(formula.index()) {
656 for(
int i = 0; i <
seq().size(); ++i) {
657 seq(i).inplace_map_(fun, *
this);
662 for(
int i = 0; i <
eseq().size(); ++i) {
663 eseq(i).inplace_map_(fun, *
this);
679 return inplace_map_(fun, *
this);
687 return std::move(copy);
692 CUDA NI
void print_sequence(
bool print_atype,
bool top_level =
false)
const {
693 const auto& op = battery::get<0>(battery::get<n>(formula));
694 const auto& children = battery::get<1>(battery::get<n>(formula));
695 if(children.size() == 0) {
699 if constexpr(n ==
Seq) {
700 if(children.size() == 1) {
701 if(op ==
ABS) printf(
"|");
702 else if(op ==
CARD) printf(
"#(");
704 children[0].print_impl(print_atype);
705 if(op ==
ABS) printf(
"|");
706 else if(op ==
CARD) printf(
")");
711 bool isprefix =
true;
712 if constexpr(n ==
Seq) {
719 for(
int i = 0; i < children.size(); ++i) {
720 children[i].print_impl(print_atype);
721 if(i < children.size() - 1) {
731 if constexpr(n ==
Seq) {
732 if(op ==
AND && top_level) {
740 CUDA NI
void print_impl(
bool print_atype =
true,
bool top_level =
false)
const {
741 switch(formula.index()) {
743 printf(
"%s",
b() ?
"true" :
"false");
749 const auto& r_lb = battery::get<0>(
r());
750 const auto& r_ub = battery::get<1>(
r());
752 printf(
"%.50lf", r_lb);
755 printf(
"[%.50lf..%.50lf]", r_lb, r_ub);
761 for(
int i = 0; i <
s().size(); ++i) {
762 const auto& lb = battery::get<0>(
s()[i]);
763 const auto& ub = battery::get<1>(
s()[i]);
765 lb.print(print_atype);
769 lb.print(print_atype);
771 ub.print(print_atype);
774 if(i <
s().size() - 1) {
781 printf(
"var(%d, %d)",
v().vid(),
v().aty());
787 if(print_atype) { printf(
"("); }
790 battery::get<0>(e).print();
792 battery::get<1>(e).print();
793 if(print_atype) { printf(
")"); }
796 case Seq: print_sequence<Seq>(print_atype, top_level);
break;
797 case ESeq: print_sequence<ESeq>(print_atype, top_level);
break;
798 default: printf(
"print: formula not handled.\n"); assert(
false);
break;
801 printf(
":%d", type_);
806 CUDA
void print(
bool print_atype =
true)
const {
807 print_impl(print_atype,
true);
811template<
typename Allocator,
typename ExtendedSig>
816template<
typename Allocator,
typename ExtendedSig>
817CUDA
bool operator!=(
const TFormula<Allocator, ExtendedSig>& lhs,
const TFormula<Allocator, ExtendedSig>& rhs) {
818 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:225
Definition abstract_deps.hpp:14
battery::vector< battery::tuple< F, F >, typename F::allocator_type > logic_set
Definition sort.hpp:127
int AType
Definition sort.hpp:18
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:338
CUDA NI constexpr bool is_associative(Sig sig)
Definition ast.hpp:204
@ 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::tuple< double, double > logic_real
Definition sort.hpp:119
long long int logic_int
Definition sort.hpp:114
bool logic_bool
Definition sort.hpp:109
battery::string< Allocator > LVar
Definition ast.hpp:25
CUDA NI constexpr bool is_prefix(Sig sig)
Definition ast.hpp:192
CUDA NI constexpr bool is_predicate(Sig sig)
Definition ast.hpp:217
CUDA NI const char * string_of_sig(Sig sig)
Definition ast.hpp:121
CUDA NI constexpr bool is_division(Sig sig)
Definition ast.hpp:196
IKind
Definition ast.hpp:28
CUDA NI constexpr bool is_logical(Sig sig)
Definition ast.hpp:213
CUDA NI constexpr bool is_modulo(Sig sig)
Definition ast.hpp:200
#define UNTYPED
Definition sort.hpp:21