Lattice land propagators completion library
Loading...
Searching...
No Matches
formula.hpp
Go to the documentation of this file.
1// Copyright 2021 Pierre Talbot
2
3#ifndef LALA_PC_FORMULA_HPP
4#define LALA_PC_FORMULA_HPP
5
6#include "lala/universes/arith_bound.hpp"
7
8namespace lala {
9namespace pc {
10
11template <class AD, class Allocator>
12class Formula;
13
14template <class AD, class Allocator>
16public:
17 using A = AD;
18 using U = typename A::local_universe;
19 using allocator_type = Allocator;
20
21 using tell_type = typename A::template tell_type<allocator_type>;
22 using ask_type = typename A::template ask_type<allocator_type>;
24
25 template <class A2, class Alloc>
26 friend class AbstractElement;
27
28private:
29 tell_type tellv;
30 tell_type not_tellv;
31 ask_type askv;
32 ask_type not_askv;
33
34public:
36
38 tell_type&& tellv, tell_type&& not_tellv,
39 ask_type&& askv, ask_type&& not_askv)
40 : tellv(std::move(tellv)), not_tellv(std::move(not_tellv)), askv(std::move(askv)), not_askv(std::move(not_askv)) {}
41
42 AbstractElement(this_type&& other) = default;
43 this_type& operator=(this_type&& other) = default;
44
45 template <class A2, class Alloc2>
47 : tellv(other.tellv, alloc), not_tellv(other.not_tellv, alloc)
48 , askv(other.askv, alloc), not_askv(other.not_askv, alloc) {}
49
50public:
51 CUDA local::B ask(const A& a) const {
52 return a.ask(askv);
53 }
54
55 CUDA local::B nask(const A& a) const {
56 return a.ask(not_askv);
57 }
58
59 CUDA bool deduce(A& a) const {
60 return a.deduce(tellv);
61 }
62
63 CUDA bool contradeduce(A& a) const {
64 return a.deduce(not_tellv);
65 }
66
67 CUDA NI void print(const A& a) const {
68 printf("<abstract element (%d)>", a.aty());
69 }
70
71 template <class Env, class Allocator2 = typename Env::allocator_type>
72 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType, Allocator2 allocator = Allocator2()) const {
73 return a.deinterpret(tellv, env, allocator);
74 }
75
76 CUDA size_t length() const { return 1; }
77};
78
79/** A Boolean variable defined on a universe of discourse supporting `0` for false and `1` for true. */
80template<class AD, bool neg>
82public:
83 using A = AD;
84 using U = typename A::local_universe;
85
86 template <class A2, bool neg2>
87 friend class VariableLiteral;
88
89private:
90 AVar avar;
91
92public:
93 VariableLiteral() = default;
94 CUDA VariableLiteral(AVar avar): avar(avar) {}
95
96 template <class A2, class Alloc>
97 CUDA VariableLiteral(const VariableLiteral<A2, neg>& other, const Alloc&): avar(other.avar) {}
98
99private:
100 template<bool negate>
101 CUDA local::B ask_impl(const A& a) const {
102 U tmp{};
103 a.project(avar, tmp);
104 if constexpr(negate) {
105 return tmp <= U::eq_zero();
106 }
107 else {
108 return !(tmp >= U::eq_zero());
109 }
110 }
111
112 template <bool negate>
113 CUDA bool deduce_impl(A& a) const {
114 if constexpr(negate) {
115 return a.embed(avar, U::eq_zero());
116 }
117 else {
118 return a.embed(avar, U::eq_one());
119 }
120 }
121
122public:
123 /** Given a variable `x` taking a value in a universe `U` denoted by \f$ a(x) \f$.
124 * - \f$ a \vDash x \f$ holds iff \f$ \lnot (a(x) \leq [\![x = 0]\!]_U) \f$.
125 * - \f$ a \vDash \lnot{x} \f$ holds iff \f$ a(x) \geq [\![x = 0]\!]_U \f$. */
126 CUDA local::B ask(const A& a) const {
127 return ask_impl<neg>(a);
128 }
129
130 /** Given a variable `x` taking a value in a universe `U` denoted by \f$ a(x) \f$.
131 * - \f$ a \nvDash x \f$ holds iff \f$ a(x) \geq [\![x = 0]\!]_U \f$.
132 * - \f$ a \nvDash \lnot{x} \f$ holds iff \f$ \lnot (a(x) \leq [\![x = 0]\!]_U) \f$. */
133 CUDA local::B nask(const A& a) const {
134 return ask_impl<!neg>(a);
135 }
136
137 /** Perform:
138 * * Positive literal: \f$ x = a(x) \sqcup [\![x = 1]\!]_U \f$
139 * * Negative literal: \f$ x = a(x) \sqcup [\![x = 0]\!]_U \f$. */
140 CUDA bool deduce(A& a) const {
141 return deduce_impl<neg>(a);
142 }
143
144 /** Perform:
145 * * Positive literal: \f$ x = a(x) \sqcup [\![x = 0]\!]_U \f$
146 * * Negative literal: \f$ x = a(x) \sqcup [\![x = 1]\!]_U \f$. */
147 CUDA bool contradeduce(A& a) const {
148 return deduce_impl<!neg>(a);
149 }
150
151 CUDA NI void print(const A& a) const {
152 if constexpr(neg) { printf("not "); }
153 printf("(%d,%d)", avar.aty(), avar.vid());
154 }
155
156 template <class Env, class Allocator = typename Env::allocator_type>
157 CUDA NI TFormula<Allocator> deinterpret(const A&, const Env& env, AType apc, Allocator allocator = Allocator()) const {
158 using F = TFormula<Allocator>;
159 auto f = F::make_lvar(avar.aty(), LVar<Allocator>(env.name_of(avar), allocator));
160 if constexpr(neg) {
161 f = F::make_unary(NOT, f, apc);
162 }
163 return f;
164 }
165
166 CUDA size_t length() const { return 1; }
167};
168
169template<class AD>
170class False {
171public:
172 using A = AD;
173 using U = typename A::local_universe;
174
175 template <class A2>
176 friend class False;
177
178public:
179 False() = default;
180
181 template <class A2, class Alloc>
182 CUDA False(const False<A2>&, const Alloc&) {}
183
184 CUDA local::B ask(const A& a) const { return a.is_bot(); }
185 CUDA local::B nask(const A&) const { return true; }
186
187 CUDA bool deduce(A& a) const {
188 if(!a.is_bot()) {
189 a.meet_bot();
190 return true;
191 }
192 return false;
193 }
194
195 CUDA bool contradeduce(A&) const { return false; }
196 CUDA NI void print(const A& a) const { printf("false"); }
197
198 template <class Env, class Allocator = typename Env::allocator_type>
199 CUDA NI TFormula<Allocator> deinterpret(const A&, const Env&, AType, Allocator allocator = Allocator()) const {
200 return TFormula<Allocator>::make_false();
201 }
202
203 CUDA size_t length() const { return 1; }
204};
205
206template<class AD>
207class True {
208public:
209 using A = AD;
210 using U = typename A::local_universe;
211
212 template <class A2>
213 friend class True;
214
215public:
216 True() = default;
217
218 template <class A2, class Alloc>
219 CUDA True(const True<A2>&, const Alloc&) {}
220
221 CUDA local::B ask(const A&) const { return true; }
222 CUDA local::B nask(const A& a) const { return a.is_bot(); }
223 CUDA bool deduce(A&) const { return false; }
224 CUDA bool contradeduce(A& a) const {
225 if(!a.is_bot()) {
226 a.meet_bot();
227 return true;
228 }
229 return false;
230 }
231 CUDA void print(const A& a) const { printf("true"); }
232
233 template <class Env, class Allocator = typename Env::allocator_type>
234 CUDA TFormula<Allocator> deinterpret(const A&, const Env&, AType, Allocator allocator = Allocator()) const {
235 return TFormula<Allocator>::make_true();
236 }
237
238 CUDA size_t length() const { return 1; }
239};
240
241template<class AD, class Allocator>
243public:
244 using A = AD;
245 using U = typename A::local_universe;
246 using allocator_type = Allocator;
249 using sub_ptr = battery::unique_ptr<sub_type, allocator_type>;
250
251 template <class A2, class Alloc2>
252 friend class Conjunction;
253
254private:
255 sub_ptr f;
256 sub_ptr g;
257
258public:
259 CUDA Conjunction(sub_ptr&& f, sub_ptr&& g): f(std::move(f)), g(std::move(g)) {}
260 CUDA Conjunction(this_type&& other): Conjunction(std::move(other.f), std::move(other.g)) {}
261
262 template <class A2, class Alloc2>
263 CUDA Conjunction(const Conjunction<A2, Alloc2>& other, const allocator_type& alloc)
264 : f(battery::allocate_unique<sub_type>(alloc, *other.f, alloc))
265 , g(battery::allocate_unique<sub_type>(alloc, *other.g, alloc))
266 {}
267
268 CUDA local::B ask(const A& a) const {
269 return f->ask(a) && g->ask(a);
270 }
271
272 CUDA local::B nask(const A& a) const {
273 return f->nask(a) || g->nask(a);
274 }
275
276 CUDA bool deduce(A& a) const {
277 bool has_changed = f->deduce(a);
278 has_changed |= g->deduce(a);
279 return has_changed;
280 }
281
282 CUDA bool contradeduce(A& a) const {
283 if(f->ask(a)) { return g->contradeduce(a); }
284 else if(g->ask(a)) { return f->contradeduce(a); }
285 return false;
286 }
287
288 CUDA NI void print(const A& a) const {
289 f->print(a);
290 printf(" /\\ ");
291 g->print(a);
292 }
293
294 template <class Env, class Allocator2 = typename Env::allocator_type>
295 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
296 auto left = f->deinterpret(a, env, apc, allocator);
297 auto right = g->deinterpret(a, env, apc, allocator);
298 if(left.is_true()) { return right; }
299 else if(right.is_true()) { return left; }
300 else if(left.is_false()) { return left; }
301 else if(right.is_false()) { return right; }
302 else {
303 return TFormula<Allocator2>::make_binary(left, AND, right, apc, allocator);
304 }
305 }
306
307 CUDA size_t length() const { return 1 + f->length() + g->length(); }
308};
309
310template<class AD, class Allocator>
312public:
313 using A = AD;
314 using U = typename A::local_universe;
315 using allocator_type = Allocator;
318 using sub_ptr = battery::unique_ptr<sub_type, allocator_type>;
319
320 template <class A2, class Alloc2>
321 friend class Disjunction;
322
323private:
324 sub_ptr f;
325 sub_ptr g;
326
327public:
328 CUDA Disjunction(sub_ptr&& f, sub_ptr&& g): f(std::move(f)), g(std::move(g)) {}
330 std::move(other.f), std::move(other.g)) {}
331
332 template <class A2, class Alloc2>
333 CUDA Disjunction(const Disjunction<A2, Alloc2>& other, const allocator_type& alloc)
334 : f(battery::allocate_unique<sub_type>(alloc, *other.f, alloc))
335 , g(battery::allocate_unique<sub_type>(alloc, *other.g, alloc))
336 {}
337
338 CUDA local::B ask(const A& a) const {
339 return f->ask(a) || g->ask(a);
340 }
341
342 CUDA local::B nask(const A& a) const {
343 return f->nask(a) && g->nask(a);
344 }
345
346 CUDA bool deduce(A& a) const {
347 if(f->nask(a)) { return g->deduce(a); }
348 else if(g->nask(a)) { return f->deduce(a); }
349 return false;
350 }
351
352 CUDA bool contradeduce(A& a) const {
353 bool has_changed = f->contradeduce(a);
354 has_changed |= g->contradeduce(a);
355 return has_changed;
356 }
357
358 CUDA NI void print(const A& a) const {
359 f->print(a);
360 printf(" \\/ ");
361 g->print(a);
362 }
363
364 template <class Env, class Allocator2 = typename Env::allocator_type>
365 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
366 auto left = f->deinterpret(a, env, apc, allocator);
367 auto right = g->deinterpret(a, env, apc, allocator);
368 if(left.is_true()) { return left; }
369 else if(right.is_true()) { return right; }
370 else if(left.is_false()) { return right; }
371 else if(right.is_false()) { return left; }
372 else {
373 return TFormula<Allocator2>::make_binary(left, OR, right, apc, allocator);
374 }
375 }
376
377 CUDA size_t length() const { return 1 + f->length() + g->length(); }
378};
379
380template<class AD, class Allocator>
382public:
383 using A = AD;
384 using U = typename A::local_universe;
385 using allocator_type = Allocator;
388 using sub_ptr = battery::unique_ptr<sub_type, allocator_type>;
389
390 template <class A2, class Alloc2>
391 friend class Biconditional;
392
393private:
394 sub_ptr f;
395 sub_ptr g;
396
397public:
398 CUDA Biconditional(sub_ptr&& f, sub_ptr&& g): f(std::move(f)), g(std::move(g)) {}
400 std::move(other.f), std::move(other.g)) {}
401
402 template <class A2, class Alloc2>
404 : f(battery::allocate_unique<sub_type>(alloc, *other.f, alloc))
405 , g(battery::allocate_unique<sub_type>(alloc, *other.g, alloc))
406 {}
407
408 CUDA local::B ask(const A& a) const {
409 return
410 (f->ask(a) && g->ask(a)) ||
411 (f->nask(a) && g->nask(a));
412 }
413
414 // note that not(f <=> g) is equivalent to (f <=> not g)
415 CUDA local::B nask(const A& a) const {
416 return
417 (f->ask(a) && g->nask(a)) ||
418 (f->nask(a) && g->ask(a));
419 }
420
421 CUDA bool deduce(A& a) const {
422 if(f->ask(a)) { return g->deduce(a); }
423 else if(f->nask(a)) { return g->contradeduce(a); }
424 else if(g->ask(a)) { return f->deduce(a); }
425 else if(g->nask(a)) { return f->contradeduce(a); }
426 return false;
427 }
428
429 // note that not(f <=> g) is equivalent to (f <=> not g)
430 CUDA bool contradeduce(A& a) const {
431 if(f->ask(a)) { return g->contradeduce(a); }
432 else if(f->nask(a)) { return g->deduce(a); }
433 else if(g->ask(a)) { return f->contradeduce(a); }
434 else if(g->nask(a)) { return f->deduce(a); }
435 return false;
436 }
437
438 CUDA NI void print(const A& a) const {
439 f->print(a);
440 printf(" <=> ");
441 g->print(a);
442 }
443
444 template <class Env, class Allocator2 = typename Env::allocator_type>
445 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
446 return TFormula<Allocator2>::make_binary(
447 f->deinterpret(a, env, apc, allocator), EQUIV, g->deinterpret(a, env, apc, allocator), apc, allocator);
448 }
449
450 CUDA size_t length() const { return 1 + f->length() + g->length(); }
451};
452
453template<class AD, class Allocator>
455public:
456 using A = AD;
457 using U = typename A::local_universe;
458 using allocator_type = Allocator;
461 using sub_ptr = battery::unique_ptr<sub_type, allocator_type>;
462
463 template <class A2, class Alloc2>
464 friend class Implication;
465
466private:
467 sub_ptr f;
468 sub_ptr g;
469
470public:
471 CUDA Implication(sub_ptr&& f, sub_ptr&& g): f(std::move(f)), g(std::move(g)) {}
473 std::move(other.f), std::move(other.g)) {}
474
475 template <class A2, class Alloc2>
476 CUDA Implication(const Implication<A2, Alloc2>& other, const allocator_type& alloc)
477 : f(battery::allocate_unique<sub_type>(alloc, *other.f, alloc))
478 , g(battery::allocate_unique<sub_type>(alloc, *other.g, alloc))
479 {}
480
481 // note that f => g is equivalent to (not f) or g.
482 CUDA local::B ask(const A& a) const {
483 return f->nask(a) || g->ask(a);
484 }
485
486 // note that not(f => g) is equivalent to f and (not g)
487 CUDA local::B nask(const A& a) const {
488 return f->ask(a) && g->nask(a);
489 }
490
491 CUDA bool deduce(A& a) const {
492 if(f->ask(a)) { return g->deduce(a); }
493 else if(g->nask(a)) { return f->contradeduce(a); }
494 return false;
495 }
496
497 CUDA bool contradeduce(A& a) const {
498 if(f->ask(a)) { return g->contradeduce(a); }
499 else if(g->nask(a)) { return f->deduce(a); }
500 return false;
501 }
502
503 CUDA NI void print(const A& a) const {
504 f->print(a);
505 printf(" => ");
506 g->print(a);
507 }
508
509 template <class Env, class Allocator2 = typename Env::allocator_type>
510 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
511 return TFormula<Allocator2>::make_binary(
512 f->deinterpret(a, env, apc, allocator), IMPLY, g->deinterpret(a, env, apc, allocator), apc, allocator);
513 }
514
515 CUDA size_t length() const { return 1 + f->length() + g->length(); }
516};
517
518template<class AD, class Allocator>
520public:
521 using A = AD;
522 using U = typename A::local_universe;
523 using allocator_type = Allocator;
526 using sub_ptr = battery::unique_ptr<sub_type, allocator_type>;
527
528 template <class A2, class Alloc2>
530
531private:
532 sub_ptr f;
533 sub_ptr g;
534
535public:
536 CUDA ExclusiveDisjunction(sub_ptr&& f, sub_ptr&& g): f(std::move(f)), g(std::move(g)) {}
538 std::move(other.f), std::move(other.g)) {}
539
540 template <class A2, class Alloc2>
542 : f(battery::allocate_unique<sub_type>(alloc, *other.f, alloc))
543 , g(battery::allocate_unique<sub_type>(alloc, *other.g, alloc))
544 {}
545
546 CUDA local::B ask(const A& a) const {
547 return
548 (f->ask(a) && g->nask(a)) ||
549 (f->nask(a) && g->ask(a));
550 }
551
552 CUDA local::B nask(const A& a) const {
553 return
554 (f->ask(a) && g->ask(a)) ||
555 (f->ask(a) && g->nask(a));
556 }
557
558 CUDA bool deduce(A& a) const {
559 if(f->ask(a)) { return g->contradeduce(a); }
560 else if(f->nask(a)) { return g->deduce(a); }
561 else if(g->ask(a)) { return f->contradeduce(a); }
562 else if(g->nask(a)) { return f->deduce(a); }
563 return false;
564 }
565
566 CUDA bool contradeduce(A& a) const {
567 if(f->ask(a)) { return g->deduce(a); }
568 else if(f->nask(a)) { return g->contradeduce(a); }
569 else if(g->ask(a)) { return f->deduce(a); }
570 else if(g->nask(a)) { return f->contradeduce(a); }
571 return false;
572 }
573
574 CUDA NI void print(const A& a) const {
575 f->print(a);
576 printf(" xor ");
577 g->print(a);
578 }
579
580 template <class Env, class Allocator2 = typename Env::allocator_type>
581 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
582 return TFormula<Allocator2>::make_binary(
583 f->deinterpret(a, env, apc, allocator), XOR, g->deinterpret(a, env, apc, allocator), apc, allocator);
584 }
585
586 CUDA size_t length() const { return 1 + f->length() + g->length(); }
587};
588
589template<class AD, class Allocator, bool neg = false>
590class Equality {
591public:
592 using A = AD;
593 using U = typename A::local_universe;
594 using allocator_type = Allocator;
597
598 template <class A2, class Alloc2, bool neg2>
599 friend class Equality;
600
601private:
602 using LB = typename U::LB::local_type;
603 using UB = typename U::UB::local_type;
604
605 sub_type left;
606 sub_type right;
607
608public:
609 CUDA Equality(sub_type&& left, sub_type&& right): left(std::move(left)), right(std::move(right)) {}
610 CUDA Equality(this_type&& other): Equality(std::move(other.left), std::move(other.right)) {}
611
612 template <class A2, class Alloc2>
613 CUDA Equality(const Equality<A2, Alloc2, neg>& other, const allocator_type& alloc):
614 left(other.left, alloc),
615 right(other.right, alloc)
616 {}
617
618private:
619 template <bool negate>
620 CUDA local::B ask_impl(const A& a) const {
621 U l{};
622 U r{};
623 left.project(a, l);
624 right.project(a, r);
625 if constexpr(negate) {
626 return fmeet(l, r).is_bot();
627 }
628 else {
629 return l == r && l.lb().value() == l.ub().value();
630 }
631 }
632
633 template <bool negate>
634 CUDA bool deduce_impl(A& a) const {
635 U l{};
636 U r{};
637 bool has_changed = false;
638 if constexpr(negate) {
639 if(!right.is(sub_type::IConstant)) {
640 left.project(a, l);
641 if(l.lb().value() == l.ub().value()) {
642 if constexpr(U::complemented) {
643 return right.embed(a, l.complement());
644 }
645 else if (U::preserve_concrete_covers && U::is_arithmetic) {
646 right.project(a, r);
647 U lb{r};
648 U ub{r};
649 lb.meet_lb(LB::prev(l.lb()));
650 ub.meet_ub(UB::prev(l.ub()));
651 return right.embed(a, fjoin(lb, ub));
652 }
653 }
654 }
655 if(!left.is(sub_type::IConstant)) {
656 right.project(a, r);
657 if(r.lb().value() == r.ub().value()) {
658 if constexpr(U::complemented) {
659 return left.embed(a, r.complement());
660 }
661 else if (U::preserve_concrete_covers && U::is_arithmetic) {
662 left.project(a, l);
663 U lb{l};
664 U ub{l};
665 lb.meet_lb(LB::prev(r.lb()));
666 ub.meet_ub(UB::prev(r.ub()));
667 return left.embed(a, fjoin(lb, ub));
668 }
669 }
670 }
671 }
672 else {
673 if(!right.is(sub_type::IConstant)) {
674 left.project(a, l);
675 has_changed = right.embed(a, l);
676 }
677 if(!left.is(sub_type::IConstant)) {
678 right.project(a, r);
679 has_changed |= left.embed(a, r);
680 }
681 }
682 return has_changed;
683 }
684
685public:
686 CUDA local::B ask(const A& a) const {
687 return ask_impl<neg>(a);
688 }
689
690 CUDA local::B nask(const A& a) const {
691 return ask_impl<!neg>(a);
692 }
693
694 CUDA bool deduce(A& a) const {
695 return deduce_impl<neg>(a);
696 }
697
698 CUDA bool contradeduce(A& a) const {
699 return deduce_impl<!neg>(a);
700 }
701
702 CUDA NI void print(const A& a) const {
703 left.print(a);
704 if constexpr(neg) {
705 printf(" != ");
706 }
707 else {
708 printf(" == ");
709 }
710 right.print(a);
711 }
712
713 template <class Env, class Allocator2 = typename Env::allocator_type>
714 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
715 auto lf = left.deinterpret(a, env, apc, allocator);
716 auto rf = right.deinterpret(a, env, apc, allocator);
717 return TFormula<Allocator2>::make_binary(std::move(lf), neg ? NEQ : EQ, std::move(rf), apc, allocator);
718 }
719
720 CUDA size_t length() const { return 1 + left.length() + right.length(); }
721};
722
723template<class AD, class Allocator>
725
726/** Implement the constraint `t1 <= t2` or `t1 > t2` if `neg` is `true`. */
727template<class AD, class Allocator, bool neg>
729public:
730 using A = AD;
731 using U = typename A::local_universe;
732 using allocator_type = Allocator;
735
736 template <class A2, class Alloc2, bool neg2>
737 friend class Inequality;
738
739private:
740 using LB = typename U::LB::local_type;
741 using UB = typename U::UB::local_type;
742
743 sub_type left;
744 sub_type right;
745
746public:
747 CUDA Inequality(sub_type&& left, sub_type&& right): left(std::move(left)), right(std::move(right)) {}
748 CUDA Inequality(this_type&& other): Inequality(std::move(other.left), std::move(other.right)) {}
749
750 template <class A2, class Alloc2>
751 CUDA Inequality(const Inequality<A2, Alloc2, neg>& other, const allocator_type& alloc):
752 left(other.left, alloc),
753 right(other.right, alloc)
754 {}
755
756private:
757 template <bool negate>
758 CUDA local::B ask_impl(const A& a) const {
759 U l{};
760 U r{};
761 left.project(a, l);
762 right.project(a, r);
763 /** Note: we need the arithmetic order to compare both values.
764 * Using the lattice order is harder to work with due to infinities and incomparable bounds. */
765 if constexpr(negate) {
766 return l.lb().value() > r.ub().value();
767 }
768 else {
769 return l.ub().value() <= r.lb().value();
770 }
771 }
772
773 template <bool negate>
774 CUDA bool deduce_impl(A& a) const {
775 U l{};
776 U r{};
777 bool has_changed = false;
778 // l > r
779 if constexpr(negate) {
780 if(!left.is(sub_type::IConstant)) {
781 right.project(a, r);
782 if constexpr(U::preserve_concrete_covers && U::is_arithmetic) {
783 r.meet_lb(LB::prev(r.lb()));
784 }
785 has_changed = left.embed(a, U(r.lb(), UB::top()));
786 }
787 if(!right.is(sub_type::IConstant)) {
788 left.project(a, l);
789 if constexpr(U::preserve_concrete_covers && U::is_arithmetic) {
790 l.meet_ub(UB::prev(l.ub()));
791 }
792 has_changed |= right.embed(a, U(LB::top(), l.ub()));
793 }
794 }
795 // l <= r
796 else {
797 if(!left.is(sub_type::IConstant)) {
798 right.project(a, r);
799 has_changed |= left.embed(a, U(LB::top(), r.ub()));
800 }
801 if(!right.is(sub_type::IConstant)) {
802 left.project(a, l);
803 has_changed = right.embed(a, U(l.lb(), UB::top()));
804 }
805 }
806 return has_changed;
807 }
808
809public:
810 CUDA local::B ask(const A& a) const {
811 return ask_impl<neg>(a);
812 }
813
814 CUDA local::B nask(const A& a) const {
815 return ask_impl<!neg>(a);
816 }
817
818 CUDA bool deduce(A& a) const {
819 return deduce_impl<neg>(a);
820 }
821
822 CUDA bool contradeduce(A& a) const {
823 return deduce_impl<!neg>(a);
824 }
825
826 CUDA NI void print(const A& a) const {
827 left.print(a);
828 if constexpr(neg) {
829 printf(" > ");
830 }
831 else {
832 printf(" <= ");
833 }
834 right.print(a);
835 }
836
837 template <class Env, class Allocator2 = typename Env::allocator_type>
838 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
839 auto lf = left.deinterpret(a, env, apc, allocator);
840 auto rf = right.deinterpret(a, env, apc, allocator);
841 return TFormula<Allocator2>::make_binary(std::move(lf), neg ? GT : LEQ, std::move(rf), apc, allocator);
842 }
843
844 CUDA size_t length() const { return 1 + left.length() + right.length(); }
845};
846
847template<class AD, class Allocator>
849
850template<class AD, class Allocator>
852
853/**
854 * A formula can occur in a term, e.g., `(x = 2) + (y = 2) + (z = 2) >= 2`
855 * In that case, the entailment of the formula is mapped onto a sublattice of `U` supporting initialization from `0` and `1`.
856 * A term can occur in a formula, as it is usually done.
857 * Therefore, a formula is both a formula and a term.
858 *
859 * A logical formula is turned into a term by mapping their satisfiability to and from a sublattice of `U` representing Boolean values:
860 * - Consists of four distinct values \f$\{[\![x = 0]\!]_U \sqcap [\![x = 1]\!]_U, [\![x = 0]\!]_U, [\![x = 1]\!]_U, \top_U \}\f$.
861 * - With \f$\{[\![x = 0]\!]_U \sqcap [\![x = 1]\!]_U \f$ meaning neither true or false yet (e.g., unknown), \f$\{[\![x = 0]\!]_U \f$ modelling falsity, \f$ [\![x = 1]\!]_U \f$ modelling truth, and \f$ \top_U \f$ a logical statement both true and false (i.e., one of the variable is top).
862*/
863template <class AD, class Allocator>
864class Formula {
865public:
866 using A = AD;
867 using allocator_type = Allocator;
869 using U = typename A::local_universe;
871 using this_ptr = battery::unique_ptr<this_type, allocator_type>;
872
885
886 static constexpr size_t IPVarLit = 0;
887 static constexpr size_t INVarLit = IPVarLit + 1;
888 static constexpr size_t ITrue = INVarLit + 1;
889 static constexpr size_t IFalse = ITrue + 1;
890 static constexpr size_t ILeq = IFalse + 1;
891 static constexpr size_t IGt = ILeq + 1;
892 static constexpr size_t IEq = IGt + 1;
893 static constexpr size_t INeq = IEq + 1;
894 static constexpr size_t IConj = INeq + 1;
895 static constexpr size_t IDisj = IConj + 1;
896 static constexpr size_t IBicond = IDisj + 1;
897 static constexpr size_t IImply = IBicond + 1;
898 static constexpr size_t IXor = IImply + 1;
899 static constexpr size_t IAE = IXor + 1;
900
901 template <class A2, class Alloc2>
902 friend class Formula;
903
904private:
905 using VFormula = battery::variant<
906 PVarLit,
907 NVarLit,
908 True<A>,
909 False<A>,
910 Leq,
911 Gt,
912 Eq,
913 Neq,
914 Conj,
915 Disj,
916 Bicond,
917 Imply,
918 Xor,
919 AE
920 >;
921
922 VFormula formula;
923
924 template <size_t I, class FormulaType, class A2, class Alloc2>
925 CUDA static VFormula create_one(const Formula<A2, Alloc2>& other, const allocator_type& allocator) {
926 return VFormula::template create<I>(FormulaType(battery::get<I>(other.formula), allocator));
927 }
928
929 template <class A2, class Alloc2>
930 CUDA NI static VFormula create(const Formula<A2, Alloc2>& other, const allocator_type& allocator) {
931 switch(other.formula.index()) {
932 case IPVarLit: return create_one<IPVarLit, PVarLit>(other, allocator);
933 case INVarLit: return create_one<INVarLit, NVarLit>(other, allocator);
934 case ITrue: return create_one<ITrue, True<A>>(other, allocator);
935 case IFalse: return create_one<IFalse, False<A>>(other, allocator);
936 case ILeq: return create_one<ILeq, Leq>(other, allocator);
937 case IGt: return create_one<IGt, Gt>(other, allocator);
938 case IEq: return create_one<IEq, Eq>(other, allocator);
939 case INeq: return create_one<INeq, Neq>(other, allocator);
940 case IConj: return create_one<IConj, Conj>(other, allocator);
941 case IDisj: return create_one<IDisj, Disj>(other, allocator);
942 case IBicond: return create_one<IBicond, Bicond>(other, allocator);
943 case IImply: return create_one<IImply, Imply>(other, allocator);
944 case IXor: return create_one<IXor, Xor>(other, allocator);
945 case IAE: return create_one<IAE, AE>(other, allocator);
946 default:
947 printf("BUG: formula not handled.\n");
948 assert(false);
949 return VFormula::template create<IFalse>(False<A>());
950 }
951 }
952
953 CUDA Formula(VFormula&& formula): formula(std::move(formula)) {}
954
955 template <class F>
956 CUDA NI auto forward(F&& f) const {
957 switch(formula.index()) {
958 case IPVarLit: return f(battery::get<IPVarLit>(formula));
959 case INVarLit: return f(battery::get<INVarLit>(formula));
960 case ITrue: return f(battery::get<ITrue>(formula));
961 case IFalse: return f(battery::get<IFalse>(formula));
962 case ILeq: return f(battery::get<ILeq>(formula));
963 case IGt: return f(battery::get<IGt>(formula));
964 case IEq: return f(battery::get<IEq>(formula));
965 case INeq: return f(battery::get<INeq>(formula));
966 case IConj: return f(battery::get<IConj>(formula));
967 case IDisj: return f(battery::get<IDisj>(formula));
968 case IBicond: return f(battery::get<IBicond>(formula));
969 case IImply: return f(battery::get<IImply>(formula));
970 case IXor: return f(battery::get<IXor>(formula));
971 case IAE: return f(battery::get<IAE>(formula));
972 default:
973 printf("BUG: formula not handled.\n");
974 assert(false);
975 return f(False<A>());
976 }
977 }
978
979 template <class F>
980 CUDA NI auto forward(F&& f) {
981 switch(formula.index()) {
982 case IPVarLit: return f(battery::get<IPVarLit>(formula));
983 case INVarLit: return f(battery::get<INVarLit>(formula));
984 case ITrue: return f(battery::get<ITrue>(formula));
985 case IFalse: return f(battery::get<IFalse>(formula));
986 case ILeq: return f(battery::get<ILeq>(formula));
987 case IGt: return f(battery::get<IGt>(formula));
988 case IEq: return f(battery::get<IEq>(formula));
989 case INeq: return f(battery::get<INeq>(formula));
990 case IConj: return f(battery::get<IConj>(formula));
991 case IDisj: return f(battery::get<IDisj>(formula));
992 case IBicond: return f(battery::get<IBicond>(formula));
993 case IImply: return f(battery::get<IImply>(formula));
994 case IXor: return f(battery::get<IXor>(formula));
995 case IAE: return f(battery::get<IAE>(formula));
996 default:
997 printf("BUG: formula not handled.\n");
998 assert(false);
999 False<A> false_{};
1000 return f(false_);
1001 }
1002 }
1003
1004public:
1005 Formula() = default;
1006 Formula(this_type&&) = default;
1008
1009 template <class A2, class Alloc2>
1010 CUDA Formula(const Formula<A2, Alloc2>& other, const Allocator& allocator = Allocator())
1011 : formula(create(other, allocator))
1012 {}
1013
1014 CUDA bool is(size_t kind) const {
1015 return formula.index() == kind;
1016 }
1017
1018 CUDA size_t kind() const {
1019 return formula.index();
1020 }
1021
1022 template <size_t I, class SubFormula>
1023 CUDA static this_type make(SubFormula&& sub_formula) {
1024 return Formula(VFormula::template create<I>(std::move(sub_formula)));
1025 }
1026
1027 CUDA static this_type make_pvarlit(const AVar& avar) {
1028 return make<IPVarLit>(PVarLit(avar));
1029 }
1030
1031 CUDA static this_type make_nvarlit(const AVar& avar) {
1032 return make<INVarLit>(NVarLit(avar));
1033 }
1034
1035 CUDA static this_type make_true() {
1036 return make<ITrue>(True<A>{});
1037 }
1038
1039 CUDA static this_type make_false() {
1040 return make<IFalse>(False<A>{});
1041 }
1042
1043 CUDA static this_type make_leq(term_type&& left, term_type&& right) {
1044 return make<ILeq>(Leq(std::move(left), std::move(right)));
1045 }
1046
1047 CUDA static this_type make_gt(term_type&& left, term_type&& right) {
1048 return make<IGt>(Gt(std::move(left), std::move(right)));
1049 }
1050
1051 CUDA static this_type make_eq(term_type&& left, term_type&& right) {
1052 return make<IEq>(Eq(std::move(left), std::move(right)));
1053 }
1054
1055 CUDA static this_type make_neq(term_type&& left, term_type&& right) {
1056 return make<INeq>(Neq(std::move(left), std::move(right)));
1057 }
1058
1059 CUDA static this_type make_conj(this_ptr&& left, this_ptr&& right) {
1060 return make<IConj>(Conj(std::move(left), std::move(right)));
1061 }
1062
1063 CUDA static this_type make_disj(this_ptr&& left, this_ptr&& right) {
1064 return make<IDisj>(Disj(std::move(left), std::move(right)));
1065 }
1066
1067 CUDA static this_type make_bicond(this_ptr&& left, this_ptr&& right) {
1068 return make<IBicond>(Bicond(std::move(left), std::move(right)));
1069 }
1070
1071 CUDA static this_type make_imply(this_ptr&& left, this_ptr&& right) {
1072 return make<IImply>(Imply(std::move(left), std::move(right)));
1073 }
1074
1075 CUDA static this_type make_xor(this_ptr&& left, this_ptr&& right) {
1076 return make<IXor>(Xor(std::move(left), std::move(right)));
1077 }
1078
1079 using tell_type = typename A::template tell_type<allocator_type>;
1080 using ask_type = typename A::template ask_type<allocator_type>;
1081
1083 tell_type&& tellv, tell_type&& not_tellv,
1084 ask_type&& askv, ask_type&& not_askv)
1085 {
1086 return make<IAE>(AE(std::move(tellv), std::move(not_tellv), std::move(askv), std::move(not_askv)));
1087 }
1088
1089 /** Call `deduce` iff \f$ u \leq [\![x = 1]\!]_U \f$ and `contradeduce` iff \f$ u \leq [\![x = 0]\!] \f$. */
1090 CUDA bool embed(A& a, const U& u) const {
1091 if(u <= U::eq_one()) { return deduce(a); }
1092 else if(u <= U::eq_zero()) { return contradeduce(a); }
1093 return false;
1094 }
1095
1096 /** Maps the truth value of \f$ \varphi \f$ to the Boolean sublattice of `U` (see above). */
1097 CUDA void project(const A& a, U& r) const {
1098 if(a.is_bot()) { r.meet_bot(); }
1099 if(ask(a)) { r.meet(U::eq_one()); }
1100 if(nask(a)) { r.meet(U::eq_zero()); }
1101 r.meet(fjoin(U::eq_zero(), U::eq_one()));
1102 }
1103
1104 CUDA void print(const A& a) const {
1105 forward([&](const auto& t) { t.print(a); });
1106 }
1107
1108 template <class Env, class Allocator2 = typename Env::allocator_type>
1109 CUDA TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
1110 return forward([&](const auto& t) { return t.deinterpret(a, env, apc, allocator); });
1111 }
1112
1113 /** Given a formula \f$ \varphi \f$, the ask operation \f$ a \vDash \varphi \f$ holds whenever we can deduce \f$ \varphi \f$ from \f$ a \f$.
1114 More precisely, if \f$ \gamma(a) \subseteq [\![\varphi]\!]^\flat \f$, which implies that \f$ \varphi \f$ cannot remove further deduce \f$ a \f$ since \f$ a \f$ is already more precise than \f$ \varphi \f$. */
1115 CUDA local::B ask(const A& a) const {
1116 return forward([&](const auto& t) { return t.ask(a); });
1117 }
1118
1119 /** Similar to `ask` but for \f$ \lnot{\varphi} \f$. */
1120 CUDA local::B nask(const A& a) const {
1121 return forward([&](const auto& t) { return t.nask(a); });
1122 }
1123
1124 /** Refine the formula by supposing it must be true. */
1125 CUDA bool deduce(A& a) const {
1126 return forward([&](const auto& t) { return t.deduce(a); });
1127 }
1128
1129 /** Refine the negation of the formula, hence we suppose the original formula needs to be false. */
1130 CUDA bool contradeduce(A& a) const {
1131 return forward([&](const auto& t) { return t.contradeduce(a); });
1132 }
1133
1134 CUDA size_t length() const {
1135 return forward([](const auto& t) { return t.length(); });
1136 }
1137};
1138
1139} // namespace pc
1140} // namespace lala
1141
1142#endif
Definition formula.hpp:15
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:72
CUDA AbstractElement()
Definition formula.hpp:35
typename A::local_universe U
Definition formula.hpp:18
CUDA local::B nask(const A &a) const
Definition formula.hpp:55
CUDA bool deduce(A &a) const
Definition formula.hpp:59
CUDA NI void print(const A &a) const
Definition formula.hpp:67
Allocator allocator_type
Definition formula.hpp:19
AbstractElement(this_type &&other)=default
AD A
Definition formula.hpp:17
CUDA AbstractElement(const AbstractElement< A2, Alloc2 > &other, const allocator_type &alloc)
Definition formula.hpp:46
typename A::template tell_type< allocator_type > tell_type
Definition formula.hpp:21
CUDA bool contradeduce(A &a) const
Definition formula.hpp:63
typename A::template ask_type< allocator_type > ask_type
Definition formula.hpp:22
this_type & operator=(this_type &&other)=default
CUDA local::B ask(const A &a) const
Definition formula.hpp:51
CUDA AbstractElement(tell_type &&tellv, tell_type &&not_tellv, ask_type &&askv, ask_type &&not_askv)
Definition formula.hpp:37
CUDA size_t length() const
Definition formula.hpp:76
Definition formula.hpp:381
Allocator allocator_type
Definition formula.hpp:385
CUDA local::B ask(const A &a) const
Definition formula.hpp:408
CUDA Biconditional(const Biconditional< A2, Alloc2 > &other, const allocator_type &alloc)
Definition formula.hpp:403
CUDA NI void print(const A &a) const
Definition formula.hpp:438
AD A
Definition formula.hpp:383
CUDA size_t length() const
Definition formula.hpp:450
typename A::local_universe U
Definition formula.hpp:384
battery::unique_ptr< sub_type, allocator_type > sub_ptr
Definition formula.hpp:388
CUDA Biconditional(sub_ptr &&f, sub_ptr &&g)
Definition formula.hpp:398
CUDA Biconditional(this_type &&other)
Definition formula.hpp:399
CUDA bool contradeduce(A &a) const
Definition formula.hpp:430
CUDA local::B nask(const A &a) const
Definition formula.hpp:415
CUDA bool deduce(A &a) const
Definition formula.hpp:421
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:445
Definition formula.hpp:242
battery::unique_ptr< sub_type, allocator_type > sub_ptr
Definition formula.hpp:249
CUDA Conjunction(const Conjunction< A2, Alloc2 > &other, const allocator_type &alloc)
Definition formula.hpp:263
CUDA bool contradeduce(A &a) const
Definition formula.hpp:282
typename A::local_universe U
Definition formula.hpp:245
Allocator allocator_type
Definition formula.hpp:246
CUDA local::B ask(const A &a) const
Definition formula.hpp:268
CUDA size_t length() const
Definition formula.hpp:307
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:295
CUDA Conjunction(this_type &&other)
Definition formula.hpp:260
CUDA Conjunction(sub_ptr &&f, sub_ptr &&g)
Definition formula.hpp:259
CUDA NI void print(const A &a) const
Definition formula.hpp:288
CUDA local::B nask(const A &a) const
Definition formula.hpp:272
CUDA bool deduce(A &a) const
Definition formula.hpp:276
AD A
Definition formula.hpp:244
Definition formula.hpp:311
CUDA bool contradeduce(A &a) const
Definition formula.hpp:352
CUDA Disjunction(const Disjunction< A2, Alloc2 > &other, const allocator_type &alloc)
Definition formula.hpp:333
typename A::local_universe U
Definition formula.hpp:314
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:365
CUDA Disjunction(sub_ptr &&f, sub_ptr &&g)
Definition formula.hpp:328
CUDA bool deduce(A &a) const
Definition formula.hpp:346
CUDA Disjunction(this_type &&other)
Definition formula.hpp:329
CUDA local::B ask(const A &a) const
Definition formula.hpp:338
CUDA NI void print(const A &a) const
Definition formula.hpp:358
battery::unique_ptr< sub_type, allocator_type > sub_ptr
Definition formula.hpp:318
CUDA size_t length() const
Definition formula.hpp:377
Allocator allocator_type
Definition formula.hpp:315
AD A
Definition formula.hpp:313
CUDA local::B nask(const A &a) const
Definition formula.hpp:342
Definition formula.hpp:590
CUDA bool deduce(A &a) const
Definition formula.hpp:694
CUDA Equality(this_type &&other)
Definition formula.hpp:610
CUDA size_t length() const
Definition formula.hpp:720
CUDA NI void print(const A &a) const
Definition formula.hpp:702
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:714
CUDA Equality(sub_type &&left, sub_type &&right)
Definition formula.hpp:609
CUDA local::B nask(const A &a) const
Definition formula.hpp:690
CUDA Equality(const Equality< A2, Alloc2, neg > &other, const allocator_type &alloc)
Definition formula.hpp:613
CUDA local::B ask(const A &a) const
Definition formula.hpp:686
AD A
Definition formula.hpp:592
CUDA bool contradeduce(A &a) const
Definition formula.hpp:698
Allocator allocator_type
Definition formula.hpp:594
typename A::local_universe U
Definition formula.hpp:593
Definition formula.hpp:519
CUDA ExclusiveDisjunction(this_type &&other)
Definition formula.hpp:537
CUDA ExclusiveDisjunction(sub_ptr &&f, sub_ptr &&g)
Definition formula.hpp:536
CUDA local::B nask(const A &a) const
Definition formula.hpp:552
CUDA ExclusiveDisjunction(const ExclusiveDisjunction< A2, Alloc2 > &other, const allocator_type &alloc)
Definition formula.hpp:541
CUDA bool deduce(A &a) const
Definition formula.hpp:558
typename A::local_universe U
Definition formula.hpp:522
CUDA local::B ask(const A &a) const
Definition formula.hpp:546
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:581
CUDA NI void print(const A &a) const
Definition formula.hpp:574
battery::unique_ptr< sub_type, allocator_type > sub_ptr
Definition formula.hpp:526
CUDA bool contradeduce(A &a) const
Definition formula.hpp:566
Allocator allocator_type
Definition formula.hpp:523
AD A
Definition formula.hpp:521
CUDA size_t length() const
Definition formula.hpp:586
Definition formula.hpp:170
AD A
Definition formula.hpp:172
CUDA bool deduce(A &a) const
Definition formula.hpp:187
CUDA local::B ask(const A &a) const
Definition formula.hpp:184
CUDA NI void print(const A &a) const
Definition formula.hpp:196
False()=default
CUDA NI TFormula< Allocator > deinterpret(const A &, const Env &, AType, Allocator allocator=Allocator()) const
Definition formula.hpp:199
CUDA False(const False< A2 > &, const Alloc &)
Definition formula.hpp:182
CUDA bool contradeduce(A &) const
Definition formula.hpp:195
typename A::local_universe U
Definition formula.hpp:173
CUDA size_t length() const
Definition formula.hpp:203
CUDA local::B nask(const A &) const
Definition formula.hpp:185
Definition formula.hpp:864
CUDA local::B ask(const A &a) const
Definition formula.hpp:1115
Formula(this_type &&)=default
static constexpr size_t IGt
Definition formula.hpp:891
static CUDA this_type make_true()
Definition formula.hpp:1035
Implication< A, allocator_type > Imply
Definition formula.hpp:882
Disjunction< A, allocator_type > Disj
Definition formula.hpp:880
ExclusiveDisjunction< A, allocator_type > Xor
Definition formula.hpp:883
typename A::template tell_type< allocator_type > tell_type
Definition formula.hpp:1079
static constexpr size_t IFalse
Definition formula.hpp:889
static constexpr size_t INVarLit
Definition formula.hpp:887
static constexpr size_t IDisj
Definition formula.hpp:895
static constexpr size_t IAE
Definition formula.hpp:899
static constexpr size_t IXor
Definition formula.hpp:898
static CUDA this_type make_imply(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1071
friend class Formula
Definition formula.hpp:902
VariableLiteral< A, true > NVarLit
Definition formula.hpp:874
this_type & operator=(this_type &&)=default
static constexpr size_t IPVarLit
Definition formula.hpp:886
static constexpr size_t INeq
Definition formula.hpp:893
static CUDA this_type make_nvarlit(const AVar &avar)
Definition formula.hpp:1031
static CUDA this_type make_false()
Definition formula.hpp:1039
CUDA bool is(size_t kind) const
Definition formula.hpp:1014
static CUDA this_type make_leq(term_type &&left, term_type &&right)
Definition formula.hpp:1043
static CUDA this_type make_xor(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1075
static constexpr size_t ILeq
Definition formula.hpp:890
static CUDA this_type make_neq(term_type &&left, term_type &&right)
Definition formula.hpp:1055
InequalityLEQ< A, allocator_type > Leq
Definition formula.hpp:875
static CUDA this_type make_eq(term_type &&left, term_type &&right)
Definition formula.hpp:1051
Allocator allocator_type
Definition formula.hpp:867
battery::unique_ptr< this_type, allocator_type > this_ptr
Definition formula.hpp:871
InequalityGT< A, allocator_type > Gt
Definition formula.hpp:876
CUDA size_t kind() const
Definition formula.hpp:1018
Equality< A, allocator_type > Eq
Definition formula.hpp:877
CUDA void print(const A &a) const
Definition formula.hpp:1104
CUDA bool embed(A &a, const U &u) const
Definition formula.hpp:1090
static CUDA this_type make_abstract_element(tell_type &&tellv, tell_type &&not_tellv, ask_type &&askv, ask_type &&not_askv)
Definition formula.hpp:1082
typename A::template ask_type< allocator_type > ask_type
Definition formula.hpp:1080
CUDA local::B nask(const A &a) const
Definition formula.hpp:1120
CUDA Formula(const Formula< A2, Alloc2 > &other, const Allocator &allocator=Allocator())
Definition formula.hpp:1010
Conjunction< A, allocator_type > Conj
Definition formula.hpp:879
static constexpr size_t IImply
Definition formula.hpp:897
CUDA bool contradeduce(A &a) const
Definition formula.hpp:1130
static CUDA this_type make(SubFormula &&sub_formula)
Definition formula.hpp:1023
static constexpr size_t ITrue
Definition formula.hpp:888
VariableLiteral< A, false > PVarLit
Definition formula.hpp:873
AD A
Definition formula.hpp:866
AbstractElement< A, allocator_type > AE
Definition formula.hpp:884
static CUDA this_type make_conj(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1059
CUDA bool deduce(A &a) const
Definition formula.hpp:1125
CUDA TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:1109
static CUDA this_type make_pvarlit(const AVar &avar)
Definition formula.hpp:1027
static constexpr size_t IEq
Definition formula.hpp:892
static CUDA this_type make_disj(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1063
static constexpr size_t IBicond
Definition formula.hpp:896
Biconditional< A, allocator_type > Bicond
Definition formula.hpp:881
static CUDA this_type make_gt(term_type &&left, term_type &&right)
Definition formula.hpp:1047
CUDA void project(const A &a, U &r) const
Definition formula.hpp:1097
static CUDA this_type make_bicond(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1067
typename A::local_universe U
Definition formula.hpp:869
Disequality< A, allocator_type > Neq
Definition formula.hpp:878
static constexpr size_t IConj
Definition formula.hpp:894
CUDA size_t length() const
Definition formula.hpp:1134
Definition formula.hpp:454
CUDA bool deduce(A &a) const
Definition formula.hpp:491
CUDA Implication(const Implication< A2, Alloc2 > &other, const allocator_type &alloc)
Definition formula.hpp:476
CUDA bool contradeduce(A &a) const
Definition formula.hpp:497
CUDA Implication(sub_ptr &&f, sub_ptr &&g)
Definition formula.hpp:471
CUDA Implication(this_type &&other)
Definition formula.hpp:472
Allocator allocator_type
Definition formula.hpp:458
CUDA NI void print(const A &a) const
Definition formula.hpp:503
CUDA size_t length() const
Definition formula.hpp:515
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:510
typename A::local_universe U
Definition formula.hpp:457
CUDA local::B nask(const A &a) const
Definition formula.hpp:487
CUDA local::B ask(const A &a) const
Definition formula.hpp:482
battery::unique_ptr< sub_type, allocator_type > sub_ptr
Definition formula.hpp:461
AD A
Definition formula.hpp:456
Definition formula.hpp:728
typename A::local_universe U
Definition formula.hpp:731
CUDA bool deduce(A &a) const
Definition formula.hpp:818
CUDA Inequality(const Inequality< A2, Alloc2, neg > &other, const allocator_type &alloc)
Definition formula.hpp:751
CUDA bool contradeduce(A &a) const
Definition formula.hpp:822
CUDA Inequality(sub_type &&left, sub_type &&right)
Definition formula.hpp:747
CUDA local::B nask(const A &a) const
Definition formula.hpp:814
CUDA NI void print(const A &a) const
Definition formula.hpp:826
Allocator allocator_type
Definition formula.hpp:732
CUDA Inequality(this_type &&other)
Definition formula.hpp:748
AD A
Definition formula.hpp:730
CUDA NI TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:838
CUDA local::B ask(const A &a) const
Definition formula.hpp:810
CUDA size_t length() const
Definition formula.hpp:844
CUDA TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition terms.hpp:750
CUDA void print(const A &a) const
Definition terms.hpp:745
CUDA bool embed(A &a, const U &u) const
Definition terms.hpp:737
CUDA void project(const A &a, U &r) const
Definition terms.hpp:741
CUDA bool is(size_t kind) const
Definition terms.hpp:664
CUDA size_t length() const
Definition terms.hpp:754
static constexpr size_t IConstant
Definition terms.hpp:552
Definition formula.hpp:207
CUDA True(const True< A2 > &, const Alloc &)
Definition formula.hpp:219
CUDA size_t length() const
Definition formula.hpp:238
CUDA void print(const A &a) const
Definition formula.hpp:231
CUDA local::B ask(const A &) const
Definition formula.hpp:221
CUDA local::B nask(const A &a) const
Definition formula.hpp:222
AD A
Definition formula.hpp:209
CUDA bool deduce(A &) const
Definition formula.hpp:223
True()=default
CUDA bool contradeduce(A &a) const
Definition formula.hpp:224
CUDA TFormula< Allocator > deinterpret(const A &, const Env &, AType, Allocator allocator=Allocator()) const
Definition formula.hpp:234
typename A::local_universe U
Definition formula.hpp:210
Definition formula.hpp:81
AD A
Definition formula.hpp:83
CUDA VariableLiteral(AVar avar)
Definition formula.hpp:94
CUDA bool contradeduce(A &a) const
Definition formula.hpp:147
CUDA NI void print(const A &a) const
Definition formula.hpp:151
typename A::local_universe U
Definition formula.hpp:84
CUDA VariableLiteral(const VariableLiteral< A2, neg > &other, const Alloc &)
Definition formula.hpp:97
CUDA local::B ask(const A &a) const
Definition formula.hpp:126
CUDA size_t length() const
Definition formula.hpp:166
CUDA NI TFormula< Allocator > deinterpret(const A &, const Env &env, AType apc, Allocator allocator=Allocator()) const
Definition formula.hpp:157
CUDA bool deduce(A &a) const
Definition formula.hpp:140
CUDA local::B nask(const A &a) const
Definition formula.hpp:133
Definition formula.hpp:8