1
0
Fork 0
mirror of synced 2025-09-23 04:08:33 +00:00

rename substitutor to canonicalizer, add tests

This commit is contained in:
dark64 2023-03-24 14:39:08 +01:00
parent 95bec7be64
commit e0b029959d
5 changed files with 99 additions and 36 deletions

View 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);
}
}

View file

@ -1,10 +1,10 @@
pub mod canonicalizer;
pub mod folder;
mod from_typed;
mod identifier;
pub mod lqc;
mod parameter;
pub mod result_folder;
pub mod substitution;
pub mod types;
mod uint;
mod variable;

View file

@ -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!(),
}
}
}

View file

@ -11,7 +11,7 @@ mod utils;
use self::utils::flat_expression_from_bits;
use zokrates_ast::zir::{
substitution::ZirSubstitutor, ConditionalExpression, Folder, SelectExpression, ShouldReduce,
canonicalizer::ZirCanonicalizer, ConditionalExpression, Folder, SelectExpression, ShouldReduce,
UMetadata, ZirAssemblyStatement, ZirExpressionList,
};
use zokrates_interpreter::Interpreter;
@ -2243,8 +2243,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
.map(|assignee| self.use_variable(&assignee))
.collect();
let mut substitutor = ZirSubstitutor::default();
let function = substitutor.fold_function(function);
let mut canonicalizer = ZirCanonicalizer::default();
let function = canonicalizer.fold_function(function);
let directive = FlatDirective::new(outputs, Solver::Zir(function), inputs);
statements_flattened.push_back(FlatStatement::Directive(directive));

View file

@ -520,7 +520,7 @@ mod tests {
// (field i0) -> i0 * i0
let solvers = vec![Solver::Zir(ZirFunction {
arguments: vec![Parameter {
id: Variable::with_id_and_type(id.id.clone(), Type::FieldElement),
id: Variable::field_element(id.id.clone()),
private: true,
}],
statements: vec![ZirStatement::Return(vec![FieldElementExpression::Mult(