33 using size_t_for_storage = uint32_t;
35 size_t_for_storage ki;
36 size_t_for_storage op0, op1;
41 explicit term(
size_t ki,
size_t op0,
size_t op1)
43 op0(std::min<size_t>(op0, op1)),
44 op1(std::max<size_t>(op0, op1)) {
48 proofs::check(ki != 0,
"ki != 0");
55 : ki(0), op0(0), op1(op) {}
57 bool ltndx(
const term& y)
const {
58 if (op1 < y.op1)
return true;
59 if (op1 > y.op1)
return false;
62 bool eqndx(
const term& y)
const {
return (op1 == y.op1 && op0 == y.op0); }
65 bool constant()
const {
return op0 == 0 && op1 == 0; }
68 bool linearp()
const {
return op0 == 0; }
70 bool operator==(
const term& y)
const {
71 return ki == y.ki && op0 == y.op0 && op1 == y.op1;
78 using size_t_for_storage = term::size_t_for_storage;
80 static const constexpr quad_corner_t kWireIdUndefined = quad_corner_t(-1);
82 size_t_for_storage depth;
83 quad_corner_t desired_wire_id_for_input;
84 quad_corner_t desired_wire_id_for_output;
85 size_t_for_storage max_needed_depth;
93 desired_wire_id_for_input(kWireIdUndefined),
94 desired_wire_id_for_output(kWireIdUndefined),
103 quad_corner_t desired_wire_id(
size_t depth0,
size_t depth_ub)
const {
104 if (is_input && depth0 == 0) {
105 return desired_wire_id_for_input;
107 if (is_output && depth0 + 1 == depth_ub) {
108 return desired_wire_id_for_output;
110 return kWireIdUndefined;
119 std::vector<term> terms;
123 explicit NodeF(quad_corner_t
id) : terms() {
124 info.is_input =
true;
125 info.desired_wire_id_for_input = id;
128 explicit NodeF(
size_t ki,
size_t op0,
size_t op1) : terms() {
130 terms.push_back(
term(ki, op0, op1));
134 explicit NodeF(
const std::vector<term>& terms) : terms(terms) {}
136 bool zero()
const {
return !info.is_input && terms.empty(); }
137 bool constant()
const {
return terms.size() == 1 && terms[0].constant(); }
138 bool linearp()
const {
return terms.size() == 1 && terms[0].linearp(); }
140 bool operator==(
const NodeF& y)
const {
141 if (info.is_input != y.info.is_input)
return false;
142 if (info.desired_wire_id_for_input != y.info.desired_wire_id_for_input)
144 if (info.is_output != y.info.is_output)
return false;
145 if (info.desired_wire_id_for_output != y.info.desired_wire_id_for_output)
147 if (info.is_input != y.info.is_input)
return false;
148 if (terms.size() != y.terms.size())
return false;
149 size_t l = terms.size();
150 for (
size_t i = 0; i < l; ++i) {
151 if (!(terms[i] == y.terms[i]))
return false;
155 uint64_t hash()
const {
157 crc = crc64::update(crc,
158 static_cast<uint64_t
>(info.desired_wire_id_for_input));
159 crc = crc64::update(crc,
160 static_cast<uint64_t
>(info.desired_wire_id_for_output));
161 crc = crc64::update(crc, info.is_input);
162 crc = crc64::update(crc, info.is_output);
163 size_t l = terms.size();
164 crc = crc64::update(crc, l);
165 for (
size_t i = 0; i < l; ++i) {
166 crc = crc64::update(crc, terms[i].ki);
167 crc = crc64::update(crc, terms[i].op0);
168 crc = crc64::update(crc, terms[i].op1);