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>";
233template<
class Allocator,
class ExtendedSig = battery::
string<Allocator>>
238 using Sequence = battery::vector<this_type, Allocator>;
249 battery::tuple<Sig, Sequence>,
250 battery::tuple<ExtendedSig, Sequence>
254 static constexpr size_t B = 0;
257 static constexpr size_t Z =
B + 1;
260 static constexpr size_t R =
Z + 1;
263 static constexpr size_t S =
R + 1;
266 static constexpr size_t V =
S + 1;
269 static constexpr size_t LV =
V + 1;
272 static constexpr size_t E =
LV + 1;
275 static constexpr size_t Seq =
E + 1;
293 template <
class Alloc2,
class ExtendedSig2>
296 template <
class Alloc2,
class ExtendedSig2>
298 : type_(other.type_), formula(
Formula::template create<
B>(true))
300 switch(other.formula.index()) {
301 case B: formula = Formula::template create<B>(other.b()); break;
302 case Z: formula = Formula::template create<Z>(other.z()); break;
303 case R: formula = Formula::template create<R>(other.r()); break;
304 case S: formula = Formula::template create<S>(LogicSet(other.s(), allocator));
306 case V: formula = Formula::template create<V>(other.v()); break;
307 case LV: formula = Formula::template create<LV>(LVar<Allocator>(other.lv(), allocator)); break;
308 case E: formula = Formula::template create<E>(
310 LVar<Allocator>(battery::get<0>(other.exists()), allocator),
311 battery::get<1>(other.exists())));
314 formula = Formula::template create<Seq>(
317 Sequence(other.seq(), allocator)));
320 formula = Formula::template create<ESeq>(
322 ExtendedSig(other.esig(), allocator),
323 Sequence(other.eseq(), allocator)));
325 default: printf(
"print: formula not handled.\n"); assert(false); break;
330 ::battery::swap(type_, other.type_);
331 ::battery::swap(formula, other.formula);
358 CUDA NI std::optional<Sort<allocator_type>>
sort()
const {
360 switch(formula.index()) {
361 case B:
return sort_t(sort_t::Bool);
362 case Z:
return sort_t(sort_t::Int);
363 case R:
return sort_t(sort_t::Real);
368 for(
int i = 0; i <
s().size(); ++i) {
369 auto subsort = battery::get<0>(
s()[i]).sort();
370 if(!subsort.has_value()) {
371 subsort = battery::get<1>(
s()[i]).sort();
373 if(subsort.has_value()) {
374 return sort_t(sort_t::Set, std::move(*subsort) ,
s().get_allocator());
379 case E:
return battery::get<1>(
exists());
388 return this_type(atype, Formula::template create<B>(
b));
392 return this_type(atype, Formula::template create<Z>(i));
398 return this_type(atype, Formula::template create<R>(battery::make_tuple(lb, ub)));
402 return this_type(atype, Formula::template create<R>(
r));
406 return this_type(atype, Formula::template create<S>(std::move(set)));
419 return this_type(ty, Formula::template create<LV>(std::move(lvar)));
423 return this_type(ty, Formula::template create<E>(battery::make_tuple(std::move(lvar), std::move(ctype))));
431 for(
size_t i = 0; i < children.size(); ++i) {
432 if(children[i].
is(
Seq) && children[i].
sig() ==
sig && children[i].
type() == atype) {
433 for(
size_t j = 0; j < children[i].seq().size(); ++j) {
434 seq.push_back(std::move(children[i].
seq(j)));
438 seq.push_back(std::move(children[i]));
441 return this_type(atype, Formula::template create<Seq>(battery::make_tuple(
sig, std::move(
seq))));
444 return this_type(atype, Formula::template create<Seq>(battery::make_tuple(
sig, std::move(children))));
467 return this_type(atype, Formula::template create<ESeq>(battery::make_tuple(std::move(
esig), std::move(children))));
471 return formula.index();
474 CUDA
bool is(
size_t kind)
const {
475 return formula.index() == kind;
479 return (
is(
B) &&
b()) || (
is(
Z) &&
z() != 0);
483 return (
is(
B) && !
b()) || (
is(
Z) &&
z() == 0);
488 return (
is(
B) ? (
b() ? 1 : 0) :
z());
500 return is(
Seq) &&
seq().size() == 1;
504 return is(
Seq) &&
seq().size() == 2;
508 return battery::get<B>(formula);
512 return battery::get<Z>(formula);
516 return battery::get<R>(formula);
520 return battery::get<S>(formula);
524 return battery::get<V>(formula);
528 return battery::get<LV>(formula);
532 return battery::get<E>(formula);
536 return battery::get<0>(battery::get<Seq>(formula));
548 CUDA
const ExtendedSig&
esig()
const {
549 return battery::get<0>(battery::get<ESeq>(formula));
553 return battery::get<1>(battery::get<Seq>(formula));
561 return battery::get<1>(battery::get<ESeq>(formula));
569 return battery::get<B>(formula);
573 return battery::get<Z>(formula);
577 return battery::get<R>(formula);
581 return battery::get<S>(formula);
585 return battery::get<V>(formula);
589 return battery::get<0>(battery::get<Seq>(formula));
593 return battery::get<0>(battery::get<ESeq>(formula));
597 return battery::get<1>(battery::get<Seq>(formula));
605 return battery::get<1>(battery::get<ESeq>(formula));
627 CUDA NI
void inplace_map_(Fun fun,
const this_type& parent) {
628 switch(formula.index()) {
630 for(
int i = 0; i <
seq().size(); ++i) {
631 seq(i).inplace_map_(fun, *
this);
636 for(
int i = 0; i <
eseq().size(); ++i) {
637 eseq(i).inplace_map_(fun, *
this);
653 return inplace_map_(fun, *
this);
661 return std::move(copy);
666 CUDA NI
void print_sequence(
bool print_atype,
bool top_level =
false)
const {
667 const auto& op = battery::get<0>(battery::get<n>(formula));
668 const auto& children = battery::get<1>(battery::get<n>(formula));
669 if(children.size() == 0) {
673 if constexpr(n ==
Seq) {
674 if(children.size() == 1) {
675 if(op ==
ABS) printf(
"|");
676 else if(op ==
CARD) printf(
"#(");
678 children[0].print_impl(print_atype);
679 if(op ==
ABS) printf(
"|");
680 else if(op ==
CARD) printf(
")");
685 bool isprefix =
true;
686 if constexpr(n ==
Seq) {
693 for(
int i = 0; i < children.size(); ++i) {
694 children[i].print_impl(print_atype);
695 if(i < children.size() - 1) {
705 if constexpr(n ==
Seq) {
706 if(op ==
AND && top_level) {
714 CUDA NI
void print_impl(
bool print_atype =
true,
bool top_level =
false)
const {
715 switch(formula.index()) {
717 printf(
"%s",
b() ?
"true" :
"false");
723 const auto& r_lb = battery::get<0>(
r());
724 const auto& r_ub = battery::get<1>(
r());
726 printf(
"%.50lf", r_lb);
729 printf(
"[%.50lf..%.50lf]", r_lb, r_ub);
735 for(
int i = 0; i <
s().size(); ++i) {
736 const auto& lb = battery::get<0>(
s()[i]);
737 const auto& ub = battery::get<1>(
s()[i]);
739 lb.print(print_atype);
743 lb.print(print_atype);
745 ub.print(print_atype);
748 if(i <
s().size() - 1) {
755 printf(
"var(%d, %d)",
v().vid(),
v().aty());
761 if(print_atype) { printf(
"("); }
764 battery::get<0>(e).print();
766 battery::get<1>(e).print();
767 if(print_atype) { printf(
")"); }
770 case Seq: print_sequence<Seq>(print_atype, top_level);
break;
771 case ESeq: print_sequence<ESeq>(print_atype, top_level);
break;
772 default: printf(
"print: formula not handled.\n"); assert(
false);
break;
775 printf(
":%d", type_);
780 CUDA
void print(
bool print_atype =
true)
const {
781 print_impl(print_atype,
true);
785template<
typename Allocator,
typename ExtendedSig>
790template<
typename Allocator,
typename ExtendedSig>
791CUDA
bool operator!=(
const TFormula<Allocator, ExtendedSig>& lhs,
const TFormula<Allocator, ExtendedSig>& rhs) {
792 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:212
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:503
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 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_modulo(Sig sig)
Definition ast.hpp:200
#define UNTYPED
Definition sort.hpp:21