1
0
Fork 0
mirror of synced 2025-09-23 20:28:36 +00:00

Rename VariableReference -> Identifier, NumberLiteral -> Number

This commit is contained in:
Dennis Kuhnert 2017-03-01 00:03:11 +01:00
parent e5cffc9763
commit 6c9fc391bb
4 changed files with 189 additions and 189 deletions

View file

@ -102,8 +102,8 @@ impl fmt::Debug for Parameter {
#[derive(Clone,PartialEq)]
pub enum Expression<T: Field> {
NumberLiteral(T),
VariableReference(String),
Number(T),
Identifier(String),
Add(Box<Expression<T>>, Box<Expression<T>>),
Sub(Box<Expression<T>>, Box<Expression<T>>),
Mult(Box<Expression<T>>, Box<Expression<T>>),
@ -115,13 +115,13 @@ pub enum Expression<T: Field> {
impl<T: Field> Expression<T> {
pub fn apply_substitution(&self, substitution: &HashMap<String, String>) -> Expression<T> {
match *self {
ref e @ Expression::NumberLiteral(_) => e.clone(),
Expression::VariableReference(ref v) => {
ref e @ Expression::Number(_) => e.clone(),
Expression::Identifier(ref v) => {
let mut new_name = v.to_string();
loop {
match substitution.get(&new_name) {
Some(x) => new_name = x.to_string(),
None => return Expression::VariableReference(new_name),
None => return Expression::Identifier(new_name),
}
}
},
@ -136,8 +136,8 @@ impl<T: Field> Expression<T> {
fn solve(&self, inputs: &mut HashMap<String, T>) -> T {
match *self {
Expression::NumberLiteral(ref x) => x.clone(),
Expression::VariableReference(ref var) => {
Expression::Number(ref x) => x.clone(),
Expression::Identifier(ref var) => {
if let None = inputs.get(var) {
if var.contains("_b") {
let var_name = var.split("_b").collect::<Vec<_>>()[0];
@ -175,15 +175,15 @@ impl<T: Field> Expression<T> {
pub fn is_linear(&self) -> bool {
match *self {
Expression::NumberLiteral(_) |
Expression::VariableReference(_) => true,
Expression::Number(_) |
Expression::Identifier(_) => true,
Expression::Add(ref x, ref y) |
Expression::Sub(ref x, ref y) => x.is_linear() && y.is_linear(),
Expression::Mult(ref x, ref y) |
Expression::Div(ref x, ref y) => match (x.clone(), y.clone()) {
(box Expression::NumberLiteral(_), box Expression::NumberLiteral(_)) |
(box Expression::NumberLiteral(_), box Expression::VariableReference(_)) |
(box Expression::VariableReference(_), box Expression::NumberLiteral(_)) => true,
(box Expression::Number(_), box Expression::Number(_)) |
(box Expression::Number(_), box Expression::Identifier(_)) |
(box Expression::Identifier(_), box Expression::Number(_)) => true,
_ => false,
},
_ => false,
@ -192,8 +192,8 @@ impl<T: Field> Expression<T> {
pub fn is_flattened(&self) -> bool {
match *self {
Expression::NumberLiteral(_) |
Expression::VariableReference(_) => true,
Expression::Number(_) |
Expression::Identifier(_) => true,
Expression::Add(ref x, ref y) |
Expression::Sub(ref x, ref y) => x.is_linear() && y.is_linear(),
Expression::Mult(ref x, ref y) |
@ -210,8 +210,8 @@ impl<T: Field> Expression<T> {
impl<T: Field> fmt::Display for Expression<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expression::NumberLiteral(ref i) => write!(f, "{}", i),
Expression::VariableReference(ref var) => write!(f, "{}", var),
Expression::Number(ref i) => write!(f, "{}", i),
Expression::Identifier(ref var) => write!(f, "{}", var),
Expression::Add(ref lhs, ref rhs) => write!(f, "({} + {})", lhs, rhs),
Expression::Sub(ref lhs, ref rhs) => write!(f, "({} - {})", lhs, rhs),
Expression::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs),
@ -225,8 +225,8 @@ impl<T: Field> fmt::Display for Expression<T> {
impl<T: Field> fmt::Debug for Expression<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expression::NumberLiteral(ref i) => write!(f, "Num({})", i),
Expression::VariableReference(ref var) => write!(f, "Ide({})", var),
Expression::Number(ref i) => write!(f, "Num({})", i),
Expression::Identifier(ref var) => write!(f, "Ide({})", var),
Expression::Add(ref lhs, ref rhs) => write!(f, "Add({:?}, {:?})", lhs, rhs),
Expression::Sub(ref lhs, ref rhs) => write!(f, "Sub({:?}, {:?})", lhs, rhs),
Expression::Mult(ref lhs, ref rhs) => write!(f, "Mult({:?}, {:?})", lhs, rhs),

View file

@ -35,7 +35,7 @@ impl Flattener {
}
}
/// Returns (condition true, condition false) `VariableReference`s for the given condition.
/// Returns (condition true, condition false) `Identifier`s for the given condition.
/// condition true = 1, if `condition` is true, 0 else
/// condition false = 1, if `condition` is false, 0 else
///
@ -61,8 +61,8 @@ impl Flattener {
statements_flattened.push(Statement::Definition(
subtraction_result.to_string(),
Sub(
box Mult(box NumberLiteral(T::from(2)), box VariableReference(lhs_name.to_string())),
box Mult(box NumberLiteral(T::from(2)), box VariableReference(rhs_name.to_string()))
box Mult(box Number(T::from(2)), box Identifier(lhs_name.to_string())),
box Mult(box Number(T::from(2)), box Identifier(rhs_name.to_string()))
)
));
for i in 0..self.bits-2 {
@ -70,16 +70,16 @@ impl Flattener {
statements_flattened.push(Statement::Definition(
new_name.to_string(),
Mult(
box VariableReference(new_name.to_string()),
box VariableReference(new_name.to_string())
box Identifier(new_name.to_string()),
box Identifier(new_name.to_string())
)
));
}
let mut expr = Add(
box VariableReference(format!("{}_b0", &subtraction_result)), // * 2^0
box Identifier(format!("{}_b0", &subtraction_result)), // * 2^0
box Mult(
box VariableReference(format!("{}_b1", &subtraction_result)),
box NumberLiteral(T::from(2))
box Identifier(format!("{}_b1", &subtraction_result)),
box Number(T::from(2))
)
);
for i in 1..self.bits/2 {
@ -87,12 +87,12 @@ impl Flattener {
box expr,
box Add(
box Mult(
box VariableReference(format!("{}_b{}", &subtraction_result, 2*i)),
box NumberLiteral(T::from(2).pow(i))
box Identifier(format!("{}_b{}", &subtraction_result, 2*i)),
box Number(T::from(2).pow(i))
),
box Mult(
box VariableReference(format!("{}_b{}", &subtraction_result, 2*i+1)),
box NumberLiteral(T::from(2).pow(i))
box Identifier(format!("{}_b{}", &subtraction_result, 2*i+1)),
box Number(T::from(2).pow(i))
),
)
);
@ -101,8 +101,8 @@ impl Flattener {
expr = Add(
box expr,
box Mult(
box VariableReference(format!("{}_b{}", &subtraction_result, self.bits - 3)),
box NumberLiteral(T::from(2).pow(self.bits - 1))
box Identifier(format!("{}_b{}", &subtraction_result, self.bits - 3)),
box Number(T::from(2).pow(self.bits - 1))
)
)
}
@ -113,8 +113,8 @@ impl Flattener {
let cond_false = format!("{}_b0", &subtraction_result);
let cond_true = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(cond_true.to_string(), Sub(box NumberLiteral(T::one()), box VariableReference(cond_false.to_string()))));
(VariableReference(cond_true), VariableReference(cond_false))
statements_flattened.push(Statement::Definition(cond_true.to_string(), Sub(box Number(T::one()), box Identifier(cond_false.to_string()))));
(Identifier(cond_true), Identifier(cond_false))
},
Condition::Eq(lhs, rhs) => {
// Wanted: (Y = (X != 0) ? 1 : 0)
@ -136,25 +136,25 @@ impl Flattener {
statements_flattened.push(Statement::Definition(name_x.to_string(), x));
statements_flattened.push(Statement::Compiler(name_y.to_string(), IfElse(
box Condition::Eq(
VariableReference(name_x.to_string()),
NumberLiteral(T::zero())
Identifier(name_x.to_string()),
Number(T::zero())
),
box NumberLiteral(T::zero()),
box NumberLiteral(T::one())
box Number(T::zero()),
box Number(T::one())
)));
statements_flattened.push(Statement::Compiler(name_m.to_string(), IfElse(
box Condition::Eq(
VariableReference(name_x.to_string()),
NumberLiteral(T::zero())
Identifier(name_x.to_string()),
Number(T::zero())
),
box NumberLiteral(T::one()),
box Div(box NumberLiteral(T::one()), box VariableReference(name_x.to_string()))
box Number(T::one()),
box Div(box Number(T::one()), box Identifier(name_x.to_string()))
)));
statements_flattened.push(Statement::Condition(VariableReference(name_y.to_string()), Mult(box VariableReference(name_x.to_string()), box VariableReference(name_m))));
statements_flattened.push(Statement::Definition(name_1_y.to_string(), Sub(box NumberLiteral(T::one()), box VariableReference(name_y.to_string()))));
statements_flattened.push(Statement::Condition(NumberLiteral(T::zero()), Mult(box VariableReference(name_1_y.to_string()), box VariableReference(name_x))));
statements_flattened.push(Statement::Condition(Identifier(name_y.to_string()), Mult(box Identifier(name_x.to_string()), box Identifier(name_m))));
statements_flattened.push(Statement::Definition(name_1_y.to_string(), Sub(box Number(T::one()), box Identifier(name_y.to_string()))));
statements_flattened.push(Statement::Condition(Number(T::zero()), Mult(box Identifier(name_1_y.to_string()), box Identifier(name_x))));
(VariableReference(name_1_y), VariableReference(name_y))
(Identifier(name_1_y), Identifier(name_y))
},
_ => unimplemented!(),
}
@ -168,8 +168,8 @@ impl Flattener {
/// * `expr` - `Expresstion` that will be flattened.
fn flatten_expression<T: Field>(&mut self, statements_flattened: &mut Vec<Statement<T>>, expr: Expression<T>) -> Expression<T> {
match expr {
x @ NumberLiteral(_) |
x @ VariableReference(_) => x,
x @ Number(_) |
x @ Identifier(_) => x,
ref x @ Add(..) |
ref x @ Sub(..) |
ref x @ Mult(..) |
@ -183,7 +183,7 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), left_flattened));
VariableReference(new_name)
Identifier(new_name)
};
let new_right = if right_flattened.is_linear() {
right_flattened
@ -191,7 +191,7 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), right_flattened));
VariableReference(new_name)
Identifier(new_name)
};
Add(box new_left, box new_right)
},
@ -204,7 +204,7 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), left_flattened));
VariableReference(new_name)
Identifier(new_name)
};
let new_right = if right_flattened.is_linear() {
right_flattened
@ -212,7 +212,7 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), right_flattened));
VariableReference(new_name)
Identifier(new_name)
};
Sub(box new_left, box new_right)
},
@ -224,7 +224,7 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), left_flattened));
VariableReference(new_name)
Identifier(new_name)
} else {
left_flattened
}
@ -232,14 +232,14 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), left_flattened));
VariableReference(new_name)
Identifier(new_name)
};
let new_right = if right_flattened.is_linear() {
if let Sub(..) = right_flattened {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), right_flattened));
VariableReference(new_name)
Identifier(new_name)
} else {
right_flattened
}
@ -247,7 +247,7 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), right_flattened));
VariableReference(new_name)
Identifier(new_name)
};
Mult(box new_left, box new_right)
},
@ -260,7 +260,7 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), left_flattened));
VariableReference(new_name)
Identifier(new_name)
};
let new_right = if right_flattened.is_linear() {
right_flattened
@ -268,22 +268,22 @@ impl Flattener {
let new_name = format!("sym_{}", self.next_var_idx);
self.next_var_idx += 1;
statements_flattened.push(Statement::Definition(new_name.to_string(), right_flattened));
VariableReference(new_name)
Identifier(new_name)
};
Div(box new_left, box new_right)
},
Pow(base, exponent) => {
// TODO currently assuming that base is number or variable
match exponent {
box NumberLiteral(ref x) if x > &T::one() => {
box Number(ref x) if x > &T::one() => {
match base {
box VariableReference(ref var) => {
box Identifier(ref var) => {
let id = if x > &T::from(2) {
let tmp_expression = self.flatten_expression(
statements_flattened,
Pow(
box VariableReference(var.to_string()),
box NumberLiteral(x.clone() - T::one())
box Identifier(var.to_string()),
box Number(x.clone() - T::one())
)
);
let new_name = format!("sym_{}", self.next_var_idx);
@ -294,13 +294,13 @@ impl Flattener {
var.to_string()
};
Mult(
box VariableReference(id.to_string()),
box VariableReference(var.to_string())
box Identifier(id.to_string()),
box Identifier(var.to_string())
)
},
box NumberLiteral(var) => Mult(
box NumberLiteral(var.clone()),
box NumberLiteral(var)
box Number(var) => Mult(
box Number(var.clone()),
box Number(var)
),
_ => panic!("Only variables and numbers allowed in pow base")
}

View file

@ -293,7 +293,7 @@ fn parse_factor1<T: Field>(expr: Expression<T>, input: String, pos: Position) ->
Ok((e1, s1, p1)) => match parse_expr1(e1, s1, p1) {
Ok((e2, s2, p2)) => match next_token::<T>(&s2, &p2) {
(Token::Pow, s3, p3) => match next_token(&s3, &p3) {
(Token::Num(x), s4, p4) => Ok((Expression::Pow(box e2, box Expression::NumberLiteral(x)), s4, p4)),
(Token::Num(x), s4, p4) => Ok((Expression::Pow(box e2, box Expression::Number(x)), s4, p4)),
(t4, _, p4) => Err(Error { expected: vec![Token::ErrNum], got: t4 , pos: p4 }),
},
_ => Ok((expr, input, pos)),
@ -314,8 +314,8 @@ fn parse_factor<T: Field>(input: &String, pos: &Position) -> Result<(Expression<
},
Err(err) => Err(err),
},
(Token::Ide(x), s1, p1) => parse_factor1(Expression::VariableReference(x), s1, p1),
(Token::Num(x), s1, p1) => parse_factor1(Expression::NumberLiteral(x), s1, p1),
(Token::Ide(x), s1, p1) => parse_factor1(Expression::Identifier(x), s1, p1),
(Token::Num(x), s1, p1) => parse_factor1(Expression::Number(x), s1, p1),
(t1, _, p1) => Err(Error { expected: vec![Token::If, Token::Open, Token::ErrIde, Token::ErrNum], got: t1 , pos: p1 }),
}
}
@ -361,7 +361,7 @@ fn parse_expr1<T: Field>(expr: Expression<T>, input: String, pos: Position) -> R
},
(Token::Pow, s1, p1) => {
match parse_num(&s1, &p1) {
(Token::Num(x), s2, p2) => match parse_term1(Expression::Pow(box expr, box Expression::NumberLiteral(x)), s2, p2) {
(Token::Num(x), s2, p2) => match parse_term1(Expression::Pow(box expr, box Expression::Number(x)), s2, p2) {
Ok((e3, s3, p3)) => parse_expr1(e3, s3, p3),
Err(err) => Err(err),
},
@ -386,13 +386,13 @@ fn parse_expr<T: Field>(input: &String, pos: &Position) -> Result<(Expression<T>
Err(err) => Err(err),
},
(Token::Ide(x), s1, p1) => {
match parse_term1(Expression::VariableReference(x), s1, p1) {
match parse_term1(Expression::Identifier(x), s1, p1) {
Ok((e2, s2, p2)) => parse_expr1(e2, s2, p2),
Err(err) => Err(err),
}
}
(Token::Num(x), s1, p1) => {
match parse_term1(Expression::NumberLiteral(x), s1, p1) {
match parse_term1(Expression::Number(x), s1, p1) {
Ok((e2, s2, p2)) => parse_expr1(e2, s2, p2),
Err(err) => Err(err),
}
@ -413,7 +413,7 @@ fn parse_statement1<T: Field>(ide: String, input: String, pos: Position) -> Resu
},
Err(err) => Err(err),
},
_ => match parse_term1(Expression::VariableReference(ide), input, pos) {
_ => match parse_term1(Expression::Identifier(ide), input, pos) {
Ok((e2, s2, p2)) => match parse_expr1(e2, s2, p2) {
Ok((e3, s3, p3)) => match next_token(&s3, &p3) {
(Token::Eqeq, s4, p4) => match parse_expr(&s4, &p4) {
@ -641,9 +641,9 @@ mod tests {
let pos = Position { line: 45, col: 121 };
let string = String::from("if a < b then c else d fi");
let expr = Expression::IfElse::<FieldPrime>(
box Condition::Lt(Expression::VariableReference(String::from("a")), Expression::VariableReference(String::from("b"))),
box Expression::VariableReference(String::from("c")),
box Expression::VariableReference(String::from("d"))
box Condition::Lt(Expression::Identifier(String::from("a")), Expression::Identifier(String::from("b"))),
box Expression::Identifier(String::from("c")),
box Expression::Identifier(String::from("d"))
);
assert_eq!(
Ok((expr, String::from(""), pos.col(string.len() as isize))),
@ -661,9 +661,9 @@ mod tests {
let pos = Position { line: 45, col: 121 };
let string = String::from("if a < b then c else d fi");
let expr = Expression::IfElse::<FieldPrime>(
box Condition::Lt(Expression::VariableReference(String::from("a")), Expression::VariableReference(String::from("b"))),
box Expression::VariableReference(String::from("c")),
box Expression::VariableReference(String::from("d"))
box Condition::Lt(Expression::Identifier(String::from("a")), Expression::Identifier(String::from("b"))),
box Expression::Identifier(String::from("c")),
box Expression::Identifier(String::from("d"))
);
assert_eq!(
Ok((expr, String::from(""), pos.col(string.len() as isize))),
@ -675,8 +675,8 @@ mod tests {
let pos = Position { line: 45, col: 121 };
let string = String::from("(5 + a * 6)");
let expr = Expression::Add(
box Expression::NumberLiteral(FieldPrime::from(5)),
box Expression::Mult(box Expression::VariableReference(String::from("a")), box Expression::NumberLiteral(FieldPrime::from(6)))
box Expression::Number(FieldPrime::from(5)),
box Expression::Mult(box Expression::Identifier(String::from("a")), box Expression::Number(FieldPrime::from(6)))
);
assert_eq!(
Ok((expr, String::from(""), pos.col(string.len() as isize))),
@ -687,7 +687,7 @@ mod tests {
fn ide() {
let pos = Position { line: 45, col: 121 };
let string = String::from("a");
let expr = Expression::VariableReference::<FieldPrime>(String::from("a"));
let expr = Expression::Identifier::<FieldPrime>(String::from("a"));
assert_eq!(
Ok((expr, String::from(""), pos.col(string.len() as isize))),
parse_factor(&string, &pos)
@ -697,7 +697,7 @@ mod tests {
fn num() {
let pos = Position { line: 45, col: 121 };
let string = String::from("234");
let expr = Expression::NumberLiteral(FieldPrime::from(234));
let expr = Expression::Number(FieldPrime::from(234));
assert_eq!(
Ok((expr, String::from(""), pos.col(string.len() as isize))),
parse_factor(&string, &pos)

View file

@ -25,8 +25,8 @@ fn get_summands<T: Field>(expr: &Expression<T>) -> Vec<&Expression<T>> {
loop {
if let Some(e) = trace.pop() {
match *e {
ref e @ NumberLiteral(_) |
ref e @ VariableReference(_) |
ref e @ Number(_) |
ref e @ Identifier(_) |
ref e @ Mult(..) |
ref e @ Sub(..) if e.is_linear() => add.push(e),
Add(ref l, ref r) => {
@ -55,20 +55,20 @@ fn count_variables_add<T: Field>(expr: &Expression<T>) -> HashMap<String, T> {
let mut count = HashMap::new();
for s in summands {
match *s {
NumberLiteral(ref x) => {
Number(ref x) => {
let num = count.entry("~one".to_string()).or_insert(T::zero());
*num = num.clone() + x;
},
VariableReference(ref v) => {
Identifier(ref v) => {
let num = count.entry(v.to_string()).or_insert(T::zero());
*num = num.clone() + T::one();
},
Mult(box NumberLiteral(ref x1), box NumberLiteral(ref x2)) => {
Mult(box Number(ref x1), box Number(ref x2)) => {
let num = count.entry("~one".to_string()).or_insert(T::zero());
*num = num.clone() + x1 + x2;
},
Mult(box NumberLiteral(ref x), box VariableReference(ref v)) |
Mult(box VariableReference(ref v), box NumberLiteral(ref x)) => {
Mult(box Number(ref x), box Identifier(ref v)) |
Mult(box Identifier(ref v), box Number(ref x)) => {
let num = count.entry(v.to_string()).or_insert(T::zero());
*num = num.clone() + x;
},
@ -92,8 +92,8 @@ fn swap_sub<T: Field>(lhs: &Expression<T>, rhs: &Expression<T>) -> (Expression<T
run = false;
for i in 0..left.len() {
match *left[i] {
ref e @ NumberLiteral(_) |
ref e @ VariableReference(_) |
ref e @ Number(_) |
ref e @ Identifier(_) |
ref e @ Mult(..) if e.is_linear() => {},
Sub(ref l, ref r) => {
run = true;
@ -106,8 +106,8 @@ fn swap_sub<T: Field>(lhs: &Expression<T>, rhs: &Expression<T>) -> (Expression<T
}
for i in 0..right.len() {
match *right[i] {
ref e @ NumberLiteral(_) |
ref e @ VariableReference(_) |
ref e @ Number(_) |
ref e @ Identifier(_) |
ref e @ Mult(..) if e.is_linear() => {},
Sub(ref l, ref r) => {
run = true;
@ -157,16 +157,16 @@ fn r1cs_expression<T: Field>(linear_expr: Expression<T>, expr: Expression<T>, va
},
Mult(lhs, rhs) => {
match lhs {
box NumberLiteral(x) => a_row.push((0, x)),
box VariableReference(x) => a_row.push((get_variable_idx(variables, &x), T::one())),
box Number(x) => a_row.push((0, x)),
box Identifier(x) => a_row.push((get_variable_idx(variables, &x), T::one())),
box e @ Add(..) => for (key, value) in count_variables_add(&e) {
a_row.push((get_variable_idx(variables, &key), value));
},
e @ _ => panic!("Not flattened: {}", e),
};
match rhs {
box NumberLiteral(x) => b_row.push((0, x)),
box VariableReference(x) => b_row.push((get_variable_idx(variables, &x), T::one())),
box Number(x) => b_row.push((0, x)),
box Identifier(x) => b_row.push((get_variable_idx(variables, &x), T::one())),
box e @ Add(..) => for (key, value) in count_variables_add(&e) {
b_row.push((get_variable_idx(variables, &key), value));
},
@ -178,23 +178,23 @@ fn r1cs_expression<T: Field>(linear_expr: Expression<T>, expr: Expression<T>, va
},
Div(lhs, rhs) => { // a / b = c --> c * b = a
match lhs {
box NumberLiteral(x) => c_row.push((0, x)),
box VariableReference(x) => c_row.push((get_variable_idx(variables, &x), T::one())),
box Number(x) => c_row.push((0, x)),
box Identifier(x) => c_row.push((get_variable_idx(variables, &x), T::one())),
box e @ Add(..) => for (key, value) in count_variables_add(&e) {
c_row.push((get_variable_idx(variables, &key), value));
},
box e @ Sub(..) => return r1cs_expression(Mult(box linear_expr, rhs), e, variables, a_row, b_row, c_row),
box Mult(box NumberLiteral(ref x1), box NumberLiteral(ref x2)) => c_row.push((0, x1.clone() * x2)),
box Mult(box NumberLiteral(ref x), box VariableReference(ref v)) |
box Mult(box VariableReference(ref v), box NumberLiteral(ref x)) => c_row.push((get_variable_idx(variables, v), x.clone())),
box Mult(box Number(ref x1), box Number(ref x2)) => c_row.push((0, x1.clone() * x2)),
box Mult(box Number(ref x), box Identifier(ref v)) |
box Mult(box Identifier(ref v), box Number(ref x)) => c_row.push((get_variable_idx(variables, v), x.clone())),
e @ _ => panic!("(lhs) not supported: {:?}", e),
};
match rhs {
box NumberLiteral(x) => b_row.push((0, x)),
box VariableReference(x) => b_row.push((get_variable_idx(variables, &x), T::one())),
box Mult(box NumberLiteral(ref x1), box NumberLiteral(ref x2)) => b_row.push((0, x1.clone() * x2)),
box Mult(box NumberLiteral(ref x), box VariableReference(ref v)) |
box Mult(box VariableReference(ref v), box NumberLiteral(ref x)) => b_row.push((get_variable_idx(variables, v), x.clone())),
box Number(x) => b_row.push((0, x)),
box Identifier(x) => b_row.push((get_variable_idx(variables, &x), T::one())),
box Mult(box Number(ref x1), box Number(ref x2)) => b_row.push((0, x1.clone() * x2)),
box Mult(box Number(ref x), box Identifier(ref v)) |
box Mult(box Identifier(ref v), box Number(ref x)) => b_row.push((get_variable_idx(variables, v), x.clone())),
e @ _ => panic!("(rhs) not supported: {:?}", e),
};
for (key, value) in count_variables_add(&linear_expr) {
@ -203,14 +203,14 @@ fn r1cs_expression<T: Field>(linear_expr: Expression<T>, expr: Expression<T>, va
},
Pow(_, _) => panic!("Pow not flattened"),
IfElse(_, _, _) => panic!("IfElse not flattened"),
VariableReference(var) => {
Identifier(var) => {
a_row.push((get_variable_idx(variables, &var), T::one()));
b_row.push((0, T::one()));
for (key, value) in count_variables_add(&linear_expr) {
c_row.push((get_variable_idx(variables, &key), value));
}
},
NumberLiteral(x) => {
Number(x) => {
a_row.push((0, x));
b_row.push((0, T::one()));
for (key, value) in count_variables_add(&linear_expr) {
@ -255,8 +255,8 @@ pub fn r1cs_program<T: Field>(prog: &Prog<T>) -> (Vec<String>, Vec<Vec<(usize, T
let mut b_row: Vec<(usize, T)> = Vec::new();
let mut c_row: Vec<(usize, T)> = Vec::new();
match *def {
Statement::Return(ref expr) => r1cs_expression(VariableReference("~out".to_string()), expr.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
Statement::Definition(ref id, ref expr) => r1cs_expression(VariableReference(id.to_string()), expr.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
Statement::Return(ref expr) => r1cs_expression(Identifier("~out".to_string()), expr.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
Statement::Definition(ref id, ref expr) => r1cs_expression(Identifier(id.to_string()), expr.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
Statement::Condition(ref expr1, ref expr2) => r1cs_expression(expr1.clone(), expr2.clone(), &mut variables, &mut a_row, &mut b_row, &mut c_row),
Statement::Compiler(..) => continue,
}
@ -290,8 +290,8 @@ mod tests {
#[test]
fn add() {
// x = y + 5
let lhs = VariableReference(String::from("x"));
let rhs = Add(box VariableReference(String::from("y")), box NumberLiteral(FieldPrime::from(5)));
let lhs = Identifier(String::from("x"));
let rhs = Add(box Identifier(String::from("y")), box Number(FieldPrime::from(5)));
let mut variables: Vec<String> = vec!["~one", "x", "y"].iter().map(|&x| String::from(x)).collect();
let mut a_row: Vec<(usize, FieldPrime)> = Vec::new();
let mut b_row: Vec<(usize, FieldPrime)> = Vec::new();
@ -312,25 +312,25 @@ mod tests {
// --> (x + y) + y + 4y + 2z + y == x + 2x + 4y + (z + 3x)
// <=> x + 7*y + 2*z == 6*x + 4y + z
let lhs = Sub(
box Add(box VariableReference(String::from("x")), box VariableReference(String::from("y"))),
box Add(box Identifier(String::from("x")), box Identifier(String::from("y"))),
box Sub(
box Add(
box VariableReference(String::from("z")),
box Mult(box NumberLiteral(FieldPrime::from(3)), box VariableReference(String::from("x")))
box Identifier(String::from("z")),
box Mult(box Number(FieldPrime::from(3)), box Identifier(String::from("x")))
),
box VariableReference(String::from("y"))
box Identifier(String::from("y"))
)
);
let rhs = Add(
box Sub(box VariableReference(String::from("x")), box VariableReference(String::from("y"))),
box Sub(box Identifier(String::from("x")), box Identifier(String::from("y"))),
box Add(
box Sub(
box Mult(box NumberLiteral(FieldPrime::from(2)), box VariableReference(String::from("x"))),
box Mult(box NumberLiteral(FieldPrime::from(4)), box VariableReference(String::from("y")))
box Mult(box Number(FieldPrime::from(2)), box Identifier(String::from("x"))),
box Mult(box Number(FieldPrime::from(4)), box Identifier(String::from("y")))
),
box Sub(
box Mult(box NumberLiteral(FieldPrime::from(4)), box VariableReference(String::from("y"))),
box Mult(box NumberLiteral(FieldPrime::from(2)), box VariableReference(String::from("z")))
box Mult(box Number(FieldPrime::from(4)), box Identifier(String::from("y"))),
box Mult(box Number(FieldPrime::from(2)), box Identifier(String::from("z")))
)
)
);
@ -352,12 +352,12 @@ mod tests {
fn sub() {
// 7 * x + y == 3 * y - z * 6
let lhs = Add(
box Mult(box NumberLiteral(FieldPrime::from(7)), box VariableReference(String::from("x"))),
box VariableReference(String::from("y"))
box Mult(box Number(FieldPrime::from(7)), box Identifier(String::from("x"))),
box Identifier(String::from("y"))
);
let rhs = Sub(
box Mult(box NumberLiteral(FieldPrime::from(3)), box VariableReference(String::from("y"))),
box Mult(box VariableReference(String::from("z")), box NumberLiteral(FieldPrime::from(6)))
box Mult(box Number(FieldPrime::from(3)), box Identifier(String::from("y"))),
box Mult(box Identifier(String::from("z")), box Number(FieldPrime::from(6)))
);
let mut variables: Vec<String> = vec!["~one", "x", "y", "z"].iter().map(|&x| String::from(x)).collect();
let mut a_row: Vec<(usize, FieldPrime)> = Vec::new();
@ -379,14 +379,14 @@ mod tests {
// --> 3*y + x == a + 12*x + 2*z
let lhs = Sub(
box Sub(
box Mult(box NumberLiteral(FieldPrime::from(3)), box VariableReference(String::from("y"))),
box Mult(box VariableReference(String::from("z")), box NumberLiteral(FieldPrime::from(2)))
box Mult(box Number(FieldPrime::from(3)), box Identifier(String::from("y"))),
box Mult(box Identifier(String::from("z")), box Number(FieldPrime::from(2)))
),
box Mult(box VariableReference(String::from("x")), box NumberLiteral(FieldPrime::from(12)))
box Mult(box Identifier(String::from("x")), box Number(FieldPrime::from(12)))
);
let rhs = Sub(
box VariableReference(String::from("a")),
box VariableReference(String::from("x"))
box Identifier(String::from("a")),
box Identifier(String::from("x"))
);
let mut variables: Vec<String> = vec!["~one", "x", "y", "z", "a"].iter().map(|&x| String::from(x)).collect();
let mut a_row: Vec<(usize, FieldPrime)> = Vec::new();
@ -407,22 +407,22 @@ mod tests {
// 4 * b + 3 * a + 3 * c == (3 * a + 6 * b + 4 * c) * (31 * a + 4 * c)
let lhs = Add(
box Add(
box Mult(box NumberLiteral(FieldPrime::from(4)), box VariableReference(String::from("b"))),
box Mult(box NumberLiteral(FieldPrime::from(3)), box VariableReference(String::from("a")))
box Mult(box Number(FieldPrime::from(4)), box Identifier(String::from("b"))),
box Mult(box Number(FieldPrime::from(3)), box Identifier(String::from("a")))
),
box Mult(box NumberLiteral(FieldPrime::from(3)), box VariableReference(String::from("c")))
box Mult(box Number(FieldPrime::from(3)), box Identifier(String::from("c")))
);
let rhs = Mult(
box Add(
box Add(
box Mult(box NumberLiteral(FieldPrime::from(3)), box VariableReference(String::from("a"))),
box Mult(box NumberLiteral(FieldPrime::from(6)), box VariableReference(String::from("b")))
box Mult(box Number(FieldPrime::from(3)), box Identifier(String::from("a"))),
box Mult(box Number(FieldPrime::from(6)), box Identifier(String::from("b")))
),
box Mult(box NumberLiteral(FieldPrime::from(4)), box VariableReference(String::from("c")))
box Mult(box Number(FieldPrime::from(4)), box Identifier(String::from("c")))
),
box Add(
box Mult(box NumberLiteral(FieldPrime::from(31)), box VariableReference(String::from("a"))),
box Mult(box NumberLiteral(FieldPrime::from(4)), box VariableReference(String::from("c")))
box Mult(box Number(FieldPrime::from(31)), box Identifier(String::from("a"))),
box Mult(box Number(FieldPrime::from(4)), box Identifier(String::from("c")))
)
);
let mut variables: Vec<String> = vec!["~one", "a", "b", "c"].iter().map(|&x| String::from(x)).collect();
@ -442,10 +442,10 @@ mod tests {
#[test]
fn div() {
// x = (3 * x) / (y * 6) --> x * (y * 6) = 3 * x
let lhs = VariableReference(String::from("x"));
let lhs = Identifier(String::from("x"));
let rhs = Div(
box Mult(box NumberLiteral(FieldPrime::from(3)), box VariableReference(String::from("x"))),
box Mult(box VariableReference(String::from("y")), box NumberLiteral(FieldPrime::from(6)))
box Mult(box Number(FieldPrime::from(3)), box Identifier(String::from("x"))),
box Mult(box Identifier(String::from("y")), box Number(FieldPrime::from(6)))
);
let mut variables: Vec<String> = vec!["~one", "x", "y"].iter().map(|&x| String::from(x)).collect();
let mut a_row: Vec<(usize, FieldPrime)> = Vec::new();
@ -477,19 +477,19 @@ mod tests {
// fn count_variables_add<T: Field>(expr: &Expression<T>) -> HashMap<String, T> {
// let mut count = HashMap::new();
// match expr.clone() {
// NumberLiteral(x) => { count.insert("~one".to_string(), x); },
// VariableReference(var) => { count.insert(var, T::one()); },
// Mult(box NumberLiteral(x1), box NumberLiteral(x2)) => { count.insert("~one".to_string(), x1 * x2); },
// Mult(box NumberLiteral(x), box VariableReference(var)) |
// Mult(box VariableReference(var), box NumberLiteral(x)) => { count.insert(var, x); },
// Number(x) => { count.insert("~one".to_string(), x); },
// Identifier(var) => { count.insert(var, T::one()); },
// Mult(box Number(x1), box Number(x2)) => { count.insert("~one".to_string(), x1 * x2); },
// Mult(box Number(x), box Identifier(var)) |
// Mult(box Identifier(var), box Number(x)) => { count.insert(var, x); },
// Add(box lhs, box rhs) => {
// match (lhs, rhs) {
// (NumberLiteral(x), NumberLiteral(y)) => {
// (Number(x), Number(y)) => {
// let num = count.entry("~one".to_string()).or_insert(T::zero());
// *num = num.clone() + x + y;
// },
// (VariableReference(v), NumberLiteral(x)) |
// (NumberLiteral(x), VariableReference(v)) => {
// (Identifier(v), Number(x)) |
// (Number(x), Identifier(v)) => {
// {
// let num = count.entry("~one".to_string()).or_insert(T::zero());
// *num = num.clone() + x;
@ -497,7 +497,7 @@ mod tests {
// let var = count.entry(v).or_insert(T::zero());
// *var = var.clone() + T::one();
// },
// (VariableReference(v1), VariableReference(v2)) => {
// (Identifier(v1), Identifier(v2)) => {
// {
// let var1 = count.entry(v1).or_insert(T::zero());
// *var1 = var1.clone() + T::one();
@ -505,8 +505,8 @@ mod tests {
// let var2 = count.entry(v2).or_insert(T::zero());
// *var2 = var2.clone() + T::one();
// },
// (NumberLiteral(x), e @ Add(..)) |
// (e @ Add(..), NumberLiteral(x)) => {
// (Number(x), e @ Add(..)) |
// (e @ Add(..), Number(x)) => {
// {
// let num = count.entry("~one".to_string()).or_insert(T::zero());
// *num = num.clone() + x;
@ -517,8 +517,8 @@ mod tests {
// *val = val.clone() + value;
// }
// },
// (VariableReference(v), e @ Add(..)) |
// (e @ Add(..), VariableReference(v)) => {
// (Identifier(v), e @ Add(..)) |
// (e @ Add(..), Identifier(v)) => {
// {
// let var = count.entry(v).or_insert(T::zero());
// *var = var.clone() + T::one();
@ -529,10 +529,10 @@ mod tests {
// *val = val.clone() + value;
// }
// },
// (NumberLiteral(x), Mult(box NumberLiteral(n), box VariableReference(v))) |
// (NumberLiteral(x), Mult(box VariableReference(v), box NumberLiteral(n))) |
// (Mult(box NumberLiteral(n), box VariableReference(v)), NumberLiteral(x)) |
// (Mult(box VariableReference(v), box NumberLiteral(n)), NumberLiteral(x)) => {
// (Number(x), Mult(box Number(n), box Identifier(v))) |
// (Number(x), Mult(box Identifier(v), box Number(n))) |
// (Mult(box Number(n), box Identifier(v)), Number(x)) |
// (Mult(box Identifier(v), box Number(n)), Number(x)) => {
// {
// let num = count.entry("~one".to_string()).or_insert(T::zero());
// *num = num.clone() + x;
@ -540,10 +540,10 @@ mod tests {
// let var = count.entry(v).or_insert(T::zero());
// *var = var.clone() + n;
// },
// (VariableReference(v1), Mult(box NumberLiteral(n), box VariableReference(v2))) |
// (VariableReference(v1), Mult(box VariableReference(v2), box NumberLiteral(n))) |
// (Mult(box NumberLiteral(n), box VariableReference(v2)), VariableReference(v1)) |
// (Mult(box VariableReference(v2), box NumberLiteral(n)), VariableReference(v1)) => {
// (Identifier(v1), Mult(box Number(n), box Identifier(v2))) |
// (Identifier(v1), Mult(box Identifier(v2), box Number(n))) |
// (Mult(box Number(n), box Identifier(v2)), Identifier(v1)) |
// (Mult(box Identifier(v2), box Number(n)), Identifier(v1)) => {
// {
// let var = count.entry(v1).or_insert(T::zero());
// *var = var.clone() + T::one();
@ -551,10 +551,10 @@ mod tests {
// let var = count.entry(v2).or_insert(T::zero());
// *var = var.clone() + n;
// },
// (e @ Add(..), Mult(box NumberLiteral(n), box VariableReference(v))) |
// (e @ Add(..), Mult(box VariableReference(v), box NumberLiteral(n))) |
// (Mult(box NumberLiteral(n), box VariableReference(v)), e @ Add(..)) |
// (Mult(box VariableReference(v), box NumberLiteral(n)), e @ Add(..)) => {
// (e @ Add(..), Mult(box Number(n), box Identifier(v))) |
// (e @ Add(..), Mult(box Identifier(v), box Number(n))) |
// (Mult(box Number(n), box Identifier(v)), e @ Add(..)) |
// (Mult(box Identifier(v), box Number(n)), e @ Add(..)) => {
// {
// let var = count.entry(v).or_insert(T::zero());
// *var = var.clone() + n;
@ -565,10 +565,10 @@ mod tests {
// *val = val.clone() + value;
// }
// },
// (Mult(box NumberLiteral(n1), box VariableReference(v1)), Mult(box NumberLiteral(n2), box VariableReference(v2))) |
// (Mult(box VariableReference(v1), box NumberLiteral(n1)), Mult(box NumberLiteral(n2), box VariableReference(v2))) |
// (Mult(box NumberLiteral(n1), box VariableReference(v1)), Mult(box VariableReference(v2), box NumberLiteral(n2))) |
// (Mult(box VariableReference(v1), box NumberLiteral(n1)), Mult(box VariableReference(v2), box NumberLiteral(n2))) => {
// (Mult(box Number(n1), box Identifier(v1)), Mult(box Number(n2), box Identifier(v2))) |
// (Mult(box Identifier(v1), box Number(n1)), Mult(box Number(n2), box Identifier(v2))) |
// (Mult(box Number(n1), box Identifier(v1)), Mult(box Identifier(v2), box Number(n2))) |
// (Mult(box Identifier(v1), box Number(n1)), Mult(box Identifier(v2), box Number(n2))) => {
// {
// let var = count.entry(v1).or_insert(T::zero());
// *var = var.clone() + n1;
@ -608,22 +608,22 @@ mod tests {
// // assert that Mult on lhs or rhs is linear!
// match (lhs.clone(), rhs.clone()) {
// // recursion end
// (v1 @ NumberLiteral(_), v2 @ NumberLiteral(_)) |
// (v1 @ VariableReference(_), v2 @ NumberLiteral(_)) |
// (v1 @ NumberLiteral(_), v2 @ VariableReference(_)) |
// (v1 @ VariableReference(_), v2 @ VariableReference(_)) |
// (v1 @ VariableReference(_), v2 @ Mult(..)) |
// (v1 @ Mult(..), v2 @ VariableReference(_)) |
// (v1 @ NumberLiteral(_), v2 @ Mult(..)) |
// (v1 @ Mult(..), v2 @ NumberLiteral(_)) |
// (v1 @ Number(_), v2 @ Number(_)) |
// (v1 @ Identifier(_), v2 @ Number(_)) |
// (v1 @ Number(_), v2 @ Identifier(_)) |
// (v1 @ Identifier(_), v2 @ Identifier(_)) |
// (v1 @ Identifier(_), v2 @ Mult(..)) |
// (v1 @ Mult(..), v2 @ Identifier(_)) |
// (v1 @ Number(_), v2 @ Mult(..)) |
// (v1 @ Mult(..), v2 @ Number(_)) |
// (v1 @ Mult(..), v2 @ Mult(..)) => {
// assert!(v1.is_linear());
// assert!(v2.is_linear());
// (v1, v2)
// },
// // Num/Var/Mult = Add
// (v @ NumberLiteral(_), Add(left, right)) |
// (v @ VariableReference(_), Add(left, right)) |
// (v @ Number(_), Add(left, right)) |
// (v @ Identifier(_), Add(left, right)) |
// (v @ Mult(..), Add(left, right)) => {
// assert!(v.is_linear());
// let (l1, r1) = swap_sub(&v, &left);
@ -631,8 +631,8 @@ mod tests {
// (l2, Add(box r1, box r2))
// },
// // Add = Num/Var/Mult
// (Add(left, right), v @ NumberLiteral(_)) |
// (Add(left, right), v @ VariableReference(_)) |
// (Add(left, right), v @ Number(_)) |
// (Add(left, right), v @ Identifier(_)) |
// (Add(left, right), v @ Mult(..)) => { // v = left + right
// assert!(v.is_linear());
// let (l1, r1) = swap_sub(&left, &v);
@ -640,16 +640,16 @@ mod tests {
// (Add(box l1, box l2), r2)
// },
// // Sub = Var/Num/Mult
// (Sub(box left, box right), v @ VariableReference(_)) |
// (Sub(box left, box right), v @ NumberLiteral(_)) |
// (Sub(box left, box right), v @ Identifier(_)) |
// (Sub(box left, box right), v @ Number(_)) |
// (Sub(box left, box right), v @ Mult(..)) => {
// assert!(v.is_linear());
// let (l, r) = swap_sub(&left, &right);
// (l, Add(box v, box r))
// },
// // Var/Num/Mult = Sub
// (v @ VariableReference(_), Sub(box left, box right)) |
// (v @ NumberLiteral(_), Sub(box left, box right)) |
// (v @ Identifier(_), Sub(box left, box right)) |
// (v @ Number(_), Sub(box left, box right)) |
// (v @ Mult(..), Sub(box left, box right)) => {
// assert!(v.is_linear());
// let (l, r) = swap_sub(&left, &right);