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

implement deduplication

This commit is contained in:
schaeff 2019-06-25 18:23:07 +02:00
parent 3ba608ccce
commit ecac773432
6 changed files with 138 additions and 11 deletions

View file

@ -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")]

View file

@ -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,

View file

@ -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>,

View file

@ -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>,

View file

@ -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>,

View file

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