constraints for loops

This commit is contained in:
collin 2020-04-16 11:36:23 -07:00
parent 0a8cda3d7f
commit 455c0b631a
7 changed files with 100 additions and 61 deletions

View File

@ -1,9 +1,6 @@
struct Foo {
bool x
}
def main() -> (field):
field[3] a = [1, 2, 3] // initialize the array
field[4] b = [42; 4]
c = a[1..3] // helloo???
bool[3] d = [true, false, true]
return a[0]
a = 1
for i in 0..4 do
a = a + 1
endfor
return a

View File

@ -639,21 +639,50 @@ impl ResolvedProgram {
)
}
// fn enforce_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
// &mut self,
// cs: &mut CS,
// statement: Statement,
// ) {
// match statement {
// Statement::Definition(variable, expression) => {
// self.enforce_definition_statement(cs, variable, expression);
// }
// Statement::Return(statements) => {
// let res = self.enforce_return_statement(cs, statements);
//
// }
// };
// }
fn enforce_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
statement: Statement,
) {
match statement {
Statement::Definition(variable, expression) => {
self.enforce_definition_statement(cs, variable, expression);
}
Statement::For(index, start, stop, statements) => {
self.enforce_for_statement(cs, index, start, stop, statements);
}
Statement::Return(statements) => {
// TODO: add support for early termination
let _res = self.enforce_return_statement(cs, statements);
}
};
}
fn enforce_for_statement<F: Field + PrimeField, CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
index: Variable,
start: FieldExpression,
stop: FieldExpression,
statements: Vec<Statement>,
) {
let start_index = self.enforce_index(cs, start);
let stop_index = self.enforce_index(cs, stop);
for i in start_index..stop_index {
// Store index
self.resolved_variables.insert(
index.clone(),
ResolvedValue::FieldElement(UInt32::constant(i as u32)),
);
// Evaluate statements
statements
.clone()
.into_iter()
.for_each(|statement| self.enforce_statement(cs, statement));
}
}
fn enforce_function<F: Field + PrimeField, CS: ConstraintSystem<F>>(
&mut self,
@ -715,7 +744,10 @@ impl ResolvedProgram {
.into_iter()
.for_each(|statement| match statement {
Statement::Definition(variable, expression) => {
self.enforce_definition_statement(cs, variable, expression)
self.enforce_definition_statement(cs, variable, expression);
}
Statement::For(index, start, stop, statements) => {
self.enforce_for_statement(cs, index, start, stop, statements);
}
Statement::Return(expressions) => {
return_values = self.enforce_return_statement(cs, expressions)

View File

@ -103,6 +103,7 @@ pub enum Expression {
pub enum Statement {
// Declaration(Variable),
Definition(Variable, Expression),
For(Variable, FieldExpression, FieldExpression, Vec<Statement>),
Return(Vec<Expression>),
}
@ -120,12 +121,6 @@ pub struct StructMember {
pub expression: Expression,
}
// #[derive(Clone, Debug)]
// pub struct StructExpression {
// pub variable: Variable,
// pub members: Vec<StructMember>
// }
#[derive(Clone)]
pub struct StructField {
pub variable: Variable,

View File

@ -6,8 +6,8 @@
use crate::aleo_program::{
BooleanExpression, BooleanSpread, BooleanSpreadOrExpression, Expression, FieldExpression,
FieldRangeOrExpression, FieldSpread, FieldSpreadOrExpression, Function, FunctionName, Parameter, Statement,
Struct, StructField, Type, Variable,
FieldRangeOrExpression, FieldSpread, FieldSpreadOrExpression, Function, FunctionName,
Parameter, Statement, Struct, StructField, Type, Variable,
};
use std::fmt;
@ -166,15 +166,22 @@ impl<'ast> fmt::Display for Expression {
impl fmt::Display for Statement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Definition(ref variable, ref statement) => {
write!(f, "{} = {}", variable, statement)
}
Statement::For(ref var, ref start, ref stop, ref list) => {
write!(f, "for {} in {}..{} do\n", var, start, stop)?;
for l in list {
write!(f, "\t\t{}\n", l)?;
}
write!(f, "\tendfor")
}
Statement::Return(ref statements) => {
statements.iter().for_each(|statement| {
write!(f, "return {}", statement).unwrap();
});
write!(f, "\n")
}
Statement::Definition(ref variable, ref statement) => {
write!(f, "{} = {}", variable, statement)
}
}
}
}
@ -182,15 +189,22 @@ impl fmt::Display for Statement {
impl fmt::Debug for Statement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Definition(ref variable, ref statement) => {
write!(f, "{} = {}", variable, statement)
}
Statement::For(ref var, ref start, ref stop, ref list) => {
write!(f, "for {:?} in {:?}..{:?} do\n", var, start, stop)?;
for l in list {
write!(f, "\t\t{:?}\n", l)?;
}
write!(f, "\tendfor")
}
Statement::Return(ref statements) => {
statements.iter().for_each(|statement| {
write!(f, "return {}", statement).unwrap();
});
write!(f, "\n")
}
Statement::Definition(ref variable, ref statement) => {
write!(f, "{} = {}", variable, statement)
}
}
}
}

View File

@ -561,10 +561,18 @@ impl<'ast> From<ast::ReturnStatement<'ast>> for types::Statement {
}
}
impl<'ast> From<ast::IterationStatement<'ast>> for types::Statement {
fn from(statement: ast::IterationStatement<'ast>) -> Self {
println!("{:#?}", statement);
unimplemented!()
impl<'ast> From<ast::ForStatement<'ast>> for types::Statement {
fn from(statement: ast::ForStatement<'ast>) -> Self {
types::Statement::For(
types::Variable::from(statement.index),
types::FieldExpression::from(statement.start),
types::FieldExpression::from(statement.stop),
statement
.statements
.into_iter()
.map(|statement| types::Statement::from(statement))
.collect(),
)
}
}
@ -704,7 +712,8 @@ impl<'ast> From<ast::Function<'ast>> for types::Function {
impl<'ast> From<ast::File<'ast>> for types::Program {
fn from(file: ast::File<'ast>) -> Self {
// 1. compile ast -> aleo program representation
// Compiled ast -> aleo program representation
let mut structs = HashMap::new();
let mut functions = HashMap::new();
@ -721,17 +730,10 @@ impl<'ast> From<ast::File<'ast>> for types::Program {
);
});
// let statements: Vec<types::Statement> = file
// .statements
// .into_iter()
// .map(|statement| types::Statement::from(statement))
// .collect();
types::Program {
id: "main".into(),
structs,
functions,
// statements,
arguments: vec![],
returns: vec![],
}

View File

@ -701,12 +701,11 @@ pub struct DefinitionStatement<'ast> {
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::statement_iteration))]
pub struct IterationStatement<'ast> {
pub ty: Type<'ast>,
#[pest_ast(rule(Rule::statement_for))]
pub struct ForStatement<'ast> {
pub index: Variable<'ast>,
pub from: Expression<'ast>,
pub to: Expression<'ast>,
pub start: Expression<'ast>,
pub stop: Expression<'ast>,
pub statements: Vec<Statement<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,
@ -725,7 +724,7 @@ pub struct ReturnStatement<'ast> {
pub enum Statement<'ast> {
Assign(AssignStatement<'ast>),
Definition(DefinitionStatement<'ast>),
Iteration(IterationStatement<'ast>),
Iteration(ForStatement<'ast>),
Return(ReturnStatement<'ast>),
}
@ -741,12 +740,12 @@ impl<'ast> fmt::Display for DefinitionStatement<'ast> {
}
}
impl<'ast> fmt::Display for IterationStatement<'ast> {
impl<'ast> fmt::Display for ForStatement<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"for {} {} in {}..{} do {:#?} endfor",
self.ty, self.index, self.from, self.to, self.statements
"for {} in {}..{} do {:#?} endfor",
self.index, self.start, self.stop, self.statements
)
}
}

View File

@ -135,11 +135,11 @@ expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
statement_assign = { variable ~ "=" ~ expression }
statement_definition = { ty ~ variable ~ "=" ~ expression }
statement_return = { "return" ~ expression_tuple }
statement_iteration = { "for" ~ ty ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
statement_for = { "for" ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
statement = {
(statement_return
| (statement_iteration
| (statement_for
| statement_definition
| statement_assign
) ~ NEWLINE