1
+ #pragma once
2
+ #include " barretenberg/stdlib_circuit_builders/standard_circuit_builder.hpp"
3
+ #include " barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp"
4
+ #include < list>
5
+ #include < set>
6
+ #include < unordered_map>
7
+ #include < unordered_set>
8
+ #include < utility>
9
+ #include < vector>
10
+
11
+ /*
12
+ * this class describes arithmetic circuit as an undirected graph, where vertices are variables from circuit.
13
+ * edges describe connections between variables through gates. We want to find variables that weren't properly
14
+ * constrainted/some connections were missed using additional metrics, like in how much gate variable was and number of
15
+ * connected components in the graph. if variable was in one connected component, it means that this variable wasn't
16
+ * constrained properly. if number of connected components > 1, it means that there were missed some connections between
17
+ * variables.
18
+ */
19
+ template <typename FF> class Graph_ {
20
+ public:
21
+ Graph_ () = default ;
22
+ Graph_ (const Graph_& other) = delete ;
23
+ Graph_ (Graph_&& other) = delete ;
24
+ Graph_& operator =(const Graph_& other) = delete ;
25
+ Graph_&& operator =(Graph_&& other) = delete ;
26
+ Graph_ (const bb::StandardCircuitBuilder_<FF>& circuit_constructor);
27
+ Graph_ (bb::UltraCircuitBuilder& ultra_circuit_constructor);
28
+
29
+ uint32_t to_real (bb::UltraCircuitBuilder& ultra_circuit_constructor, const uint32_t & variable_index)
30
+ {
31
+ return ultra_circuit_constructor.real_variable_index [variable_index];
32
+ };
33
+ void process_gate_variables (bb::UltraCircuitBuilder& ultra_circuit_constructor,
34
+ std::vector<uint32_t >& gate_variables);
35
+
36
+ std::unordered_map<uint32_t , size_t > get_variables_gate_counts () { return this ->variables_gate_counts ; };
37
+
38
+ std::vector<uint32_t > get_arithmetic_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
39
+ size_t index);
40
+ std::vector<uint32_t > get_elliptic_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
41
+ size_t index);
42
+ std::vector<uint32_t > get_plookup_gate_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
43
+ size_t index);
44
+ std::vector<uint32_t > get_sort_constraint_connected_component (bb::UltraCircuitBuilder& ultra_circuit_builder,
45
+ size_t index);
46
+
47
+ void add_new_edge (const uint32_t & first_variable_index, const uint32_t & second_variable_index);
48
+ std::vector<uint32_t > get_variable_adjacency_list (const uint32_t & variable_index)
49
+ {
50
+ return variable_adjacency_lists[variable_index];
51
+ };
52
+
53
+ void depth_first_search (const uint32_t & variable_index,
54
+ std::unordered_set<uint32_t >& is_used,
55
+ std::vector<uint32_t >& connected_component);
56
+ std::vector<std::vector<uint32_t >> find_connected_components ();
57
+
58
+ std::vector<uint32_t > find_variables_with_degree_one ();
59
+ std::unordered_set<uint32_t > get_variables_in_one_gate ();
60
+
61
+ bool find_arithmetic_gate_for_variable (bb::UltraCircuitBuilder& ultra_circuit_builder,
62
+ const uint32_t & variable_idx);
63
+ bool find_elliptic_gate_for_variable (bb::UltraCircuitBuilder& ultra_circuit_builder, const uint32_t & variable_idx);
64
+ bool find_lookup_gate_for_variable (bb::UltraCircuitBuilder& ultra_circuit_builder, const uint32_t & variable_idx);
65
+
66
+ size_t get_distance_between_variables (const uint32_t & first_variable_index, const uint32_t & second_variable_index);
67
+ bool check_vertex_in_connected_component (const std::vector<uint32_t >& connected_component,
68
+ const uint32_t & var_index);
69
+
70
+ void connect_all_variables_in_vector (bb::UltraCircuitBuilder& ultra_circuit_builder,
71
+ const std::vector<uint32_t >& variables_vector,
72
+ bool is_sorted_variables);
73
+ bool check_is_not_constant_variable (bb::UltraCircuitBuilder& ultra_circuit_builder, const uint32_t & variable_index);
74
+
75
+ std::pair<std::vector<uint32_t >, size_t > get_connected_component_with_index (
76
+ const std::vector<std::vector<uint32_t >>& connected_components, size_t index);
77
+
78
+ std::unordered_set<uint32_t > get_variables_in_one_gate_without_range_constraints (
79
+ bb::UltraCircuitBuilder& ultra_circuit_builder);
80
+
81
+ size_t process_current_decompose_chain (bb::UltraCircuitBuilder& ultra_circuit_constructor,
82
+ std::unordered_set<uint32_t >& variables_in_one_gate,
83
+ size_t index);
84
+ void process_current_plookup_gate (bb::UltraCircuitBuilder& ultra_circuit_builder,
85
+ std::unordered_set<uint32_t >& variables_in_one_gate,
86
+ size_t gate_index);
87
+ void remove_unnecessary_decompose_variables (bb::UltraCircuitBuilder& ultra_circuit_builder,
88
+ std::unordered_set<uint32_t >& variables_in_on_gate,
89
+ const std::unordered_set<uint32_t >& decompose_variables);
90
+ void remove_unnecessary_plookup_variables (bb::UltraCircuitBuilder& ultra_circuit_builder,
91
+ std::unordered_set<uint32_t >& variables_in_on_gate);
92
+ std::unordered_set<uint32_t > show_variables_in_one_gate (bb::UltraCircuitBuilder& ultra_circuit_builder);
93
+
94
+ void remove_unnecessary_aes_plookup_variables (std::unordered_set<uint32_t >& variables_in_one_gate,
95
+ bb::UltraCircuitBuilder& ultra_circuit_builder,
96
+ bb::plookup::BasicTableId& table_id,
97
+ size_t gate_index);
98
+ void remove_unnecessary_sha256_plookup_variables (std::unordered_set<uint32_t >& variables_in_one_gate,
99
+ bb::UltraCircuitBuilder& ultra_circuit_builder,
100
+ bb::plookup::BasicTableId& table_id,
101
+ size_t gate_index);
102
+
103
+ void print_graph ();
104
+ void print_connected_components ();
105
+ void print_variables_gate_counts ();
106
+ void print_variables_edge_counts ();
107
+ ~Graph_ () = default ;
108
+
109
+ private:
110
+ std::unordered_map<uint32_t , std::vector<uint32_t >>
111
+ variable_adjacency_lists; // we use this data structure to contain information about variables and their
112
+ // connections between each other
113
+ std::unordered_map<uint32_t , size_t >
114
+ variables_gate_counts; // we use this data structure to count, how many gates use every variable
115
+ std::unordered_map<uint32_t , size_t >
116
+ variables_degree; // we use this data structure to count, how many every variable have edges
117
+ };
118
+
119
+ using Graph = Graph_<bb::fr>;
0 commit comments