Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
test_interaction_builder.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstdint>
5#include <string>
6
13
14namespace bb::avm2::tracegen {
15
16// Adds checks to a lookup builder. The BaseBuilder needs to be an IndexedLookupTraceBuilder.
17template <typename BaseBuilder> class AddChecksToBuilder : public BaseBuilder {
19 "BaseBuilder must be an IndexedLookupTraceBuilder");
20
21 public:
22 // Inherit the base constructors (incl. the outer_dst_selector one) so a strict-mode interaction can be
23 // registered with an explicit outer selector.
24 using BaseBuilder::BaseBuilder;
25
26 using TupleType = typename BaseBuilder::TupleType;
27 ~AddChecksToBuilder() override = default;
28
29 void init(TraceContainer& trace) override
30 {
31 BaseBuilder::init(trace);
32 this->trace = &trace;
33 }
34
35 uint32_t find_in_dst(const TupleType& src_values) const override
36 {
37 uint32_t dst_row = BaseBuilder::find_in_dst(src_values);
38
39 auto dst_values = trace->get_multiple(BaseBuilder::LookupSettings::DST_COLUMNS, dst_row);
40 if (src_values != dst_values) {
41 throw std::runtime_error("Failed computing counts for " + std::string(BaseBuilder::LookupSettings::NAME) +
42 ". Could not find tuple in destination. " + "SRC tuple: " +
43 column_values_to_string(src_values, BaseBuilder::LookupSettings::SRC_COLUMNS));
44 }
45
46 return dst_row;
47 }
48
49 private:
51};
52
53// Builds a permutation and performs additional checks.
54// Only use in tests and debugging. This is slow and memory intensive.
55template <typename PermutationSettings>
56class CheckingPermutationBuilder : public PermutationBuilder<PermutationSettings> {
57 public:
58 // Owning value array; see get_multiple_as_array in interaction_builder.hpp for why we can't key on RefTuple.
60
61 void process(TraceContainer& trace) override
62 {
64
65 // Collect the source and destination tuples.
66 source_tuples.clear();
67 trace.visit_column(PermutationSettings::SRC_SELECTOR, [&](uint32_t row, const FF&) {
68 source_tuples[get_multiple_as_array(trace, PermutationSettings::SRC_COLUMNS, row)].insert(row);
69 });
70 destination_tuples.clear();
71 trace.visit_column(PermutationSettings::DST_SELECTOR, [&](uint32_t row, const FF&) {
72 destination_tuples[get_multiple_as_array(trace, PermutationSettings::DST_COLUMNS, row)].insert(row);
73 });
74
75 auto build_error_message =
76 [&](const ArrayTuple& tuple, const auto& columns, const auto& src_rows, const auto& dst_rows) {
77 std::string error = "Failure to build permutation " + std::string(PermutationSettings::NAME) + ".\n";
78 error += format("Tuple ",
79 column_values_to_string(tuple, columns),
80 " has multiplicity ",
81 src_rows.size(),
82 " in the source, but ",
83 dst_rows.size(),
84 " in the destination.\n");
85 error += format("Source rows: ");
86 for (auto row : src_rows) {
87 error += format(row, " ");
88 }
89 error += format("\n");
90 error += format("Destination rows: ");
91 for (auto row : dst_rows) {
92 error += format(row, " ");
93 }
94 return error;
95 };
96
97 // Check that every source tuple is found in the destination with the same multiplicity.
98 for (const auto& [src_tuple, src_rows] : source_tuples) {
99 auto dst_rows = destination_tuples.contains(src_tuple) ? destination_tuples.at(src_tuple)
101 if (src_rows.size() != dst_rows.size()) {
102 throw std::runtime_error(
103 build_error_message(src_tuple, PermutationSettings::SRC_COLUMNS, src_rows, dst_rows));
104 }
105 }
106 // Check that every destination tuple is found in the source with the same multiplicity.
107 for (const auto& [dst_tuple, dst_rows] : destination_tuples) {
108 auto src_rows =
109 source_tuples.contains(dst_tuple) ? source_tuples.at(dst_tuple) : unordered_flat_set<uint32_t>();
110 if (src_rows.size() != dst_rows.size()) {
111 throw std::runtime_error(
112 build_error_message(dst_tuple, PermutationSettings::DST_COLUMNS, src_rows, dst_rows));
113 }
114 }
115 }
116
117 private:
120};
121
122} // namespace bb::avm2::tracegen
uint32_t find_in_dst(const TupleType &src_values) const override
void init(TraceContainer &trace) override
unordered_flat_map< ArrayTuple, unordered_flat_set< uint32_t > > source_tuples
unordered_flat_map< ArrayTuple, unordered_flat_set< uint32_t > > destination_tuples
std::array< FF, PermutationSettings::COLUMNS_PER_SET > ArrayTuple
void process(TraceContainer &) override
auto get_multiple(const std::array< ColumnAndShifts, N > &cols, uint32_t row) const
std::string format(Args... args)
Definition log.hpp:23
TestTraceContainer trace
std::array< FF, N > get_multiple_as_array(const TraceContainer &trace, const std::array< ColumnAndShifts, N > &cols, uint32_t row)
::ankerl::unordered_dense::set< Key > unordered_flat_set
Definition set.hpp:11
AvmFlavorSettings::FF FF
Definition field.hpp:10
std::string column_values_to_string(const std::array< FF, N > &arr, const std::array< ColumnAndShifts, N > &columns)
Definition stringify.hpp:46
::ankerl::unordered_dense::map< Key, T > unordered_flat_map
Definition map.hpp:15
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13