6#include <gtest/gtest.h>
11#pragma GCC diagnostic ignored "-Wunused-const-variable"
17template <
class Builder_>
class BoolTest :
public ::testing::Test {
34 for (
bool is_const : {
false,
true }) {
35 for (
bool value : {
false,
true }) {
36 for (
bool is_inverted : {
false,
true }) {
52 const std::function<
bool(
bool,
bool)>& expected_op)
61 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
63 if (!
a.is_constant() && !
b.is_constant()) {
64 a.set_origin_tag(submitted_value_origin_tag);
65 b.set_origin_tag(challenge_origin_tag);
69 bool expected = expected_op(lhs.value ^ lhs.is_inverted, rhs.value ^ rhs.is_inverted);
72 <<
"Failed on " << op_name <<
" with inputs: lhs = {const=" << lhs.is_const <<
", val=" << lhs.value
73 <<
", inv=" << lhs.is_inverted <<
"}, rhs = {const=" << rhs.is_const <<
", val=" << rhs.value
74 <<
", inv=" << rhs.is_inverted <<
"}";
76 if (
a.is_constant() &&
b.is_constant()) {
80 if (!
a.is_constant() && !
b.is_constant()) {
87 size_t diff =
builder.get_estimated_num_finalized_gates() - num_gates_start;
89 EXPECT_EQ(diff,
static_cast<size_t>(!
a.is_constant() && !
b.is_constant()));
99 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
107 EXPECT_TRUE(num_gates_start ==
builder.get_estimated_num_finalized_gates());
113 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
114 const size_t witness_idx_zero =
builder.add_variable(
bb::fr(0));
115 const size_t witness_idx_one =
builder.add_variable(
bb::fr(1));
116 const size_t non_bool_witness_idx =
builder.add_variable(
bb::fr(15));
119 EXPECT_EQ(bool_witness.
get_value(),
false);
122 EXPECT_EQ(bool_witness.
get_value(),
true);
124 EXPECT_EQ(
builder.get_estimated_num_finalized_gates() - num_gates_start, 0);
128 "bool_t: creating a witness bool from a non-boolean value");
133 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
142 EXPECT_TRUE(
builder.get_estimated_num_finalized_gates() - num_gates_start == 2);
149 if (random_value * random_value - random_value != 0) {
151 "((other.witness == bb::fr::one()) || (other.witness == bb::fr::zero()))");
157 const bool use_range_constraint =
true;
159 for (
size_t num_inputs = 1; num_inputs < 50; num_inputs++) {
161 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
163 std::vector<uint32_t> indices;
164 for (
size_t idx = 0; idx < num_inputs; idx++) {
169 const size_t sorted_list_size = num_inputs + 2;
174 size_t expected = (sorted_list_size == 4) ? 4 : ((sorted_list_size + 3) / 4) + 2;
176 EXPECT_EQ(
builder.get_estimated_num_finalized_gates() - num_gates_start, expected);
178 builder.create_unconstrained_gates(indices);
186 "bool_t: witness value is not 0 or 1");
223 [](
bool a,
bool b) {
return !
a ||
b; });
231 [](
bool a,
bool b) {
return !(
a ^
b); });
244 if (
a.is_constant() &&
b.is_constant() && !(!
a.get_value() ||
b.get_value())) {
247 bool result_is_constant = (!
a ||
b).is_constant();
249 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
251 if (!
a.is_constant() && !
b.is_constant()) {
252 a.set_origin_tag(submitted_value_origin_tag);
253 b.set_origin_tag(challenge_origin_tag);
258 bool expected = !(lhs.value ^ lhs.is_inverted) || rhs.value ^ rhs.is_inverted;
260 size_t diff =
builder.get_estimated_num_finalized_gates() - num_gates_start;
262 if (!
a.is_constant() && !
b.is_constant()) {
267 if (result_is_constant) {
271 if (!result_is_constant &&
a.is_constant() && !
b.is_constant()) {
274 EXPECT_EQ(diff,
static_cast<size_t>(!
b.is_inverted()));
277 if (!result_is_constant && !
a.is_constant() &&
b.is_constant()) {
280 EXPECT_EQ(diff,
static_cast<size_t>(
a.is_inverted()));
299 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
300 if (!
a.is_constant() && !
b.is_constant()) {
302 a.set_origin_tag(challenge_origin_tag);
303 b.set_origin_tag(next_challenge_tag);
307 size_t diff =
builder.get_estimated_num_finalized_gates() - num_gates_start;
308 if (!
a.is_constant() && !
b.is_constant()) {
309 EXPECT_EQ(result.
get_origin_tag(), first_second_third_merged_tag);
311 bool expected = (condition.
get_value()) ?
a.get_value() :
b.get_value();
331 size_t num_gates_start =
builder.get_estimated_num_finalized_gates();
332 if (!
a.is_constant()) {
333 a.set_origin_tag(submitted_value_origin_tag);
337 if (!
a.is_constant()) {
341 size_t diff =
builder.get_estimated_num_finalized_gates() - num_gates_start;
344 EXPECT_EQ(diff,
static_cast<size_t>(!
a.is_constant() && a_raw.is_inverted));
360 bool failed =
a.get_value() !=
b.get_value();
362 if (!
a.is_constant() && !
b.is_constant()) {
365 EXPECT_EQ(
builder.failed(), failed);
366 }
else if (!
a.is_constant() || !
b.is_constant()) {
382 auto gates_before =
builder.get_estimated_num_finalized_gates();
387 a.set_origin_tag(submitted_value_origin_tag);
388 b.set_origin_tag(challenge_origin_tag);
391 EXPECT_EQ(
a.get_value(), 1);
394 EXPECT_EQ(
a.get_origin_tag(), first_two_merged_tag);
397 EXPECT_EQ(
b.get_value(), 1);
400 EXPECT_EQ(
b.get_origin_tag(), challenge_origin_tag);
402 a.set_origin_tag(submitted_value_origin_tag);
431 EXPECT_EQ(result,
true);
433 auto gates_after =
builder.get_estimated_num_finalized_gates();
434 EXPECT_EQ(gates_after - gates_before, 6UL);
456 bool_ct rhs = ((
a &&
b) || (
a && c)) ^ (!d || f);
462 info(
"a: ",
a.get_value(),
" b: ",
b.get_value(),
" c: ", c.
get_value());
481 TestFixture::test_construct_from_const_bool();
486 TestFixture::test_construct_from_witness();
490 TestFixture::test_construct_from_witness_range_constraint();
495 TestFixture::test_normalize();
499 TestFixture::test_xor();
504 TestFixture::test_AND();
509 TestFixture::test_OR();
514 TestFixture::test_EQ();
519 TestFixture::test_NEQ();
524 TestFixture::test_implies();
529 TestFixture::test_implies_both_ways();
534 TestFixture::test_must_imply();
539 TestFixture::test_conditional_assign();
544 TestFixture::test_basic_operations_tags();
549 TestFixture::test_simple_proof();
553 TestFixture::test_assert_equal();
#define EXPECT_THROW_OR_ABORT(statement, matcher)
void test_construct_from_witness_index()
void test_implies_both_ways()
void test_conditional_assign()
void test_binary_op(std::string const &op_name, const std::function< bool_ct(const bool_ct &, const bool_ct &)> &op, const std::function< bool(bool, bool)> &expected_op)
void test_basic_operations_tags()
void test_construct_from_const_bool()
std::array< BoolInput, 8 > all_inputs
void test_construct_from_witness_range_constraint()
stdlib::witness_t< Builder > witness_ct
void test_construct_from_witness()
static bool_ct create_bool_ct(const BoolInput &in, Builder *builder)
stdlib::bool_t< Builder > bool_ct
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
Implements boolean logic in-circuit.
void set_origin_tag(const OriginTag &new_tag) const
bool_t implies(const bool_t &other) const
Implements implication operator in circuit.
bool_t normalize() const
A bool_t element is normalized if witness_inverted == false. For a given *this, output its normalized...
static bool_t conditional_assign(const bool_t< Builder > &predicate, const bool_t &lhs, const bool_t &rhs)
Implements the ternary operator - if predicate == true then return lhs, else return rhs.
static bool_t from_witness_index_unsafe(Builder *ctx, uint32_t witness_index)
Create a bool_t from a witness index that is known to contain a constrained bool value.
bool_t implies_both_ways(const bool_t &other) const
Implements a "double-implication" (<=>), a.k.a "iff", a.k.a. "biconditional".
OriginTag get_origin_tag() const
testing::Types< bb::UltraCircuitBuilder, bb::MegaCircuitBuilder > CircuitTypes
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
#define STANDARD_TESTING_TAGS
static constexpr field one()
static constexpr field zero()