mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
test field comparators
This commit is contained in:
parent
82ba9560be
commit
c8229cef18
@ -90,10 +90,10 @@ pub enum BinaryOperator {
|
||||
Or,
|
||||
And,
|
||||
Eq,
|
||||
Neq,
|
||||
Geq,
|
||||
Ne,
|
||||
Ge,
|
||||
Gt,
|
||||
Leq,
|
||||
Le,
|
||||
Lt,
|
||||
Add,
|
||||
Sub,
|
||||
@ -812,10 +812,10 @@ fn precedence_climber() -> PrecClimber<Rule> {
|
||||
Operator::new(Rule::operation_or, Assoc::Left),
|
||||
Operator::new(Rule::operation_and, Assoc::Left),
|
||||
Operator::new(Rule::operation_eq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_neq, Assoc::Left),
|
||||
Operator::new(Rule::operation_geq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_ne, Assoc::Left),
|
||||
Operator::new(Rule::operation_ge, Assoc::Left)
|
||||
| Operator::new(Rule::operation_gt, Assoc::Left)
|
||||
| Operator::new(Rule::operation_leq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_le, Assoc::Left)
|
||||
| Operator::new(Rule::operation_lt, Assoc::Left),
|
||||
Operator::new(Rule::operation_add, Assoc::Left)
|
||||
| Operator::new(Rule::operation_sub, Assoc::Left),
|
||||
@ -927,10 +927,10 @@ fn binary_expression<'ast>(
|
||||
Rule::operation_or => Expression::binary(BinaryOperator::Or, lhs, rhs, span),
|
||||
Rule::operation_and => Expression::binary(BinaryOperator::And, lhs, rhs, span),
|
||||
Rule::operation_eq => Expression::binary(BinaryOperator::Eq, lhs, rhs, span),
|
||||
Rule::operation_neq => Expression::binary(BinaryOperator::Neq, lhs, rhs, span),
|
||||
Rule::operation_geq => Expression::binary(BinaryOperator::Geq, lhs, rhs, span),
|
||||
Rule::operation_ne => Expression::binary(BinaryOperator::Ne, lhs, rhs, span),
|
||||
Rule::operation_ge => Expression::binary(BinaryOperator::Ge, lhs, rhs, span),
|
||||
Rule::operation_gt => Expression::binary(BinaryOperator::Gt, lhs, rhs, span),
|
||||
Rule::operation_leq => Expression::binary(BinaryOperator::Leq, lhs, rhs, span),
|
||||
Rule::operation_le => Expression::binary(BinaryOperator::Le, lhs, rhs, span),
|
||||
Rule::operation_lt => Expression::binary(BinaryOperator::Lt, lhs, rhs, span),
|
||||
Rule::operation_add => Expression::binary(BinaryOperator::Add, lhs, rhs, span),
|
||||
Rule::operation_sub => Expression::binary(BinaryOperator::Sub, lhs, rhs, span),
|
||||
|
@ -230,22 +230,23 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_geq_expression(
|
||||
fn evaluate_ge_expression(
|
||||
&mut self,
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_geq(fe_1, fe_2)
|
||||
// }
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
let result = fe_1.ge(&fe_2);
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
self.evaluate_geq_expression(val_1, val_2)
|
||||
self.evaluate_ge_expression(val_1, val_2)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.evaluate_geq_expression(val_1, val_2)
|
||||
self.evaluate_ge_expression(val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} >= {}, values must be fields",
|
||||
@ -260,9 +261,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_gt(fe_1, fe_2)
|
||||
// }
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
let result = fe_1.gt(&fe_2);
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
self.evaluate_gt_expression(val_1, val_2)
|
||||
@ -278,22 +280,23 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_leq_expression(
|
||||
fn evaluate_le_expression(
|
||||
&mut self,
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_leq(fe_1, fe_2)
|
||||
// }
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
let result = fe_1.le(&fe_2);
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
self.evaluate_leq_expression(val_1, val_2)
|
||||
self.evaluate_le_expression(val_1, val_2)
|
||||
}
|
||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.evaluate_leq_expression(val_1, val_2)
|
||||
self.evaluate_le_expression(val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} <= {}, values must be fields",
|
||||
@ -308,9 +311,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_lt(fe_1, fe_2)
|
||||
// }
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
let result = fe_1.lt(&fe_2);
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
self.evaluate_lt_expression(val_1, val_2)
|
||||
@ -930,7 +934,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
|
||||
Ok(self.evaluate_eq_expression(resolved_left, resolved_right)?)
|
||||
}
|
||||
Expression::Geq(left, right) => {
|
||||
Expression::Ge(left, right) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -940,7 +944,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
*right,
|
||||
)?;
|
||||
|
||||
Ok(self.evaluate_geq_expression(resolved_left, resolved_right)?)
|
||||
Ok(self.evaluate_ge_expression(resolved_left, resolved_right)?)
|
||||
}
|
||||
Expression::Gt(left, right) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
@ -954,7 +958,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
|
||||
Ok(self.evaluate_gt_expression(resolved_left, resolved_right)?)
|
||||
}
|
||||
Expression::Leq(left, right) => {
|
||||
Expression::Le(left, right) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -964,7 +968,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
*right,
|
||||
)?;
|
||||
|
||||
Ok(self.evaluate_leq_expression(resolved_left, resolved_right)?)
|
||||
Ok(self.evaluate_le_expression(resolved_left, resolved_right)?)
|
||||
}
|
||||
Expression::Lt(left, right) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
|
@ -433,10 +433,6 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
val_1,
|
||||
val_2
|
||||
)
|
||||
// return Err(StatementError::AssertEq(
|
||||
// val_1.to_string(),
|
||||
// val_2.to_string(),
|
||||
// ))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum FieldType<F: Field + PrimeField> {
|
||||
@ -185,6 +186,15 @@ impl<F: Field + PrimeField> PartialEq for FieldType<F> {
|
||||
|
||||
impl<F: Field + PrimeField> Eq for FieldType<F> {}
|
||||
|
||||
impl<F: Field + PrimeField> PartialOrd for FieldType<F> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
let self_value = self.get_value();
|
||||
let other_value = other.get_value();
|
||||
|
||||
Option::from(self_value.cmp(&other_value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> EqGadget<F> for FieldType<F> {}
|
||||
|
||||
impl<F: Field + PrimeField> ConditionalEqGadget<F> for FieldType<F> {
|
||||
|
@ -25,11 +25,11 @@ operation_and = { "&&" }
|
||||
operation_or = { "||" }
|
||||
|
||||
operation_eq = { "==" }
|
||||
operation_neq = { "!=" }
|
||||
operation_ne = { "!=" }
|
||||
|
||||
operation_geq = { ">=" }
|
||||
operation_ge = { ">=" }
|
||||
operation_gt = { ">" }
|
||||
operation_leq = { "<=" }
|
||||
operation_le = { "<=" }
|
||||
operation_lt = { "<" }
|
||||
|
||||
operation_add = { "+" }
|
||||
@ -39,9 +39,9 @@ operation_div = { "/" }
|
||||
operation_pow = { "**" }
|
||||
|
||||
operation_compare = _{
|
||||
operation_eq | operation_neq |
|
||||
operation_geq | operation_gt |
|
||||
operation_leq | operation_lt
|
||||
operation_eq | operation_ne |
|
||||
operation_ge | operation_gt |
|
||||
operation_le | operation_lt
|
||||
}
|
||||
|
||||
operation_binary = _{
|
||||
|
@ -82,9 +82,9 @@ pub enum Expression {
|
||||
Or(Box<Expression>, Box<Expression>),
|
||||
And(Box<Expression>, Box<Expression>),
|
||||
Eq(Box<Expression>, Box<Expression>),
|
||||
Geq(Box<Expression>, Box<Expression>),
|
||||
Ge(Box<Expression>, Box<Expression>),
|
||||
Gt(Box<Expression>, Box<Expression>),
|
||||
Leq(Box<Expression>, Box<Expression>),
|
||||
Le(Box<Expression>, Box<Expression>),
|
||||
Lt(Box<Expression>, Box<Expression>),
|
||||
|
||||
// Conditionals
|
||||
|
@ -93,9 +93,9 @@ impl<'ast> fmt::Display for Expression {
|
||||
Expression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs),
|
||||
Expression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs),
|
||||
Expression::Eq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
||||
Expression::Geq(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
|
||||
Expression::Ge(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
|
||||
Expression::Gt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs),
|
||||
Expression::Leq(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
|
||||
Expression::Le(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
|
||||
Expression::Lt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs),
|
||||
|
||||
// Conditionals
|
||||
|
@ -191,10 +191,10 @@ impl<'ast> From<ast::BinaryExpression<'ast>> for types::Expression {
|
||||
Box::new(types::Expression::from(*expression.left)),
|
||||
Box::new(types::Expression::from(*expression.right)),
|
||||
),
|
||||
ast::BinaryOperator::Neq => {
|
||||
ast::BinaryOperator::Ne => {
|
||||
types::Expression::Not(Box::new(types::Expression::from(expression)))
|
||||
}
|
||||
ast::BinaryOperator::Geq => types::Expression::Geq(
|
||||
ast::BinaryOperator::Ge => types::Expression::Ge(
|
||||
Box::new(types::Expression::from(*expression.left)),
|
||||
Box::new(types::Expression::from(*expression.right)),
|
||||
),
|
||||
@ -202,7 +202,7 @@ impl<'ast> From<ast::BinaryExpression<'ast>> for types::Expression {
|
||||
Box::new(types::Expression::from(*expression.left)),
|
||||
Box::new(types::Expression::from(*expression.right)),
|
||||
),
|
||||
ast::BinaryOperator::Leq => types::Expression::Leq(
|
||||
ast::BinaryOperator::Le => types::Expression::Le(
|
||||
Box::new(types::Expression::from(*expression.left)),
|
||||
Box::new(types::Expression::from(*expression.right)),
|
||||
),
|
||||
|
@ -8,22 +8,21 @@ use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/boolean/";
|
||||
|
||||
pub fn output_true(program: EdwardsTestCompiler) {
|
||||
pub fn output_expected_boolean(program: EdwardsTestCompiler, boolean: bool) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(true))])
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(boolean))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
pub fn output_true(program: EdwardsTestCompiler) {
|
||||
output_expected_boolean(program, true)
|
||||
}
|
||||
|
||||
pub fn output_false(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(false))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
output_expected_boolean(program, false)
|
||||
}
|
||||
|
||||
fn fail_evaluate(program: EdwardsTestCompiler) {
|
||||
|
3
compiler/tests/field/ge.leo
Normal file
3
compiler/tests/field/ge.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a >= b
|
||||
}
|
3
compiler/tests/field/gt.leo
Normal file
3
compiler/tests/field/gt.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a > b
|
||||
}
|
3
compiler/tests/field/le.leo
Normal file
3
compiler/tests/field/le.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a <= b
|
||||
}
|
3
compiler/tests/field/lt.leo
Normal file
3
compiler/tests/field/lt.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a < b
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use crate::boolean::{output_false, output_true};
|
||||
use crate::boolean::{output_false, output_true, output_expected_boolean};
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, FieldError, FunctionError},
|
||||
@ -219,29 +219,23 @@ fn test_div() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq_true() {
|
||||
fn test_eq() {
|
||||
for _ in 0..10 {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
]);
|
||||
|
||||
output_true(program)
|
||||
}
|
||||
}
|
||||
output_true(program);
|
||||
|
||||
#[test]
|
||||
fn test_eq_false() {
|
||||
for _ in 0..10 {
|
||||
let r1: u64 = rand::random();
|
||||
// test not equal
|
||||
let r2: u64 = rand::random();
|
||||
|
||||
if r1 == r2 {
|
||||
continue;
|
||||
}
|
||||
let result = r1.eq(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
@ -249,7 +243,129 @@ fn test_eq_false() {
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
]);
|
||||
|
||||
output_false(program)
|
||||
output_expected_boolean(program, result)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_ge() {
|
||||
for _ in 0..10 {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "ge.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
]);
|
||||
|
||||
output_true(program);
|
||||
|
||||
// test greater than
|
||||
let r2: u64 = rand::random();
|
||||
|
||||
let result = r1.ge(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "ge.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
]);
|
||||
|
||||
output_expected_boolean(program, result)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gt() {
|
||||
for _ in 0..10 {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "gt.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
]);
|
||||
|
||||
output_false(program);
|
||||
|
||||
// test greater than
|
||||
let r2: u64 = rand::random();
|
||||
|
||||
let result = r1.gt(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "gt.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
]);
|
||||
|
||||
output_expected_boolean(program, result)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_le() {
|
||||
for _ in 0..10 {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "le.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
]);
|
||||
|
||||
output_true(program);
|
||||
|
||||
// test greater than
|
||||
let r2: u64 = rand::random();
|
||||
|
||||
let result = r1.le(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "le.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
]);
|
||||
|
||||
output_expected_boolean(program, result)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lt() {
|
||||
for _ in 0..10 {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "lt.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
]);
|
||||
|
||||
output_false(program);
|
||||
|
||||
// test greater than
|
||||
let r2: u64 = rand::random();
|
||||
|
||||
let result = r1.lt(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "lt.leo").unwrap();
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
]);
|
||||
|
||||
output_expected_boolean(program, result)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user