Lattice Land Core Library
Loading...
Searching...
No Matches
nbitset.hpp
Go to the documentation of this file.
1// Copyright 2024 Pierre Talbot
2
3#ifndef LALA_CORE_NBITSET_HPP
4#define LALA_CORE_NBITSET_HPP
5
6#include "primitive_upset.hpp"
7#include "battery/bitset.hpp"
8
9namespace lala {
10
11/** This class represents a set of integer values with a fixed-size bitset.
12 * In order to have well-defined arithmetic operations preserving bottom and top elements, the first and last bits (written L and R below) of the bitset are reserved.
13 * The meaning of L is to include all negative integers and the meaning of R is to include all integers greater than the size of the bitset.
14 * Given a bitset \f$ Lb_0b_1...b_nR \f$ of size n + 3, the concretization function is given as follows:
15 * \f$ \gamma(Lb_0b_1...b_nR) = \{ i \in \mathbb{Z} \mid 0 \leq i \leq n \land b_i = 1 \} \cup \{ i \in \mathbb{Z} \;|\; i < 0 \land L = 1 \} \cup \{ i \in \mathbb{Z} \;|\; i > n \land R = 1 \} \f$
16 */
17template <size_t N, class Mem, class T = unsigned long long>
19{
20public:
21 using memory_type = Mem;
22 using bitset_type = battery::bitset<N, Mem, T>;
24 template <class M> using this_type2 = NBitset<N, M, T>;
26
27 using LB = local::ZInc;
28 using UB = local::ZDec;
29 using value_type = typename LB::value_type;
30
31 template <size_t N2, class Mem2, class T2>
32 friend class NBitset;
33
34 constexpr static const bool is_abstract_universe = true;
35 constexpr static const bool sequential = Mem::sequential;
36 constexpr static const bool is_totally_ordered = false;
37 constexpr static const bool preserve_bot = true;
38 constexpr static const bool preserve_top = true;
39 constexpr static const bool preserve_join = true;
40 constexpr static const bool preserve_meet = true;
41 constexpr static const bool injective_concretization = true;
42 constexpr static const bool preserve_concrete_covers = false;
43 constexpr static const bool complemented = true;
44 constexpr static const char* name = "NBitset";
45
46private:
47 bitset_type bits;
48
49 struct top_constructor_tag {};
50 CUDA constexpr NBitset(top_constructor_tag) {}
51
52public:
53 /** Initialize to bottom (all bits at `1`). */
54 CUDA constexpr NBitset() {
55 bits.set();
56 }
57
58 CUDA constexpr static this_type from_set(const battery::vector<int>& values) {
59 this_type b(top());
60 for(int i = 0; i < values.size(); ++i) {
61 b.bits.set(battery::min(static_cast<int>(N)-1, battery::max(values[i]+1,0)), true);
62 }
63 return b;
64 }
65
66 CUDA constexpr NBitset(const this_type& other): NBitset(other.bits) {}
67 constexpr NBitset(this_type&&) = default;
68
69 /** Given a value \f$ x \in U \f$ where \f$ U \f$ is the universe of discourse, we initialize a singleton bitset \f$ 0_0..1_{x+1}...0_n \f$. */
70 CUDA constexpr NBitset(value_type x) {
71 bits.set(battery::min(static_cast<int>(N)-1, battery::max(0, x+1)));
72 }
73
74 CUDA constexpr NBitset(value_type lb, value_type ub): bits(
75 battery::min(static_cast<int>(N)-1, battery::max(lb+1,0)),
76 battery::min(static_cast<int>(N)-1, battery::max(ub+1, 0)))
77 {}
78
79 template<class M>
80 CUDA constexpr NBitset(const this_type2<M>& other): bits(other.bits) {}
81
82 template<class M>
83 CUDA constexpr NBitset(this_type2<M>&& other): bits(std::move(other.bits)) {}
84
85 template<class M>
86 CUDA constexpr NBitset(const battery::bitset<N, M, T>& bits): bits(bits) {}
87
88 /** The assignment operator can only be used in a sequential context.
89 * It is monotone but not extensive. */
90 template <class M>
91 CUDA constexpr this_type& operator=(const this_type2<M>& other) {
92 bits = other.bits;
93 return *this;
94 }
95
96 CUDA constexpr this_type& operator=(const this_type& other) {
97 bits = other.bits;
98 return *this;
99 }
100
101 /** Pre-interpreted formula `x == 0`. */
102 CUDA constexpr static local_type eq_zero() { return local_type(0); }
103 /** Pre-interpreted formula `x == 1`. */
104 CUDA constexpr static local_type eq_one() { return local_type(1); }
105
106 CUDA constexpr static local_type bot() { return NBitset(); }
107 CUDA constexpr static local_type top() { return NBitset(top_constructor_tag{}); }
108 CUDA constexpr local::BInc is_top() const { return bits.none(); }
109 CUDA constexpr local::BDec is_bot() const { return bits.all(); }
110 CUDA constexpr const bitset_type& value() const { return bits; }
111
112private:
113 template<bool diagnose, class F, class Env, class M>
114 CUDA NI static bool interpret_existential(const F& f, const Env& env, this_type2<M>& k, IDiagnostics& diagnostics) {
115 const auto& sort = battery::get<1>(f.exists());
116 if(sort.is_int()) {
117 return true;
118 }
119 else if(sort.is_bool()) {
120 k.tell(local_type(0,1));
121 return true;
122 }
123 else {
124 const auto& vname = battery::get<0>(f.exists());
125 RETURN_INTERPRETATION_ERROR(("NBitset only supports variables of type `Int` or `Bool`, but `" + vname + "` has another sort."));
126 }
127 }
128
129 template<bool diagnose, bool negated, class F, class M>
130 CUDA NI static bool interpret_tell_set(const F& f, const F& k, this_type2<M>& tell, IDiagnostics& diagnostics) {
131 using sort_type = Sort<typename F::allocator_type>;
132 thrust::optional<sort_type> sort = k.sort();
133 if(sort.has_value() &&
134 (sort.value() == sort_type(sort_type::Set, sort_type(sort_type::Int))
135 || sort.value() == sort_type(sort_type::Set, sort_type(sort_type::Bool))))
136 {
137 const auto& set = k.s();
138 local_type meet_s(top_constructor_tag{});
139 bool over_appx = false;
140 for(int i = 0; i < set.size(); ++i) {
141 int l = battery::get<0>(set[i]).to_z();
142 int u = battery::get<1>(set[i]).to_z();
143 meet_s.dtell(local_type(l, u));
144 if(l < 0 || u >= meet_s.bits.size() - 2) {
145 over_appx = true;
146 }
147 }
148 if constexpr(negated) {
149 meet_s = meet_s.complement();
150 // In any case it must be set to true: if no element is below zero, then some elements in the negation are; and if some elements are below zero it's not all of them.
151 meet_s.bits.set(0, true);
152 meet_s.bits.set(meet_s.bits.size()-1, true);
153 }
154 tell.tell(meet_s);
155 if(over_appx) {
156 RETURN_INTERPRETATION_WARNING("Constraint `x in S` is over-approximated because some elements of `S` fall outside the bitset.");
157 }
158 return true;
159 }
160 else {
161 RETURN_INTERPRETATION_ERROR("NBitset only supports membership (`x in S`) where `S` is a set of integers.");
162 }
163 }
164
165 template<bool diagnose, class F, class M>
166 CUDA NI static bool interpret_tell_x_op_k(const F& f, logic_int k, Sig sig, this_type2<M>& tell, IDiagnostics& diagnostics) {
167 if(sig == LT) {
168 return interpret_tell_x_op_k<diagnose>(f, k-1, LEQ, tell, diagnostics);
169 }
170 else if(sig == GT) {
171 return interpret_tell_x_op_k<diagnose>(f, k+1, GEQ, tell, diagnostics);
172 }
173 else if(k < 0 || k >= tell.bits.size() - 2) {
174 if((k == -1 && sig == LEQ) || (k == tell.bits.size() - 2 && sig == GEQ)) {
175 // this is fine because x <= -1 and x >= n-2 can be represented exactly.
176 }
177 else {
178 INTERPRETATION_WARNING("Constraint `x <op> k` is over-approximated because `k` is not representable in the bitset. Note that for a bitset of size `n`, the only values representable exactly are in the interval `[0, n-3]` because two bits are used to represent all negative values and all values exceeding the size of the bitset.");
179 // If it is NEQ, we can't give a better approximation than bot.
180 if(sig == NEQ) {
181 return true;
182 }
183 }
184 }
185 switch(sig) {
186 case EQ: tell.tell(local_type(k, k)); break;
187 case NEQ: tell.tell(local_type(k, k).complement()); break;
188 case LEQ: tell.tell(local_type(-1, k)); break;
189 case GEQ: tell.tell(local_type(k, tell.bits.size())); break;
190 default: RETURN_INTERPRETATION_ERROR("This symbol is not supported.");
191 }
192 return true;
193 }
194
195 template<bool diagnose, bool negated, class F, class Env, class M>
196 CUDA NI static bool interpret_binary(const F& f, const Env& env, this_type2<M>& tell, IDiagnostics& diagnostics) {
197 int idx_constant = f.seq(0).is_constant() ? 0 : (f.seq(1).is_constant() ? 1 : 100);
198 int idx_variable = f.seq(0).is_variable() ? 0 : (f.seq(1).is_variable() ? 1 : 100);
199 if(idx_constant + idx_variable != 1) {
200 RETURN_INTERPRETATION_ERROR("Only binary formulas of the form `t1 <sig> t2` where if t1 is a constant and t2 is a variable (or conversely) are supported.");
201 }
202 const auto& k = f.seq(idx_constant);
203 if(f.sig() == IN) {
204 if(idx_constant == 0) { // `k in x` is equivalent to `{k} \subseteq x`.
205 RETURN_INTERPRETATION_ERROR("The formula `k in x` is not supported in this abstract universe (`x in k` is supported).");
206 }
207 else {
208 return interpret_tell_set<diagnose, negated>(f, k, tell, diagnostics);
209 }
210 }
211 else if(is_arithmetic_comparison(f)) {
212 Sig sig = idx_constant == 0 ? converse_comparison(f.sig()) : f.sig();
213 sig = negated ? negate_arithmetic_comparison(sig) : sig;
214 if(f.seq(idx_constant).is(F::Z) || f.seq(idx_constant).is(F::B)) {
215 return interpret_tell_x_op_k<diagnose>(f, k.to_z(), sig, tell, diagnostics);
216 }
217 else {
218 RETURN_INTERPRETATION_ERROR("Only integer and Boolean constants are supported in NBitset.");
219 }
220 }
221 else {
222 RETURN_INTERPRETATION_ERROR("This symbol is not supported.");
223 }
224 }
225
226public:
227 /** Support the following language where all constants `k` are integer or Boolean values:
228 * * `var x:Z`
229 * * `var x:B`
230 * * `x <op> k` where `k` is an integer constant and `<op>` in {==, !=, <, <=, >, >=}.
231 * * `x in S` where `S` is a set of integers.
232 * It can be over-approximated if the element `k` falls out of the bitset. */
233 template<bool diagnose = false, class F, class Env, class M>
234 CUDA NI static bool interpret_tell(const F& f, const Env& env, this_type2<M>& tell, IDiagnostics& diagnostics) {
235 using sort_type = Sort<typename F::allocator_type>;
236 if(f.is(F::E)) {
237 return interpret_existential<diagnose>(f, env, tell, diagnostics);
238 }
239 else if(f.is_unary() && f.sig() == NOT && f.seq(0).is_binary()) {
240 return interpret_binary<diagnose, true>(f.seq(0), env, tell, diagnostics);
241 }
242 else if(f.is_binary()) {
243 return interpret_binary<diagnose, false>(f, env, tell, diagnostics);
244 }
245 else {
246 RETURN_INTERPRETATION_ERROR("Only binary constraints are supported.");
247 }
248 }
249
250 /** Support the same language than the "tell language" without existential. */
251 template<bool diagnose = false, class F, class Env, class M>
252 CUDA NI static bool interpret_ask(const F& f, const Env& env, this_type2<M>& k, IDiagnostics& diagnostics) {
254 auto nf = negate(f);
255 if(!nf.has_value()) {
256 RETURN_INTERPRETATION_ERROR("Could not negate the formula in order to interpret_ask it.");
257 }
258 if(f.is(F::E)) {
259 RETURN_INTERPRETATION_ERROR("Existential quantification is not supported in ask interpretation.");
260 }
261 if(interpret_tell<diagnose>(nf.value(), env, b, diagnostics)) {
262 k.tell(b.complement());
263 return true;
264 }
265 else {
266 return false;
267 }
268 }
269
270 template<IKind kind, bool diagnose = false, class F, class Env, class M>
271 CUDA NI static bool interpret(const F& f, const Env& env, this_type2<M>& k, IDiagnostics& diagnostics) {
272 if constexpr(kind == IKind::ASK) {
273 return interpret_ask<diagnose>(f, env, k, diagnostics);
274 }
275 else {
276 return interpret_tell<diagnose>(f, env, k, diagnostics);
277 }
278 }
279
280 CUDA constexpr LB lb() const {
281 value_type l = bits.countr_zero();
282 return l == 0 ? LB::bot() :
283 (l == bits.size() ? LB::top() : LB::geq_k(l-1));
284 }
285
286 CUDA constexpr UB ub() const {
287 value_type r = bits.countl_zero();
288 return r == 0 ? UB::bot() :
289 (r == bits.size() ? UB::top() : UB::leq_k(bits.size() - r - 2));
290 }
291
292 CUDA constexpr local_type complement() const {
293 local_type c(bits);
294 c.bits.flip();
295 return c;
296 }
297
298 CUDA constexpr this_type& tell_top() {
299 bits.reset();
300 return *this;
301 }
302
303 template<class A, class M>
304 CUDA constexpr this_type& tell_lb(const A& lb, BInc<M>& has_changed) {
305 return tell(local_type(lb.value(), bits.size()), has_changed);
306 }
307
308 template<class A, class M>
309 CUDA constexpr this_type& tell_ub(const A& ub, BInc<M>& has_changed) {
310 return tell(local_type(-1, ub.value()), has_changed);
311 }
312
313 template<class M1, class M2>
314 CUDA constexpr this_type& tell(const this_type2<M1>& other, BInc<M2>& has_changed) {
315 if(!bits.is_subset_of(other.bits)) {
316 bits &= other.bits;
317 has_changed.tell_top();
318 }
319 return *this;
320 }
321
322 template<class M>
323 CUDA constexpr this_type& tell(const this_type2<M>& other) {
324 if(!bits.is_subset_of(other.bits)) {
325 bits &= other.bits;
326 }
327 return *this;
328 }
329
330 CUDA constexpr this_type& dtell_bot() {
331 bits.set();
332 return *this;
333 }
334
335 template<class M1, class M2>
336 CUDA constexpr this_type& dtell(const this_type2<M1>& other, BInc<M2>& has_changed) {
337 if(!other.bits.is_subset_of(bits)) {
338 bits |= other.bits;
339 has_changed.tell_top();
340 }
341 return *this;
342 }
343
344 template<class M>
345 CUDA constexpr this_type& dtell(const this_type2<M>& other) {
346 if(!other.bits.is_subset_of(bits)) {
347 bits |= other.bits;
348 }
349 return *this;
350 }
351
352 template <class M>
353 CUDA constexpr bool extract(this_type2<M>& ua) const {
354 ua.bits = bits;
355 return true;
356 }
357
358 template<class Env>
361 if(is_bot()) {
362 return F::make_true();
363 }
364 else if(is_top()) {
365 return F::make_false();
366 }
367 else {
368 typename F::Sequence seq{env.get_allocator()};
369 if(bits.test(0)) {
370 seq.push_back(F::make_binary(F::make_avar(x), LEQ, F::make_z(-1), UNTYPED, env.get_allocator()));
371 }
372 if(bits.test(bits.size()-1)) {
373 seq.push_back(F::make_binary(F::make_avar(x), GEQ, F::make_z(bits.size()-2), UNTYPED, env.get_allocator()));
374 }
375 logic_set<F> logical_set(env.get_allocator());
376 for(int i = 1; i < bits.size()-1; ++i) {
377 if(bits.test(i)) {
378 int l = i - 1;
379 for(i = i + 1; i < bits.size()-1 && bits.test(i); ++i) {}
380 int u = i - 2;
381 logical_set.push_back(battery::make_tuple(F::make_z(l), F::make_z(u)));
382 }
383 }
384 if(logical_set.size() > 0) {
385 seq.push_back(F::make_binary(F::make_avar(x), IN, F::make_set(std::move(logical_set)), UNTYPED, env.get_allocator()));
386 }
387 if(seq.size() == 1) {
388 return std::move(seq[0]);
389 }
390 else {
391 return F::make_nary(OR, std::move(seq));
392 }
393 }
394 }
395
396 /** Deinterpret the current value to a logical constant.
397 * The lower bound is deinterpreted, and it is up to the user to check that interval is a singleton.
398 */
399 template<class F>
400 CUDA NI F deinterpret() const {
401 return lb().template deinterpret<F>();
402 }
403
404 CUDA NI void print() const {
405 printf("{");
406 bool comma_needed = false;
407 if(bits.test(0)) {
408 printf(".., -1");
409 comma_needed = true;
410 }
411 for(int i = 1; i < bits.size() - 1; ++i) {
412 if(bits.test(i)) {
413 if(comma_needed) { printf(", "); }
414 printf("%d", i-1);
415 comma_needed = true;
416 }
417 }
418 if(bits.test(bits.size()-1)) {
419 if(comma_needed) { printf(", "); }
420 printf("%d, ..", static_cast<int>(bits.size())-2);
421 }
422 printf("}");
423 }
424
425 CUDA NI constexpr static bool is_supported_fun(Sig sig) {
426 switch(sig) {
427 case ABS:
428 case NEG: return true;
429 default: return false;
430 }
431 }
432
433public:
434 template<class M>
435 CUDA constexpr static local_type neg(const this_type2<M>& x) {
436 if(x.bits.test(0)) {
437 return x.bits.count() == 1 ? x.complement() : local_type::bot();
438 }
439 else {
440 return x.bits.count() == 0 ? local_type::top() : local_type(-1);
441 }
442 }
443
444 template<class M>
445 CUDA constexpr static local_type abs(const this_type2<M>& x) {
446 return x.bits.test(0) ? local_type(0, x.bits.size()) : x;
447 }
448
449 template<Sig sig, class M>
450 CUDA constexpr static local_type fun(const this_type2<M>& x) {
451 static_assert(sig == NEG || sig == ABS, "Unsupported unary function.");
452 switch(sig) {
453 case NEG: return neg(x);
454 case ABS: return abs(x);
455 default:
456 assert(0); return x;
457 }
458 }
459
460 template <class M>
461 CUDA constexpr static local_type additive_inverse(const this_type2<M>& x) {
462 printf("%% additive_inverse is unsupported\n");
463 int* ptr = nullptr;
464 ptr[1] = 193;
465 return local_type::bot();
466 }
467
468 template<Sig sig, class M1, class M2>
469 CUDA constexpr static local_type fun(const this_type2<M1>& x, const this_type2<M2>& y) {
470 printf("%% binary functions %s are unsupported\n", string_of_sig(sig));
471 int* ptr = nullptr;
472 ptr[1] = 193;
473 return local_type::bot();
474 }
475
476 CUDA constexpr local_type width() const {
477 if(bits.test(0) || bits.test(bits.size() - 1)) { return bot(); }
478 else { return local_type(bits.count()); }
479 }
480
481 /** \return The median value of the bitset. */
482 CUDA constexpr local_type median() const {
483 if(is_top()) { return local_type::top(); }
484 int total = bits.count();
485 int current = 0;
486 for(int i = 0; i < bits.size(); ++i) {
487 if(bits.test(i)) {
488 ++current;
489 if(current == total/2) {
490 return local_type(i-1);
491 }
492 }
493 }
494 return local_type::top();
495 }
496};
497
498// Lattice operations
499
500template<size_t N, class M1, class M2, class T>
505
506template<size_t N, class M1, class M2, class T>
511
512template<size_t N, class M1, class M2, class T>
513CUDA constexpr bool operator<=(const NBitset<N, M1, T>& a, const NBitset<N, M2, T>& b)
514{
515 return b.value().is_subset_of(a.value());
516}
517
518template<size_t N, class M1, class M2, class T>
519CUDA constexpr bool operator<(const NBitset<N, M1, T>& a, const NBitset<N, M2, T>& b)
520{
521 return b.value().is_proper_subset_of(a.value());
522}
523
524template<size_t N, class M1, class M2, class T>
525CUDA constexpr bool operator>=(const NBitset<N, M1, T>& a, const NBitset<N, M2, T>& b)
526{
527 return b <= a;
528}
529
530template<size_t N, class M1, class M2, class T>
531CUDA constexpr bool operator>(const NBitset<N, M1, T>& a, const NBitset<N, M2, T>& b)
532{
533 return b < a;
534}
535
536template<size_t N, class M1, class M2, class T>
537CUDA constexpr bool operator==(const NBitset<N, M1, T>& a, const NBitset<N, M2, T>& b)
538{
539 return a.value() == b.value();
540}
541
542template<size_t N, class M1, class M2, class T>
543CUDA constexpr bool operator!=(const NBitset<N, M1, T>& a, const NBitset<N, M2, T>& b)
544{
545 return a.value() != b.value();
546}
547
548template<size_t N, class M, class T>
549std::ostream& operator<<(std::ostream &s, const NBitset<N, M, T> &a) {
550 s << "{";
551 bool comma_needed = false;
552 if(a.value().test(0)) {
553 s << ".., -1";
554 comma_needed = true;
555 }
556 for(int i = 1; i < a.value().size() - 1; ++i) {
557 if(a.value().test(i)) {
558 if(comma_needed) { s << ", "; }
559 s << (i-1);
560 comma_needed = true;
561 }
562 }
563 if(a.value().test(a.value().size()-1)) {
564 if(comma_needed) { s << ", "; }
565 s << a.value().size()-2 << ", ..";
566 }
567 s << "}";
568 return s;
569}
570
571} // end namespace lala
572
573#endif
Definition ast.hpp:38
Definition diagnostics.hpp:19
Definition nbitset.hpp:19
CUDA static constexpr local_type neg(const this_type2< M > &x)
Definition nbitset.hpp:435
CUDA static NI bool interpret(const F &f, const Env &env, this_type2< M > &k, IDiagnostics &diagnostics)
Definition nbitset.hpp:271
CUDA constexpr this_type & tell(const this_type2< M1 > &other, BInc< M2 > &has_changed)
Definition nbitset.hpp:314
static constexpr const bool complemented
Definition nbitset.hpp:43
static constexpr const char * name
Definition nbitset.hpp:44
CUDA constexpr this_type & tell_top()
Definition nbitset.hpp:298
battery::bitset< N, Mem, T > bitset_type
Definition nbitset.hpp:22
CUDA static NI bool interpret_tell(const F &f, const Env &env, this_type2< M > &tell, IDiagnostics &diagnostics)
Definition nbitset.hpp:234
friend class NBitset
Definition nbitset.hpp:32
static constexpr const bool preserve_join
Definition nbitset.hpp:39
static constexpr const bool is_abstract_universe
Definition nbitset.hpp:34
CUDA static constexpr local_type eq_zero()
Definition nbitset.hpp:102
CUDA constexpr this_type & tell_lb(const A &lb, BInc< M > &has_changed)
Definition nbitset.hpp:304
CUDA constexpr NBitset(value_type x)
Definition nbitset.hpp:70
static constexpr const bool preserve_concrete_covers
Definition nbitset.hpp:42
static constexpr const bool preserve_top
Definition nbitset.hpp:38
CUDA constexpr local::BDec is_bot() const
Definition nbitset.hpp:109
CUDA static constexpr local_type top()
Definition nbitset.hpp:107
CUDA constexpr local::BInc is_top() const
Definition nbitset.hpp:108
CUDA constexpr this_type & dtell(const this_type2< M > &other)
Definition nbitset.hpp:345
CUDA NI static constexpr bool is_supported_fun(Sig sig)
Definition nbitset.hpp:425
static constexpr const bool injective_concretization
Definition nbitset.hpp:41
CUDA constexpr this_type & dtell(const this_type2< M1 > &other, BInc< M2 > &has_changed)
Definition nbitset.hpp:336
CUDA constexpr NBitset(const battery::bitset< N, M, T > &bits)
Definition nbitset.hpp:86
CUDA constexpr LB lb() const
Definition nbitset.hpp:280
CUDA static constexpr local_type bot()
Definition nbitset.hpp:106
CUDA constexpr this_type & operator=(const this_type2< M > &other)
Definition nbitset.hpp:91
CUDA static constexpr local_type abs(const this_type2< M > &x)
Definition nbitset.hpp:445
constexpr NBitset(this_type &&)=default
CUDA constexpr bool extract(this_type2< M > &ua) const
Definition nbitset.hpp:353
static constexpr const bool is_totally_ordered
Definition nbitset.hpp:36
CUDA NI void print() const
Definition nbitset.hpp:404
CUDA NI F deinterpret() const
Definition nbitset.hpp:400
CUDA constexpr this_type & tell_ub(const A &ub, BInc< M > &has_changed)
Definition nbitset.hpp:309
CUDA constexpr NBitset(value_type lb, value_type ub)
Definition nbitset.hpp:74
CUDA constexpr NBitset(this_type2< M > &&other)
Definition nbitset.hpp:83
CUDA static constexpr local_type eq_one()
Definition nbitset.hpp:104
CUDA TFormula< typename Env::allocator_type > deinterpret(AVar x, const Env &env) const
Definition nbitset.hpp:359
CUDA constexpr this_type & dtell_bot()
Definition nbitset.hpp:330
CUDA static constexpr local_type additive_inverse(const this_type2< M > &x)
Definition nbitset.hpp:461
CUDA static constexpr local_type fun(const this_type2< M1 > &x, const this_type2< M2 > &y)
Definition nbitset.hpp:469
CUDA static NI bool interpret_ask(const F &f, const Env &env, this_type2< M > &k, IDiagnostics &diagnostics)
Definition nbitset.hpp:252
static constexpr const bool preserve_bot
Definition nbitset.hpp:37
static constexpr const bool preserve_meet
Definition nbitset.hpp:40
CUDA constexpr UB ub() const
Definition nbitset.hpp:286
Mem memory_type
Definition nbitset.hpp:21
this_type2< battery::local_memory > local_type
Definition nbitset.hpp:25
CUDA constexpr local_type median() const
Definition nbitset.hpp:482
CUDA static constexpr this_type from_set(const battery::vector< int > &values)
Definition nbitset.hpp:58
CUDA constexpr NBitset(const this_type &other)
Definition nbitset.hpp:66
typename LB::value_type value_type
Definition nbitset.hpp:29
CUDA constexpr local_type complement() const
Definition nbitset.hpp:292
CUDA constexpr local_type width() const
Definition nbitset.hpp:476
CUDA constexpr this_type & operator=(const this_type &other)
Definition nbitset.hpp:96
static constexpr const bool sequential
Definition nbitset.hpp:35
CUDA constexpr NBitset()
Definition nbitset.hpp:54
CUDA constexpr NBitset(const this_type2< M > &other)
Definition nbitset.hpp:80
CUDA static constexpr local_type fun(const this_type2< M > &x)
Definition nbitset.hpp:450
CUDA constexpr this_type & tell(const this_type2< M > &other)
Definition nbitset.hpp:323
CUDA constexpr const bitset_type & value() const
Definition nbitset.hpp:110
Definition primitive_upset.hpp:118
CUDA constexpr value_type value() const
Definition primitive_upset.hpp:219
static CUDA constexpr this_type geq_k(value_type k)
Definition primitive_upset.hpp:154
static CUDA constexpr local_type bot()
Definition primitive_upset.hpp:182
static CUDA constexpr this_type leq_k(value_type k)
Definition primitive_upset.hpp:165
typename pre_universe::value_type value_type
Definition primitive_upset.hpp:122
static CUDA constexpr local_type top()
Definition primitive_upset.hpp:185
CUDA constexpr this_type & tell_top()
Definition primitive_upset.hpp:233
Definition ast.hpp:234
#define INTERPRETATION_WARNING(MSG)
Definition diagnostics.hpp:150
#define RETURN_INTERPRETATION_WARNING(MSG)
Definition diagnostics.hpp:159
#define RETURN_INTERPRETATION_ERROR(MSG)
Definition diagnostics.hpp:155
Definition ast.hpp:210
::lala::ZDec< int, battery::local_memory > ZDec
Definition primitive_upset.hpp:82
::lala::ZInc< int, battery::local_memory > ZInc
Definition primitive_upset.hpp:81
Definition abstract_deps.hpp:14
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition cartesian_product.hpp:597
battery::vector< battery::tuple< F, F >, typename F::allocator_type > logic_set
Definition sort.hpp:127
CUDA NI Sig converse_comparison(Sig sig)
Definition algorithm.hpp:377
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:572
CUDA NI bool is_arithmetic_comparison(const F &f)
Definition algorithm.hpp:320
Sig
Definition ast.hpp:94
@ NEQ
Equality relations.
Definition ast.hpp:112
@ LEQ
Unary arithmetic function symbols.
Definition ast.hpp:113
@ NOT
Unary arithmetic function symbols.
Definition ast.hpp:114
@ OR
Unary arithmetic function symbols.
Definition ast.hpp:114
@ EQ
Unary arithmetic function symbols.
Definition ast.hpp:112
@ GEQ
Unary arithmetic function symbols.
Definition ast.hpp:113
@ IN
Set membership predicate.
Definition ast.hpp:108
@ GT
Arithmetic comparison predicates. When applied to set, it corresponds to the lexicographic ordering o...
Definition ast.hpp:113
@ LT
Unary arithmetic function symbols.
Definition ast.hpp:113
@ ABS
Unary arithmetic function symbols.
Definition ast.hpp:96
@ NEG
Unary arithmetic function symbols.
Definition ast.hpp:96
CUDA constexpr auto join(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:534
long long int logic_int
Definition sort.hpp:114
CUDA constexpr auto meet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:541
CUDA constexpr bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:554
CUDA NI const char * string_of_sig(Sig sig)
Definition ast.hpp:121
CUDA constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:566
CUDA NI thrust::optional< F > negate(const F &f)
Definition algorithm.hpp:266
CUDA Sig negate_arithmetic_comparison(Sig sig)
Definition algorithm.hpp:306
#define UNTYPED
Definition sort.hpp:21
Definition sort.hpp:26