rename substitutor to canonicalizer, add tests
This commit is contained in:
parent
95bec7be64
commit
e0b029959d
5 changed files with 99 additions and 36 deletions
94
zokrates_ast/src/zir/canonicalizer.rs
Normal file
94
zokrates_ast/src/zir/canonicalizer.rs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
use super::{Folder, Identifier, Parameter, Variable, ZirAssignee};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use zokrates_field::Field;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ZirCanonicalizer<'ast> {
|
||||||
|
identifier_map: HashMap<Identifier<'ast>, usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast, T: Field> Folder<'ast, T> for ZirCanonicalizer<'ast> {
|
||||||
|
fn fold_parameter(&mut self, p: Parameter<'ast>) -> Parameter<'ast> {
|
||||||
|
let new_id = self.identifier_map.len();
|
||||||
|
self.identifier_map.insert(p.id.id.clone(), new_id);
|
||||||
|
|
||||||
|
Parameter {
|
||||||
|
id: Variable::with_id_and_type(Identifier::internal(new_id), p.id._type),
|
||||||
|
..p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn fold_assignee(&mut self, a: ZirAssignee<'ast>) -> ZirAssignee<'ast> {
|
||||||
|
let new_id = self.identifier_map.len();
|
||||||
|
self.identifier_map.insert(a.id.clone(), new_id);
|
||||||
|
ZirAssignee::with_id_and_type(Identifier::internal(new_id), a._type)
|
||||||
|
}
|
||||||
|
fn fold_name(&mut self, n: Identifier<'ast>) -> Identifier<'ast> {
|
||||||
|
match self.identifier_map.get(&n) {
|
||||||
|
Some(v) => Identifier::internal(*v),
|
||||||
|
None => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::zir::{
|
||||||
|
FieldElementExpression, IdentifierExpression, Signature, Type, ZirAssignee, ZirFunction,
|
||||||
|
ZirStatement,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use zokrates_field::Bn128Field;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn canonicalize() {
|
||||||
|
let func = ZirFunction::<Bn128Field> {
|
||||||
|
arguments: vec![Parameter {
|
||||||
|
id: Variable::field_element("a"),
|
||||||
|
private: true,
|
||||||
|
}],
|
||||||
|
statements: vec![
|
||||||
|
ZirStatement::Definition(
|
||||||
|
ZirAssignee::field_element("b"),
|
||||||
|
FieldElementExpression::Identifier(IdentifierExpression::new("a".into()))
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
ZirStatement::Return(vec![FieldElementExpression::Identifier(
|
||||||
|
IdentifierExpression::new("b".into()),
|
||||||
|
)
|
||||||
|
.into()]),
|
||||||
|
],
|
||||||
|
signature: Signature::new()
|
||||||
|
.inputs(vec![Type::FieldElement])
|
||||||
|
.outputs(vec![Type::FieldElement]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut canonicalizer = ZirCanonicalizer::default();
|
||||||
|
let result = canonicalizer.fold_function(func);
|
||||||
|
|
||||||
|
let expected = ZirFunction::<Bn128Field> {
|
||||||
|
arguments: vec![Parameter {
|
||||||
|
id: Variable::field_element(Identifier::internal(0usize)),
|
||||||
|
private: true,
|
||||||
|
}],
|
||||||
|
statements: vec![
|
||||||
|
ZirStatement::Definition(
|
||||||
|
ZirAssignee::field_element(Identifier::internal(1usize)),
|
||||||
|
FieldElementExpression::Identifier(IdentifierExpression::new(
|
||||||
|
Identifier::internal(0usize),
|
||||||
|
))
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
ZirStatement::Return(vec![FieldElementExpression::Identifier(
|
||||||
|
IdentifierExpression::new(Identifier::internal(1usize)),
|
||||||
|
)
|
||||||
|
.into()]),
|
||||||
|
],
|
||||||
|
signature: Signature::new()
|
||||||
|
.inputs(vec![Type::FieldElement])
|
||||||
|
.outputs(vec![Type::FieldElement]),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(result, expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
|
pub mod canonicalizer;
|
||||||
pub mod folder;
|
pub mod folder;
|
||||||
mod from_typed;
|
mod from_typed;
|
||||||
mod identifier;
|
mod identifier;
|
||||||
pub mod lqc;
|
pub mod lqc;
|
||||||
mod parameter;
|
mod parameter;
|
||||||
pub mod result_folder;
|
pub mod result_folder;
|
||||||
pub mod substitution;
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
mod uint;
|
mod uint;
|
||||||
mod variable;
|
mod variable;
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
use super::{Folder, Identifier, Parameter, Variable, ZirAssignee};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use zokrates_field::Field;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct ZirSubstitutor<'ast> {
|
|
||||||
substitution: HashMap<Identifier<'ast>, usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast, T: Field> Folder<'ast, T> for ZirSubstitutor<'ast> {
|
|
||||||
fn fold_parameter(&mut self, p: Parameter<'ast>) -> Parameter<'ast> {
|
|
||||||
let new_id = self.substitution.len();
|
|
||||||
self.substitution.insert(p.id.id.clone(), new_id);
|
|
||||||
|
|
||||||
Parameter {
|
|
||||||
id: Variable::with_id_and_type(Identifier::internal(new_id), p.id._type),
|
|
||||||
..p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn fold_assignee(&mut self, a: ZirAssignee<'ast>) -> ZirAssignee<'ast> {
|
|
||||||
let new_id = self.substitution.len();
|
|
||||||
self.substitution.insert(a.id.clone(), new_id);
|
|
||||||
ZirAssignee::with_id_and_type(Identifier::internal(new_id), a._type)
|
|
||||||
}
|
|
||||||
fn fold_name(&mut self, n: Identifier<'ast>) -> Identifier<'ast> {
|
|
||||||
match self.substitution.get(&n) {
|
|
||||||
Some(v) => Identifier::internal(*v),
|
|
||||||
None => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,7 +11,7 @@ mod utils;
|
||||||
|
|
||||||
use self::utils::flat_expression_from_bits;
|
use self::utils::flat_expression_from_bits;
|
||||||
use zokrates_ast::zir::{
|
use zokrates_ast::zir::{
|
||||||
substitution::ZirSubstitutor, ConditionalExpression, Folder, SelectExpression, ShouldReduce,
|
canonicalizer::ZirCanonicalizer, ConditionalExpression, Folder, SelectExpression, ShouldReduce,
|
||||||
UMetadata, ZirAssemblyStatement, ZirExpressionList,
|
UMetadata, ZirAssemblyStatement, ZirExpressionList,
|
||||||
};
|
};
|
||||||
use zokrates_interpreter::Interpreter;
|
use zokrates_interpreter::Interpreter;
|
||||||
|
@ -2243,8 +2243,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
||||||
.map(|assignee| self.use_variable(&assignee))
|
.map(|assignee| self.use_variable(&assignee))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut substitutor = ZirSubstitutor::default();
|
let mut canonicalizer = ZirCanonicalizer::default();
|
||||||
let function = substitutor.fold_function(function);
|
let function = canonicalizer.fold_function(function);
|
||||||
|
|
||||||
let directive = FlatDirective::new(outputs, Solver::Zir(function), inputs);
|
let directive = FlatDirective::new(outputs, Solver::Zir(function), inputs);
|
||||||
statements_flattened.push_back(FlatStatement::Directive(directive));
|
statements_flattened.push_back(FlatStatement::Directive(directive));
|
||||||
|
|
|
@ -520,7 +520,7 @@ mod tests {
|
||||||
// (field i0) -> i0 * i0
|
// (field i0) -> i0 * i0
|
||||||
let solvers = vec![Solver::Zir(ZirFunction {
|
let solvers = vec![Solver::Zir(ZirFunction {
|
||||||
arguments: vec![Parameter {
|
arguments: vec![Parameter {
|
||||||
id: Variable::with_id_and_type(id.id.clone(), Type::FieldElement),
|
id: Variable::field_element(id.id.clone()),
|
||||||
private: true,
|
private: true,
|
||||||
}],
|
}],
|
||||||
statements: vec![ZirStatement::Return(vec![FieldElementExpression::Mult(
|
statements: vec![ZirStatement::Return(vec![FieldElementExpression::Mult(
|
||||||
|
|
Loading…
Reference in a new issue