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 && dual<UB>(l.lb()) == l.ub();
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(dual<UB>(l.lb()) == l.ub()) {
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(dual<UB>(r.lb()) == r.ub()) {
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 if constexpr(negate) {
764 return dual<UB>(l.lb()) > r.ub();
765 }
766 else {
767 return l.ub() <= dual<UB>(r.lb());
768 }
769 }
770
771 template <bool negate>
772 CUDA bool deduce_impl(A& a) const {
773 U l{};
774 U r{};
775 bool has_changed = false;
776 // l > r
777 if constexpr(negate) {
778 if(!left.is(sub_type::IConstant)) {
779 right.project(a, r);
780 if constexpr(U::preserve_concrete_covers && U::is_arithmetic) {
781 r.meet_lb(LB::prev(r.lb()));
782 }
783 has_changed = left.embed(a, U(r.lb(), UB::top()));
784 }
785 if(!right.is(sub_type::IConstant)) {
786 left.project(a, l);
787 if constexpr(U::preserve_concrete_covers && U::is_arithmetic) {
788 l.meet_ub(UB::prev(l.ub()));
789 }
790 has_changed |= right.embed(a, U(LB::top(), l.ub()));
791 }
792 }
793 // l <= r
794 else {
795 if(!left.is(sub_type::IConstant)) {
796 right.project(a, r);
797 has_changed |= left.embed(a, U(LB::top(), r.ub()));
798 }
799 if(!right.is(sub_type::IConstant)) {
800 left.project(a, l);
801 has_changed = right.embed(a, U(l.lb(), UB::top()));
802 }
803 }
804 return has_changed;
805 }
806
807public:
808 CUDA local::B ask(const A& a) const {
809 return ask_impl<neg>(a);
810 }
811
812 CUDA local::B nask(const A& a) const {
813 return ask_impl<!neg>(a);
814 }
815
816 CUDA bool deduce(A& a) const {
817 return deduce_impl<neg>(a);
818 }
819
820 CUDA bool contradeduce(A& a) const {
821 return deduce_impl<!neg>(a);
822 }
823
824 CUDA NI void print(const A& a) const {
825 left.print(a);
826 if constexpr(neg) {
827 printf(" > ");
828 }
829 else {
830 printf(" <= ");
831 }
832 right.print(a);
833 }
834
835 template <class Env, class Allocator2 = typename Env::allocator_type>
836 CUDA NI TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
837 auto lf = left.deinterpret(a, env, apc, allocator);
838 auto rf = right.deinterpret(a, env, apc, allocator);
839 return TFormula<Allocator2>::make_binary(std::move(lf), neg ? GT : LEQ, std::move(rf), apc, allocator);
840 }
841
842 CUDA size_t length() const { return 1 + left.length() + right.length(); }
843};
844
845template<class AD, class Allocator>
847
848template<class AD, class Allocator>
850
851/**
852 * A formula can occur in a term, e.g., `(x = 2) + (y = 2) + (z = 2) >= 2`
853 * In that case, the entailment of the formula is mapped onto a sublattice of `U` supporting initialization from `0` and `1`.
854 * A term can occur in a formula, as it is usually done.
855 * Therefore, a formula is both a formula and a term.
856 *
857 * A logical formula is turned into a term by mapping their satisfiability to and from a sublattice of `U` representing Boolean values:
858 * - Consists of four distinct values \f$\{[\![x = 0]\!]_U \sqcap [\![x = 1]\!]_U, [\![x = 0]\!]_U, [\![x = 1]\!]_U, \top_U \}\f$.
859 * - 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).
860*/
861template <class AD, class Allocator>
862class Formula {
863public:
864 using A = AD;
865 using allocator_type = Allocator;
867 using U = typename A::local_universe;
869 using this_ptr = battery::unique_ptr<this_type, allocator_type>;
870
883
884 static constexpr size_t IPVarLit = 0;
885 static constexpr size_t INVarLit = IPVarLit + 1;
886 static constexpr size_t ITrue = INVarLit + 1;
887 static constexpr size_t IFalse = ITrue + 1;
888 static constexpr size_t ILeq = IFalse + 1;
889 static constexpr size_t IGt = ILeq + 1;
890 static constexpr size_t IEq = IGt + 1;
891 static constexpr size_t INeq = IEq + 1;
892 static constexpr size_t IConj = INeq + 1;
893 static constexpr size_t IDisj = IConj + 1;
894 static constexpr size_t IBicond = IDisj + 1;
895 static constexpr size_t IImply = IBicond + 1;
896 static constexpr size_t IXor = IImply + 1;
897 static constexpr size_t IAE = IXor + 1;
898
899 template <class A2, class Alloc2>
900 friend class Formula;
901
902private:
903 using VFormula = battery::variant<
904 PVarLit,
905 NVarLit,
906 True<A>,
907 False<A>,
908 Leq,
909 Gt,
910 Eq,
911 Neq,
912 Conj,
913 Disj,
914 Bicond,
915 Imply,
916 Xor,
917 AE
918 >;
919
920 VFormula formula;
921
922 template <size_t I, class FormulaType, class A2, class Alloc2>
923 CUDA static VFormula create_one(const Formula<A2, Alloc2>& other, const allocator_type& allocator) {
924 return VFormula::template create<I>(FormulaType(battery::get<I>(other.formula), allocator));
925 }
926
927 template <class A2, class Alloc2>
928 CUDA NI static VFormula create(const Formula<A2, Alloc2>& other, const allocator_type& allocator) {
929 switch(other.formula.index()) {
930 case IPVarLit: return create_one<IPVarLit, PVarLit>(other, allocator);
931 case INVarLit: return create_one<INVarLit, NVarLit>(other, allocator);
932 case ITrue: return create_one<ITrue, True<A>>(other, allocator);
933 case IFalse: return create_one<IFalse, False<A>>(other, allocator);
934 case ILeq: return create_one<ILeq, Leq>(other, allocator);
935 case IGt: return create_one<IGt, Gt>(other, allocator);
936 case IEq: return create_one<IEq, Eq>(other, allocator);
937 case INeq: return create_one<INeq, Neq>(other, allocator);
938 case IConj: return create_one<IConj, Conj>(other, allocator);
939 case IDisj: return create_one<IDisj, Disj>(other, allocator);
940 case IBicond: return create_one<IBicond, Bicond>(other, allocator);
941 case IImply: return create_one<IImply, Imply>(other, allocator);
942 case IXor: return create_one<IXor, Xor>(other, allocator);
943 case IAE: return create_one<IAE, AE>(other, allocator);
944 default:
945 printf("BUG: formula not handled.\n");
946 assert(false);
947 return VFormula::template create<IFalse>(False<A>());
948 }
949 }
950
951 CUDA Formula(VFormula&& formula): formula(std::move(formula)) {}
952
953 template <class F>
954 CUDA NI auto forward(F&& f) const {
955 switch(formula.index()) {
956 case IPVarLit: return f(battery::get<IPVarLit>(formula));
957 case INVarLit: return f(battery::get<INVarLit>(formula));
958 case ITrue: return f(battery::get<ITrue>(formula));
959 case IFalse: return f(battery::get<IFalse>(formula));
960 case ILeq: return f(battery::get<ILeq>(formula));
961 case IGt: return f(battery::get<IGt>(formula));
962 case IEq: return f(battery::get<IEq>(formula));
963 case INeq: return f(battery::get<INeq>(formula));
964 case IConj: return f(battery::get<IConj>(formula));
965 case IDisj: return f(battery::get<IDisj>(formula));
966 case IBicond: return f(battery::get<IBicond>(formula));
967 case IImply: return f(battery::get<IImply>(formula));
968 case IXor: return f(battery::get<IXor>(formula));
969 case IAE: return f(battery::get<IAE>(formula));
970 default:
971 printf("BUG: formula not handled.\n");
972 assert(false);
973 return f(False<A>());
974 }
975 }
976
977 template <class F>
978 CUDA NI auto forward(F&& f) {
979 switch(formula.index()) {
980 case IPVarLit: return f(battery::get<IPVarLit>(formula));
981 case INVarLit: return f(battery::get<INVarLit>(formula));
982 case ITrue: return f(battery::get<ITrue>(formula));
983 case IFalse: return f(battery::get<IFalse>(formula));
984 case ILeq: return f(battery::get<ILeq>(formula));
985 case IGt: return f(battery::get<IGt>(formula));
986 case IEq: return f(battery::get<IEq>(formula));
987 case INeq: return f(battery::get<INeq>(formula));
988 case IConj: return f(battery::get<IConj>(formula));
989 case IDisj: return f(battery::get<IDisj>(formula));
990 case IBicond: return f(battery::get<IBicond>(formula));
991 case IImply: return f(battery::get<IImply>(formula));
992 case IXor: return f(battery::get<IXor>(formula));
993 case IAE: return f(battery::get<IAE>(formula));
994 default:
995 printf("BUG: formula not handled.\n");
996 assert(false);
997 False<A> false_{};
998 return f(false_);
999 }
1000 }
1001
1002public:
1003 Formula() = default;
1004 Formula(this_type&&) = default;
1006
1007 template <class A2, class Alloc2>
1008 CUDA Formula(const Formula<A2, Alloc2>& other, const Allocator& allocator = Allocator())
1009 : formula(create(other, allocator))
1010 {}
1011
1012 CUDA bool is(size_t kind) const {
1013 return formula.index() == kind;
1014 }
1015
1016 CUDA size_t kind() const {
1017 return formula.index();
1018 }
1019
1020 template <size_t I, class SubFormula>
1021 CUDA static this_type make(SubFormula&& sub_formula) {
1022 return Formula(VFormula::template create<I>(std::move(sub_formula)));
1023 }
1024
1025 CUDA static this_type make_pvarlit(const AVar& avar) {
1026 return make<IPVarLit>(PVarLit(avar));
1027 }
1028
1029 CUDA static this_type make_nvarlit(const AVar& avar) {
1030 return make<INVarLit>(NVarLit(avar));
1031 }
1032
1033 CUDA static this_type make_true() {
1034 return make<ITrue>(True<A>{});
1035 }
1036
1037 CUDA static this_type make_false() {
1038 return make<IFalse>(False<A>{});
1039 }
1040
1041 CUDA static this_type make_leq(term_type&& left, term_type&& right) {
1042 return make<ILeq>(Leq(std::move(left), std::move(right)));
1043 }
1044
1045 CUDA static this_type make_gt(term_type&& left, term_type&& right) {
1046 return make<IGt>(Gt(std::move(left), std::move(right)));
1047 }
1048
1049 CUDA static this_type make_eq(term_type&& left, term_type&& right) {
1050 return make<IEq>(Eq(std::move(left), std::move(right)));
1051 }
1052
1053 CUDA static this_type make_neq(term_type&& left, term_type&& right) {
1054 return make<INeq>(Neq(std::move(left), std::move(right)));
1055 }
1056
1057 CUDA static this_type make_conj(this_ptr&& left, this_ptr&& right) {
1058 return make<IConj>(Conj(std::move(left), std::move(right)));
1059 }
1060
1061 CUDA static this_type make_disj(this_ptr&& left, this_ptr&& right) {
1062 return make<IDisj>(Disj(std::move(left), std::move(right)));
1063 }
1064
1065 CUDA static this_type make_bicond(this_ptr&& left, this_ptr&& right) {
1066 return make<IBicond>(Bicond(std::move(left), std::move(right)));
1067 }
1068
1069 CUDA static this_type make_imply(this_ptr&& left, this_ptr&& right) {
1070 return make<IImply>(Imply(std::move(left), std::move(right)));
1071 }
1072
1073 CUDA static this_type make_xor(this_ptr&& left, this_ptr&& right) {
1074 return make<IXor>(Xor(std::move(left), std::move(right)));
1075 }
1076
1077 using tell_type = typename A::template tell_type<allocator_type>;
1078 using ask_type = typename A::template ask_type<allocator_type>;
1079
1081 tell_type&& tellv, tell_type&& not_tellv,
1082 ask_type&& askv, ask_type&& not_askv)
1083 {
1084 return make<IAE>(AE(std::move(tellv), std::move(not_tellv), std::move(askv), std::move(not_askv)));
1085 }
1086
1087 /** Call `deduce` iff \f$ u \leq [\![x = 1]\!]_U \f$ and `contradeduce` iff \f$ u \leq [\![x = 0]\!] \f$. */
1088 CUDA bool embed(A& a, const U& u) const {
1089 if(u <= U::eq_one()) { return deduce(a); }
1090 else if(u <= U::eq_zero()) { return contradeduce(a); }
1091 return false;
1092 }
1093
1094 /** Maps the truth value of \f$ \varphi \f$ to the Boolean sublattice of `U` (see above). */
1095 CUDA void project(const A& a, U& r) const {
1096 if(a.is_bot()) { r.meet_bot(); }
1097 if(ask(a)) { r.meet(U::eq_one()); }
1098 if(nask(a)) { r.meet(U::eq_zero()); }
1099 r.meet(fjoin(U::eq_zero(), U::eq_one()));
1100 }
1101
1102 CUDA void print(const A& a) const {
1103 forward([&](const auto& t) { t.print(a); });
1104 }
1105
1106 template <class Env, class Allocator2 = typename Env::allocator_type>
1107 CUDA TFormula<Allocator2> deinterpret(const A& a, const Env& env, AType apc, Allocator2 allocator = Allocator2()) const {
1108 return forward([&](const auto& t) { return t.deinterpret(a, env, apc, allocator); });
1109 }
1110
1111 /** 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$.
1112 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$. */
1113 CUDA local::B ask(const A& a) const {
1114 return forward([&](const auto& t) { return t.ask(a); });
1115 }
1116
1117 /** Similar to `ask` but for \f$ \lnot{\varphi} \f$. */
1118 CUDA local::B nask(const A& a) const {
1119 return forward([&](const auto& t) { return t.nask(a); });
1120 }
1121
1122 /** Refine the formula by supposing it must be true. */
1123 CUDA bool deduce(A& a) const {
1124 return forward([&](const auto& t) { return t.deduce(a); });
1125 }
1126
1127 /** Refine the negation of the formula, hence we suppose the original formula needs to be false. */
1128 CUDA bool contradeduce(A& a) const {
1129 return forward([&](const auto& t) { return t.contradeduce(a); });
1130 }
1131
1132 CUDA size_t length() const {
1133 return forward([](const auto& t) { return t.length(); });
1134 }
1135};
1136
1137} // namespace pc
1138} // namespace lala
1139
1140#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 terms.hpp:16
CUDA local::B ask(const A &a) const
Definition formula.hpp:1113
Formula(this_type &&)=default
static constexpr size_t IGt
Definition formula.hpp:889
static CUDA this_type make_true()
Definition formula.hpp:1033
Implication< A, allocator_type > Imply
Definition formula.hpp:880
Disjunction< A, allocator_type > Disj
Definition formula.hpp:878
ExclusiveDisjunction< A, allocator_type > Xor
Definition formula.hpp:881
typename A::template tell_type< allocator_type > tell_type
Definition formula.hpp:1077
static constexpr size_t IFalse
Definition formula.hpp:887
static constexpr size_t INVarLit
Definition formula.hpp:885
static constexpr size_t IDisj
Definition formula.hpp:893
static constexpr size_t IAE
Definition formula.hpp:897
static constexpr size_t IXor
Definition formula.hpp:896
static CUDA this_type make_imply(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1069
friend class Formula
Definition formula.hpp:900
VariableLiteral< A, true > NVarLit
Definition formula.hpp:872
this_type & operator=(this_type &&)=default
static constexpr size_t IPVarLit
Definition formula.hpp:884
static constexpr size_t INeq
Definition formula.hpp:891
static CUDA this_type make_nvarlit(const AVar &avar)
Definition formula.hpp:1029
static CUDA this_type make_false()
Definition formula.hpp:1037
CUDA bool is(size_t kind) const
Definition formula.hpp:1012
static CUDA this_type make_leq(term_type &&left, term_type &&right)
Definition formula.hpp:1041
static CUDA this_type make_xor(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1073
static constexpr size_t ILeq
Definition formula.hpp:888
static CUDA this_type make_neq(term_type &&left, term_type &&right)
Definition formula.hpp:1053
InequalityLEQ< A, allocator_type > Leq
Definition formula.hpp:873
static CUDA this_type make_eq(term_type &&left, term_type &&right)
Definition formula.hpp:1049
Allocator allocator_type
Definition formula.hpp:865
battery::unique_ptr< this_type, allocator_type > this_ptr
Definition formula.hpp:869
InequalityGT< A, allocator_type > Gt
Definition formula.hpp:874
CUDA size_t kind() const
Definition formula.hpp:1016
Equality< A, allocator_type > Eq
Definition formula.hpp:875
CUDA void print(const A &a) const
Definition formula.hpp:1102
CUDA bool embed(A &a, const U &u) const
Definition formula.hpp:1088
static CUDA this_type make_abstract_element(tell_type &&tellv, tell_type &&not_tellv, ask_type &&askv, ask_type &&not_askv)
Definition formula.hpp:1080
typename A::template ask_type< allocator_type > ask_type
Definition formula.hpp:1078
CUDA local::B nask(const A &a) const
Definition formula.hpp:1118
CUDA Formula(const Formula< A2, Alloc2 > &other, const Allocator &allocator=Allocator())
Definition formula.hpp:1008
Conjunction< A, allocator_type > Conj
Definition formula.hpp:877
static constexpr size_t IImply
Definition formula.hpp:895
CUDA bool contradeduce(A &a) const
Definition formula.hpp:1128
static CUDA this_type make(SubFormula &&sub_formula)
Definition formula.hpp:1021
static constexpr size_t ITrue
Definition formula.hpp:886
VariableLiteral< A, false > PVarLit
Definition formula.hpp:871
AD A
Definition formula.hpp:864
AbstractElement< A, allocator_type > AE
Definition formula.hpp:882
static CUDA this_type make_conj(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1057
CUDA bool deduce(A &a) const
Definition formula.hpp:1123
CUDA TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition formula.hpp:1107
static CUDA this_type make_pvarlit(const AVar &avar)
Definition formula.hpp:1025
static constexpr size_t IEq
Definition formula.hpp:890
static CUDA this_type make_disj(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1061
static constexpr size_t IBicond
Definition formula.hpp:894
Biconditional< A, allocator_type > Bicond
Definition formula.hpp:879
static CUDA this_type make_gt(term_type &&left, term_type &&right)
Definition formula.hpp:1045
CUDA void project(const A &a, U &r) const
Definition formula.hpp:1095
static CUDA this_type make_bicond(this_ptr &&left, this_ptr &&right)
Definition formula.hpp:1065
typename A::local_universe U
Definition formula.hpp:867
Disequality< A, allocator_type > Neq
Definition formula.hpp:876
static constexpr size_t IConj
Definition formula.hpp:892
CUDA size_t length() const
Definition formula.hpp:1132
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:816
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:820
CUDA Inequality(sub_type &&left, sub_type &&right)
Definition formula.hpp:747
CUDA local::B nask(const A &a) const
Definition formula.hpp:812
CUDA NI void print(const A &a) const
Definition formula.hpp:824
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:836
CUDA local::B ask(const A &a) const
Definition formula.hpp:808
CUDA size_t length() const
Definition formula.hpp:842
CUDA TFormula< Allocator2 > deinterpret(const A &a, const Env &env, AType apc, Allocator2 allocator=Allocator2()) const
Definition terms.hpp:724
CUDA void print(const A &a) const
Definition terms.hpp:719
CUDA bool embed(A &a, const U &u) const
Definition terms.hpp:711
CUDA void project(const A &a, U &r) const
Definition terms.hpp:715
CUDA bool is(size_t kind) const
Definition terms.hpp:638
CUDA size_t length() const
Definition terms.hpp:728
static constexpr size_t IConstant
Definition terms.hpp:526
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