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 Tables;
18 struct is_table_like {
19 static constexpr bool value =
false;
21 template<
class A,
class U,
class Alloc>
22 struct is_table_like<Tables<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 =
"Tables";
58 battery::vector<universe_type, allocator_type>,
62 using bitset_type = battery::dynamic_bitset<memory_type, allocator_type>;
73 battery::vector<size_t, allocator_type> table_idx_to_column;
74 battery::vector<size_t, allocator_type> column_to_table_idx;
79 battery::vector<bitset_type, allocator_type> bitset_store;
80 battery::vector<AVar, allocator_type> header2var;
84 battery::vector<int, allocator_type> header;
85 battery::vector<bitset_type, allocator_type> cbitsets;
88 Table(
size_t table_num, battery::vector<int, allocator_type>&& header)
89 : table_num(table_num)
90 , header(std::move(header))
91 , cbitsets(header.size(), header.get_allocator())
92 , eliminated_rows(header.get_allocator())
101 for(
int j = 0;
j < tell_tables[table_num].size(); ++
j) {
102 if(!eliminated_rows.test(
j)) {
103 tell_tables[table_num][
j][
i].value()
107 bitset_store[header[
i]]
115 if(!eliminated_rows[table_num].
test(
row))
118 eliminated_rows[table_num].set(
row);
128 template <
class Alloc>
136 battery::vector<battery::vector<
137 battery::vector<universe_type, Alloc>,
140 battery::vector<battery::vector<
141 battery::vector<universe_type, Alloc>,
155 template <
class TableTellType>
164 return headers.get_allocator();
167 template <
class Alloc2>
171 template <
class Alloc>
177 battery::vector<battery::vector<
178 battery::vector<universe_type, Alloc>,
191 template <
class TableAskType>
199 return headers.get_allocator();
202 template <
class Alloc2>
206 template <
class A2,
class U2,
class Alloc2>
212 , store_aty(store_aty)
213 , sub(std::
move(sub))
217 , eliminated_rows(
alloc)
218 , table_idx_to_column({0},
alloc)
219 , column_to_table_idx(
alloc)
221 , bitset_store(
alloc)
232 , store_aty(
other.store_aty)
240 , total_cells(
other.total_cells)
250 return headers.get_allocator();
258 return tell_tables.size() == 0 && sub->is_bot();
262 for(
int i = 0;
i < eliminated_rows.size(); ++
i) {
263 if(eliminated_rows[
i].
count() == tell_tables[
i].size()) {
267 return sub->is_top();
293 AType atype =
env.extends_abstract_dom();
303 AType atype =
env.extends_abstract_dom();
307 template <
class Alloc2>
320 template <
class SnapshotType>
336 template <
class Alloc2 = allocator_type>
341 template <
class Alloc2>
343 sub->restore(
snap.sub_snap);
344 total_cells =
snap.total_cells;
345 table_idx_to_column.resize(
snap.num_tables + 1);
346 headers.resize(
snap.num_tables);
347 column_to_table_idx.resize(table_idx_to_column.back());
348 tell_tables.resize(
snap.num_tables);
349 ask_tables.resize(
snap.num_tables);
350 eliminated_rows.resize(
snap.num_tables);
351 for(
int i = 0;
i < eliminated_rows.size(); ++
i) {
352 eliminated_rows[
i].reset();
354 bitset_store.resize(
snap.bitset_store.size());
355 header2var.resize(
snap.bitset_store.size());
356 for(
int i = 0;
i < bitset_store.size(); ++
i) {
357 bitset_store[
i].resize(
snap.bitset_store[
i].size());
358 bitset_store[
i] =
snap.bitset_store[
i];
364 if(
f.is(F::Seq) &&
f.sig() ==
AND) {
365 for(
int i = 0;
i <
f.seq().size(); ++
i) {
376 if(
f.is(F::Seq) &&
f.sig() ==
OR) {
377 for(
int i = 0;
i <
f.seq().size(); ++
i) {
405 template <IKind kind,
bool diagnose = false,
class F,
class Env,
class Alloc>
407 battery::vector<AVar, Alloc>& header,
408 battery::vector<battery::vector<local_universe, Alloc>,
Alloc>& tell_table,
409 battery::vector<battery::vector<local_universe, Alloc>,
Alloc>& ask_table,
417 if(!
x_opt.has_value() || !
x_opt->get().avar_of(store_aty).has_value()) {
420 AVar x =
x_opt->get().avar_of(store_aty).value();
422 for(;
idx < header.size() && header[
idx] != x; ++
idx) {}
424 if(
idx == header.size()) {
426 for(
int i = 0;
i < tell_table.size(); ++
i) {
427 if constexpr(
kind == IKind::TELL) {
428 tell_table[
i].push_back(local_universe::bot());
430 ask_table[
i].push_back(local_universe::bot());
436 if constexpr(
kind == IKind::TELL) {
454 template <IKind kind,
bool diagnose = false,
class F,
class Env,
class I>
457 using Alloc =
typename I::allocator_type;
458 if(
f.is(F::Seq) &&
f.sig() ==
OR) {
459 battery::vector<AVar, Alloc> header(
intermediate.get_allocator());
460 battery::vector<battery::vector<local_universe, Alloc>,
Alloc> tell_table(
intermediate.get_allocator());
461 battery::vector<battery::vector<local_universe, Alloc>,
Alloc> ask_table(
intermediate.get_allocator());
462 for(
int i = 0;
i <
f.seq().size(); ++
i) {
464 tell_table.push_back(battery::vector<local_universe, Alloc>(header.size(), local_universe::bot(),
intermediate.get_allocator()));
465 ask_table.push_back(battery::vector<local_universe, Alloc>(header.size(), local_universe::bot(),
intermediate.get_allocator()));
466 if(
f.seq(
i).is(F::Seq) &&
f.seq(
i).sig() ==
AND) {
467 const auto&
row =
f.seq(
i).seq();
468 for(
int j = 0;
j <
row.size(); ++
j) {
491 if constexpr(
kind == IKind::TELL) {
492 intermediate.tell_tables.push_back(std::move(tell_table));
494 intermediate.ask_tables.push_back(std::move(ask_table));
502 else if(
f.is(F::ESeq) &&
f.esig() ==
"tables") {
507 battery::vector<battery::vector<AVar, Alloc>,
Alloc> headers(
intermediate.get_allocator());
509 headers.push_back(battery::vector<AVar, Alloc>(
intermediate.get_allocator()));
510 for(
int j = 0;
j <
c; ++
j) {
512 if(!
fvar.is_variable()) {
513 RETURN_INTERPRETATION_ERROR(
"Ill-formed predicate `tables(N, C, 1D ... table, x1,..,xN, y1,..,yN, ...)`: expected variable names after the table.");
516 if(!
x_opt.has_value() || !
x_opt->get().avar_of(store_aty).has_value()) {
519 AVar x =
x_opt->get().avar_of(store_aty).value();
520 headers.back().push_back(x);
523 battery::vector<battery::vector<local_universe, Alloc>,
Alloc> tell_table(
intermediate.get_allocator());
524 battery::vector<battery::vector<local_universe, Alloc>,
Alloc> ask_table(
intermediate.get_allocator());
525 for(
int i = 0;
i <
n; ++
i) {
526 tell_table.push_back(battery::vector<local_universe, Alloc>(
intermediate.get_allocator()));
527 ask_table.push_back(battery::vector<local_universe, Alloc>(
intermediate.get_allocator()));
528 for(
int j = 0;
j <
c; ++
j) {
529 tell_table[
i].push_back(universe_type::bot());
530 ask_table[
i].push_back(universe_type::bot());
533 for(
int i = 0;
i <
n; ++
i) {
534 for(
int j = 0;
j <
c; ++
j) {
540 if constexpr(
kind == IKind::TELL) {
557 if constexpr(
kind == IKind::TELL) {
558 intermediate.tell_tables.push_back(std::move(tell_table));
560 intermediate.ask_tables.push_back(std::move(ask_table));
568 template <
bool diagnose = false,
class F,
class Env,
class Alloc>
573 template <
bool diagnose = false,
class F,
class Env,
class Alloc>
587 return headers.size();
591 template <IKind kind>
593 if constexpr(std::is_same_v<universe_type, sub_universe_type>) {
607 template <
class Alloc,
class Mem>
609 if(
t.headers.size() > 0) {
613 for(
int i = 0;
i <
t.headers.size(); ++
i) {
614 headers.push_back(battery::vector<AVar, allocator_type>(
t.headers[
i],
get_allocator()));
615 for(
int j = 0;
j <
t.headers[
i].size(); ++
j) {
616 column_to_table_idx.push_back(
i);
618 table_idx_to_column.push_back(table_idx_to_column.back() +
t.tell_tables[
i][0].size());
622 total_cells += tell_tables.back().size() * tell_tables.back()[0].size();
627 template <
class Alloc>
645 template <
class Alloc>
646 CUDA local::BInc ask(
const battery::vector<battery::vector<AVar, Alloc>,
Alloc>& header,
647 const battery::vector<battery::vector<battery::vector<universe_type, Alloc>,
Alloc>,
Alloc>& ask_tables)
const
649 for(
int i = 0;
i < ask_tables.size(); ++
i) {
653 for(
int k = 0;
k < ask_tables[
i][
j].size(); ++
k) {
671 template <
class Alloc>
679 for(
int j = 0;
j < tell_tables[table_num].size(); ++
j) {
680 if(!eliminated_rows[table_num].
test(
j)) {
690 if(!eliminated_rows[table_num].
test(
row))
693 eliminated_rows[table_num].set(
row);
701 sub->num_refinements() +
702 column_to_table_idx.size() +
713 i -= sub->num_refinements();
714 if(
i < column_to_table_idx.size()) {
718 i -= column_to_table_idx.size();
719 size_t table_num = 0;
722 for(
int j = 0;
j < tell_tables.size(); ++
j) {
723 size_t dim_table = tell_tables[
j].size() * tell_tables[
j][0].size();
728 lrefine(table_num,
i / tell_tables[table_num][0].size(),
i % tell_tables[table_num][0].size(),
has_changed);
733 template <
class ExtractionStrategy = NonAtomicExtraction>
736 return ask(headers, ask_tables) && sub->is_extractable(
strategy);
743 if constexpr(impl::is_table_like<B>::value) {
744 sub->extract(*
ua.sub);
752 return sub->project(x);
759 typename F::Sequence
seq{
env.get_allocator()};
766 for(
int i = 0;
i < headers.size(); ++
i) {
768 for(
int j = 0;
j < tell_tables[
i].size(); ++
j) {
769 if(!eliminated_rows[
i].
test(
j)) {
771 for(
int k = 0;
k < tell_tables[
i][
j].size(); ++
k) {
781 return F::make_nary(
AND, std::move(
seq));
typename A::allocator_type sub_allocator_type
Definition tables.hpp:35
battery::vector< table_type, allocator_type > table_collection_type
Definition tables.hpp:61
CUDA NI bool interpret_ask(const F &f, const Env &env, ask_type< Alloc > &ask, IDiagnostics &diagnostics) const
Definition tables.hpp:569
static constexpr const bool preserve_meet
Definition tables.hpp:52
CUDA bool is_extractable(const ExtractionStrategy &strategy=ExtractionStrategy()) const
Definition tables.hpp:734
battery::vector< battery::vector< int, allocator_type >, allocator_type > table_headers
Definition tables.hpp:60
CUDA void lrefine(size_t table_num, size_t row, size_t col, BInc< Mem > &has_changed)
Definition tables.hpp:688
CUDA allocator_type get_allocator() const
Definition tables.hpp:249
CUDA NI Tables(const Tables< A2, U2, Alloc2 > &other, AbstractDeps< Allocators... > &deps)
Definition tables.hpp:230
CUDA NI bool interpret_tell(const F &f, Env &env, tell_type< Alloc > &tell, IDiagnostics &diagnostics) const
Definition tables.hpp:574
static constexpr const bool is_totally_ordered
Definition tables.hpp:47
CUDA local::BInc is_top() const
Definition tables.hpp:261
CUDA NI bool interpret(const F &f2, Env &env, I &intermediate, IDiagnostics &diagnostics) const
Definition tables.hpp:455
CUDA void refine(size_t i, BInc< Mem > &has_changed)
Definition tables.hpp:707
static constexpr const char * name
Definition tables.hpp:55
CUDA this_type & tell(AVar x, const sub_universe_type &dom)
Definition tables.hpp:633
CUDA NI bool interpret_atom(battery::vector< AVar, Alloc > &header, battery::vector< battery::vector< local_universe, Alloc >, Alloc > &tell_table, battery::vector< battery::vector< local_universe, Alloc >, Alloc > &ask_table, const F &f, Env &env, IDiagnostics &diagnostics) const
Definition tables.hpp:406
static constexpr const bool preserve_join
Definition tables.hpp:51
static constexpr const bool preserve_concrete_covers
Definition tables.hpp:54
CUDA size_t vars() const
Definition tables.hpp:582
typename universe_type::local_type local_universe
Definition tables.hpp:37
CUDA snapshot_type< Alloc2 > snapshot(const Alloc2 &alloc=Alloc2()) const
Definition tables.hpp:337
static constexpr const bool preserve_top
Definition tables.hpp:49
CUDA void extract(B &ua) const
Definition tables.hpp:742
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 tables.hpp:270
CUDA local::BInc ask(const ask_type< Alloc > &a) const
Definition tables.hpp:672
typename sub_universe_type::local_type sub_local_universe
Definition tables.hpp:39
CUDA Tables(AType uid, sub_ptr sub, const allocator_type &alloc=allocator_type())
Definition tables.hpp:225
CUDA void flatten_or(const F &f, typename F::Sequence &disjuncts) const
Definition tables.hpp:375
CUDA this_type & tell(AVar x, const sub_universe_type &dom, BInc< Mem > &has_changed)
Definition tables.hpp:639
static constexpr const bool sequential
Definition tables.hpp:46
CUDA void crefine(size_t table_num, size_t col, BInc< Mem > &has_changed)
Definition tables.hpp:677
CUDA void restore(const snapshot_type< Alloc2 > &snap)
Definition tables.hpp:342
static constexpr const bool preserve_bot
Definition tables.hpp:48
CUDA AType aty() const
Definition tables.hpp:245
battery::vector< battery::vector< universe_type, allocator_type >, allocator_type > table_type
Definition tables.hpp:59
abstract_ptr< sub_type > sub_ptr
Definition tables.hpp:42
CUDA size_t num_tables() const
Definition tables.hpp:586
static CUDA this_type bot(Env &env, const allocator_type &alloc=allocator_type(), const sub_allocator_type &sub_alloc=sub_allocator_type())
Definition tables.hpp:288
CUDA this_type & tell(const tell_type< Alloc > &t)
Definition tables.hpp:628
Allocator allocator_type
Definition tables.hpp:34
CUDA Tables(AType uid, AType store_aty, sub_ptr sub, const allocator_type &alloc=allocator_type())
Definition tables.hpp:210
typename A::universe_type sub_universe_type
Definition tables.hpp:38
CUDA void flatten_and(const F &f, typename F::Sequence &conjuncts) const
Definition tables.hpp:363
CUDA size_t num_refinements() const
Definition tables.hpp:699
A sub_type
Definition tables.hpp:41
CUDA F flatten(const F &f, const typename F::allocator_type &alloc) const
Definition tables.hpp:394
U universe_type
Definition tables.hpp:36
CUDA NI TFormula< typename Env::allocator_type > deinterpret(const Env &env) const
Definition tables.hpp:756
CUDA sub_universe_type project(AVar x) const
Definition tables.hpp:751
CUDA this_type & tell(const tell_type< Alloc > &t, BInc< Mem > &has_changed)
Definition tables.hpp:608
static constexpr const bool is_abstract_universe
Definition tables.hpp:45
CUDA local::BDec is_bot() const
Definition tables.hpp:257
CUDA sub_ptr subdomain() const
Definition tables.hpp:253
typename universe_type::memory_type memory_type
Definition tables.hpp:40
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 tables.hpp:279
static constexpr const bool injective_concretization
Definition tables.hpp:53
battery::dynamic_bitset< memory_type, allocator_type > bitset_type
Definition tables.hpp:62
static CUDA this_type top(Env &env, const allocator_type &alloc=allocator_type(), const sub_allocator_type &sub_alloc=sub_allocator_type())
Definition tables.hpp:298
CUDA const sub_universe_type & operator[](int x) const
Definition tables.hpp:578
Definition tables.hpp:172
CUDA ask_type(const Alloc &alloc=Alloc{})
Definition tables.hpp:181
ask_type(ask_type &&)=default
CUDA allocator_type get_allocator() const
Definition tables.hpp:198
battery::vector< battery::vector< battery::vector< universe_type, Alloc >, Alloc >, Alloc > ask_tables
Definition tables.hpp:179
ask_type(const ask_type &)=default
CUDA NI ask_type(const TableAskType &other, const Alloc &alloc=Alloc{})
Definition tables.hpp:192
ask_type & operator=(ask_type &&)=default
A::template ask_type< Alloc > sub
Definition tables.hpp:175
Alloc allocator_type
Definition tables.hpp:173
battery::vector< battery::vector< AVar, Alloc >, Alloc > headers
Definition tables.hpp:176
ask_type & operator=(const ask_type &)=default
Definition tables.hpp:308
snapshot_type(const snapshot_type< Alloc2 > &)=default
sub_snap_type sub_snap
Definition tables.hpp:310
size_t num_tables
Definition tables.hpp:311
battery::vector< bitset_type, Alloc2 > bitset_store
Definition tables.hpp:313
snapshot_type< Alloc2 > & operator=(const snapshot_type< Alloc2 > &)=default
sub_type::template snapshot_type< Alloc2 > sub_snap_type
Definition tables.hpp:309
CUDA snapshot_type(const SnapshotType &other, const Alloc2 &alloc=Alloc2())
Definition tables.hpp:321
snapshot_type(snapshot_type< Alloc2 > &&)=default
snapshot_type< Alloc2 > & operator=(snapshot_type< Alloc2 > &&)=default
CUDA snapshot_type(sub_snap_type &&sub_snap, size_t num_tables, size_t total_cells, const battery::vector< bitset_type, allocator_type > &bitset_store, const Alloc2 &alloc=Alloc2())
Definition tables.hpp:328
size_t total_cells
Definition tables.hpp:312
Definition tables.hpp:129
tell_type(const tell_type &)=default
battery::vector< battery::vector< battery::vector< universe_type, Alloc >, Alloc >, Alloc > tell_tables
Definition tables.hpp:138
CUDA tell_type(const Alloc &alloc=Alloc{})
Definition tables.hpp:144
battery::vector< battery::vector< AVar, Alloc >, Alloc > headers
Definition tables.hpp:134
Alloc allocator_type
Definition tables.hpp:130
tell_type(tell_type &&)=default
CUDA allocator_type get_allocator() const
Definition tables.hpp:163
battery::vector< battery::vector< battery::vector< universe_type, Alloc >, Alloc >, Alloc > ask_tables
Definition tables.hpp:142
tell_type & operator=(const tell_type &)=default
CUDA NI tell_type(const TableTellType &other, const Alloc &alloc=Alloc{})
Definition tables.hpp:156
tell_type & operator=(tell_type &&)=default
A::template tell_type< Alloc > sub
Definition tables.hpp:132