Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 9_conditional end to end test #1951

Merged
merged 13 commits into from
Jul 19, 2023
28 changes: 14 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ edition = "2021"
rust-version = "1.66"

[workspace.dependencies]
acvm = "0.19.0"
acvm = "0.19.1"
arena = { path = "crates/arena" }
fm = { path = "crates/fm" }
iter-extended = { path = "crates/iter-extended" }
Expand All @@ -40,7 +40,7 @@ noir_wasm = { path = "crates/wasm" }

cfg-if = "1.0.0"
clap = { version = "4.1.4", features = ["derive"] }
codespan = {version = "0.11.1", features = ["serialization"]}
codespan = { version = "0.11.1", features = ["serialization"] }
codespan-lsp = "0.11.1"
codespan-reporting = "0.11.1"
chumsky = { git = "https://github.com/jfecher/chumsky", rev = "ad9d312" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
c=[2, 4, 3, 0, ]
a=0
x = [104, 101, 108, 108, 111]

result = [
0x2c,
0xf2,
0x4d,
0xba,
0x5f,
0xb0,
0xa3,
0x0e,
0x26,
0xe8,
0x3b,
0x2a,
0xc5,
0xb9,
0xe2,
0x9e,
0x1b,
0x16,
0x1e,
0x5c,
0x1f,
0xa7,
0x42,
0x5e,
0x73,
0x04,
0x33,
0x62,
0x93,
0x8b,
0x98,
0x24,
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use dep::std;



fn main(a: u32, mut c: [u32; 4], x: [u8; 5], result: pub [u8; 32]){
if a == 0 {
c[0] = 3;
} else {
c[0] = 1;
c[1] = c[2] / a + 11 % a;
let f1 = a as Field;
assert(10/f1 != 0);
}
assert(c[0] == 3);
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,11 @@ impl AcirContext {

/// Adds a new Variable to context whose value will
/// be constrained to be the inverse of `var`.
pub(crate) fn inv_var(&mut self, var: AcirVar) -> Result<AcirVar, AcirGenError> {
pub(crate) fn inv_var(
&mut self,
var: AcirVar,
predicate: AcirVar,
) -> Result<AcirVar, AcirGenError> {
let var_data = &self.vars[&var];
if let AcirVarData::Const(constant) = var_data {
// Note that this will return a 0 if the inverse is not available
Expand All @@ -169,23 +173,36 @@ impl AcirContext {
let field_type = AcirType::NumericType(NumericType::NativeField);

let results = self.brillig(
None,
Some(predicate),
inverse_code,
vec![AcirValue::Var(var, field_type.clone())],
vec![field_type],
);
let inverted_var = Self::expect_one_var(results);

let should_be_one = self.mul_var(inverted_var, var)?;
self.assert_eq_one(should_be_one)?;
self.maybe_eq_predicate(should_be_one, predicate)?;

Ok(inverted_var)
}

/// Constrains the lhs to be equal to the constant value `1`
// Constrains `var` to be equal to the constant value `1`
pub(crate) fn assert_eq_one(&mut self, var: AcirVar) -> Result<(), AcirGenError> {
let one_var = self.add_constant(FieldElement::one());
self.assert_eq_var(var, one_var)
let one = self.add_constant(FieldElement::one());
self.assert_eq_var(var, one)
}

// Constrains `var` to be equal to predicate if the predicate is true
// or to be equal to 0 if the predicate is false.
//
// Since we multiply `var` by the predicate, this is a no-op if the predicate is false
pub(crate) fn maybe_eq_predicate(
&mut self,
var: AcirVar,
predicate: AcirVar,
) -> Result<(), AcirGenError> {
let pred_mul_var = self.mul_var(var, predicate)?;
self.assert_eq_var(pred_mul_var, predicate)
}

// Returns the variable from the results, assuming it is the only result
Expand Down Expand Up @@ -296,6 +313,7 @@ impl AcirContext {
lhs: AcirVar,
rhs: AcirVar,
typ: AcirType,
predicate: AcirVar,
) -> Result<AcirVar, AcirGenError> {
let numeric_type = match typ {
AcirType::NumericType(numeric_type) => numeric_type,
Expand All @@ -305,12 +323,12 @@ impl AcirContext {
};
match numeric_type {
NumericType::NativeField => {
let inv_rhs = self.inv_var(rhs)?;
let inv_rhs = self.inv_var(rhs, predicate)?;
self.mul_var(lhs, inv_rhs)
}
NumericType::Unsigned { bit_size } => {
let (quotient_var, _remainder_var) =
self.euclidean_division_var(lhs, rhs, bit_size)?;
self.euclidean_division_var(lhs, rhs, bit_size, predicate)?;
Ok(quotient_var)
}
NumericType::Signed { bit_size } => {
Expand Down Expand Up @@ -430,17 +448,18 @@ impl AcirContext {
lhs: AcirVar,
rhs: AcirVar,
bit_size: u32,
predicate: AcirVar,
) -> Result<(AcirVar, AcirVar), AcirGenError> {
let predicate = Expression::one();

let lhs_data = &self.vars[&lhs];
let rhs_data = &self.vars[&rhs];
let predicate_data = &self.vars[&predicate];

let lhs_expr = lhs_data.to_expression();
let rhs_expr = rhs_data.to_expression();
let predicate_expr = predicate_data.to_expression();

let (quotient, remainder) =
self.acir_ir.euclidean_division(&lhs_expr, &rhs_expr, bit_size, &predicate)?;
self.acir_ir.euclidean_division(&lhs_expr, &rhs_expr, bit_size, &predicate_expr)?;

let quotient_var = self.add_data(AcirVarData::Witness(quotient));
let remainder_var = self.add_data(AcirVarData::Witness(remainder));
Expand Down Expand Up @@ -485,8 +504,9 @@ impl AcirContext {
lhs: AcirVar,
rhs: AcirVar,
bit_size: u32,
predicate: AcirVar,
) -> Result<AcirVar, AcirGenError> {
let (_, remainder) = self.euclidean_division_var(lhs, rhs, bit_size)?;
let (_, remainder) = self.euclidean_division_var(lhs, rhs, bit_size, predicate)?;
Ok(remainder)
}

Expand All @@ -505,6 +525,7 @@ impl AcirContext {
lhs: AcirVar,
rhs: AcirVar,
typ: AcirType,
predicate: AcirVar,
) -> Result<AcirVar, AcirGenError> {
let rhs_data = &self.vars[&rhs];

Expand All @@ -515,7 +536,7 @@ impl AcirContext {
};
let two_pow_rhs_var = self.add_constant(two_pow_rhs);

self.div_var(lhs, two_pow_rhs_var, typ)
self.div_var(lhs, two_pow_rhs_var, typ, predicate)
}

/// Converts the `AcirVar` to a `Witness` if it hasn't been already, and appends it to the
Expand Down Expand Up @@ -575,7 +596,7 @@ impl AcirContext {
lhs: AcirVar,
rhs: AcirVar,
bit_size: u32,
predicate: Option<AcirVar>,
predicate: AcirVar,
) -> Result<AcirVar, AcirGenError> {
let lhs_data = &self.vars[&lhs];
let rhs_data = &self.vars[&rhs];
Expand All @@ -586,10 +607,9 @@ impl AcirContext {
// TODO: check what happens when we do (a as u8) >= (b as u32)
// TODO: The frontend should shout in this case

let predicate = predicate.map(|acir_var| {
let predicate_data = &self.vars[&acir_var];
predicate_data.to_expression().into_owned()
});
let predicate_data = &self.vars[&predicate];
let predicate = predicate_data.to_expression().into_owned();

let is_greater_than_eq =
self.acir_ir.more_than_eq_comparison(&lhs_expr, &rhs_expr, bit_size, predicate)?;

Expand All @@ -607,7 +627,7 @@ impl AcirContext {
) -> Result<AcirVar, AcirGenError> {
// Flip the result of calling more than equal method to
// compute less than.
let comparison = self.more_than_eq_var(lhs, rhs, bit_size, Some(predicate))?;
let comparison = self.more_than_eq_var(lhs, rhs, bit_size, predicate)?;

let one = self.add_constant(FieldElement::one());
self.sub_var(one, comparison) // comparison_negated
Expand Down Expand Up @@ -858,6 +878,7 @@ impl AcirContext {
&mut self,
inputs: Vec<AcirVar>,
bit_size: u32,
predicate: AcirVar,
) -> Result<Vec<AcirVar>, AcirGenError> {
let len = inputs.len();
// Convert the inputs into expressions
Expand All @@ -875,7 +896,7 @@ impl AcirContext {

// Enforce the outputs to be sorted
for i in 0..(outputs_var.len() - 1) {
self.less_than_constrain(outputs_var[i], outputs_var[i + 1], bit_size, None)?;
self.less_than_constrain(outputs_var[i], outputs_var[i + 1], bit_size, predicate)?;
}

Ok(outputs_var)
Expand All @@ -887,10 +908,10 @@ impl AcirContext {
lhs: AcirVar,
rhs: AcirVar,
bit_size: u32,
predicate: Option<AcirVar>,
predicate: AcirVar,
) -> Result<(), AcirGenError> {
let lhs_less_than_rhs = self.more_than_eq_var(rhs, lhs, bit_size, predicate)?;
self.assert_eq_one(lhs_less_than_rhs)
self.maybe_eq_predicate(lhs_less_than_rhs, predicate)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,14 @@ impl GeneratedAcir {
// true.
let mut rhs_constraint = (rhs * &Expression::from(q_witness)).unwrap();
rhs_constraint = &rhs_constraint + r_witness;
rhs_constraint = (&rhs_constraint * predicate).unwrap();
let lhs_constraint = (lhs * predicate).unwrap();
let div_euclidean = &lhs_constraint - &rhs_constraint;

// Reduce the rhs_constraint to a witness
let rhs_reduced: Expression = self.create_witness_for_expression(&rhs_constraint).into();
// Reduce the lhs_constraint to a witness
let lhs_reduced: Expression = self.create_witness_for_expression(lhs).into();

let div_euclidean =
&(&lhs_reduced * predicate).unwrap() - &(&rhs_reduced * predicate).unwrap();
kevaundray marked this conversation as resolved.
Show resolved Hide resolved

self.push_opcode(AcirOpcode::Arithmetic(div_euclidean));

Expand Down Expand Up @@ -711,7 +716,7 @@ impl GeneratedAcir {
a: &Expression,
b: &Expression,
max_bits: u32,
predicate: Option<Expression>,
predicate: Expression,
) -> Result<Witness, AcirGenError> {
// Ensure that 2^{max_bits + 1} is less than the field size
//
Expand All @@ -737,7 +742,7 @@ impl GeneratedAcir {
let (q_witness, r_witness) = self.quotient_directive(
comparison_evaluation.clone(),
two_max_bits.into(),
predicate,
Some(predicate),
q_max_bits,
r_max_bits,
)?;
Expand Down
Loading