1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

fix examples

This commit is contained in:
schaeff 2018-09-12 14:13:54 +02:00
parent 60c63c1aef
commit fec876a32a
14 changed files with 142 additions and 80 deletions

View file

@ -1,5 +1,5 @@
def sub(field a) -> (field):
field a = a + 3
a = a + 3
return a
def main() -> (field):

View file

@ -0,0 +1,7 @@
def foo() -> (field):
return 1
def main() -> (field):
bool a
field a = foo()
return 1

View file

@ -4,7 +4,7 @@ def add(field a,field b) -> (field):
// Expected for inputs 1,1: c=4, d=7, e=10
def main(field a,field b) -> (field):
field c = add(a*2+3*b-a,b-1)
field d = add(a*b+2, a*b*c)
field e = add(add(a,d),add(a,b))
c = add(a*2+3*b-a,b-1)
d = add(a*b+2, a*b*c)
e = add(add(a,d),add(a,b))
return e

View file

@ -2,5 +2,5 @@ def add(field f,field g) -> (field):
return f+g
def main(field a, field b) -> (field):
field c = add(a,b)
c = add(a,b)
return c

View file

@ -4,10 +4,10 @@ def add(field a, field b) -> (field):
def main(field a, field b,field c, field d) -> (field):
field g = a + b
field x = add(a,b)
field y = add(c,d)
field g = add(x, g)
x = add(a,b)
y = add(c,d)
g = add(x, g)
g = add(x, g)
field f = c + d + a
field g = add(g+a, add(x,b))
g = add(g+a, add(x,b))
return x + y + g + f

View file

@ -6,6 +6,6 @@ def sub(field a, field b) -> (field):
return a-b
def main(field a, field b) -> (field):
field c = add(a,b)
field d = sub(a,b)
c = add(a,b)
d = sub(a,b)
return 0

View file

@ -2,7 +2,7 @@ def const() -> (field):
return 123123
def add(field a,field b) -> (field):
field a=const()
a=const()
return a+b
def main(field a,field b) -> (field):

View file

@ -3,5 +3,5 @@ def main(field x) -> (field):
field b = a + x
a = 7
field c = a + b
field a = a + 5
a = a + 5
return a + c

View file

@ -6,5 +6,5 @@ import "./or.code" as OR
def main(field a, field b, field car) -> (field, field):
out1, car1 = HALFADD(a, b)
out2, car2 = HALFADD(out1, car)
field car3 = OR(car1, car2)
car3 = OR(car1, car2)
return out2, car3

View file

@ -1,7 +1,7 @@
def wtax(debt,wealth):
x = if wealth < debt then 0 else (wealth-debt) fi
def wtax(field debt, field wealth) -> (field):
field x = if wealth < debt then 0 else (wealth-debt) fi
return x
def main(debt, wealth):
tax = wtax(debt,wealth)
def main(private field debt, private field wealth) -> (field):
field tax = wtax(debt,wealth)
return tax

View file

@ -550,31 +550,31 @@ mod tests {
use super::*;
use self::glob::glob;
// #[test]
// fn examples() {
// for p in glob("./examples/**/*.code").expect("Failed to read glob pattern") {
// let path = match p {
// Ok(x) => x,
// Err(why) => panic!("Error: {:?}", why),
// };
#[test]
fn examples() {
for p in glob("./examples/**/*.code").expect("Failed to read glob pattern") {
let path = match p {
Ok(x) => x,
Err(why) => panic!("Error: {:?}", why),
};
// if path.to_str().unwrap().contains("error") {
// continue
// }
if path.to_str().unwrap().contains("error") {
continue
}
// println!("Testing {:?}", path);
println!("Testing {:?}", path);
// let file = File::open(path.clone()).unwrap();
let file = File::open(path.clone()).unwrap();
// let mut reader = BufReader::new(file);
// let location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap();
let mut reader = BufReader::new(file);
let location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap();
// let program_flattened: FlatProg<FieldPrime> =
// compile(&mut reader, Some(location), Some(fs_resolve), true, false).unwrap();
let program_flattened: FlatProg<FieldPrime> =
compile(&mut reader, Some(location), Some(fs_resolve), true, false).unwrap();
// let (..) = r1cs_program(&program_flattened);
// }
// }
let (..) = r1cs_program(&program_flattened);
}
}
#[test]
fn examples_with_input_success() {

View file

@ -501,7 +501,7 @@ impl Flattener {
}
}
panic!(
"TypedFunction definition for function {} with {:?} argument(s) not found.",
"TypedFunction definition for function {} with {:?} argument(s) not found. Should have been detected during semantic checking.",
id,
param_expressions
);
@ -743,7 +743,15 @@ impl Flattener {
expr_subbed,
)
},
_ => panic!("Functions can only return expressions of type FieldElement")
TypedExpression::Boolean(e) => {
let expr_subbed = e.apply_substitution(&self.substitution);
self.flatten_boolean_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
expr_subbed,
)
}
}
}).collect();
@ -764,26 +772,35 @@ impl Flattener {
// define n variables with n the number of primitive types for v_type
// assign them to the n primitive types for expr
match expr {
let rhs = match expr {
TypedExpression::FieldElement(expr) => {
let expr_subbed = expr.apply_substitution(&self.substitution);
let rhs = self.flatten_field_expression(
self.flatten_field_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
expr_subbed,
);
let var = self.use_variable(&v.id);
// handle return of function call
let var_to_replace = self.get_latest_var_substitution(&v.id);
if !(var == var_to_replace) && self.variables.contains(&var_to_replace) && !self.substitution.contains_key(&var_to_replace){
self.substitution.insert(var_to_replace.clone().to_string(),var.clone());
}
statements_flattened.push(FlatStatement::Definition(var, rhs));
)
},
_ => panic!("Definitions must have type FieldElement")
TypedExpression::Boolean(expr) => {
let expr_subbed = expr.apply_substitution(&self.substitution);
self.flatten_boolean_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
expr_subbed,
)
},
};
let var = self.use_variable(&v.id);
// handle return of function call
let var_to_replace = self.get_latest_var_substitution(&v.id);
if !(var == var_to_replace) && self.variables.contains(&var_to_replace) && !self.substitution.contains_key(&var_to_replace){
self.substitution.insert(var_to_replace.clone().to_string(),var.clone());
}
statements_flattened.push(FlatStatement::Definition(var, rhs));
}
TypedStatement::Condition(expr1, expr2) => {
@ -831,7 +848,47 @@ impl Flattener {
};
statements_flattened.push(FlatStatement::Condition(lhs, rhs));
},
_ => panic!("Conditions (Assertions) must be applied to expressions of type FieldElement")
(TypedExpression::Boolean(e1), TypedExpression::Boolean(e2)) => {
let e1_subbed = e1.apply_substitution(&self.substitution);
let e2_subbed = e2.apply_substitution(&self.substitution);
let (lhs, rhs) = if e1_subbed.is_linear() {
(
self.flatten_boolean_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
e1_subbed
),
self.flatten_boolean_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
e2_subbed,
),
)
} else if e2_subbed.is_linear() {
(
self.flatten_boolean_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
e2_subbed,
),
self.flatten_boolean_expression(
functions_flattened,
arguments_flattened,
statements_flattened,
e1_subbed,
),
)
} else {
unimplemented!()
};
statements_flattened.push(FlatStatement::Condition(lhs, rhs));
},
_ => panic!("non matching types in condition should have been caught at semantic stage")
}
}
TypedStatement::For(var, start, end, statements) => {
@ -862,7 +919,7 @@ impl Flattener {
let rhs_subbed = rhs.apply_substitution(&self.substitution);
match rhs_subbed {
TypedExpressionList::FunctionCall(fun_id, exprs, types) => {
TypedExpressionList::FunctionCall(fun_id, exprs, _) => {
let rhs_flattened = self.flatten_function_call(
functions_flattened,
arguments_flattened,
@ -872,21 +929,15 @@ impl Flattener {
&exprs,
);
// this will change for types that have multiple underlying fe
for (i, v) in vars.into_iter().enumerate() {
let var_type = &types[i];
match var_type {
Type::FieldElement => {
let var = self.use_variable(&v.id);
// handle return of function call
let var_to_replace = self.get_latest_var_substitution(&v.id);
if !(var == var_to_replace) && self.variables.contains(&var_to_replace) && !self.substitution.contains_key(&var_to_replace){
self.substitution.insert(var_to_replace.clone().to_string(),var.clone());
}
statements_flattened.push(FlatStatement::Definition(var, rhs_flattened.expressions[i].clone()));
},
_ => panic!("MultipleDefinition has to define expressions of type FieldElement")
let var = self.use_variable(&v.id);
// handle return of function call
let var_to_replace = self.get_latest_var_substitution(&v.id);
if !(var == var_to_replace) && self.variables.contains(&var_to_replace) && !self.substitution.contains_key(&var_to_replace){
self.substitution.insert(var_to_replace.clone().to_string(),var.clone());
}
statements_flattened.push(FlatStatement::Definition(var, rhs_flattened.expressions[i].clone()));
}
},
}

View file

@ -184,7 +184,7 @@ impl Checker {
0 => {
},
_ => panic!("dupllicate function declaration should have been caught")
_ => panic!("duplicate function declaration should have been caught")
}
self.enter_scope();
@ -413,7 +413,20 @@ impl Checker {
(TypedExpression::Boolean(condition), TypedExpression::FieldElement(consequence), TypedExpression::FieldElement(alternative)) => {
Ok(FieldElementExpression::IfElse(box condition, box consequence, box alternative).into())
},
_ => panic!("id else only for bool fe fe")
(condition, consequence, alternative) =>
Err(
Error {
message:
format!("if {{condition}} then {{consequence}} else {{alternative}} should have types {}, {}, {}, found {}, {}, {}",
Type::Boolean,
Type::FieldElement,
Type::FieldElement,
condition.get_type(),
consequence.get_type(),
alternative.get_type(),
)
}
)
}
},
&Expression::Number(ref n) => Ok(FieldElementExpression::Number(n.clone()).into()),
@ -443,9 +456,9 @@ impl Checker {
let f = &candidates[0];
// the return count has to be 1
if f.signature.outputs.len() == 1 {
match f.signature.outputs[0] {
Type::FieldElement => return Ok(FieldElementExpression::FunctionCall(f.id.clone(), arguments_checked).into()),
_ => panic!("cannot return booleans")
return match f.signature.outputs[0] {
Type::FieldElement => Ok(FieldElementExpression::FunctionCall(f.id.clone(), arguments_checked).into()),
ref t => Err( Error { message: format!("Outside of assignments, functions must return a single element of type {}, found type {}", Type::FieldElement, t)})
}
}
Err(Error { message: format!("{} returns {} values but is called outside of a definition", f.id, f.signature.outputs.len()) })

View file

@ -258,15 +258,6 @@ impl<T: Field> Typed for TypedExpression<T> {
}
}
impl<T: Field> TypedExpression<T> {
pub fn is_linear(&self) -> bool {
match self {
TypedExpression::Boolean(e) => e.is_linear(),
TypedExpression::FieldElement(e) => e.is_linear()
}
}
}
pub trait MultiTyped
{
fn get_types(&self) -> &Vec<Type>;