remove non-formatted errors for program value

This commit is contained in:
collin 2020-06-20 20:40:17 -07:00
parent d506158499
commit 9f27d22486
7 changed files with 139 additions and 112 deletions

View File

@ -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,
)),
} }
} }

View File

@ -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(

View File

@ -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"),
} }

View File

@ -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::*;

View File

@ -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)),
} }

View File

@ -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),
} }

View File

@ -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),