mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-26 11:45:00 +03:00
remove non-formatted errors for program value
This commit is contained in:
parent
d506158499
commit
9f27d22486
@ -1,10 +1,6 @@
|
|||||||
//! Methods to enforce constraints on booleans in a resolved Leo program.
|
//! Methods to enforce constraints on booleans in a resolved Leo program.
|
||||||
|
|
||||||
use crate::{
|
use crate::{constraints::ConstrainedValue, errors::BooleanError, GroupType};
|
||||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
|
||||||
errors::BooleanError,
|
|
||||||
GroupType,
|
|
||||||
};
|
|
||||||
use leo_types::{InputValue, Span};
|
use leo_types::{InputValue, Span};
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
@ -16,85 +12,84 @@ use snarkos_models::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
pub(crate) fn new_bool_constant(string: String, span: Span) -> Result<Boolean, BooleanError> {
|
||||||
pub(crate) fn bool_from_input<CS: ConstraintSystem<F>>(
|
let boolean = string
|
||||||
&mut self,
|
.parse::<bool>()
|
||||||
cs: &mut CS,
|
.map_err(|_| BooleanError::invalid_boolean(string, span))?;
|
||||||
name: String,
|
|
||||||
input_value: Option<InputValue>,
|
Ok(Boolean::constant(boolean))
|
||||||
span: Span,
|
}
|
||||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
|
||||||
// Check that the input value is the correct type
|
pub(crate) fn bool_from_input<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||||
let bool_value = match input_value {
|
cs: &mut CS,
|
||||||
Some(input) => {
|
name: String,
|
||||||
if let InputValue::Boolean(bool) = input {
|
input_value: Option<InputValue>,
|
||||||
Some(bool)
|
span: Span,
|
||||||
} else {
|
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||||
return Err(BooleanError::invalid_boolean(name, span));
|
// Check that the input value is the correct type
|
||||||
}
|
let bool_value = match input_value {
|
||||||
|
Some(input) => {
|
||||||
|
if let InputValue::Boolean(bool) = input {
|
||||||
|
Some(bool)
|
||||||
|
} else {
|
||||||
|
return Err(BooleanError::invalid_boolean(name, span));
|
||||||
}
|
}
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let boolean_name = format!("{}: bool", name);
|
|
||||||
let boolean_name_unique = format!("`{}` {}:{}", boolean_name, span.line, span.start);
|
|
||||||
let number = Boolean::alloc(cs.ns(|| boolean_name_unique), || {
|
|
||||||
bool_value.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})
|
|
||||||
.map_err(|_| BooleanError::missing_boolean(boolean_name, span))?;
|
|
||||||
|
|
||||||
Ok(ConstrainedValue::Boolean(number))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn evaluate_not(
|
|
||||||
value: ConstrainedValue<F, G>,
|
|
||||||
span: Span,
|
|
||||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
|
||||||
match value {
|
|
||||||
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
|
|
||||||
value => Err(BooleanError::cannot_evaluate(format!("!{}", value), span)),
|
|
||||||
}
|
}
|
||||||
}
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn enforce_or<CS: ConstraintSystem<F>>(
|
let boolean_name = format!("{}: bool", name);
|
||||||
&mut self,
|
let boolean_name_unique = format!("`{}` {}:{}", boolean_name, span.line, span.start);
|
||||||
cs: &mut CS,
|
let number = Boolean::alloc(cs.ns(|| boolean_name_unique), || {
|
||||||
left: ConstrainedValue<F, G>,
|
bool_value.ok_or(SynthesisError::AssignmentMissing)
|
||||||
right: ConstrainedValue<F, G>,
|
})
|
||||||
span: Span,
|
.map_err(|_| BooleanError::missing_boolean(boolean_name, span))?;
|
||||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
|
||||||
match (left, right) {
|
|
||||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => {
|
|
||||||
Ok(ConstrainedValue::Boolean(
|
|
||||||
Boolean::or(cs, &left_bool, &right_bool)
|
|
||||||
.map_err(|e| BooleanError::cannot_enforce(format!("||"), e, span))?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(left_value, right_value) => Err(BooleanError::cannot_evaluate(
|
|
||||||
format!("{} || {}", left_value, right_value),
|
|
||||||
span,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn enforce_and<CS: ConstraintSystem<F>>(
|
Ok(ConstrainedValue::Boolean(number))
|
||||||
&mut self,
|
}
|
||||||
cs: &mut CS,
|
|
||||||
left: ConstrainedValue<F, G>,
|
pub(crate) fn evaluate_not<F: Field + PrimeField, G: GroupType<F>>(
|
||||||
right: ConstrainedValue<F, G>,
|
value: ConstrainedValue<F, G>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||||
match (left, right) {
|
match value {
|
||||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => {
|
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
|
||||||
Ok(ConstrainedValue::Boolean(
|
value => Err(BooleanError::cannot_evaluate(format!("!{}", value), span)),
|
||||||
Boolean::and(cs, &left_bool, &right_bool)
|
}
|
||||||
.map_err(|e| BooleanError::cannot_enforce(format!("&&"), e, span))?,
|
}
|
||||||
))
|
|
||||||
}
|
pub(crate) fn enforce_or<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||||
(left_value, right_value) => Err(BooleanError::cannot_evaluate(
|
cs: &mut CS,
|
||||||
format!("{} && {}", left_value, right_value),
|
left: ConstrainedValue<F, G>,
|
||||||
span,
|
right: ConstrainedValue<F, G>,
|
||||||
)),
|
span: Span,
|
||||||
}
|
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||||
|
match (left, right) {
|
||||||
|
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(ConstrainedValue::Boolean(
|
||||||
|
Boolean::or(cs, &left_bool, &right_bool)
|
||||||
|
.map_err(|e| BooleanError::cannot_enforce(format!("||"), e, span))?,
|
||||||
|
)),
|
||||||
|
(left_value, right_value) => Err(BooleanError::cannot_evaluate(
|
||||||
|
format!("{} || {}", left_value, right_value),
|
||||||
|
span,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn enforce_and<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||||
|
cs: &mut CS,
|
||||||
|
left: ConstrainedValue<F, G>,
|
||||||
|
right: ConstrainedValue<F, G>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||||
|
match (left, right) {
|
||||||
|
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(ConstrainedValue::Boolean(
|
||||||
|
Boolean::and(cs, &left_bool, &right_bool)
|
||||||
|
.map_err(|e| BooleanError::cannot_enforce(format!("&&"), e, span))?,
|
||||||
|
)),
|
||||||
|
(left_value, right_value) => Err(BooleanError::cannot_evaluate(
|
||||||
|
format!("{} && {}", left_value, right_value),
|
||||||
|
span,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue},
|
constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue},
|
||||||
|
enforce_and,
|
||||||
|
enforce_or,
|
||||||
errors::ExpressionError,
|
errors::ExpressionError,
|
||||||
|
evaluate_not,
|
||||||
new_scope,
|
new_scope,
|
||||||
FieldType,
|
FieldType,
|
||||||
GroupType,
|
GroupType,
|
||||||
@ -968,7 +971,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Boolean operations
|
// Boolean operations
|
||||||
Expression::Not(expression, span) => Ok(Self::evaluate_not(
|
Expression::Not(expression, span) => Ok(evaluate_not(
|
||||||
self.enforce_expression(cs, file_scope, function_scope, expected_types, *expression)?,
|
self.enforce_expression(cs, file_scope, function_scope, expected_types, *expression)?,
|
||||||
span,
|
span,
|
||||||
)?),
|
)?),
|
||||||
@ -983,7 +986,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(self.enforce_or(cs, resolved_left, resolved_right, span)?)
|
Ok(enforce_or(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::And(left, right, span) => {
|
Expression::And(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
@ -996,7 +999,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(self.enforce_and(cs, resolved_left, resolved_right, span)?)
|
Ok(enforce_and(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Eq(left, right, span) => {
|
Expression::Eq(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
//! a resolved Leo program.
|
//! a resolved Leo program.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
bool_from_input,
|
||||||
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
|
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
|
||||||
errors::{FunctionError, ImportError},
|
errors::{FunctionError, ImportError},
|
||||||
field_from_input,
|
field_from_input,
|
||||||
@ -173,7 +174,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
)?)),
|
)?)),
|
||||||
Type::Field => Ok(field_from_input(cs, name, input_value, span)?),
|
Type::Field => Ok(field_from_input(cs, name, input_value, span)?),
|
||||||
Type::Group => Ok(group_from_input(cs, name, input_value, span)?),
|
Type::Group => Ok(group_from_input(cs, name, input_value, span)?),
|
||||||
Type::Boolean => Ok(self.bool_from_input(cs, name, input_value, span)?),
|
Type::Boolean => Ok(bool_from_input(cs, name, input_value, span)?),
|
||||||
Type::Array(_type, dimensions) => self.allocate_array(cs, name, *_type, dimensions, input_value, span),
|
Type::Array(_type, dimensions) => self.allocate_array(cs, name, *_type, dimensions, input_value, span),
|
||||||
_ => unimplemented!("main function input not implemented for type"),
|
_ => unimplemented!("main function input not implemented for type"),
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Module containing methods to enforce constraints in an Leo program
|
//! Module containing methods to enforce constraints in an Leo program
|
||||||
|
|
||||||
pub mod boolean;
|
pub(crate) mod boolean;
|
||||||
pub use boolean::*;
|
pub(crate) use boolean::*;
|
||||||
|
|
||||||
pub mod function;
|
pub mod function;
|
||||||
pub use function::*;
|
pub use function::*;
|
||||||
|
@ -1,20 +1,14 @@
|
|||||||
//! The in memory stored value for a defined name in a resolved Leo program.
|
//! The in memory stored value for a defined name in a resolved Leo program.
|
||||||
|
|
||||||
use crate::{errors::ValueError, FieldType, GroupType};
|
use crate::{errors::ValueError, new_bool_constant, FieldType, GroupType};
|
||||||
use leo_types::{Circuit, Function, Identifier, Integer, IntegerType, Span, Type};
|
use leo_types::{Circuit, Function, Identifier, Integer, Span, Type};
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
gadgets::{
|
gadgets::{
|
||||||
r1cs::ConstraintSystem,
|
r1cs::ConstraintSystem,
|
||||||
utilities::{
|
utilities::{alloc::AllocGadget, boolean::Boolean, eq::ConditionalEqGadget, select::CondSelectGadget},
|
||||||
alloc::AllocGadget,
|
|
||||||
boolean::Boolean,
|
|
||||||
eq::ConditionalEqGadget,
|
|
||||||
select::CondSelectGadget,
|
|
||||||
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -51,16 +45,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
|||||||
|
|
||||||
pub(crate) fn from_type(value: String, _type: &Type, span: Span) -> Result<Self, ValueError> {
|
pub(crate) fn from_type(value: String, _type: &Type, span: Span) -> Result<Self, ValueError> {
|
||||||
match _type {
|
match _type {
|
||||||
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(match integer_type {
|
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(Integer::new_constant(
|
||||||
IntegerType::U8 => Integer::U8(UInt8::constant(value.parse::<u8>()?)),
|
integer_type,
|
||||||
IntegerType::U16 => Integer::U16(UInt16::constant(value.parse::<u16>()?)),
|
value,
|
||||||
IntegerType::U32 => Integer::U32(UInt32::constant(value.parse::<u32>()?)),
|
span,
|
||||||
IntegerType::U64 => Integer::U64(UInt64::constant(value.parse::<u64>()?)),
|
)?)),
|
||||||
IntegerType::U128 => Integer::U128(UInt128::constant(value.parse::<u128>()?)),
|
|
||||||
})),
|
|
||||||
Type::Field => Ok(ConstrainedValue::Field(FieldType::constant(value, span)?)),
|
Type::Field => Ok(ConstrainedValue::Field(FieldType::constant(value, span)?)),
|
||||||
Type::Group => Ok(ConstrainedValue::Group(G::constant(value, span)?)),
|
Type::Group => Ok(ConstrainedValue::Group(G::constant(value, span)?)),
|
||||||
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(value.parse::<bool>()?))),
|
Type::Boolean => Ok(ConstrainedValue::Boolean(new_bool_constant(value, span)?)),
|
||||||
Type::Array(ref _type, _dimensions) => ConstrainedValue::from_type(value, _type, span),
|
Type::Array(ref _type, _dimensions) => ConstrainedValue::from_type(value, _type, span),
|
||||||
_ => Ok(ConstrainedValue::Unresolved(value)),
|
_ => Ok(ConstrainedValue::Unresolved(value)),
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use crate::errors::{FieldError, GroupError};
|
use crate::errors::{BooleanError, FieldError, GroupError};
|
||||||
use leo_types::IntegerError;
|
use leo_types::IntegerError;
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use std::{num::ParseIntError, str::ParseBoolError};
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ValueError {
|
pub enum ValueError {
|
||||||
|
#[error("{}", _0)]
|
||||||
|
BooleanError(#[from] BooleanError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
FieldError(#[from] FieldError),
|
FieldError(#[from] FieldError),
|
||||||
|
|
||||||
@ -15,12 +17,6 @@ pub enum ValueError {
|
|||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
IntegerError(#[from] IntegerError),
|
IntegerError(#[from] IntegerError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
|
||||||
ParseBoolError(#[from] ParseBoolError),
|
|
||||||
|
|
||||||
#[error("{}", _0)]
|
|
||||||
ParseIntError(#[from] ParseIntError),
|
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
SynthesisError(#[from] SynthesisError),
|
SynthesisError(#[from] SynthesisError),
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,46 @@ impl<'ast> Integer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Integer {
|
impl Integer {
|
||||||
|
pub fn new_constant(integer_type: &IntegerType, string: String, span: Span) -> Result<Self, IntegerError> {
|
||||||
|
match integer_type {
|
||||||
|
IntegerType::U8 => {
|
||||||
|
let number = string
|
||||||
|
.parse::<u8>()
|
||||||
|
.map_err(|_| IntegerError::invalid_integer(string, span))?;
|
||||||
|
|
||||||
|
Ok(Integer::U8(UInt8::constant(number)))
|
||||||
|
}
|
||||||
|
IntegerType::U16 => {
|
||||||
|
let number = string
|
||||||
|
.parse::<u16>()
|
||||||
|
.map_err(|_| IntegerError::invalid_integer(string, span))?;
|
||||||
|
|
||||||
|
Ok(Integer::U16(UInt16::constant(number)))
|
||||||
|
}
|
||||||
|
IntegerType::U32 => {
|
||||||
|
let number = string
|
||||||
|
.parse::<u32>()
|
||||||
|
.map_err(|_| IntegerError::invalid_integer(string, span))?;
|
||||||
|
|
||||||
|
Ok(Integer::U32(UInt32::constant(number)))
|
||||||
|
}
|
||||||
|
IntegerType::U64 => {
|
||||||
|
let number = string
|
||||||
|
.parse::<u64>()
|
||||||
|
.map_err(|_| IntegerError::invalid_integer(string, span))?;
|
||||||
|
|
||||||
|
Ok(Integer::U64(UInt64::constant(number)))
|
||||||
|
}
|
||||||
|
IntegerType::U128 => {
|
||||||
|
let number = string
|
||||||
|
.parse::<u128>()
|
||||||
|
.map_err(|_| IntegerError::invalid_integer(string, span))?;
|
||||||
|
|
||||||
|
Ok(Integer::U128(UInt128::constant(number)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_value(&self) -> Option<u128> {
|
pub fn get_value(&self) -> Option<u128> {
|
||||||
match self {
|
match self {
|
||||||
Integer::U8(u8) => u8.value.map(|v| v as u128),
|
Integer::U8(u8) => u8.value.map(|v| v as u128),
|
||||||
|
Loading…
Reference in New Issue
Block a user