3#ifndef LALA_CORE_VSTORE_HPP
4#define LALA_CORE_VSTORE_HPP
14 static constexpr bool atoms =
false;
18 static constexpr bool atoms =
true;
37template<
class U,
class Allocator>
45 template <
class Alloc>
53 template <
class VarDom>
57 template <
class Alloc>
58 using tell_type = battery::vector<var_dom<Alloc>, Alloc>;
60 template <
class Alloc>
63 template <
class Alloc = allocator_type>
67 constexpr static const bool sequential = universe_type::sequential;
71 constexpr static const bool preserve_join = universe_type::preserve_join;
72 constexpr static const bool preserve_meet = universe_type::preserve_meet;
75 constexpr static const char*
name =
"VStore";
77 template<
class U2,
class Alloc2>
81 using store_type = battery::vector<universe_type, allocator_type>;
82 using memory_type =
typename universe_type::memory_type;
90 : atype(other.atype), data(other.data), is_at_bot(other.is_at_bot)
95 : atype(atype), data(alloc), is_at_bot(false)
99 : atype(atype), data(size, alloc), is_at_bot(false)
104 : atype(other.atype), data(other.data), is_at_bot(other.is_at_bot)
107 template<
class R,
class Alloc2>
109 : atype(other.atype), data(other.data, alloc), is_at_bot(other.is_at_bot)
114 template<
class R,
class Alloc2,
class... Allocators>
119 atype(other.atype), data(std::move(other.data)), is_at_bot(other.is_at_bot) {}
122 return data.get_allocator();
137 return VStore(atype, alloc);
144 auto s =
VStore{atype, alloc};
153 return bot(env.extends_abstract_dom(), alloc);
160 return top(env.extends_abstract_dom(), alloc);
174 if(is_at_bot) {
return false; }
175 for(
int i = 0; i <
vars(); ++i) {
184 template <
class Alloc = allocator_type>
189 template <
class Alloc>
191 while(snap.size() < data.size()) {
194 is_at_bot.meet_bot();
195 for(
int i = 0; i < snap.size(); ++i) {
196 data[i].join(snap[i]);
197 is_at_bot.join(data[i].
is_bot());
203 template <
bool diagnose,
class F,
class Env,
class Alloc2>
204 CUDA NI
bool interpret_existential(
const F& f, Env& env, tell_type<Alloc2>& tell,
IDiagnostics& diagnostics)
const {
207 if(local_universe::template interpret_tell<diagnose>(f, env, k.dom, diagnostics)) {
208 if(env.interpret(f.map_atype(atype), k.avar, diagnostics)) {
209 assert(k.avar.aty() ==
aty());
218 template <
bool diagnose,
class F,
class Env,
class Alloc2>
219 CUDA NI
bool interpret_zero_predicate(
const F& f,
const Env& env, tell_type<Alloc2>& tell, IDiagnostics& diagnostics)
const {
223 else if(f.is_false()) {
224 tell.push_back(var_dom<Alloc2>(AVar{}, U::bot()));
233 template <IKind kind,
bool diagnose,
class F,
class Env,
class Alloc2>
234 CUDA NI
bool interpret_unary_predicate(
const F& f,
const Env& env, tell_type<Alloc2>& tell, IDiagnostics& diagnostics)
const {
236 bool res = local_universe::template interpret<kind, diagnose>(f, env, u, diagnostics);
238 const auto& varf =
var_in(f);
242 if(varf.v().aty() ==
aty() || varf.v().aty() ==
UNTYPED) {
243 tell.push_back(var_dom<Alloc2>(varf.v(), u));
246 RETURN_INTERPRETATION_ERROR(
"The variable was not declared in the current abstract element (but exists in other abstract elements).");
250 auto var =
var_in(f, env);
251 if(!var.has_value()) {
254 auto avar = var->get().avar_of(atype);
255 if(!avar.has_value()) {
256 RETURN_INTERPRETATION_ERROR(
"The variable was not declared in the current abstract element (but exists in other abstract elements).");
258 assert(avar->aty() ==
aty());
259 tell.push_back(var_dom<Alloc2>(*avar, u));
268 template <IKind kind,
bool diagnose,
class F,
class Env,
class Alloc2>
269 CUDA NI
bool interpret_predicate(
const F& f, Env& env, tell_type<Alloc2>& tell, IDiagnostics& diagnostics)
const {
270 if(f.type() !=
UNTYPED && f.type() !=
aty()) {
275 return interpret_existential<diagnose>(f, env, tell, diagnostics);
279 case 0:
return interpret_zero_predicate<diagnose>(f, env, tell, diagnostics);
280 case 1:
return interpret_unary_predicate<kind, diagnose>(f, env, tell, diagnostics);
286 template <IKind kind,
bool diagnose = false,
class F,
class Env,
class I>
288 if(f.is_untyped() || f.type() ==
aty()) {
289 return interpret_predicate<kind, diagnose>(f, env, intermediate, diagnostics);
307 template <
bool diagnose = false,
class F,
class Env,
class Alloc2>
309 return interpret<IKind::TELL, diagnose>(f, env, tell, diagnostics);
313 template <
bool diagnose = false,
class F,
class Env,
class Alloc2>
315 return const_cast<this_type*
>(
this)->interpret<IKind::ASK, diagnose>(f,
const_cast<Env&
>(env),
ask, diagnostics);
318 template <
class Group,
class Store>
319 CUDA
void copy_to(Group& group, Store& store)
const {
320 assert(
vars() == store.vars());
321 if(group.thread_rank() == 0) {
322 store.is_at_bot = is_at_bot;
327 for (
int i = group.thread_rank(); i < store.vars(); i += group.num_threads()) {
328 store.data[i] = data[i];
332 template <
class Store>
334 assert(
vars() == store.vars());
335 store.is_at_bot = is_at_bot;
339 for (
int i = 0; i < store.vars(); ++i) {
340 store.data[i] = data[i];
346 void prefetch(
int dstDevice)
const {
348 cudaMemPrefetchAsync(data.data(), data.size() *
sizeof(
universe_type), dstDevice);
355 data = store_type(data.size(), alloc);
358 template <
class Univ>
365 assert(x.
vid() < data.size());
366 return data[x.
vid()];
379 is_at_bot.join_top();
387 assert(x < data.size());
388 bool has_changed = data[x].meet(dom);
389 if(has_changed && data[x].
is_bot()) {
390 is_at_bot.join_top();
404 template <
class Alloc2>
410 for(
int i = 0; i < t.size(); ++i) {
411 if(t[i].avar ==
AVar{}) {
412 return is_at_bot.join(
local::B(
true));
414 largest_vid = battery::max(largest_vid, t[i].avar.vid());
416 if(largest_vid >= data.size()) {
417 data.resize(largest_vid+1);
419 bool has_changed =
false;
420 for(
int i = 0; i < t.size(); ++i) {
421 has_changed |=
embed(t[i].avar, t[i].dom);
427 template <
class U2,
class Alloc2>
429 bool has_changed = is_at_bot.join(other.is_at_bot);
430 int min_size = battery::min(
vars(), other.
vars());
431 for(
int i = 0; i < min_size; ++i) {
432 has_changed |= data[i].meet(other[i]);
434 for(
int i = min_size; i < other.
vars(); ++i) {
435 assert(other[i].
is_top());
441 is_at_bot.meet_bot();
442 for(
int i = 0; i < data.size(); ++i) {
448 template <
class U2,
class Alloc2>
453 int min_size = battery::min(
vars(), other.
vars());
454 bool has_changed = is_at_bot.meet(other.is_at_bot);
455 for(
int i = 0; i < min_size; ++i) {
456 has_changed |= data[i].join(other[i]);
458 for(
int i = min_size; i <
vars(); ++i) {
459 has_changed |= data[i].join(U::top());
461 for(
int i = min_size; i < other.
vars(); ++i) {
462 assert(other[i].
is_top());
470 template <
class Alloc2>
472 for(
int i = 0; i < t.size(); ++i) {
473 if(!(data[t[i].avar.vid()] <= t[i].dom)) {
486 template<
class ExtractionStrategy = NonAtomicExtraction>
487 CUDA
bool is_extractable(
const ExtractionStrategy& strategy = ExtractionStrategy())
const {
491 if constexpr(ExtractionStrategy::atoms) {
492 for(
int i = 0; i < data.size(); ++i) {
493 if(data[i].lb().value() != data[i].ub().value()) {
502 template<
class ExtractionStrategy = NonAtomicExtraction>
503 __device__
bool is_extractable(
auto& group,
const ExtractionStrategy& strategy = ExtractionStrategy())
const {
507 if constexpr(ExtractionStrategy::atoms) {
509 if(group.thread_rank() == 0) {
513 for(
int i = group.thread_rank(); i < data.size(); i += group.num_threads()) {
514 if(data[i].lb().value() != data[i].ub().value()) {
530 template<
class U2,
class Alloc2>
532 if((
void*)&ua != (
void*)
this) {
534 ua.is_at_bot.meet_bot();
539 template<
class U2,
class Env,
class Allocator2>
541 auto f = dom.deinterpret(avar, env, allocator);
548 template<
class Env,
class Allocator2 =
typename Env::allocator_type>
551 if(data.size() == 0) {
552 return is_bot() ? F::make_false() : F::make_true();
554 typename F::Sequence seq{allocator};
555 for(
int i = 0; i < data.size(); ++i) {
557 seq.push_back(F::make_exists(
aty(), env.name_of(v), env.sort_of(v)));
558 seq.push_back(deinterpret(
AVar(
aty(), i), data[i], env, allocator));
560 return F::make_nary(
AND, std::move(seq),
aty());
563 template<
class I,
class Env,
class Allocator2 =
typename Env::allocator_type>
566 if(intermediate.size() == 0) {
567 return F::make_true();
569 else if(intermediate.size() == 1) {
570 return deinterpret(intermediate[0].avar, intermediate[0].dom, env, allocator);
573 typename F::Sequence seq{allocator};
574 for(
int i = 0; i < intermediate.size(); ++i) {
575 seq.push_back(deinterpret(intermediate[i].avar, intermediate[i].dom, env, allocator));
577 return F::make_nary(
AND, std::move(seq),
aty());
586 for(
int i = 0; i <
vars(); ++i) {
588 printf(
"%s", (i+1 ==
vars() ?
"" :
", "));
598template<
class L,
class K,
class Alloc>
601 using U =
decltype(
fmeet(a[0], b[0]));
605 int max_size = battery::max(a.
vars(), b.
vars());
606 int min_size = battery::min(a.
vars(), b.
vars());
608 for(
int i = 0; i < min_size; ++i) {
611 for(
int i = min_size; i < a.
vars(); ++i) {
614 for(
int i = min_size; i < b.
vars(); ++i) {
620template<
class L,
class K,
class Alloc>
623 using U =
decltype(
fjoin(a[0], b[0]));
636 int min_size = battery::min(a.
vars(), b.
vars());
638 for(
int i = 0; i < min_size; ++i) {
645template<
class L,
class K,
class Alloc1,
class Alloc2>
646CUDA
bool operator<=(
const VStore<L, Alloc1>& a,
const VStore<K, Alloc2>& b)
652 int min_size = battery::min(a.vars(), b.vars());
653 for(
int i = 0; i < min_size; ++i) {
654 if(!(a[i] <= b[i])) {
658 for(
int i = min_size; i < b.vars(); ++i) {
667template<
class L,
class K,
class Alloc1,
class Alloc2>
674 int min_size = battery::min(a.
vars(), b.
vars());
676 for(
int i = 0; i < a.
vars(); ++i) {
681 else if(!(a[i] <= b[i])) {
685 else if(!a[i].is_top()) {
690 for(
int i = min_size; i < b.
vars(); ++i) {
699template<
class L,
class K,
class Alloc1,
class Alloc2>
700CUDA
bool operator>=(
const VStore<L, Alloc1>& a,
const VStore<K, Alloc2>& b)
705template<
class L,
class K,
class Alloc1,
class Alloc2>
711template<
class L,
class K,
class Alloc1,
class Alloc2>
721 int min_size = battery::min(a.
vars(), b.
vars());
722 for(
int i = 0; i < min_size; ++i) {
727 for(
int i = min_size; i < a.
vars(); ++i) {
732 for(
int i = min_size; i < b.
vars(); ++i) {
741template<
class L,
class K,
class Alloc1,
class Alloc2>
742CUDA
bool operator!=(
const VStore<L, Alloc1>& a,
const VStore<K, Alloc2>& b)
747template<
class L,
class Alloc>
754 for(
int i = 0; i < vstore.
vars(); ++i) {
755 s << vstore[i] << (i+1 == vstore.
vars() ?
"" :
", ");
CUDA constexpr int vid() const
Definition ast.hpp:69
CUDA constexpr int aty() const
Definition ast.hpp:65
Definition abstract_deps.hpp:28
Definition diagnostics.hpp:19
battery::vector< var_dom< Alloc >, Alloc > tell_type
Definition vstore.hpp:58
static CUDA this_type top(AType atype=UNTYPED, const allocator_type &alloc=allocator_type{})
Definition vstore.hpp:134
CUDA int vars() const
Definition vstore.hpp:130
static constexpr const bool is_abstract_universe
Definition vstore.hpp:66
CUDA bool deduce(const tell_type< Alloc2 > &t)
Definition vstore.hpp:405
static constexpr const bool preserve_top
Definition vstore.hpp:70
CUDA local::B is_top() const
Definition vstore.hpp:173
static constexpr const bool preserve_bot
Definition vstore.hpp:69
CUDA bool join(const VStore< U2, Alloc2 > &other)
Definition vstore.hpp:449
CUDA bool meet(const VStore< U2, Alloc2 > &other)
Definition vstore.hpp:428
CUDA void copy_to(Group &group, Store &store) const
Definition vstore.hpp:319
static CUDA this_type bot(AType atype=UNTYPED, const allocator_type &alloc=allocator_type{})
Definition vstore.hpp:141
CUDA const universe_type & project(AVar x) const
Definition vstore.hpp:363
CUDA AType aty() const
Definition vstore.hpp:125
CUDA VStore(AType atype, const allocator_type &alloc=allocator_type())
Definition vstore.hpp:94
static constexpr const bool sequential
Definition vstore.hpp:67
CUDA int num_deductions() const
Definition vstore.hpp:480
tell_type< Alloc > ask_type
Definition vstore.hpp:61
CUDA bool is_extractable(const ExtractionStrategy &strategy=ExtractionStrategy()) const
Definition vstore.hpp:487
CUDA void print() const
Definition vstore.hpp:581
static CUDA this_type top(Env &env, const allocator_type &alloc=allocator_type{})
Definition vstore.hpp:157
CUDA allocator_type get_allocator() const
Definition vstore.hpp:121
CUDA NI TFormula< Allocator2 > deinterpret(const I &intermediate, const Env &env, const Allocator2 &allocator=Allocator2()) const
Definition vstore.hpp:564
CUDA local::B ask(const ask_type< Alloc2 > &t) const
Definition vstore.hpp:471
CUDA void project(AVar x, Univ &u) const
Definition vstore.hpp:359
CUDA void copy_to(Store &store) const
Definition vstore.hpp:333
CUDA void join_top()
Definition vstore.hpp:440
CUDA bool embed(AVar x, const universe_type &dom)
Definition vstore.hpp:396
battery::vector< local_universe, Alloc > snapshot_type
Definition vstore.hpp:64
CUDA local::B is_bot() const
Definition vstore.hpp:166
U universe_type
Definition vstore.hpp:40
static constexpr const bool preserve_join
Definition vstore.hpp:71
CUDA VStore(const VStore< R, allocator_type > &other)
Definition vstore.hpp:103
static constexpr const char * name
Definition vstore.hpp:75
CUDA snapshot_type< Alloc > snapshot(const Alloc &alloc=Alloc()) const
Definition vstore.hpp:185
typename universe_type::local_type local_universe
Definition vstore.hpp:41
friend class VStore
Definition vstore.hpp:78
CUDA bool embed(int x, const universe_type &dom)
Definition vstore.hpp:386
CUDA NI bool interpret(const F &f, Env &env, I &intermediate, IDiagnostics &diagnostics) const
Definition vstore.hpp:287
CUDA this_type & restore(const snapshot_type< Alloc > &snap)
Definition vstore.hpp:190
CUDA const universe_type & operator[](int x) const
Definition vstore.hpp:370
static constexpr const bool injective_concretization
Definition vstore.hpp:73
static constexpr const bool preserve_concrete_covers
Definition vstore.hpp:74
CUDA VStore(AType atype, int size, const allocator_type &alloc=allocator_type())
Definition vstore.hpp:98
CUDA void meet_bot()
Definition vstore.hpp:378
CUDA NI bool interpret_ask(const F &f, const Env &env, ask_type< Alloc2 > &ask, IDiagnostics &diagnostics) const
Definition vstore.hpp:314
CUDA VStore(this_type &&other)
Definition vstore.hpp:118
CUDA VStore(const this_type &other)
Definition vstore.hpp:89
static constexpr const bool is_totally_ordered
Definition vstore.hpp:68
CUDA local::B deduce(int) const
Definition vstore.hpp:481
CUDA const universe_type & operator[](AVar x) const
Definition vstore.hpp:374
CUDA void reset_data(allocator_type alloc)
Definition vstore.hpp:354
static constexpr const bool preserve_meet
Definition vstore.hpp:72
CUDA NI TFormula< Allocator2 > deinterpret(const Env &env, const Allocator2 &allocator=Allocator2()) const
Definition vstore.hpp:549
CUDA void extract(VStore< U2, Alloc2 > &ua) const
Definition vstore.hpp:531
CUDA VStore(const VStore< R, Alloc2 > &other, const allocator_type &alloc=allocator_type())
Definition vstore.hpp:108
CUDA VStore(const VStore< R, Alloc2 > &other, const AbstractDeps< Allocators... > &deps)
Definition vstore.hpp:115
Allocator allocator_type
Definition vstore.hpp:42
CUDA NI bool interpret_tell(const F &f, Env &env, tell_type< Alloc2 > &tell, IDiagnostics &diagnostics) const
Definition vstore.hpp:308
static CUDA this_type bot(Env &env, const allocator_type &alloc=allocator_type{})
Definition vstore.hpp:150
#define RETURN_INTERPRETATION_ERROR(MSG)
Definition diagnostics.hpp:155
Definition abstract_deps.hpp:14
std::ostream & operator<<(std::ostream &s, const CartesianProduct< A, As... > &cp)
Definition cartesian_product.hpp:531
CUDA NI void map_avar_to_lvar(F &f, const Env &env, bool erase_type=false)
Definition algorithm.hpp:438
CUDA constexpr auto fjoin(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:464
CUDA constexpr bool operator==(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:504
@ AND
Unary arithmetic function symbols.
Definition ast.hpp:114
int AType
Definition sort.hpp:18
CUDA constexpr bool operator<(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:485
CUDA constexpr auto fmeet(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:471
CUDA constexpr bool operator>(const CartesianProduct< As... > &a, const CartesianProduct< Bs... > &b)
Definition cartesian_product.hpp:498
CUDA NI int num_vars(const F &f)
Definition algorithm.hpp:154
CUDA const TFormula< Allocator, ExtendedSig > & var_in(const TFormula< Allocator, ExtendedSig > &f)
Definition algorithm.hpp:146
#define UNTYPED
Definition sort.hpp:21
CUDA var_dom(const Alloc &)
Definition vstore.hpp:51
var_dom(const var_dom< Alloc > &)=default
CUDA var_dom(AVar avar, const local_universe &dom)
Definition vstore.hpp:52
AVar avar
Definition vstore.hpp:47
local_universe dom
Definition vstore.hpp:48
CUDA var_dom(const VarDom &other)
Definition vstore.hpp:54