mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 18:21:38 +03:00
constraints bool and field spreads
This commit is contained in:
parent
e1db8ed483
commit
1743c7a1f1
@ -1,10 +1,4 @@
|
|||||||
struct Point {
|
def main() -> (bool[4]):
|
||||||
field x
|
bool[2] a = [true, true]
|
||||||
field y
|
bool[4] x = [...a, ...a]
|
||||||
}
|
return x
|
||||||
|
|
||||||
def main() -> ():
|
|
||||||
Point p = Point { x: 1, y: 1 }
|
|
||||||
p.x = 2
|
|
||||||
p.y = 2
|
|
||||||
return p
|
|
@ -167,7 +167,7 @@ impl ResolvedProgram {
|
|||||||
// TODO: return synthesis error: "assignment missing" here
|
// TODO: return synthesis error: "assignment missing" here
|
||||||
match self.get(&variable_name).unwrap() {
|
match self.get(&variable_name).unwrap() {
|
||||||
ResolvedValue::FieldElement(field) => field.clone(),
|
ResolvedValue::FieldElement(field) => field.clone(),
|
||||||
_ => panic!("expected a field, got boolean"),
|
value => panic!("expected a field, got {}", value),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let argument = std::env::args()
|
let argument = std::env::args()
|
||||||
@ -326,23 +326,44 @@ impl ResolvedProgram {
|
|||||||
self.enforce_boolean_expression(cs, scope, *third)
|
self.enforce_boolean_expression(cs, scope, *third)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BooleanExpression::Array(array) => ResolvedValue::BooleanArray(
|
BooleanExpression::Array(array) => {
|
||||||
array
|
let mut result = vec![];
|
||||||
.into_iter()
|
array.into_iter().for_each(|element| match *element {
|
||||||
.map(|element| match *element {
|
BooleanSpreadOrExpression::Spread(spread) => match spread.0 {
|
||||||
BooleanSpreadOrExpression::Spread(_spread) => {
|
BooleanExpression::Variable(variable) => {
|
||||||
unimplemented!("spreads not enforced yet")
|
let array_name = new_scope_from_variable(scope.clone(), &variable);
|
||||||
}
|
match self.get(&array_name) {
|
||||||
BooleanSpreadOrExpression::BooleanExpression(expression) => {
|
Some(value) => match value {
|
||||||
match self.enforce_boolean_expression(cs, scope.clone(), expression) {
|
ResolvedValue::BooleanArray(array) => {
|
||||||
ResolvedValue::Boolean(value) => value,
|
result.extend(array.clone())
|
||||||
_ => unimplemented!("cannot resolve boolean"),
|
}
|
||||||
|
value => unimplemented!(
|
||||||
|
"spreads only implemented for arrays, got {}",
|
||||||
|
value
|
||||||
|
),
|
||||||
|
},
|
||||||
|
None => unimplemented!(
|
||||||
|
"cannot copy elements from array that does not exist {}",
|
||||||
|
variable.0
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
value => {
|
||||||
.collect::<Vec<Boolean>>(),
|
unimplemented!("spreads only implemented for arrays, got {}", value)
|
||||||
),
|
}
|
||||||
_ => unimplemented!(),
|
},
|
||||||
|
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)
|
self.enforce_field_expression(cs, scope, *third)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldExpression::Array(array) => ResolvedValue::FieldElementArray(
|
FieldExpression::Array(array) => {
|
||||||
array
|
let mut result = vec![];
|
||||||
.into_iter()
|
array.into_iter().for_each(|element| match *element {
|
||||||
.map(|element| match *element {
|
FieldSpreadOrExpression::Spread(spread) => match spread.0 {
|
||||||
FieldSpreadOrExpression::Spread(_spread) => {
|
FieldExpression::Variable(variable) => {
|
||||||
unimplemented!("spreads not enforced yet")
|
let array_name = new_scope_from_variable(scope.clone(), &variable);
|
||||||
}
|
match self.get(&array_name) {
|
||||||
FieldSpreadOrExpression::FieldExpression(expression) => {
|
Some(value) => match value {
|
||||||
match self.enforce_field_expression(cs, scope.clone(), expression) {
|
ResolvedValue::FieldElementArray(array) => {
|
||||||
ResolvedValue::FieldElement(value) => value,
|
result.extend(array.clone())
|
||||||
_ => unimplemented!("cannot resolve field"),
|
}
|
||||||
|
value => unimplemented!(
|
||||||
|
"spreads only implemented for arrays, got {}",
|
||||||
|
value
|
||||||
|
),
|
||||||
|
},
|
||||||
|
None => unimplemented!(
|
||||||
|
"cannot copy elements from array that does not exist {}",
|
||||||
|
variable.0
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
value => {
|
||||||
.collect::<Vec<UInt32>>(),
|
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>>(
|
fn enforce_definition_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
|
@ -405,6 +405,9 @@ impl<'ast> From<ast::Spread<'ast>> for types::BooleanSpread {
|
|||||||
let boolean_expression = types::Expression::from(spread.expression);
|
let boolean_expression = types::Expression::from(spread.expression);
|
||||||
match boolean_expression {
|
match boolean_expression {
|
||||||
types::Expression::Boolean(expression) => types::BooleanSpread(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"),
|
_ => 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 {
|
impl<'ast> From<ast::Spread<'ast>> for types::FieldSpread {
|
||||||
fn from(spread: ast::Spread<'ast>) -> Self {
|
fn from(spread: ast::Spread<'ast>) -> Self {
|
||||||
let field_expression = types::Expression::from(spread.expression);
|
match types::Expression::from(spread.expression) {
|
||||||
match field_expression {
|
|
||||||
types::Expression::FieldElement(expression) => types::FieldSpread(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
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user