impl for loop statements for conditional

This commit is contained in:
collin 2020-06-13 02:04:31 -07:00
parent 2d17b39da6
commit c7eccdc87e
6 changed files with 43 additions and 11 deletions

View File

@ -391,6 +391,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
cs: &mut CS,
file_scope: String,
function_scope: String,
indicator: Option<Boolean>,
index: Identifier,
start: Integer,
stop: Integer,
@ -408,12 +409,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
ConstrainedValue::Integer(Integer::U32(UInt32::constant(i as u32))),
);
cs.ns(|| format!("loop {} = {}", index.to_string(), i));
// Evaluate statements and possibly return early
if let Some(early_return) = self.evaluate_branch(
cs,
file_scope.clone(),
function_scope.clone(),
None,
indicator,
statements.clone(),
return_types.clone(),
)? {
@ -473,6 +476,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
cs,
file_scope,
function_scope,
indicator,
index,
start,
stop,

View File

@ -0,0 +1,11 @@
function main(cond: bool) -> u32 {
let mut a = 0u32;
if cond {
for i in 0..4 {
a += i;
}
}
return a
}

View File

@ -9,6 +9,7 @@ use crate::{
use leo_inputs::types::{IntegerType, U32Type};
use leo_types::InputValue;
use crate::integers::u32::output_number;
use snarkos_curves::edwards_bls12::Fq;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
@ -29,7 +30,7 @@ fn empty_output_satisfied(program: EdwardsTestCompiler) {
// }
#[test]
fn conditional_basic() {
let bytes = include_bytes!("conditional_basic.leo");
let bytes = include_bytes!("assert.leo");
let mut program_1_pass = parse_program(bytes).unwrap();
let mut program_0_pass = program_1_pass.clone();
let mut program_2_fail = program_1_pass.clone();
@ -54,7 +55,7 @@ fn conditional_basic() {
#[test]
fn conditional_mutate() {
let bytes = include_bytes!("conditional_mutate.leo");
let bytes = include_bytes!("mutate.leo");
let mut program_1_true = parse_program(bytes).unwrap();
let mut program_0_pass = program_1_true.clone();
@ -68,3 +69,20 @@ fn conditional_mutate() {
program_0_pass.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 0))]);
output_zero(program_0_pass);
}
#[test]
fn conditional_for_loop() {
let bytes = include_bytes!("for_loop.leo");
let mut program_true_6 = parse_program(bytes).unwrap();
let mut program_false_0 = program_true_6.clone();
// Check that an input value of 1 satisfies the constraint system
program_true_6.set_inputs(vec![Some(InputValue::Boolean(true))]);
output_number(program_true_6, 6u32);
// Check that an input value of 0 satisfies the constraint system
program_false_0.set_inputs(vec![Some(InputValue::Boolean(false))]);
output_zero(program_false_0);
}

View File

@ -28,22 +28,21 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
}
}
pub(crate) fn output_zero(program: EdwardsTestCompiler) {
pub(crate) fn output_number(program: EdwardsTestCompiler, number: u32) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0u32)))])
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(number)))])
.to_string(),
output.to_string()
)
}
pub(crate) fn output_zero(program: EdwardsTestCompiler) {
output_number(program, 0u32);
}
pub(crate) fn output_one(program: EdwardsTestCompiler) {
let output = get_output(program);
assert_eq!(
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32)))])
.to_string(),
output.to_string()
)
output_number(program, 1u32);
}
#[test]