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.
use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::BooleanError,
GroupType,
};
use crate::{constraints::ConstrainedValue, errors::BooleanError, GroupType};
use leo_types::{InputValue, Span};
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 bool_from_input<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
name: String,
input_value: Option<InputValue>,
span: Span,
) -> Result<ConstrainedValue<F, G>, BooleanError> {
// 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));
}
pub(crate) fn new_bool_constant(string: String, span: Span) -> Result<Boolean, BooleanError> {
let boolean = string
.parse::<bool>()
.map_err(|_| BooleanError::invalid_boolean(string, span))?;
Ok(Boolean::constant(boolean))
}
pub(crate) fn bool_from_input<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
cs: &mut CS,
name: String,
input_value: Option<InputValue>,
span: Span,
) -> Result<ConstrainedValue<F, G>, BooleanError> {
// 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>>(
&mut self,
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::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,
)),
}
}
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))?;
pub(crate) fn enforce_and<CS: ConstraintSystem<F>>(
&mut self,
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,
)),
}
Ok(ConstrainedValue::Boolean(number))
}
pub(crate) fn evaluate_not<F: Field + PrimeField, G: GroupType<F>>(
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)),
}
}
pub(crate) fn enforce_or<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::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::{
constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue},
enforce_and,
enforce_or,
errors::ExpressionError,
evaluate_not,
new_scope,
FieldType,
GroupType,
@ -968,7 +971,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
// 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)?,
span,
)?),
@ -983,7 +986,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
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) => {
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(),
)?;
Ok(self.enforce_and(cs, resolved_left, resolved_right, span)?)
Ok(enforce_and(cs, resolved_left, resolved_right, span)?)
}
Expression::Eq(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(

View File

@ -2,6 +2,7 @@
//! a resolved Leo program.
use crate::{
bool_from_input,
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
errors::{FunctionError, ImportError},
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::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),
_ => unimplemented!("main function input not implemented for type"),
}

View File

@ -1,7 +1,7 @@
//! Module containing methods to enforce constraints in an Leo program
pub mod boolean;
pub use boolean::*;
pub(crate) mod boolean;
pub(crate) use boolean::*;
pub mod function;
pub use function::*;

View File

@ -1,20 +1,14 @@
//! The in memory stored value for a defined name in a resolved Leo program.
use crate::{errors::ValueError, FieldType, GroupType};
use leo_types::{Circuit, Function, Identifier, Integer, IntegerType, Span, Type};
use crate::{errors::ValueError, new_bool_constant, FieldType, GroupType};
use leo_types::{Circuit, Function, Identifier, Integer, Span, Type};
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::{
r1cs::ConstraintSystem,
utilities::{
alloc::AllocGadget,
boolean::Boolean,
eq::ConditionalEqGadget,
select::CondSelectGadget,
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
},
utilities::{alloc::AllocGadget, boolean::Boolean, eq::ConditionalEqGadget, select::CondSelectGadget},
},
};
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> {
match _type {
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(match integer_type {
IntegerType::U8 => Integer::U8(UInt8::constant(value.parse::<u8>()?)),
IntegerType::U16 => Integer::U16(UInt16::constant(value.parse::<u16>()?)),
IntegerType::U32 => Integer::U32(UInt32::constant(value.parse::<u32>()?)),
IntegerType::U64 => Integer::U64(UInt64::constant(value.parse::<u64>()?)),
IntegerType::U128 => Integer::U128(UInt128::constant(value.parse::<u128>()?)),
})),
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(Integer::new_constant(
integer_type,
value,
span,
)?)),
Type::Field => Ok(ConstrainedValue::Field(FieldType::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),
_ => 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 snarkos_errors::gadgets::SynthesisError;
use std::{num::ParseIntError, str::ParseBoolError};
#[derive(Debug, Error)]
pub enum ValueError {
#[error("{}", _0)]
BooleanError(#[from] BooleanError),
#[error("{}", _0)]
FieldError(#[from] FieldError),
@ -15,12 +17,6 @@ pub enum ValueError {
#[error("{}", _0)]
IntegerError(#[from] IntegerError),
#[error("{}", _0)]
ParseBoolError(#[from] ParseBoolError),
#[error("{}", _0)]
ParseIntError(#[from] ParseIntError),
#[error("{}", _0)]
SynthesisError(#[from] SynthesisError),
}

View File

@ -58,6 +58,46 @@ impl<'ast> 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> {
match self {
Integer::U8(u8) => u8.value.map(|v| v as u128),