Skip to content

Commit

Permalink
Implement Sum and Product for Expression (#209)
Browse files Browse the repository at this point in the history
* Make it Eq to make it easier for tests

* Implement Sum and Product for Expression

* Make it readable
  • Loading branch information
pnyda authored Sep 27, 2023
1 parent 4455c2f commit 0c3e3b5
Showing 1 changed file with 63 additions and 4 deletions.
67 changes: 63 additions & 4 deletions halo2_proofs/src/plonk/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use ff::Field;
use sealed::SealedPhase;
use std::collections::HashMap;
use std::fmt::Debug;
use std::iter::{Product, Sum};
use std::{
convert::TryFrom,
ops::{Neg, Sub},
Expand Down Expand Up @@ -478,7 +479,7 @@ impl Selector {
}

/// Query of fixed column at a certain relative location
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct FixedQuery {
/// Query index
pub(crate) index: Option<usize>,
Expand All @@ -501,7 +502,7 @@ impl FixedQuery {
}

/// Query of advice column at a certain relative location
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct AdviceQuery {
/// Query index
pub(crate) index: Option<usize>,
Expand Down Expand Up @@ -531,7 +532,7 @@ impl AdviceQuery {
}

/// Query of instance column at a certain relative location
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct InstanceQuery {
/// Query index
pub(crate) index: Option<usize>,
Expand Down Expand Up @@ -792,7 +793,7 @@ pub trait Circuit<F: Field> {
}

/// Low-degree expression representing an identity that must hold over the committed columns.
#[derive(Clone)]
#[derive(Clone, PartialEq, Eq)]
pub enum Expression<F> {
/// This is a constant polynomial
Constant(F),
Expand Down Expand Up @@ -1352,6 +1353,20 @@ impl<F: Field> Mul<F> for Expression<F> {
}
}

impl<F: Field> Sum<Self> for Expression<F> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.reduce(|acc, x| acc + x)
.unwrap_or(Expression::Constant(F::ZERO))
}
}

impl<F: Field> Product<Self> for Expression<F> {
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.reduce(|acc, x| acc * x)
.unwrap_or(Expression::Constant(F::ONE))
}
}

/// Represents an index into a vector where each entry corresponds to a distinct
/// point that polynomials are queried at.
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -2439,3 +2454,47 @@ impl<'a, F: Field> VirtualCells<'a, F> {
Expression::Challenge(challenge)
}
}

#[cfg(test)]
mod tests {
use super::Expression;
use halo2curves::bn256::Fr;

#[test]
fn iter_sum() {
let exprs: Vec<Expression<Fr>> = vec![
Expression::Constant(1.into()),
Expression::Constant(2.into()),
Expression::Constant(3.into()),
];
let happened: Expression<Fr> = exprs.into_iter().sum();
let expected: Expression<Fr> = Expression::Sum(
Box::new(Expression::Sum(
Box::new(Expression::Constant(1.into())),
Box::new(Expression::Constant(2.into())),
)),
Box::new(Expression::Constant(3.into())),
);

assert_eq!(happened, expected);
}

#[test]
fn iter_product() {
let exprs: Vec<Expression<Fr>> = vec![
Expression::Constant(1.into()),
Expression::Constant(2.into()),
Expression::Constant(3.into()),
];
let happened: Expression<Fr> = exprs.into_iter().product();
let expected: Expression<Fr> = Expression::Product(
Box::new(Expression::Product(
Box::new(Expression::Constant(1.into())),
Box::new(Expression::Constant(2.into())),
)),
Box::new(Expression::Constant(3.into())),
);

assert_eq!(happened, expected);
}
}

0 comments on commit 0c3e3b5

Please sign in to comment.