Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
data_structures.hpp
Go to the documentation of this file.
1#pragma once
2#include <algorithm>
3#include <concepts>
4#include <iterator>
5
6#include "term.hpp"
7
8namespace smt_terms {
9using namespace smt_solver;
10
16class STuple {
17 public:
19 cvc5::Term term;
21
23 : solver(nullptr)
24 , term(cvc5::Term()) {};
25
26 STuple(const cvc5::Term& term, Solver* s, TermType type = TermType::STuple)
27 : solver(s)
28 , term(term)
29 , type(type) {};
30
37 {
38 if (terms.size() == 0) {
39 throw std::invalid_argument("Empty vector occured during STuple initialization");
40 }
41 this->solver = terms[0].solver;
42
44 terms_.reserve(terms.size());
45 auto map = [](const STerm& t) -> cvc5::Term { return t.term; };
46 std::transform(terms.begin(), terms.end(), std::back_inserter(terms_), map);
47 this->term = this->solver->term_manager.mkTuple(terms_);
48 }
49
54 void operator==(const STuple& other) const
55 {
56 cvc5::Term eq = this->solver->term_manager.mkTerm(cvc5::Kind::EQUAL, { this->term, other.term });
57 this->solver->assertFormula(eq);
58 }
59
64 void operator!=(const STuple& other) const
65 {
66 cvc5::Term eq = this->solver->term_manager.mkTerm(cvc5::Kind::EQUAL, { this->term, other.term });
67 eq = this->solver->term_manager.mkTerm(cvc5::Kind::NOT, { eq });
68 this->solver->assertFormula(eq);
69 }
70
76 cvc5::Sort get_sort() const { return this->term.getSort(); }
77
78 operator std::string() const { return this->solver->stringify_term(term); };
79 operator cvc5::Term() const { return term; };
80
81 friend std::ostream& operator<<(std::ostream& out, const STuple& term)
82 {
83 return out << static_cast<std::string>(term);
84 };
85
86 STuple(const STuple& other) = default;
87 STuple(STuple&& other) = default;
88 STuple& operator=(const STuple& right) = default;
89 STuple& operator=(STuple&& right) = default;
90 ~STuple() = default;
91};
92
93template <typename T>
94concept ConstructibleFromTerm = requires(const cvc5::Term& term, Solver* s, TermType type) { T{ term, s, type }; };
95
108template <typename sym_index, ConstructibleFromTerm sym_entry> class SymArray {
109 private:
110 public:
112 cvc5::Term term;
113
117
123
125 : solver(s)
126 , term(term)
127 , type(type)
128 {
129 if (!this->solver->lookup_enabled) {
130 throw std::logic_error("You have to enable lookups during Solver initialization");
131 }
132 };
133
144 SymArray(const cvc5::Sort& index_sort,
145 const TermType& index_type,
146 const cvc5::Sort& entry_sort,
147 const TermType& entry_type,
148 Solver* s,
149 const std::string& name = "")
150 : solver(s)
153 {
154 if (!this->solver->lookup_enabled) {
155 throw std::logic_error("You have to enable lookups during Solver initialization");
156 }
157
158 cvc5::Sort Array = this->solver->term_manager.mkArraySort(index_sort, entry_sort);
159 if (name.empty()) {
160 this->term = this->solver->term_manager.mkConst(Array);
161 } else {
162 this->term = this->solver->term_manager.mkConst(Array, name);
163 }
164 }
165
174 const std::vector<sym_entry>& entries,
175 const std::string& name = "")
176 {
177 if (entries.size() == 0 || indicies.size() == 0) {
178 throw std::invalid_argument("Empty vector occured during SymArray initialization");
179 }
180
181 if (entries.size() != indicies.size()) {
182 throw std::invalid_argument("Indicies must have the same dimension as entries.");
183 }
184
185 this->solver = entries[0].solver;
186
187 if (!this->solver->lookup_enabled) {
188 throw std::logic_error("You have to enable lookups during Solver initialization");
189 }
190
191 this->ind_type = indicies[0].type;
192 this->entry_type = entries[0].type;
193
194 cvc5::Sort ind_sort = indicies[0].term.getSort();
195 cvc5::Sort entry_sort = entries[0].term.getSort();
196 cvc5::Sort Array = this->solver->term_manager.mkArraySort(ind_sort, entry_sort);
197 if (name.empty()) {
198 this->term = this->solver->term_manager.mkConst(Array);
199 } else {
200 this->term = this->solver->term_manager.mkConst(Array, name);
201 }
202
203 for (size_t i = 0; i < indicies.size(); i++) {
204 this->term =
205 this->solver->term_manager.mkTerm(cvc5::Kind::STORE, { this->term, indicies[i].term, entries[i].term });
206 }
207 }
208
218 SymArray(const std::vector<sym_entry>& entries, const STerm& index_base, const std::string& name = "")
220 {
221 if (entries.size() == 0) {
222 throw std::invalid_argument("Empty vector occured during SymArray initialization");
223 }
224 this->solver = entries[0].solver;
225
226 if (!this->solver->lookup_enabled) {
227 throw std::logic_error("You have to enable lookups during Solver initialization");
228 }
229
230 this->entry_type = entries[0].type;
231
232 cvc5::Sort ind_sort = index_base.term.getSort();
233 cvc5::Sort entry_sort = entries[0].term.getSort();
234 cvc5::Sort Array = this->solver->term_manager.mkArraySort(ind_sort, entry_sort);
235 if (name.empty()) {
236 this->term = this->solver->term_manager.mkConst(Array);
237 } else {
238 this->term = this->solver->term_manager.mkConst(Array, name);
239 }
240
241 for (size_t i = 0; i < entries.size(); i++) {
242 STerm idx = STerm::Const(i, this->solver, this->ind_type);
243 this->term = this->solver->term_manager.mkTerm(cvc5::Kind::STORE, { this->term, idx, entries[i] });
244 }
245 }
246
248 {
249 cvc5::Term res_term = this->solver->term_manager.mkTerm(cvc5::Kind::SELECT, { this->term, ind.term });
250 return { res_term, this->solver, this->entry_type };
251 }
252
253 sym_entry operator[](const sym_index& ind) const { return this->get(ind); }
254
255 void put(const sym_index& ind, const sym_entry& entry)
256 {
257 this->term = this->solver->term_manager.mkTerm(cvc5::Kind::STORE, { this->term, ind.term, entry.term });
258 }
259
260 operator std::string() const { return this->solver->stringify_term(term); };
261 operator cvc5::Term() const { return term; };
262
263 void print_trace() const { this->solver->print_array_trace(this->term); }
264
265 friend std::ostream& operator<<(std::ostream& out, const SymArray& term)
266 {
268 };
269
270 SymArray(const SymArray& other) = default;
271 SymArray(SymArray&& other) = default;
272 SymArray& operator=(const SymArray& right) = default;
273 SymArray& operator=(SymArray&& right) = default;
274 ~SymArray() = default;
275};
276
289template <ConstructibleFromTerm sym_entry> class SymSet {
290 private:
291 public:
293 cvc5::Term term;
294
297
299 : solver(nullptr)
300 , term(cvc5::Term())
302
303 SymSet(const cvc5::Term& term, Solver* s, TermType type = TermType::SymSet)
304 : solver(s)
305 , term(term)
306 , type(type) {};
307
316 SymSet(const cvc5::Sort& entry_sort, TermType entry_type, Solver* s, const std::string& name = "")
317 : solver(s)
319 {
320 if (!this->solver->lookup_enabled) {
321 throw std::logic_error("You have to enable lookups during Solver initialization");
322 }
323
324 cvc5::Sort Array = this->solver->term_manager.mkSetSort(entry_sort);
325 if (name.empty()) {
326 this->term = this->solver->term_manager.mkConst(Array);
327 } else {
328 this->term = this->solver->term_manager.mkConst(Array, name);
329 }
330 }
331
338 SymSet(const std::vector<sym_entry>& entries, const std::string& name = "")
339 {
340 if (entries.size() == 0) {
341 throw std::invalid_argument("Empty vector occured during SymSet initialization");
342 }
343
344 this->solver = entries[0].solver;
345 if (!this->solver->lookup_enabled) {
346 throw std::logic_error("You have to enable lookups during Solver initialization");
347 }
348
349 this->entry_type = entries[0].type;
350
351 cvc5::Sort entry_sort = entries[0].term.getSort();
352 cvc5::Sort SET = this->solver->term_manager.mkSetSort(entry_sort);
353 if (name.empty()) {
354 this->term = this->solver->term_manager.mkConst(SET);
355 } else {
356 this->term = this->solver->term_manager.mkConst(SET, name);
357 }
358
360 terms_.reserve(entries.size() + 1);
361 auto map = [](const sym_entry& t) -> cvc5::Term { return t.term; };
362 std::transform(entries.begin(), entries.end(), std::back_inserter(terms_), map);
363
364 terms_.push_back(this->term);
365 this->term = this->solver->term_manager.mkTerm(cvc5::Kind::SET_INSERT, terms_);
366 }
367
368 void insert(const sym_entry& entry)
369 {
370 this->term = this->solver->term_manager.mkTerm(cvc5::Kind::SET_INSERT, { entry.term, this->term });
371 }
372
379 void contains(const sym_entry& entry) const
380 {
381 // TODO(alex): Should use entry.normalize() here, but didn't come up with any quick solution
382 // other than adding a SymbolicBase class or smth
383 sym_entry left = entry;
384 cvc5::Term inclusion = this->solver->term_manager.mkTerm(cvc5::Kind::SET_MEMBER, { entry.term, this->term });
385 this->solver->assertFormula(inclusion);
386 }
387
393 void not_contains(const sym_entry& entry) const
394 {
395 // TODO(alex): Should use entry.normalize() here, but didn't come up with any quick solution
396 // other than adding a SymbolicBase class or smth
397 sym_entry left = entry;
398 cvc5::Term inclusion = this->solver->term_manager.mkTerm(cvc5::Kind::SET_MEMBER, { entry.term, this->term });
399 cvc5::Term not_inclusion = this->solver->term_manager.mkTerm(cvc5::Kind::NOT, { inclusion });
400 this->solver->assertFormula(not_inclusion);
401 }
402
403 operator std::string() const { return this->solver->stringify_term(term); };
404 operator cvc5::Term() const { return term; };
405
406 void print_trace() const { this->solver->print_set_trace(this->term); }
407
408 friend std::ostream& operator<<(std::ostream& out, const SymSet& term)
409 {
410 return out << static_cast<std::string>(term);
411 };
412
413 SymSet(const SymSet& other) = default;
414 SymSet(SymSet&& other) = default;
415 SymSet& operator=(const SymSet& right) = default;
416 SymSet& operator=(SymSet&& right) = default;
417 ~SymSet() = default;
418};
419
420} // namespace smt_terms
Class for the solver.
Definition solver.hpp:80
std::pair< std::string, size_t > print_set_trace(const cvc5::Term &term, bool is_head=true)
print the trace of SET insertions up to previously printed ones
Definition solver.cpp:168
void assertFormula(const cvc5::Term &term) const
Definition solver.hpp:158
std::pair< std::string, size_t > print_array_trace(const cvc5::Term &term, bool is_head=true)
print the trace of array assigments up to previously printed ones
Definition solver.cpp:116
cvc5::Solver solver
Definition solver.hpp:83
cvc5::TermManager term_manager
Definition solver.hpp:82
std::string stringify_term(const cvc5::Term &term, bool parenthesis=false)
Definition solver.cpp:235
Symbolic term element class.
Definition term.hpp:114
static STerm Const(const std::string &val, Solver *slv, uint32_t base=16, TermType type=TermType::FFTerm)
Definition term.cpp:29
sym Tuple class
STuple & operator=(STuple &&right)=default
STuple(const std::vector< STerm > &terms)
Construct a new STuple object.
friend std::ostream & operator<<(std::ostream &out, const STuple &term)
void operator!=(const STuple &other) const
STuple & operator=(const STuple &right)=default
STuple(STuple &&other)=default
void operator==(const STuple &other) const
cvc5::Sort get_sort() const
Get the obtained tuple sort.
operator cvc5::Term() const
STuple(const cvc5::Term &term, Solver *s, TermType type=TermType::STuple)
STuple(const STuple &other)=default
symbolic Array class
void put(const sym_index &ind, const sym_entry &entry)
SymArray & operator=(SymArray &&right)=default
SymArray(const cvc5::Term &term, Solver *s, TermType type=TermType::SymArray)
sym_entry get(const sym_index &ind) const
SymArray(const cvc5::Sort &index_sort, const TermType &index_type, const cvc5::Sort &entry_sort, const TermType &entry_type, Solver *s, const std::string &name="")
Construct an empty Symbolic Array object.
operator cvc5::Term() const
SymArray & operator=(const SymArray &right)=default
SymArray(const std::vector< sym_entry > &entries, const STerm &index_base, const std::string &name="")
Construct a new Symbolic Array object.
sym_entry operator[](const sym_index &ind) const
SymArray(const SymArray &other)=default
friend std::ostream & operator<<(std::ostream &out, const SymArray &term)
SymArray(const std::vector< sym_index > &indicies, const std::vector< sym_entry > &entries, const std::string &name="")
Construct a new Symbolic Array object.
SymArray(SymArray &&other)=default
symbolic Set class
void insert(const sym_entry &entry)
SymSet(const std::vector< sym_entry > &entries, const std::string &name="")
Construct a new Symbolic Set object.
SymSet & operator=(const SymSet &right)=default
SymSet(SymSet &&other)=default
SymSet(const SymSet &other)=default
void not_contains(const sym_entry &entry) const
Create an inclusion constraint.
operator cvc5::Term() const
SymSet(const cvc5::Term &term, Solver *s, TermType type=TermType::SymSet)
SymSet(const cvc5::Sort &entry_sort, TermType entry_type, Solver *s, const std::string &name="")
Construct a new empty Symbolic Set object.
friend std::ostream & operator<<(std::ostream &out, const SymSet &term)
SymSet & operator=(SymSet &&right)=default
void contains(const sym_entry &entry) const
Create an inclusion constraint.
TermType
Allows to define three types of symbolic terms STerm - Symbolic Variables acting like a Finte Field e...
Definition term.hpp:15
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13