3#ifndef LALA_CORE_ALGORITHM_HPP
4#define LALA_CORE_ALGORITHM_HPP
12template<
class Allocator,
class ExtendedSig>
17 && (f.
seq(0).is(F::LV) || f.
seq(0).is(F::V))
18 && f.
seq(1).is_constant();
22template<
class Allocator,
class ExtendedSig>
27 && (f.
seq(0).is(F::LV) || f.
seq(0).is(F::V))
32template<
class Allocator,
class ExtendedSig>
37 && (f.
seq(0).is(F::LV) || f.
seq(0).is(F::V))
38 && (f.
seq(1).is(F::LV) || f.
seq(1).is(F::V));
41template<
class Allocator>
44 return F::make_binary(F::make_lvar(
UNTYPED, std::move(v)), sig, F::make_z(z), aty, allocator);
47template<
class Allocator>
50 return F::make_binary(F::make_avar(v), sig, F::make_z(z), aty, allocator);
53template <
class Allocator>
56 assert(f.
is(F::S) || f.
is(F::Z) || f.
is(F::R));
60template <
class Allocator>
63 assert(f.
is(F::S) || f.
is(F::Z) || f.
is(F::R));
68 template<
class Allocator,
class ExtendedSig>
69 CUDA NI
const TFormula<Allocator, ExtendedSig>& var_in_impl(
const TFormula<Allocator, ExtendedSig>& f,
bool& found);
71 template<
size_t n,
class Allocator,
class ExtendedSig>
72 CUDA NI
const TFormula<Allocator, ExtendedSig>& find_var_in_seq(
const TFormula<Allocator, ExtendedSig>& f,
bool& found) {
73 const auto& children = battery::get<1>(battery::get<n>(f.data()));
74 for(
int i = 0; i < children.size(); ++i) {
75 const auto& subformula = var_in_impl(children[i], found);
83 template<
class Allocator,
class ExtendedSig>
84 CUDA NI
const TFormula<Allocator, ExtendedSig>& var_in_impl(
const TFormula<Allocator, ExtendedSig>& f,
bool& found)
86 using F = TFormula<Allocator, ExtendedSig>;
97 case F::Seq:
return find_var_in_seq<F::Seq>(f, found);
98 case F::ESeq:
return find_var_in_seq<F::ESeq>(f, found);
99 default: printf(
"var_in: formula not handled.\n"); assert(
false);
return f;
103 template<
size_t n,
class F>
104 CUDA NI
int num_vars_in_seq(
const F& f) {
105 const auto& children = battery::get<1>(battery::get<n>(f.data()));
107 for(
int i = 0; i < children.size(); ++i) {
114 CUDA NI
int num_qf_vars(
const F& f,
bool type_filter,
AType aty);
116 template<
size_t n,
class F>
117 CUDA NI
int num_qf_vars_in_seq(
const F& f,
bool type_filter,
AType aty) {
118 const auto& children = battery::get<1>(battery::get<n>(f.data()));
120 for(
int i = 0; i < children.size(); ++i) {
121 total += num_qf_vars(children[i], type_filter, aty);
127 CUDA NI
int num_qf_vars(
const F& f,
bool type_filter,
AType aty) {
131 return f.type() == aty ? 1 : 0;
136 case F::Seq:
return impl::num_qf_vars_in_seq<F::Seq>(f, type_filter, aty);
137 case F::ESeq:
return impl::num_qf_vars_in_seq<F::ESeq>(f, type_filter, aty);
145template<
typename Allocator,
typename ExtendedSig>
148 return impl::var_in_impl(f, found);
161 case F::Seq:
return impl::num_vars_in_seq<F::Seq>(f);
162 case F::ESeq:
return impl::num_vars_in_seq<F::ESeq>(f);
170 return impl::num_qf_vars(f,
false,
UNTYPED);
176 return impl::num_qf_vars(f,
true, aty);
187 for(
int i = 0; i < f.seq().size(); ++i) {
208 for(
int i = 0; i < f.seq().size(); ++i) {
221 for(
int i = 0; i < seq.size(); ++i) {
228 else if(ty != seq[i].type()) {
238 assert(f.is(F::Seq));
239 const auto& seq = f.seq();
240 typename F::Sequence fty;
241 typename F::Sequence other;
242 for(
int i = 0; i < seq.size(); ++i) {
244 if(seq[i].is(F::Seq) && seq[i].sig() ==
AND) {
246 auto& fty_ = battery::get<0>(r).seq();
247 auto& other_ = battery::get<1>(r).seq();
248 for(
int i = 0; i < fty_.size(); ++i) {
249 fty.push_back(std::move(fty_[i]));
251 for(
int i = 0; i < other_.size(); ++i) {
252 other.push_back(std::move(other_[i]));
255 else if(seq[i].type() == ty) {
256 fty.push_back(seq[i]);
259 other.push_back(seq[i]);
262 AType other_ty = type_of_conjunction<F>(other);
263 return battery::make_tuple(
264 F::make_nary(
AND, std::move(fty), ty),
265 F::make_nary(
AND, std::move(other), other_ty));
269CUDA NI std::optional<F>
negate(
const F& f);
276 typename F::Sequence neg_seq(seq.size());
277 for(
int i = 0; i < f.seq().size(); ++i) {
278 auto neg_i =
negate(seq[i]);
279 if(neg_i.has_value()) {
286 return F::make_nary(sig_neg, neg_seq, f.type());
291 assert(f.is_binary() && f.sig() ==
EQ);
292 if(f.seq(0).is(F::B)) {
295 return F::make_binary(b,
EQ, f.seq(1), f.type(), f.seq().get_allocator());
297 else if(f.seq(1).is(F::B)) {
300 return F::make_binary(f.seq(0),
EQ, b, f.type(), f.seq().get_allocator());
302 return F::make_nary(
NEQ, f.seq(), f.type());
306CUDA NI std::optional<F>
negate(
const F& f) {
308 return F::make_false();
310 else if(f.is_false()) {
311 return F::make_true();
313 else if(f.is_variable()) {
314 return F::make_unary(
NOT, f, f.type());
316 else if(f.is(F::Seq)) {
319 case NOT:
return f.seq(0);
322 case LEQ: neg_sig =
GT;
break;
323 case GEQ: neg_sig =
LT;
break;
324 case NEQ: neg_sig =
EQ;
break;
325 case LT: neg_sig =
GEQ;
break;
326 case GT: neg_sig =
LEQ;
break;
333 return F::make_unary(
NOT, f, f.type());
341 return F::make_nary(neg_sig, f.seq(), f.type());
354 default: assert(0);
return sig;
424 case NEQ:
return sig;
437template <
class F,
class Env>
441 f = F::make_lvar(erase_type ?
UNTYPED : f.v().aty(), env.name_of(f.v()));
444 for(
int i = 0; i < f.seq().size(); ++i) {
449 for(
int i = 0; i < f.eseq().size(); ++i) {
459 CUDA
bool is_bz(
const F& f) {
460 return f.is(F::Z) || f.is(F::B);
464 CUDA
bool is_binary_bz(
const typename F::Sequence& seq) {
465 return seq.size() == 2 && is_bz(seq[0]) && is_bz(seq[1]);
469 CUDA
bool is_binary_z(
const typename F::Sequence& seq) {
470 return seq.size() == 2 && seq[0].is(F::Z) && seq[1].is(F::Z);
477 CUDA F eval_seq(
Sig sig,
const typename F::Sequence& seq,
AType atype) {
480 typename F::Sequence residual;
481 for(
int i = 0; i < seq.size(); ++i) {
482 if(seq[i].is_false()) {
483 return F::make_false();
485 else if(!seq[i].is_true()) {
486 residual.push_back(seq[i]);
489 if(residual.size() == 0) {
490 return F::make_true();
492 else if(residual.size() == 1) {
496 return F::make_nary(
AND, std::move(residual), atype);
500 typename F::Sequence residual;
501 for(
int i = 0; i < seq.size(); ++i) {
502 if(seq[i].is_true()) {
503 return F::make_true();
505 else if(!seq[i].is_false()) {
506 residual.push_back(seq[i]);
509 if(residual.size() == 0) {
510 return F::make_false();
512 else if(residual.size() == 1) {
516 return F::make_nary(
OR, std::move(residual), atype);
520 if(is_binary_bz<F>(seq)) {
521 return seq[0].is_false() || seq[1].is_true() ? F::make_true() : F::make_false();
523 else if(seq.size() == 2) {
524 if(seq[0].is_true()) {
return seq[1]; }
525 else if(seq[0].is_false()) {
return F::make_true(); }
526 else if(seq[1].is_true()) {
return F::make_true(); }
527 else if(seq[1].is_false()) {
537 if(is_binary_bz<F>(seq)) {
538 return (seq[0].is_true() == seq[1].is_true()) ? F::make_true() : F::make_false();
540 else if(seq.size() == 2) {
541 if(seq[0].is_true()) {
return seq[1]; }
542 else if(seq[0].is_false()) {
return F::make_unary(
NOT, seq[1], atype); }
543 else if(seq[1].is_true()) {
return seq[0]; }
544 else if(seq[1].is_false()) {
return F::make_unary(
NOT, seq[0], atype); }
549 if(seq.size() == 1 && is_bz(seq[0])) {
550 return seq[0].is_true() ? F::make_false() : F::make_true();
552 if(seq.size() == 1 && seq[0].is_unary() && seq[0].sig() ==
NOT) {
553 return seq[0].seq(0);
558 if(is_binary_bz<F>(seq)) {
559 return (seq[0].is_true() != seq[1].is_true()) ? F::make_true() : F::make_false();
564 if(seq.size() == 3 && is_bz(seq[0])) {
565 return seq[0].is_true() ? seq[1] : seq[2];
570 if(seq.size() == 2 && seq[0].is_constant() && seq[1].is_constant()) {
571 return seq[0] == seq[1] ? F::make_true() : F::make_false();
574 if(seq.size() == 2 && seq[0].is_binary() &&
575 seq[1].is(F::Z) && seq[1].z() == 0 &&
576 seq[0].sig() ==
ADD &&
577 seq[0].seq(1).is_unary() && seq[0].seq(1).sig() ==
NEG && seq[0].seq(1).seq(0).is_variable() &&
578 seq[0].seq(0).is_variable())
580 return F::make_binary(seq[0].seq(0),
EQ, seq[0].seq(1).seq(0), atype);
585 if(seq.size() == 2 && seq[0].is_constant() && seq[1].is_constant()) {
586 return seq[0] != seq[1] ? F::make_true() : F::make_false();
589 if(seq.size() == 2 && seq[0].is_binary() &&
590 seq[1].is(F::Z) && seq[1].z() == 0 &&
591 seq[0].sig() ==
ADD &&
592 seq[0].seq(1).is_unary() && seq[0].seq(1).sig() ==
NEG && seq[0].seq(1).seq(0).is_variable() &&
593 seq[0].seq(0).is_variable())
595 return F::make_binary(seq[0].seq(0),
NEQ, seq[0].seq(1).seq(0), atype);
598 if(seq.size() == 2 && seq[0].is_binary() &&
600 seq[0].sig() ==
ADD &&
601 is_bz(seq[0].seq(1)))
603 return F::make_binary(seq[0].seq(0),
NEQ, F::make_z(seq[1].to_z() - seq[0].seq(1).to_z()), atype);
606 if(seq.size() == 2 && is_bz(seq[0]) && seq[1].is_unary() && seq[1].sig() ==
NEG && seq[1].seq(0).is_variable()) {
607 return F::make_binary(F::make_z(-seq[0].to_z()),
NEQ, seq[1].seq(0), atype);
610 if(seq.size() == 2 && is_bz(seq[1]) && seq[0].is_unary() && seq[0].sig() ==
NEG && seq[0].seq(0).is_variable()) {
611 return F::make_binary(seq[0].seq(0),
NEQ, F::make_z(-seq[1].to_z()), atype);
616 if(is_binary_z<F>(seq)) {
617 return seq[0].z() < seq[1].z() ? F::make_true() : F::make_false();
622 if(is_binary_z<F>(seq)) {
623 return seq[0].z() <= seq[1].z() ? F::make_true() : F::make_false();
628 if(is_binary_z<F>(seq)) {
629 return seq[0].z() > seq[1].z() ? F::make_true() : F::make_false();
634 if(is_binary_z<F>(seq)) {
635 return seq[0].z() >= seq[1].z() ? F::make_true() : F::make_false();
640 if(is_binary_z<F>(seq)) {
641 return F::make_z(battery::min(seq[0].z(), seq[1].z()));
646 if(is_binary_z<F>(seq)) {
647 return F::make_z(battery::max(seq[0].z(), seq[1].z()));
652 if(seq.size() == 1 && is_bz(seq[0])) {
653 return F::make_z(-seq[0].to_z());
655 if(seq.size() == 1 && seq[0].is_unary() && seq[0].sig() ==
NEG) {
656 return seq[0].seq(0);
661 if(seq.size() == 1 && is_bz(seq[0])) {
662 return F::make_z(abs(seq[0].to_z()));
667 typename F::Sequence residual;
669 for(
int i = 0; i < seq.size(); ++i) {
671 sum += seq[i].to_z();
674 residual.push_back(seq[i]);
677 if(residual.size() == 0) {
678 return F::make_z(sum);
682 residual.push_back(F::make_z(sum));
684 if(residual.size() == 1) {
688 return F::make_nary(
ADD, std::move(residual), atype);
693 typename F::Sequence residual;
695 for(
int i = 0; i < seq.size(); ++i) {
697 prod *= seq[i].to_z();
700 residual.push_back(seq[i]);
703 if(residual.size() == 0) {
704 return F::make_z(prod);
710 else if(prod == -1 && residual.size() > 0) {
711 residual[0] = F::make_unary(
NEG, std::move(residual[0]), atype);
714 residual.push_back(F::make_z(prod));
716 if(residual.size() == 1) {
720 return F::make_nary(
MUL, std::move(residual), atype);
725 if(is_binary_bz<F>(seq)) {
726 return F::make_z(seq[0].to_z() - seq[1].to_z());
728 else if(seq.size() == 2 && is_bz(seq[1]) && seq[1].to_z() == 0) {
731 else if(seq.size() == 2 && is_bz(seq[0]) && seq[0].to_z() == 0) {
732 return F::make_unary(
NEG, seq[1], atype);
740 if(is_binary_z<F>(seq)) {
742 case TDIV:
return F::make_z(battery::tdiv(seq[0].z(), seq[1].z()));
743 case FDIV:
return F::make_z(battery::fdiv(seq[0].z(), seq[1].z()));
744 case CDIV:
return F::make_z(battery::cdiv(seq[0].z(), seq[1].z()));
745 case EDIV:
return F::make_z(battery::ediv(seq[0].z(), seq[1].z()));
746 default: assert(0);
break;
749 else if(seq.size() == 2 && is_bz(seq[0]) && seq[0].to_z() == 0) {
752 else if(seq.size() == 2 && is_bz(seq[1]) && seq[1].to_z() == 1) {
758 if(is_binary_z<F>(seq)) {
759 return F::make_z(battery::tmod(seq[0].z(), seq[1].z()));
764 if(is_binary_z<F>(seq)) {
765 return F::make_z(battery::fmod(seq[0].z(), seq[1].z()));
770 if(is_binary_z<F>(seq)) {
771 return F::make_z(battery::cmod(seq[0].z(), seq[1].z()));
776 if(is_binary_z<F>(seq)) {
777 return F::make_z(battery::emod(seq[0].z(), seq[1].z()));
782 if(is_binary_bz<F>(seq)) {
783 return F::make_z(battery::ipow(seq[0].to_z(), seq[1].to_z()));
785 else if(seq.size() == 2 && is_bz(seq[1]) && seq[1].to_z() == 0) {
791 if(seq.size() == 2 && is_bz(seq[0]) && seq[1].is(F::S)) {
792 const auto& set = seq[1].s();
794 for(
int i = 0; i < set.size(); ++i) {
795 const auto& lb = battery::get<0>(set[i]);
796 const auto& ub = battery::get<1>(set[i]);
797 if(is_bz(lb) && is_bz(ub) && left >= lb.to_z() && left <= ub.to_z()) {
798 return F::make_true();
801 return F::make_false();
803 else if(seq.size() == 2 && seq[1].is(F::S) && seq[1].s().size() == 0) {
804 return F::make_false();
809 return F::make_nary(sig, seq, atype);
822 case F::LV:
return f;
824 const auto& seq = f.seq();
825 typename F::Sequence evaluated_seq(seq.get_allocator());
826 for(
int i = 0; i < seq.size(); ++i) {
827 evaluated_seq.push_back(
eval(seq[i]));
829 return impl::eval_seq<F>(f.sig(), evaluated_seq, f.type());
832 auto eseq = f.eseq();
833 typename F::Sequence evaluated_eseq(eseq.get_allocator());
834 for(
int i = 0; i < eseq.size(); ++i) {
835 evaluated_eseq.push_back(
eval(eseq[i]));
837 return F::make_nary(f.esig(), std::move(evaluated_eseq), f.type());
839 default: assert(
false);
return f;
854template <
class F,
class Alloc = battery::standard_allocator>
855CUDA NI F
normalize(
const F& f, battery::vector<F, Alloc>& extra) {
875 assert(f.seq().size() == 1);
876 if(f.seq(0).is_variable()) {
877 return F::make_binary(f.seq(0),
EQ, F::make_z(0), f.type());
881 if(not_f.has_value() && *not_f != f) {
885 return F::make_unary(
NOT, std::move(fi), f.type());
888 if(f.is_binary() &&
is_comparison(f) && f.seq(0).is_constant()) {
889 return F::make_binary(
891 f.type(), f.seq().get_allocator());
893 else if(f.is_binary() &&
is_comparison(f) && !f.seq(0).is_variable() && f.seq(1).is_variable()) {
894 return F::make_binary(
896 f.type(), f.seq().get_allocator());
899 else if(f.is_binary() && f.sig() ==
IN && f.seq(1).is(F::S) && f.seq(1).s().size() == 1 && battery::get<0>(f.seq(1).s()[0]) == battery::get<1>(f.seq(1).s()[0])) {
900 return F::make_binary(f.seq(0),
EQ, battery::get<0>(f.seq(1).s()[0]), f.type());
903 typename F::Sequence normalized_seq(f.seq().get_allocator());
904 for(
int i = 0; i < f.seq().size(); ++i) {
907 return F::make_nary(f.sig(), std::move(normalized_seq), f.type(),
true);
910 default: assert(
false);
return f;
916 battery::vector<F, battery::standard_allocator> extra;
923CUDA F itv_to_formula(
const F& f,
const battery::tuple<F, F>& itv,
const typename F::allocator_type& alloc =
typename F::allocator_type()) {
924 const auto& [l, u] = itv;
926 return F::make_binary(f,
EQ, l, f.type(), alloc);
933 F::make_binary(f, geq_sig, l, f.type(), alloc),
935 F::make_binary(f, leq_sig, u, f.type(), alloc),
945 if(f.is_binary() && f.sig() ==
IN && f.seq(1).is(F::S)) {
946 const auto& set = f.seq(1).s();
947 if(set.size() == 1) {
948 return impl::itv_to_formula(f.seq(0), set[0], alloc);
951 typename F::Sequence disjunction(alloc);
952 disjunction.reserve(set.size());
953 for(
size_t i = 0; i < set.size(); ++i) {
954 disjunction.push_back(impl::itv_to_formula(f.seq(0), set[i], alloc));
956 return F::make_nary(
OR, std::move(disjunction), f.type());
965 if(f.is_binary() && f.sig() ==
NEQ) {
966 return F::make_binary(
967 F::make_binary(f.seq(0),
LT, f.seq(1), f.type(), alloc),
969 F::make_binary(f.seq(0),
GT, f.seq(1), f.type(), alloc),
989 return {f.seq(0).lv()};
992 for(
int i = 0; i < f.seq().size(); ++i) {
994 if(res.has_value()) {
1000 return std::nullopt;
1006 if(battery::get<0>(f.exists()) == var) {
1007 return {f.exists()};
1010 else if(f.is(F::Seq) && f.sig() ==
Sig::AND) {
1011 for(
int i = 0; i < f.seq().size(); ++i) {
1013 if(res.has_value()) {
1018 return std::nullopt;
Definition abstract_deps.hpp:14
CUDA NI std::optional< F > negate_eq(const F &f)
Definition algorithm.hpp:290
CUDA NI bool is_v_op_constant(const TFormula< Allocator, ExtendedSig > &f, Sig sig)
Definition algorithm.hpp:13
std::optional< F > decompose_set_constraints(const F &f, std::map< std::string, std::vector< std::string > > &set2bool_vars)
Definition algorithm.hpp:981
CUDA NI void map_avar_to_lvar(F &f, const Env &env, bool erase_type=false)
Definition algorithm.hpp:438
CUDA NI std::optional< F > de_morgan_law(Sig sig_neg, const F &f)
Definition algorithm.hpp:274
CUDA size_t num_tnf_constraints(const F &f)
Definition algorithm.hpp:199
long long int logic_int
Definition sort.hpp:114
CUDA size_t num_constraints(const F &f)
Definition algorithm.hpp:180
CUDA NI Sig converse_comparison(Sig sig)
Definition algorithm.hpp:417
CUDA NI bool is_arithmetic_comparison(const F &f)
Definition algorithm.hpp:360
@ XOR
Logical connector.
Definition ast.hpp:114
@ ITE
If-then-else.
Definition ast.hpp:115
@ NEQ
Equality relations.
Definition ast.hpp:112
@ LEQ
Unary arithmetic function symbols.
Definition ast.hpp:113
@ NOT
Unary arithmetic function symbols.
Definition ast.hpp:114
@ IMPLY
Unary arithmetic function symbols.
Definition ast.hpp:114
@ TMOD
Truncated division, present in most programming languages, is defined as , i.e., it rounds towards ze...
Definition ast.hpp:102
@ SUPSETEQ
Set inclusion predicates.
Definition ast.hpp:107
@ OR
Unary arithmetic function symbols.
Definition ast.hpp:114
@ EQ
Unary arithmetic function symbols.
Definition ast.hpp:112
@ 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
@ POW
Unary arithmetic function symbols.
Definition ast.hpp:97
@ MIN
Unary arithmetic function symbols.
Definition ast.hpp:97
@ EDIV
Unary arithmetic function symbols.
Definition ast.hpp:105
@ 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
@ 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
@ 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
@ SUB
Unary arithmetic function symbols.
Definition ast.hpp:97
@ SUPSET
Unary arithmetic function symbols.
Definition ast.hpp:107
@ MUL
Unary arithmetic function symbols.
Definition ast.hpp:97
@ CMOD
Ceil division is defined as . Modulus is defined as .
Definition ast.hpp:104
@ 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
std::optional< LVar< typename F::allocator_type > > find_maximize_var(const F &f)
Definition algorithm.hpp:986
CUDA NI std::optional< F > negate(const F &f)
Definition algorithm.hpp:306
CUDA size_t num_quantified_vars(const F &f)
Definition algorithm.hpp:169
int AType
Definition sort.hpp:18
CUDA NI bool is_var_equality(const TFormula< Allocator, ExtendedSig > &f)
Definition algorithm.hpp:33
CUDA NI TFormula< Allocator > make_v_op_z(LVar< Allocator > v, Sig sig, logic_int z, AType aty=UNTYPED, const Allocator &allocator=Allocator())
Definition algorithm.hpp:42
CUDA NI battery::tuple< F, F > extract_ty(const F &f, AType ty)
Definition algorithm.hpp:237
CUDA NI bool is_v_op_z(const TFormula< Allocator, ExtendedSig > &f, Sig sig)
Definition algorithm.hpp:23
CUDA NI AType type_of_conjunction(const typename F::Sequence &seq)
Definition algorithm.hpp:219
CUDA Sig leq_of_constant(const TFormula< Allocator > &f)
Definition algorithm.hpp:61
CUDA NI bool is_comparison(const F &f)
Definition algorithm.hpp:396
CUDA F decompose_arith_neq_constraint(const F &f, const typename F::allocator_type &alloc=typename F::allocator_type())
Definition algorithm.hpp:964
CUDA Sig geq_of_constant(const TFormula< Allocator > &f)
Definition algorithm.hpp:54
CUDA NI int num_vars(const F &f)
Definition algorithm.hpp:154
battery::string< Allocator > LVar
Definition ast.hpp:25
CUDA NI F normalize(const F &f, battery::vector< F, Alloc > &extra)
Definition algorithm.hpp:855
CUDA Sig negate_arithmetic_comparison(Sig sig)
Definition algorithm.hpp:346
CUDA const TFormula< Allocator, ExtendedSig > & var_in(const TFormula< Allocator, ExtendedSig > &f)
Definition algorithm.hpp:146
std::optional< typename F::Existential > find_existential_of(const F &f, const LVar< typename F::allocator_type > &var)
Definition algorithm.hpp:1004
CUDA NI F eval(const F &f)
Definition algorithm.hpp:814
CUDA bool is_tnf(const F &f)
Definition ternarize.hpp:28
CUDA F decompose_in_constraint(const F &f, const typename F::allocator_type &alloc=typename F::allocator_type())
Definition algorithm.hpp:944
CUDA NI bool is_set_comparison(const F &f)
Definition algorithm.hpp:378
#define UNTYPED
Definition sort.hpp:21