implement deduplication
This commit is contained in:
parent
3ba608ccce
commit
ecac773432
6 changed files with 138 additions and 11 deletions
|
@ -53,7 +53,7 @@ impl<T: Field> fmt::Display for DirectiveStatement<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Hash, Eq)]
|
||||
pub enum Helper {
|
||||
Rust(RustHelper),
|
||||
#[cfg(feature = "wasm")]
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
|||
use zokrates_embed::generate_sha256_round_witness;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Hash, Eq)]
|
||||
pub enum RustHelper {
|
||||
Identity,
|
||||
ConditionEq,
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::rc::Rc;
|
|||
use wasmi::{ImportsBuilder, ModuleInstance, ModuleRef, NopExternals};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[derive(Clone, Debug, Serialize, PartialEq, Hash, Eq)]
|
||||
pub struct WasmHelper(
|
||||
#[serde(skip)] std::rc::Rc<ModuleRef>,
|
||||
#[serde(serialize_with = "serde_bytes::serialize")] Vec<u8>,
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::fmt;
|
|||
use std::ops::{Add, Div, Mul, Sub};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Hash, Eq)]
|
||||
pub struct QuadComb<T: Field> {
|
||||
pub left: LinComb<T>,
|
||||
pub right: LinComb<T>,
|
||||
|
|
|
@ -10,13 +10,13 @@ mod from_flat;
|
|||
mod interpreter;
|
||||
mod witness;
|
||||
|
||||
use self::expression::QuadComb;
|
||||
pub use self::expression::QuadComb;
|
||||
pub use self::expression::{CanonicalLinComb, LinComb};
|
||||
|
||||
pub use self::interpreter::{Error, ExecutionResult};
|
||||
pub use self::witness::Witness;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Hash, Eq)]
|
||||
pub enum Statement<T: Field> {
|
||||
Constraint(QuadComb<T>, LinComb<T>),
|
||||
Directive(Directive<T>),
|
||||
|
@ -32,7 +32,7 @@ impl<T: Field> Statement<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Hash, Eq)]
|
||||
pub struct Directive<T: Field> {
|
||||
pub inputs: Vec<LinComb<T>>,
|
||||
pub outputs: Vec<FlatVariable>,
|
||||
|
@ -102,7 +102,7 @@ impl<T: Field> fmt::Display for Function<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
pub struct Prog<T: Field> {
|
||||
pub main: Function<T>,
|
||||
pub private: Vec<bool>,
|
||||
|
|
|
@ -2,15 +2,142 @@
|
|||
|
||||
use crate::ir::folder::Folder;
|
||||
use crate::ir::*;
|
||||
use std::collections::{hash_map::DefaultHasher, HashSet};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
type Hash = u64;
|
||||
|
||||
fn hash<T: Field>(s: &Statement<T>) -> Hash {
|
||||
use std::hash::Hash;
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = DefaultHasher::new();
|
||||
s.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DuplicateOptimizer {}
|
||||
pub struct DuplicateOptimizer {
|
||||
seen: HashSet<Hash>,
|
||||
}
|
||||
|
||||
impl DuplicateOptimizer {
|
||||
fn new() -> Self {
|
||||
DuplicateOptimizer {
|
||||
seen: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn optimize<T: Field>(p: Prog<T>) -> Prog<T> {
|
||||
p
|
||||
Self::new().fold_program(p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Folder<T> for DuplicateOptimizer {}
|
||||
impl<T: Field> Folder<T> for DuplicateOptimizer {
|
||||
fn fold_statement(&mut self, s: Statement<T>) -> Vec<Statement<T>> {
|
||||
let hashed = hash(&s);
|
||||
let result = match self.seen.get(&hashed) {
|
||||
Some(_) => vec![],
|
||||
None => vec![s],
|
||||
};
|
||||
|
||||
self.seen.insert(hashed);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use flat_absy::FlatVariable;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
fn identity() {
|
||||
use num::Zero;
|
||||
|
||||
let p: Prog<FieldPrime> = Prog {
|
||||
private: vec![],
|
||||
main: Function {
|
||||
id: "main".to_string(),
|
||||
statements: vec![
|
||||
Statement::Constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(3, FlatVariable::new(3)),
|
||||
LinComb::summand(3, FlatVariable::new(3)),
|
||||
),
|
||||
LinComb::one(),
|
||||
),
|
||||
Statement::Constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(3, FlatVariable::new(42)),
|
||||
LinComb::summand(3, FlatVariable::new(3)),
|
||||
),
|
||||
LinComb::zero(),
|
||||
),
|
||||
],
|
||||
returns: vec![],
|
||||
arguments: vec![],
|
||||
},
|
||||
};
|
||||
|
||||
let expected = p.clone();
|
||||
|
||||
assert_eq!(DuplicateOptimizer::optimize(p), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_duplicates() {
|
||||
use num::Zero;
|
||||
|
||||
let constraint = Statement::Constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(3, FlatVariable::new(3)),
|
||||
LinComb::summand(3, FlatVariable::new(3)),
|
||||
),
|
||||
LinComb::one(),
|
||||
);
|
||||
|
||||
let p: Prog<FieldPrime> = Prog {
|
||||
private: vec![],
|
||||
main: Function {
|
||||
id: "main".to_string(),
|
||||
statements: vec![
|
||||
constraint.clone(),
|
||||
constraint.clone(),
|
||||
Statement::Constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(3, FlatVariable::new(42)),
|
||||
LinComb::summand(3, FlatVariable::new(3)),
|
||||
),
|
||||
LinComb::zero(),
|
||||
),
|
||||
constraint.clone(),
|
||||
constraint.clone(),
|
||||
],
|
||||
returns: vec![],
|
||||
arguments: vec![],
|
||||
},
|
||||
};
|
||||
|
||||
let expected = Prog {
|
||||
private: vec![],
|
||||
main: Function {
|
||||
id: "main".to_string(),
|
||||
statements: vec![
|
||||
constraint.clone(),
|
||||
Statement::Constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(3, FlatVariable::new(42)),
|
||||
LinComb::summand(3, FlatVariable::new(3)),
|
||||
),
|
||||
LinComb::zero(),
|
||||
),
|
||||
],
|
||||
returns: vec![],
|
||||
arguments: vec![],
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(DuplicateOptimizer::optimize(p), expected);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue