Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 17 additions & 32 deletions compiler/noirc_evaluator/src/acir/acir_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,45 +273,30 @@ impl<F: AcirField> AcirContext<F> {
predicate: AcirVar,
) -> Result<AcirVar, RuntimeError> {
let var_data = &self.vars[&var];
if let AcirVarData::Const(constant) = var_data {
let inverted_var = if let AcirVarData::Const(constant) = var_data {
// Note that this will return a 0 if the inverse is not available
let inverted_var = self.add_data(AcirVarData::Const(constant.inverse()));

// Check that the inverted var is valid.
// This check prevents invalid divisions by zero.
let should_be_one = self.mul_var(inverted_var, var)?;
self.maybe_eq_predicate(should_be_one, predicate)?;

return Ok(inverted_var);
}

let results = self.stdlib_brillig_call(
predicate,
BrilligStdlibFunc::Inverse,
vec![AcirValue::Var(var, AcirType::field())],
vec![AcirType::field()],
)?;
let inverted_var = Self::expect_one_var(results);
self.add_data(AcirVarData::Const(constant.inverse()))
} else {
let results = self.stdlib_brillig_call(
predicate,
BrilligStdlibFunc::Inverse,
vec![AcirValue::Var(var, AcirType::field())],
vec![AcirType::field()],
)?;
Self::expect_one_var(results)
};

// Check that the inverted var is valid.
// This check prevents invalid divisions by zero.
let should_be_one = self.mul_var(inverted_var, var)?;
self.maybe_eq_predicate(should_be_one, predicate)?;

Ok(inverted_var)
}
// `predicate * should_be_one = predicate`
// -> `predicate * (should_be_one - 1) = 0`
// so either `should_be_one` is one or `predicate` is zero
let pred_mul_should_be_one = self.mul_var(should_be_one, predicate)?;
self.assert_eq_var(pred_mul_should_be_one, predicate, None)?;

// 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<(), RuntimeError> {
let pred_mul_var = self.mul_var(var, predicate)?;
self.assert_eq_var(pred_mul_var, predicate, None)
Ok(inverted_var)
}

// Returns the variable from the results, assuming it is the only result
Expand Down
Loading