6#include <unordered_map>
8#include "barretenberg/serialize/cbind.hpp"
9#include "barretenberg/serialize/msgpack.hpp"
11#include "barretenberg/smt_verification/terms/bool.hpp"
12#include "barretenberg/smt_verification/terms/ffiterm.hpp"
13#include "barretenberg/smt_verification/terms/ffterm.hpp"
15namespace smt_circuit {
16using namespace smt_solver;
17using namespace smt_terms;
21 std::vector<uint32_t> public_inps;
22 std::unordered_map<uint32_t, std::string> vars_of_interest;
23 std::vector<barretenberg::fr> variables;
24 std::vector<std::vector<barretenberg::fr>> selectors;
25 std::vector<std::vector<uint32_t>> wires;
26 MSGPACK_FIELDS(modulus, public_inps, vars_of_interest, variables, selectors, wires);
43 std::vector<std::string> variables;
44 std::vector<uint32_t> public_inps;
45 std::unordered_map<uint32_t, std::string> vars_of_interest;
46 std::unordered_map<std::string, uint32_t> terms;
47 std::vector<std::vector<std::string>> selectors;
48 std::vector<std::vector<uint32_t>> wires_idxs;
59 FF operator[](
const uint32_t& idx) {
return vars[idx]; };
60 inline uint32_t get_num_gates()
const {
return static_cast<uint32_t
>(selectors.size()); };
61 inline uint32_t get_num_vars()
const {
return static_cast<uint32_t
>(vars.size()); };
73 : public_inps(circuit_info.public_inps)
74 , vars_of_interest(circuit_info.vars_of_interest)
75 , wires_idxs(circuit_info.wires)
79 if (!this->tag.empty()) {
80 if (this->tag[0] !=
'_') {
81 this->tag =
"_" + this->tag;
85 for (
auto var : circuit_info.variables) {
86 std::stringstream buf;
88 std::string tmp = buf.str();
90 variables.push_back(tmp);
93 for (
auto& x : vars_of_interest) {
94 terms.insert({ x.second, x.first });
97 vars_of_interest.insert({ 0,
"zero" });
98 vars_of_interest.insert({ 1,
"one" });
99 terms.insert({
"zero", 0 });
100 terms.insert({
"one", 1 });
102 for (
auto sel : circuit_info.selectors) {
103 std::vector<std::string> tmp_sel;
104 for (
size_t j = 0; j < 5; j++) {
105 std::stringstream buf;
107 std::string q_i = buf.str();
109 tmp_sel.push_back(q_i);
111 selectors.push_back(tmp_sel);
125 size_t num_vars = variables.size();
127 vars.push_back(FF::Var(
"zero" + this->tag, this->solver));
128 vars.push_back(FF::Var(
"one" + this->tag, this->solver));
130 for (
size_t i = 2; i < num_vars; i++) {
131 if (vars_of_interest.contains(
static_cast<uint32_t
>(i))) {
132 std::string name = vars_of_interest[
static_cast<uint32_t
>(i)];
133 vars.push_back(FF::Var(name + this->tag, this->solver));
135 vars.push_back(FF::Var(
"var_" + std::to_string(i) + this->tag, this->solver));
139 vars[0] == FF::Const(
"0", this->solver);
140 vars[1] == FF::Const(
"1", this->solver);
142 for (
auto i : public_inps) {
143 vars[i] == FF::Const(variables[i], this->solver);
151template <
typename FF>
void Circuit<FF>::add_gates()
153 for (
size_t i = 0; i < get_num_gates(); i++) {
154 FF q_m = FF::Const(selectors[i][0], this->solver);
155 FF q_1 = FF::Const(selectors[i][1], this->solver);
156 FF q_2 = FF::Const(selectors[i][2], this->solver);
157 FF q_3 = FF::Const(selectors[i][3], this->solver);
158 FF q_c = FF::Const(selectors[i][4], this->solver);
160 uint32_t w_l = wires_idxs[i][0];
161 uint32_t w_r = wires_idxs[i][1];
162 uint32_t w_o = wires_idxs[i][2];
170 if (w_l == w_r && w_r == w_o) {
171 if (std::string(q_m) ==
"1" && std::string(q_1) ==
"0" && std::string(q_2) ==
"0" &&
172 std::string(q_3) ==
"-1" && std::string(q_c) ==
"0") {
173 (
Bool(vars[w_l]) ==
Bool(vars[0]) |
Bool(vars[w_l]) ==
Bool(vars[1])).assert_term();
180 if (std::string(q_m) !=
"0") {
181 eq += q_m * vars[w_l] * vars[w_r];
184 if (std::string(q_1) !=
"0") {
185 eq += q_1 * vars[w_l];
188 if (std::string(q_2) !=
"0") {
189 eq += q_2 * vars[w_r];
192 if (std::string(q_3) !=
"0") {
193 eq += q_3 * vars[w_o];
196 if (std::string(q_c) !=
"0") {
211 if (!this->terms.contains(name)) {
212 throw std::length_error(
"No such an item " + name +
" in vars or it vas not declared as interesting");
214 uint32_t idx = this->terms[name];
215 return this->vars[idx];
218CircuitSchema unpack_from_buffer(
const msgpack::sbuffer& buf);
221template <
typename FF>
224 const std::vector<std::string>& equal = {},
225 const std::vector<std::string>& not_equal = {},
226 const std::vector<std::string>& equal_at_the_same_time = {},
227 const std::vector<std::string>& not_eqaul_at_the_same_time = {});
229extern template std::pair<Circuit<FFTerm>, Circuit<FFTerm>> unique_witness(
230 CircuitSchema& circuit_info,
232 const std::vector<std::string>& equal = {},
233 const std::vector<std::string>& not_equal = {},
234 const std::vector<std::string>& equal_at_the_same_time = {},
235 const std::vector<std::string>& not_eqaul_at_the_same_time = {});
237extern template std::pair<Circuit<FFITerm>, Circuit<FFITerm>> unique_witness(
238 CircuitSchema& circuit_info,
240 const std::vector<std::string>& equal = {},
241 const std::vector<std::string>& not_equal = {},
242 const std::vector<std::string>& equal_at_the_same_time = {},
243 const std::vector<std::string>& not_eqaul_at_the_same_time = {});
Symbolic Circuit class.
Definition: circuit.hpp:37
FF operator[](const std::string &name)
Returns a previously named symbolic variable.
Definition: circuit.hpp:209
Class for the solver.
Definition: solver.hpp:28
Bool element class.
Definition: bool.hpp:15
Definition: circuit.hpp:19