3#ifndef LALA_CORE_NBITSET_HPP
4#define LALA_CORE_NBITSET_HPP
7#include "battery/bitset.hpp"
17template <
size_t N,
class Mem,
class T =
unsigned long long>
31 template <
size_t N2,
class Mem2,
class T2>
35 constexpr static const bool sequential = Mem::sequential;
45 constexpr static const char*
name =
"NBitset";
50 struct bot_constructor_tag {};
51 CUDA
constexpr NBitset(bot_constructor_tag) {}
61 for(
int i = 0; i < values.size(); ++i) {
62 b.bits.set(battery::min(
static_cast<int>(N)-1, battery::max(values[i]+1,0)),
true);
72 bits.set(battery::min(
static_cast<int>(N)-1, battery::max(0, x+1)));
87 CUDA
constexpr NBitset(
const battery::bitset<N, M, T>& bits): bits(bits) {}
114 template<
bool diagnose,
class F,
class Env,
class M>
116 const auto& sort = battery::get<1>(f.exists());
120 else if(sort.is_bool()) {
125 const auto& vname = battery::get<0>(f.exists());
130 template<
bool diagnose,
bool negated,
class F,
class M>
131 CUDA NI
static bool interpret_tell_set(
const F& f,
const F& k,
this_type2<M>& tell, IDiagnostics& diagnostics) {
132 using sort_type = Sort<typename F::allocator_type>;
133 std::optional<sort_type> sort = f.seq(1).sort();
134 if(sort.has_value() &&
135 (sort.value() == sort_type(sort_type::Set, sort_type(sort_type::Int))
136 || sort.value() == sort_type(sort_type::Set, sort_type(sort_type::Bool))))
138 const auto& set = f.seq(1).s();
140 bool over_appx =
false;
141 for(
int i = 0; i < set.size(); ++i) {
142 int l = battery::get<0>(set[i]).to_z();
143 int u = battery::get<1>(set[i]).to_z();
145 if(l < 0 || u >= join_s.bits.size() - 2) {
149 if constexpr(negated) {
150 join_s = join_s.complement();
152 join_s.bits.set(0,
true);
153 join_s.bits.set(join_s.bits.size()-1,
true);
166 template<
bool diagnose,
class F,
class M>
167 CUDA NI
static bool interpret_tell_x_op_k(
const F& f,
logic_int k,
Sig sig,
this_type2<M>& tell, IDiagnostics& diagnostics) {
169 return interpret_tell_x_op_k<diagnose>(f, k-1,
LEQ, tell, diagnostics);
172 return interpret_tell_x_op_k<diagnose>(f, k+1,
GEQ, tell, diagnostics);
174 else if(k < 0 || k >= tell.bits.size() - 2) {
175 if((k == -1 && sig ==
LEQ) || (k == tell.bits.size() - 2 && sig ==
GEQ)) {
179 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.");
196 template<
bool diagnose,
bool negated,
class F,
class Env,
class M>
197 CUDA NI
static bool interpret_binary(
const F& f,
const Env& env,
this_type2<M>& tell, IDiagnostics& diagnostics) {
199 return interpret_tell_set<diagnose, negated>(f, f.seq(1), tell, diagnostics);
201 else if(f.seq(1).is(F::Z) || f.seq(1).is(F::B)) {
202 return interpret_tell_x_op_k<diagnose>(f, f.seq(1).to_z(), f.sig(), tell, diagnostics);
216 template<
bool diagnose = false,
class F,
class Env,
class M>
220 return interpret_existential<diagnose>(f, env, tell, diagnostics);
222 else if(f.is_unary() && f.sig() ==
NOT && f.seq(0).is_binary()) {
223 return interpret_binary<diagnose, true>(f.seq(0), env, tell, diagnostics);
225 else if(f.is_binary() && f.seq(0).is_variable() && f.seq(1).is_constant()) {
226 return interpret_binary<diagnose, false>(f, env, tell, diagnostics);
229 RETURN_INTERPRETATION_ERROR(
"Only binary formulas of the form `x <sig> k` where if x is a variable and k is a constant are supported. We also supports existential quantifier and membership in a set of integers (x in S).");
234 template<
bool diagnose = false,
class F,
class Env,
class M>
238 if(!nf.has_value()) {
253 template<IKind kind,
bool diagnose = false,
class F,
class Env,
class M>
297 if(!other.bits.is_subset_of(bits)) {
320 if(!bits.is_subset_of(other.bits)) {
333 template<
class Env,
class Allocator =
typename Env::allocator_type>
337 return F::make_false();
340 return F::make_true();
343 typename F::Sequence seq{allocator};
345 seq.push_back(F::make_binary(F::make_avar(x),
LEQ, F::make_z(-1),
UNTYPED, allocator));
347 if(bits.test(bits.size()-1)) {
348 seq.push_back(F::make_binary(F::make_avar(x),
GEQ, F::make_z(bits.size()-2),
UNTYPED, allocator));
351 for(
int i = 1; i < bits.size()-1; ++i) {
354 for(i = i + 1; i < bits.size()-1 && bits.test(i); ++i) {}
356 logical_set.push_back(battery::make_tuple(F::make_z(l), F::make_z(u)));
359 if(logical_set.size() > 0) {
360 seq.push_back(F::make_binary(F::make_avar(x),
IN, F::make_set(std::move(logical_set)),
UNTYPED, allocator));
362 if(seq.size() == 1) {
363 return std::move(seq[0]);
366 return F::make_nary(
OR, std::move(seq));
381 bool comma_needed =
false;
386 for(
int i = 1; i < bits.size() - 1; ++i) {
388 if(comma_needed) { printf(
", "); }
393 if(bits.test(bits.size()-1)) {
394 if(comma_needed) { printf(
", "); }
395 printf(
"%d, ..",
static_cast<int>(bits.size())-2);
403 case NEG:
return false;
404 default:
return true;
412 if(x.bits.count() == 1) {
416 else if(x.bits.count() == 0) {
442 printf(
"%% additive_inverse is unsupported\n");
448 printf(
"%% binary functions %s are unsupported\n",
string_of_sig(fun));
454 if(bits.test(0) || bits.test(bits.size() - 1)) {
return top(); }
461 int total = bits.count();
463 for(
int i = 0; i < bits.size(); ++i) {
466 if(current == total/2 || total == 1) {
477template<
size_t N,
class M1,
class M2,
class T>
483template<
size_t N,
class M1,
class M2,
class T>
489template<
size_t N,
class M1,
class M2,
class T>
490CUDA
constexpr bool operator<=(
const NBitset<N, M1, T>& a,
const NBitset<N, M2, T>& b)
492 return a.value().is_subset_of(b.value());
495template<
size_t N,
class M1,
class M2,
class T>
498 return a.
value().is_proper_subset_of(b.
value());
501template<
size_t N,
class M1,
class M2,
class T>
502CUDA
constexpr bool operator>=(
const NBitset<N, M1, T>& a,
const NBitset<N, M2, T>& b)
507template<
size_t N,
class M1,
class M2,
class T>
513template<
size_t N,
class M1,
class M2,
class T>
519template<
size_t N,
class M1,
class M2,
class T>
520CUDA
constexpr bool operator!=(
const NBitset<N, M1, T>& a,
const NBitset<N, M2, T>& b)
522 return a.value() != b.value();
525template<
size_t N,
class M,
class T>
528 bool comma_needed =
false;
529 if(a.
value().test(0)) {
533 for(
int i = 1; i < a.
value().size() - 1; ++i) {
534 if(a.
value().test(i)) {
535 if(comma_needed) { s <<
", "; }
541 if(comma_needed) { s <<
", "; }
542 s << a.
value().size()-2 <<
", ..";
Definition arith_bound.hpp:118
static CUDA constexpr this_type leq_k(value_type k)
Definition arith_bound.hpp:166
CUDA constexpr value_type value() const
Definition arith_bound.hpp:209
static CUDA constexpr local_type bot()
Definition arith_bound.hpp:182
static CUDA constexpr this_type geq_k(value_type k)
Definition arith_bound.hpp:156
typename pre_universe::value_type value_type
Definition arith_bound.hpp:122
static CUDA constexpr local_type top()
Definition arith_bound.hpp:185
Definition diagnostics.hpp:19
Definition nbitset.hpp:19
CUDA static NI bool interpret(const F &f, const Env &env, this_type2< M > &k, IDiagnostics &diagnostics)
Definition nbitset.hpp:254
static constexpr const bool complemented
Definition nbitset.hpp:43
CUDA constexpr bool join_lb(const A &lb)
Definition nbitset.hpp:286
static constexpr const char * name
Definition nbitset.hpp:45
CUDA constexpr void join_top()
Definition nbitset.hpp:281
CUDA constexpr void project(Sig fun, const local_type &x, const local_type &y)
Definition nbitset.hpp:447
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:217
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 constexpr bool meet_lb(const A &lb)
Definition nbitset.hpp:309
CUDA static constexpr local_type eq_zero()
Definition nbitset.hpp:103
CUDA constexpr NBitset(value_type x)
Definition nbitset.hpp:71
static constexpr const bool preserve_concrete_covers
Definition nbitset.hpp:42
static constexpr const bool preserve_top
Definition nbitset.hpp:38
CUDA static constexpr local_type top()
Definition nbitset.hpp:108
static constexpr const bool injective_concretization
Definition nbitset.hpp:41
CUDA constexpr void meet_bot()
Definition nbitset.hpp:304
CUDA constexpr NBitset(const battery::bitset< N, M, T > &bits)
Definition nbitset.hpp:87
CUDA constexpr LB lb() const
Definition nbitset.hpp:263
CUDA static constexpr local_type bot()
Definition nbitset.hpp:107
CUDA constexpr local::B is_bot() const
Definition nbitset.hpp:110
CUDA constexpr void abs(const local_type &x)
Definition nbitset.hpp:424
CUDA constexpr void project(Sig fun, const local_type &x)
Definition nbitset.hpp:434
CUDA constexpr this_type & operator=(const this_type2< M > &other)
Definition nbitset.hpp:92
static constexpr const bool is_arithmetic
Definition nbitset.hpp:44
CUDA NI static constexpr bool is_trivial_fun(Sig sig)
Definition nbitset.hpp:400
CUDA constexpr bool join_ub(const A &ub)
Definition nbitset.hpp:291
CUDA constexpr bool join(const this_type2< M > &other)
Definition nbitset.hpp:296
constexpr NBitset(this_type &&)=default
CUDA constexpr bool extract(this_type2< M > &ua) const
Definition nbitset.hpp:328
static constexpr const bool is_totally_ordered
Definition nbitset.hpp:36
CUDA NI void print() const
Definition nbitset.hpp:379
CUDA NI F deinterpret() const
Definition nbitset.hpp:375
NBitset< N, M, T > this_type2
Definition nbitset.hpp:24
CUDA TFormula< Allocator > deinterpret(AVar x, const Env &env, const Allocator &allocator=Allocator()) const
Definition nbitset.hpp:334
CUDA constexpr NBitset(value_type lb, value_type ub)
Definition nbitset.hpp:75
CUDA constexpr bool meet_ub(const A &ub)
Definition nbitset.hpp:314
CUDA constexpr NBitset(this_type2< M > &&other)
Definition nbitset.hpp:84
CUDA static constexpr local_type eq_one()
Definition nbitset.hpp:105
CUDA static NI bool interpret_ask(const F &f, const Env &env, this_type2< M > &k, IDiagnostics &diagnostics)
Definition nbitset.hpp:235
CUDA constexpr void additive_inverse(const local_type &x)
Definition nbitset.hpp:441
CUDA constexpr void neg(const local_type &x)
Definition nbitset.hpp:409
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:269
Mem memory_type
Definition nbitset.hpp:21
CUDA constexpr local::B is_top() const
Definition nbitset.hpp:109
this_type2< battery::local_memory > local_type
Definition nbitset.hpp:25
CUDA constexpr local_type median() const
Definition nbitset.hpp:459
CUDA static constexpr this_type from_set(const battery::vector< int > &values)
Definition nbitset.hpp:59
CUDA constexpr NBitset(const this_type &other)
Definition nbitset.hpp:67
typename LB::value_type value_type
Definition nbitset.hpp:29
CUDA constexpr local_type complement() const
Definition nbitset.hpp:275
CUDA constexpr bool meet(const this_type2< M > &other)
Definition nbitset.hpp:319
CUDA constexpr local_type width() const
Definition nbitset.hpp:453
CUDA constexpr this_type & operator=(const this_type &other)
Definition nbitset.hpp:97
static constexpr const bool sequential
Definition nbitset.hpp:35
CUDA constexpr NBitset()
Definition nbitset.hpp:55
CUDA constexpr NBitset(const this_type2< M > &other)
Definition nbitset.hpp:81
CUDA constexpr const bitset_type & value() const
Definition nbitset.hpp:111
#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
::lala::ZLB< int, battery::local_memory > ZLB
Definition arith_bound.hpp:68
::lala::ZUB< int, battery::local_memory > ZUB
Definition arith_bound.hpp:69
Definition abstract_deps.hpp:14
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition cartesian_product.hpp:530
battery::vector< battery::tuple< F, F >, typename F::allocator_type > logic_set
Definition sort.hpp:127
CUDA constexpr auto fjoin(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:463
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:503
@ 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 NI std::optional< F > negate(const F &f)
Definition algorithm.hpp:266
long long int logic_int
Definition sort.hpp:114
CUDA constexpr bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:484
CUDA NI const char * string_of_sig(Sig sig)
Definition ast.hpp:121
CUDA constexpr auto fmeet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:470
CUDA constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:497
#define UNTYPED
Definition sort.hpp:21