constraints bool and field spreads

This commit is contained in:
collin 2020-04-16 22:46:51 -07:00
parent e1db8ed483
commit 1743c7a1f1
3 changed files with 85 additions and 51 deletions

View File

@ -1,10 +1,4 @@
struct Point {
field x
field y
}
def main() -> ():
Point p = Point { x: 1, y: 1 }
p.x = 2
p.y = 2
return p
def main() -> (bool[4]):
bool[2] a = [true, true]
bool[4] x = [...a, ...a]
return x

View File

@ -167,7 +167,7 @@ impl ResolvedProgram {
// TODO: return synthesis error: "assignment missing" here
match self.get(&variable_name).unwrap() {
ResolvedValue::FieldElement(field) => field.clone(),
_ => panic!("expected a field, got boolean"),
value => panic!("expected a field, got {}", value),
}
} else {
let argument = std::env::args()
@ -326,23 +326,44 @@ impl ResolvedProgram {
self.enforce_boolean_expression(cs, scope, *third)
}
}
BooleanExpression::Array(array) => ResolvedValue::BooleanArray(
array
.into_iter()
.map(|element| match *element {
BooleanSpreadOrExpression::Spread(_spread) => {
unimplemented!("spreads not enforced yet")
}
BooleanSpreadOrExpression::BooleanExpression(expression) => {
match self.enforce_boolean_expression(cs, scope.clone(), expression) {
ResolvedValue::Boolean(value) => value,
_ => unimplemented!("cannot resolve boolean"),
BooleanExpression::Array(array) => {
let mut result = vec![];
array.into_iter().for_each(|element| match *element {
BooleanSpreadOrExpression::Spread(spread) => match spread.0 {
BooleanExpression::Variable(variable) => {
let array_name = new_scope_from_variable(scope.clone(), &variable);
match self.get(&array_name) {
Some(value) => match value {
ResolvedValue::BooleanArray(array) => {
result.extend(array.clone())
}
value => unimplemented!(
"spreads only implemented for arrays, got {}",
value
),
},
None => unimplemented!(
"cannot copy elements from array that does not exist {}",
variable.0
),
}
}
})
.collect::<Vec<Boolean>>(),
),
_ => unimplemented!(),
value => {
unimplemented!("spreads only implemented for arrays, got {}", value)
}
},
BooleanSpreadOrExpression::BooleanExpression(expression) => {
match self.enforce_boolean_expression(cs, scope.clone(), expression) {
ResolvedValue::Boolean(value) => result.push(value),
value => {
unimplemented!("expected boolean for boolean array, got {}", value)
}
}
}
});
ResolvedValue::BooleanArray(result)
}
expression => unimplemented!("boolean expression {}", expression),
}
}
@ -481,22 +502,41 @@ impl ResolvedProgram {
self.enforce_field_expression(cs, scope, *third)
}
}
FieldExpression::Array(array) => ResolvedValue::FieldElementArray(
array
.into_iter()
.map(|element| match *element {
FieldSpreadOrExpression::Spread(_spread) => {
unimplemented!("spreads not enforced yet")
}
FieldSpreadOrExpression::FieldExpression(expression) => {
match self.enforce_field_expression(cs, scope.clone(), expression) {
ResolvedValue::FieldElement(value) => value,
_ => unimplemented!("cannot resolve field"),
FieldExpression::Array(array) => {
let mut result = vec![];
array.into_iter().for_each(|element| match *element {
FieldSpreadOrExpression::Spread(spread) => match spread.0 {
FieldExpression::Variable(variable) => {
let array_name = new_scope_from_variable(scope.clone(), &variable);
match self.get(&array_name) {
Some(value) => match value {
ResolvedValue::FieldElementArray(array) => {
result.extend(array.clone())
}
value => unimplemented!(
"spreads only implemented for arrays, got {}",
value
),
},
None => unimplemented!(
"cannot copy elements from array that does not exist {}",
variable.0
),
}
}
})
.collect::<Vec<UInt32>>(),
),
value => {
unimplemented!("spreads only implemented for arrays, got {}", value)
}
},
FieldSpreadOrExpression::FieldExpression(expression) => {
match self.enforce_field_expression(cs, scope.clone(), expression) {
ResolvedValue::FieldElement(value) => result.push(value),
_ => unimplemented!("cannot resolve field"),
}
}
});
ResolvedValue::FieldElementArray(result)
}
}
}
@ -704,14 +744,6 @@ impl ResolvedProgram {
}
}
// fn modify_array<F: Field + PrimeField, CS: ConstraintSystem<F>>(
// &mut self,
// cs: &mut CS,
// scope: String,
// assignee: Assignee,
// expression: Expression,
// )
fn enforce_definition_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,

View File

@ -405,6 +405,9 @@ impl<'ast> From<ast::Spread<'ast>> for types::BooleanSpread {
let boolean_expression = types::Expression::from(spread.expression);
match boolean_expression {
types::Expression::Boolean(expression) => types::BooleanSpread(expression),
types::Expression::Variable(variable) => {
types::BooleanSpread(types::BooleanExpression::Variable(variable))
}
_ => unimplemented!("cannot create boolean spread from field type"),
}
}
@ -441,10 +444,15 @@ impl<'ast> From<ast::SpreadOrExpression<'ast>> for types::BooleanSpreadOrExpress
impl<'ast> From<ast::Spread<'ast>> for types::FieldSpread {
fn from(spread: ast::Spread<'ast>) -> Self {
let field_expression = types::Expression::from(spread.expression);
match field_expression {
match types::Expression::from(spread.expression) {
types::Expression::FieldElement(expression) => types::FieldSpread(expression),
_ => unimplemented!("cannot create field spread from boolean type"),
types::Expression::Variable(variable) => {
types::FieldSpread(types::FieldExpression::Variable(variable))
}
expression => unimplemented!(
"cannot create field spread from boolean type {}",
expression
),
}
}
}