3#ifndef LALA_POWER_TABLES_HPP
4#define LALA_POWER_TABLES_HPP
6#include "battery/vector.hpp"
7#include "battery/shared_ptr.hpp"
8#include "battery/dynamic_bitset.hpp"
9#include "lala/logic/logic.hpp"
10#include "lala/universes/primitive_upset.hpp"
11#include "lala/abstract_deps.hpp"
15template <
class A,
class U,
class Alloc>
class Table;
18 struct is_table_like {
19 static constexpr bool value =
false;
21 template<
class A,
class U,
class Alloc>
22 struct is_table_like<Table<A, U, Alloc>> {
23 static constexpr bool value =
true;
31template <
class A,
class U =
typename A::universe_type,
class Allocator =
typename A::allocator_type>
46 constexpr static const bool sequential = sub_type::sequential;
55 constexpr static const char*
name =
"Table";
57 using table_type = battery::vector<universe_type, allocator_type>;
58 using bitset_type = battery::dynamic_bitset<memory_type, allocator_type>;
66 battery::vector<battery::vector<AVar, allocator_type>,
allocator_type> headers;
69 battery::vector<bitset_type, allocator_type> eliminated_rows;
73 battery::vector<bitset_type, allocator_type> bitset_store;
76 template <
class Alloc>
98 template <
class TableTellType>
107 return headers.get_allocator();
110 template <
class Alloc2>
114 template <
class Alloc>
132 template <
class TableAskType>
140 return headers.get_allocator();
143 template <
class Alloc2>
147 template <
class A2,
class U2,
class Alloc2>
153 , store_aty(store_aty)
154 , sub(std::
move(sub))
158 , eliminated_rows(
alloc)
168 , store_aty(
other.store_aty)
181 return headers.get_allocator();
189 return tell_table.size() == 0 && sub->is_bot();
193 for(
int i = 0;
i < eliminated_rows.size(); ++
i) {
194 if(eliminated_rows[
i].
count() == tell_table.size()) {
198 return sub->is_top();
224 AType atype =
env.extends_abstract_dom();
234 AType atype =
env.extends_abstract_dom();
238 template <
class Alloc2>
249 template <
class SnapshotType>
261 template <
class Alloc2 = allocator_type>
266 template <
class Alloc2>
268 sub->restore(
snap.sub_snap);
269 headers.resize(
snap.num_tables);
270 if(
snap.num_tables == 0) {
271 tell_table.resize(0);
274 eliminated_rows.resize(
snap.num_tables);
275 for(
int i = 0;
i < eliminated_rows.size(); ++
i) {
276 eliminated_rows[
i].reset();
282 if(
f.is(F::Seq) &&
f.sig() ==
AND) {
283 for(
int i = 0;
i <
f.seq().size(); ++
i) {
294 if(
f.is(F::Seq) &&
f.sig() ==
OR) {
295 for(
int i = 0;
i <
f.seq().size(); ++
i) {
323 template <IKind kind,
bool diagnose = false,
class F,
class Env,
class Alloc>
325 battery::vector<AVar, Alloc>& header,
326 battery::vector<battery::vector<local_universe, Alloc>,
Alloc>&
tell_table2,
327 battery::vector<battery::vector<local_universe, Alloc>,
Alloc>&
ask_table2,
335 if(!
x_opt.has_value() || !
x_opt->get().avar_of(store_aty).has_value()) {
338 AVar x =
x_opt->get().avar_of(store_aty).value();
340 for(;
idx < header.size() && header[
idx] != x; ++
idx) {}
342 if(
idx == header.size()) {
345 if constexpr(
kind == IKind::TELL) {
354 if constexpr(
kind == IKind::TELL) {
371 template <
class Alloc1,
class Alloc2>
375 if(
table.size() == 0) {
return battery::vector<local_universe, Alloc2>(
alloc);}
376 battery::vector<local_universe, Alloc2>
res(
alloc);
378 for(
int i = 0;
i <
table.size(); ++
i) {
379 for(
int j = 0;
j <
table[
i].size(); ++
j) {
383 return std::move(
res);
387 template <IKind kind,
bool diagnose = false,
class F,
class Env,
class I>
390 using Alloc =
typename I::allocator_type;
391 if(
f.is(F::Seq) &&
f.sig() ==
OR) {
392 battery::vector<AVar, Alloc> header(
intermediate.get_allocator());
395 for(
int i = 0;
i <
f.seq().size(); ++
i) {
397 tell_table2.push_back(battery::vector<local_universe, Alloc>(header.size(), local_universe::bot(),
intermediate.get_allocator()));
398 ask_table2.push_back(battery::vector<local_universe, Alloc>(header.size(), local_universe::bot(),
intermediate.get_allocator()));
399 if(
f.seq(
i).is(F::Seq) &&
f.seq(
i).sig() ==
AND) {
400 const auto&
row =
f.seq(
i).seq();
401 for(
int j = 0;
j <
row.size(); ++
j) {
424 if(header.size() > 1) {
430 if(
intermediate.ask_table.size() == 0 && ask_table.size() == 0) {
431 if constexpr(
kind == IKind::TELL) {
439 RETURN_INTERPRETATION_ERROR(
"This abstract domain can only represent multiple tables over a same matrix of values, but a difference was detected.");
446 template <
bool diagnose = false,
class F,
class Env,
class Alloc>
451 template <
bool diagnose = false,
class F,
class Env,
class Alloc>
465 return headers.size();
469 template <IKind kind>
471 if constexpr(std::is_same_v<universe_type, sub_universe_type>) {
484 CUDA size_t num_columns()
const {
485 return headers[0].size();
488 CUDA size_t num_rows()
const {
489 return tell_table.size() / num_columns();
493 template <
class Alloc,
class Mem>
495 if(
t.headers.size() > 0) {
500 if(
t.tell_table.size() > 0) {
502 assert(tell_table.size() == 0);
503 tell_table =
t.tell_table;
504 ask_table =
t.ask_table;
507 for(
int i = 0;
i <
t.headers.size(); ++
i) {
509 headers.push_back(battery::vector<AVar, allocator_type>(
t.headers[
i],
get_allocator()));
515 template <
class Alloc>
535 template <
class Alloc>
536 CUDA local::BInc ask(
const battery::vector<battery::vector<AVar, Alloc>,
Alloc>& headers)
const
538 for(
int i = 0;
i < headers.size(); ++
i) {
540 for(
int j = 0;
j < num_rows(); ++
j) {
542 for(
int k = 0;
k < num_columns(); ++
k) {
558 template <
class Alloc>
567 for(
int j = 0;
j < num_rows(); ++
j) {
569 if(!eliminated_rows[table_num].
test(
j)) {
570 if(
join(
r, sub->project(headers[table_num][
col])).is_top()) {
571 eliminated_rows[table_num].set(
j);
585 sub->num_refinements() +
586 headers.size() * num_columns();
596 i -= sub->num_refinements();
602 template <
class ExtractionStrategy = NonAtomicExtraction>
605 return ask(headers) && sub->is_extractable(
strategy);
612 if constexpr(impl::is_table_like<B>::value) {
613 sub->extract(*
ua.sub);
621 return sub->project(x);
628 typename F::Sequence
seq{
env.get_allocator()};
635 for(
int i = 0;
i < headers.size(); ++
i) {
637 for(
int j = 0;
j < num_rows(); ++
j) {
638 if(!eliminated_rows[
i].
test(
j)) {
640 for(
int k = 0;
k < num_columns(); ++
k) {
650 return F::make_nary(
AND, std::move(
seq));
battery::vector< universe_type, allocator_type > table_type
Definition table.hpp:57
CUDA NI Table(const Table< A2, U2, Alloc2 > &other, AbstractDeps< Allocators... > &deps)
Definition table.hpp:166
static CUDA this_type top(Env &env, const allocator_type &alloc=allocator_type(), const sub_allocator_type &sub_alloc=sub_allocator_type())
Definition table.hpp:229
CUDA NI bool interpret_atom(battery::vector< AVar, Alloc > &header, battery::vector< battery::vector< local_universe, Alloc >, Alloc > &tell_table2, battery::vector< battery::vector< local_universe, Alloc >, Alloc > &ask_table2, const F &f, Env &env, IDiagnostics &diagnostics) const
Definition table.hpp:324
static constexpr const bool is_totally_ordered
Definition table.hpp:47
CUDA Table(AType uid, AType store_aty, sub_ptr sub, const allocator_type &alloc=allocator_type())
Definition table.hpp:151
static constexpr const bool preserve_join
Definition table.hpp:51
CUDA size_t vars() const
Definition table.hpp:460
CUDA NI TFormula< typename Env::allocator_type > deinterpret(const Env &env) const
Definition table.hpp:625
CUDA this_type & tell(const tell_type< Alloc > &t, BInc< Mem > &has_changed)
Definition table.hpp:494
static constexpr const bool preserve_bot
Definition table.hpp:48
Allocator allocator_type
Definition table.hpp:34
CUDA sub_universe_type project(AVar x) const
Definition table.hpp:620
static CUDA this_type top(AType atype=UNTYPED, AType atype_sub=UNTYPED, const allocator_type &alloc=allocator_type(), const sub_allocator_type &sub_alloc=sub_allocator_type())
Definition table.hpp:210
abstract_ptr< sub_type > sub_ptr
Definition table.hpp:42
typename sub_universe_type::local_type sub_local_universe
Definition table.hpp:39
CUDA sub_ptr subdomain() const
Definition table.hpp:184
CUDA size_t num_tables() const
Definition table.hpp:464
static CUDA this_type bot(AType atype=UNTYPED, AType atype_sub=UNTYPED, const allocator_type &alloc=allocator_type(), const sub_allocator_type &sub_alloc=sub_allocator_type())
Definition table.hpp:201
typename universe_type::memory_type memory_type
Definition table.hpp:40
CUDA NI bool interpret_tell(const F &f, Env &env, tell_type< Alloc > &tell, IDiagnostics &diagnostics) const
Definition table.hpp:452
CUDA size_t to1D(int i, int j) const
Definition table.hpp:532
CUDA local::BInc is_top() const
Definition table.hpp:192
static constexpr const bool preserve_meet
Definition table.hpp:52
CUDA battery::vector< local_universe, Alloc2 > flatten_table(const battery::vector< battery::vector< local_universe, Alloc1 >, Alloc1 > &table, const Alloc2 &alloc) const
Definition table.hpp:372
static constexpr const char * name
Definition table.hpp:55
battery::dynamic_bitset< memory_type, allocator_type > bitset_type
Definition table.hpp:58
typename A::allocator_type sub_allocator_type
Definition table.hpp:35
typename universe_type::local_type local_universe
Definition table.hpp:37
CUDA allocator_type get_allocator() const
Definition table.hpp:180
typename A::universe_type sub_universe_type
Definition table.hpp:38
static constexpr const bool preserve_concrete_covers
Definition table.hpp:54
CUDA local::BInc ask(const ask_type< Alloc > &a) const
Definition table.hpp:559
CUDA NI bool interpret(const F &f2, Env &env, I &intermediate, IDiagnostics &diagnostics) const
Definition table.hpp:388
static constexpr const bool preserve_top
Definition table.hpp:49
A sub_type
Definition table.hpp:41
CUDA bool is_extractable(const ExtractionStrategy &strategy=ExtractionStrategy()) const
Definition table.hpp:603
CUDA snapshot_type< Alloc2 > snapshot(const Alloc2 &alloc=Alloc2()) const
Definition table.hpp:262
CUDA local::BDec is_bot() const
Definition table.hpp:188
CUDA AType aty() const
Definition table.hpp:176
static constexpr const bool is_abstract_universe
Definition table.hpp:45
static CUDA this_type bot(Env &env, const allocator_type &alloc=allocator_type(), const sub_allocator_type &sub_alloc=sub_allocator_type())
Definition table.hpp:219
CUDA const sub_universe_type & operator[](int x) const
Definition table.hpp:456
CUDA this_type & tell(AVar x, const sub_universe_type &dom)
Definition table.hpp:521
CUDA NI bool interpret_ask(const F &f, const Env &env, ask_type< Alloc > &ask, IDiagnostics &diagnostics) const
Definition table.hpp:447
CUDA Table(AType uid, sub_ptr sub, const allocator_type &alloc=allocator_type())
Definition table.hpp:161
CUDA void flatten_or(const F &f, typename F::Sequence &disjuncts) const
Definition table.hpp:293
CUDA this_type & tell(const tell_type< Alloc > &t)
Definition table.hpp:516
CUDA void refine(size_t i, BInc< Mem > &has_changed)
Definition table.hpp:590
CUDA size_t num_refinements() const
Definition table.hpp:583
CUDA this_type & tell(AVar x, const sub_universe_type &dom, BInc< Mem > &has_changed)
Definition table.hpp:527
U universe_type
Definition table.hpp:36
CUDA void extract(B &ua) const
Definition table.hpp:611
CUDA void restore(const snapshot_type< Alloc2 > &snap)
Definition table.hpp:267
static constexpr const bool sequential
Definition table.hpp:46
static constexpr const bool injective_concretization
Definition table.hpp:53
CUDA void flatten_and(const F &f, typename F::Sequence &conjuncts) const
Definition table.hpp:281
CUDA F flatten(const F &f, const typename F::allocator_type &alloc) const
Definition table.hpp:312
ask_type(ask_type &&)=default
ask_type & operator=(ask_type &&)=default
CUDA NI ask_type(const TableAskType &other, const Alloc &alloc=Alloc{})
Definition table.hpp:133
Alloc allocator_type
Definition table.hpp:116
CUDA ask_type(const Alloc &alloc=Alloc{})
Definition table.hpp:122
battery::vector< battery::vector< AVar, Alloc >, Alloc > headers
Definition table.hpp:119
battery::vector< universe_type, Alloc > ask_table
Definition table.hpp:120
ask_type(const ask_type &)=default
CUDA allocator_type get_allocator() const
Definition table.hpp:139
ask_type & operator=(const ask_type &)=default
A::template ask_type< Alloc > sub
Definition table.hpp:118
snapshot_type< Alloc2 > & operator=(const snapshot_type< Alloc2 > &)=default
sub_snap_type sub_snap
Definition table.hpp:241
CUDA snapshot_type(sub_snap_type &&sub_snap, size_t num_tables)
Definition table.hpp:255
sub_type::template snapshot_type< Alloc2 > sub_snap_type
Definition table.hpp:240
snapshot_type< Alloc2 > & operator=(snapshot_type< Alloc2 > &&)=default
snapshot_type(snapshot_type< Alloc2 > &&)=default
CUDA snapshot_type(const SnapshotType &other, const Alloc2 &alloc=Alloc2())
Definition table.hpp:250
snapshot_type(const snapshot_type< Alloc2 > &)=default
size_t num_tables
Definition table.hpp:242
A::template tell_type< Alloc > sub
Definition table.hpp:80
tell_type(const tell_type &)=default
CUDA NI tell_type(const TableTellType &other, const Alloc &alloc=Alloc{})
Definition table.hpp:99
Alloc allocator_type
Definition table.hpp:78
tell_type & operator=(tell_type &&)=default
battery::vector< universe_type, Alloc > ask_table
Definition table.hpp:85
tell_type(tell_type &&)=default
tell_type & operator=(const tell_type &)=default
CUDA allocator_type get_allocator() const
Definition table.hpp:106
battery::vector< battery::vector< AVar, Alloc >, Alloc > headers
Definition table.hpp:82
battery::vector< universe_type, Alloc > tell_table
Definition table.hpp:84
CUDA tell_type(const Alloc &alloc=Alloc{})
Definition table.hpp:87