Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
data_structures.test.cpp
Go to the documentation of this file.
1#include "data_structures.hpp"
3
4#include <gtest/gtest.h>
5
6namespace {
8}
9
10using namespace bb;
11using namespace smt_terms;
12
13// --- Basic initialization tests
14
15// Test that tuple is constructed without any issues
16TEST(SymbolicTuple, Initialization)
17{
18 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
19 STerm x = FFVar("x", &s);
20 STerm y = FFVar("y", &s);
21 STerm z = x + y;
22 STuple tup({ x, y, z });
23 info(tup);
24 info(tup.get_sort());
25}
26
27// Test Array initialization FF -> FF, from unordered_map
28TEST(SymbolicArray, InitMapSTermSTerm)
29{
30 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
31 STerm x = FFVar("x", &s);
32 STerm y = FFVar("y", &s);
33 STerm z = x + y;
34 STerm q = x * y;
35
36 std::vector<STerm> indicies = { x, q };
37 std::vector<STerm> entries = { q, y };
38 SymArray<STerm, STerm> arr(indicies, entries, "Array");
39 info(arr);
40 arr.print_trace();
41}
42
43// Test Array initialization FF -> FF, from vector
44TEST(SymbolicArray, InitVecSTerm)
45{
46 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
47 STerm x = FFVar("x", &s);
48 STerm y = FFVar("y", &s);
49 STerm z = x + y;
50 STerm q = x * y;
51
52 std::vector<STerm> entries = { q, y };
53 SymArray<STerm, STerm> arr(entries, FFConst(1, &s), "Array");
54 info(arr);
55 arr.print_trace();
56}
57
58// Test Array initialization Tuple<FF> -> Tuple<FF>, from unordered_map
59TEST(SymbolicArray, InitMapSTupleSTuple)
60{
61 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
62 STerm x = FFVar("x", &s);
63 STerm y = FFVar("y", &s);
64 STerm z = x + y;
65 STerm q = x * y;
66
67 STuple t1({ x, y });
68 STuple t2({ z, x });
69 STuple t3({ q, z });
70 STuple t4({ q + z, x });
71
72 std::vector<STuple> indicies = { t1, t2 };
73 std::vector<STuple> entries = { t3, t4 };
74 SymArray<STuple, STuple> arr(indicies, entries, /*name=*/"Array");
75 info(arr);
76 arr.print_trace();
77}
78
79// Test Array initialization Int -> Tuple<FF>, from vector
80TEST(SymbolicArray, InitVecSTuple)
81{
82 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
83 STerm x = FFVar("x", &s);
84 STerm y = FFVar("y", &s);
85 STerm z = x + y;
86 STerm q = x * y;
87
88 STuple t1({ x, y });
89 STuple t2({ z, x });
90 STuple t3({ q, z });
91 STuple t4({ q + z, x });
92
93 std::vector<STuple> entries = { t3, t4 };
94 SymArray<STerm, STuple> arr(entries, IConst(1, &s), "Array");
95 info(arr);
96 arr.print_trace();
97}
98
99// Test Array initialization Tuple<FF> -> FF, from unordered_map
100TEST(SymbolicArray, InitMapSTupleSTerm)
101{
102 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
103 STerm x = FFVar("x", &s);
104 STerm y = FFVar("y", &s);
105 STerm z = x + y;
106 STerm q = x * y;
107
108 STuple t1({ x, y });
109 STuple t2({ z, x });
110 STuple t3({ q, z });
111 STuple t4({ q + z, x });
112
113 std::vector<STuple> indicies = { t3, t4 };
114 std::vector<STerm> entries = { q, z };
115 SymArray<STuple, STerm> arr(indicies, entries, "Array");
116 info(arr);
117 arr.print_trace();
118}
119
120// Test Set initialization { FF }, from vector
121TEST(SymbolicSet, InitVecSTerm)
122{
123 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
124 STerm x = FFVar("x", &s);
125 STerm y = FFVar("y", &s);
126 STerm z = x + y;
127 STerm q = x * y;
128
129 SymSet<STerm> set({ x, y, z, q }, "Set");
130 info(set);
131 set.print_trace();
132}
133
134// Test Set initialization { Tuple<FF> }, from vector
135TEST(SymbolicSet, InitVecSTuple)
136{
137 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
138 STerm x = FFVar("x", &s);
139 STerm y = FFVar("y", &s);
140 STerm z = x + y;
141 STerm q = x * y;
142
143 STuple t1({ x, y });
144 STuple t2({ z, x });
145 STuple t3({ q, z });
146 STuple t4({ q + z, x });
147
148 SymSet<STuple> arr({ t1, t2, t3, t4 }, "Set");
149 info(arr);
150 arr.print_trace();
151}
152
153// Test
154// - empty set initialization
155// - Set insert method
156// - Set contains method
157TEST(SymbolicSet, Contains)
158{
159 Solver slv("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
160 STerm x = FFVar("x", &slv);
161 x == 1;
162 STerm y = x + 1;
163
164 SymSet<STerm> set(x.term.getSort(), x.type, &slv, "Set");
165 set.insert(x);
166 set.insert(y);
167
168 STerm z = FFConst(3, &slv);
169 set.not_contains(z);
170
171 set.insert(-x);
172 STerm q = 2 * x;
173 set.contains(q);
174
175 slv.print_assertions();
176 ASSERT_TRUE(slv.check());
177}
178
179// --- Advanced tests
180
181// Test an empty Array initialization (Tuple<FF> -> FF) -> FF:
182// - we can create an empty array
183// - we can pass Symbolic Array as index for another Symbolic Array
184// - we can put values in Array
185// - we can get vlalues from Array
186// Also test the trigger case for printing an array trace
187TEST(SymbolicArray, InitSymArraySTerm)
188{
189 Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
190 STerm x = FFVar("x", &s);
191 STerm y = FFVar("y", &s);
192 STerm z = x + y;
193 STerm q = x * y;
194
195 STuple t1({ x, y });
196 STuple t2({ z, x });
197 STuple t3({ q, z });
198 STuple t4({ q + z, x });
199
200 std::vector<STuple> indicies = { t1, t2, t3 };
201 std::vector<STerm> entries = { x, z, q };
202 SymArray<STuple, STerm> arr(indicies, entries, "mini_arr");
203
204 cvc5::Sort ind_sort = arr.term.getSort();
205 TermType ind_type = arr.type;
206 cvc5::Sort entry_sort = x.term.getSort();
207 TermType entry_type = x.type;
208 SymArray<SymArray<STuple, STerm>, STerm> arrarr(ind_sort, ind_type, entry_sort, entry_type, &s, "BIG_arr");
209
210 arrarr.put(arr, y);
211 // this will not print anything related to `arr`
212 info(arrarr);
213 arrarr.print_trace();
214
215 arrarr.put(arr, arr.get(t1));
216 // this will
217 info(arrarr);
218 arrarr.print_trace();
219}
220
221// Example of a somewhat unordinary array use case
222// Take an array that maps int -> FF
223// Obtain two different solutions to x^2 + y^2 = 50 over integers
224// constrain the array entries so we can have a unique solution
225TEST(SymbolicArray, SimpleUseCase)
226{
227 Solver slv("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
228 STerm x = IVar("x", &slv);
229 STerm y = IVar("y", &slv);
230 x > 0;
231 y > 0;
232 x < y;
233 STerm z = x * x + y * y;
234 STerm q = x * y + y * x;
235
236 STerm a = FFVar("a", &slv);
237 STerm b = FFVar("c", &slv);
238 STerm c = a * a - b;
239 c == 17;
240
241 cvc5::Sort ind_sort = z.term.getSort();
242 TermType ind_type = z.type;
243 cvc5::Sort entry_sort = c.term.getSort();
244 TermType entry_type = c.type;
245 // Indicies are ints and entries are FF!
246 SymArray<STerm, STerm> arr(ind_sort, ind_type, entry_sort, entry_type, &slv, "Int -> FF");
247
248 arr.put(z, b);
249 arr.put(q, a);
250
251 STerm m = IVar("m", &slv);
252 STerm n = IVar("n", &slv);
253 m > 0;
254 n > 0;
255 m <= n;
256
257 STerm k = m * m + n * n;
258 // 50 = 25 + 25 = 1 + 49
259 k == 50;
260 z == 50;
261 m != x;
262 n != y;
263
264 // k was not in the array, but the value is the same
265 STerm result = arr[k];
266 // In this particular system same as b == -1
267 result == bb::fr::neg_one();
268 slv.print_assertions();
269
270 ASSERT_TRUE(slv.check());
271 ASSERT_EQ(string_to_fr(slv[x], /*base=*/10), bb::fr(1));
272 ASSERT_EQ(string_to_fr(slv[y], /*base=*/10), bb::fr(7));
273 ASSERT_EQ(string_to_fr(slv[m], /*base=*/10), bb::fr(5));
274 ASSERT_EQ(string_to_fr(slv[n], /*base=*/10), bb::fr(5));
275 ASSERT_EQ(string_to_fr(slv[a * a], /*base=*/10), bb::fr(16));
276}
277
278// Test that we can successfully overwrite values in the array
279TEST(SymbolicArray, OverWrite)
280{
281 Solver slv("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
282 STerm x = BVVar("x", &slv);
283 STerm y = BVVar("y", &slv);
284
285 STerm a = IConst(3, &slv);
286 STerm b = IConst("4", &slv, /*base=*/10);
287 ;
288
289 SymArray<STerm, STerm> table(x.term.getSort(), x.type, a.term.getSort(), a.type, &slv, /*name=*/"rewrite");
290
291 table.put(x, a);
292 table.put(y, b);
293 x == y;
294
295 STerm z = table[x];
296
297 ASSERT_TRUE(slv.check());
298 ASSERT_EQ(string_to_fr(slv[z], /*base=*/10), bb::fr(4));
299}
300
301// Test that we can mimic lookup tables functionality using arrays
302TEST(SymbolicArray, LookupTable)
303{
304 Solver slv("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
305
306 STuple table_idx1({ FFConst("1", &slv), FFConst("2", &slv) });
307 STerm table_entry1 = FFConst("3", &slv);
308
309 STuple table_idx2({ FFConst("4", &slv), FFConst("5", &slv) });
310 STerm table_entry2 = FFConst("6", &slv);
311
312 SymArray<STuple, STerm> stable({ table_idx1, table_idx2 }, { table_entry1, table_entry2 }, "guess_next");
313
314 STerm x = FFVar("x", &slv);
315 STerm y = FFVar("y", &slv);
316 STuple entry({ x, y });
317
318 STerm z = stable[entry];
319 y - x == 1;
320 y + x == 3;
321
322 ASSERT_TRUE(slv.check());
323
324 std::string xval = slv[x];
325 ASSERT_EQ(xval, "1");
326 std::string yval = slv[y];
327 ASSERT_EQ(yval, "2");
328 std::string zval = slv[z];
329 ASSERT_EQ(zval, "3");
330}
331
332// Test that we can mimic lookup tables functionality using sets
333TEST(SymbolicSet, LookupTable)
334{
335 Solver slv("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001");
336
337 STuple table_entry1({ FFConst("1", &slv), FFConst("2", &slv), FFConst("3", &slv) });
338 STuple table_entry2({ FFConst("4", &slv), FFConst("5", &slv), FFConst("6", &slv) });
339 SymSet<STuple> stable({ table_entry1, table_entry2 }, "guess_next");
340
341 STerm x = FFVar("x", &slv);
342 STerm y = FFVar("y", &slv);
343 STerm z = FFVar("z", &slv);
344 STuple entry({ x, y, z });
345
346 stable.contains(entry);
347 x != 4;
348
349 ASSERT_TRUE(slv.check());
350
351 std::string xval = slv[x];
352 ASSERT_EQ(xval, "1");
353 std::string yval = slv[y];
354 ASSERT_EQ(yval, "2");
355 std::string zval = slv[z];
356 ASSERT_EQ(zval, "3");
357}
Class for the solver.
Definition solver.hpp:80
void print_assertions()
Definition solver.cpp:421
Symbolic term element class.
Definition term.hpp:114
TermType type
Definition term.hpp:123
cvc5::Term term
Definition term.hpp:121
sym Tuple class
symbolic Array class
void put(const sym_index &ind, const sym_entry &entry)
sym_entry get(const sym_index &ind) const
symbolic Set class
void insert(const sym_entry &entry)
void not_contains(const sym_entry &entry) const
Create an inclusion constraint.
void contains(const sym_entry &entry) const
Create an inclusion constraint.
void info(Args... args)
Definition log.hpp:70
FF a
FF b
numeric::RNG & engine
RNG & get_randomness()
Definition engine.cpp:203
Entry point for Barretenberg command-line interface.
TEST(MegaCircuitBuilder, CopyConstructor)
STerm IVar(const std::string &name, Solver *slv)
Definition term.cpp:600
STerm FFVar(const std::string &name, Solver *slv)
Definition term.cpp:570
STerm IConst(const std::string &val, Solver *slv, uint32_t base)
Definition term.cpp:605
STerm BVVar(const std::string &name, Solver *slv)
Definition term.cpp:615
STerm FFConst(const std::string &val, Solver *slv, uint32_t base)
Definition term.cpp:575
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
bb::fr string_to_fr(const std::string &number, int base, bool is_signed, size_t step)
Converts a string of an arbitrary base to fr. Note: there should be no prefix.
Definition smt_util.cpp:13
static constexpr field neg_one()