use std::hash::{Hash, Hasher}; use std::rc::Rc; use crate::circuit_data::CircuitConfig; use crate::constraint_polynomial::{ConstraintPolynomial, EvaluationVars}; use crate::field::field::Field; use crate::generator::WitnessGenerator; use num::ToPrimitive; /// A custom gate. // TODO: Remove CircuitConfig params? Could just use fields within each struct. pub trait Gate: 'static { fn id(&self) -> String; /// A set of expressions which must evaluate to zero. fn constraints(&self, config: CircuitConfig) -> Vec>; // fn eval_constraints(&self, config: CircuitConfig, vars: EvaluationVars) -> Vec { // self.constraints(config) // .into_iter() // .map(|c| c.evaluate(vars)) // .collect() // } fn generators( &self, config: CircuitConfig, gate_index: usize, // TODO: Switch to slices? local_constants: Vec, next_constants: Vec, ) -> Vec>>; /// The number of constants used by this gate. fn num_constants(&self, config: CircuitConfig) -> usize { self.constraints(config) .into_iter() .map(|c| c.max_constant_index().map_or(0, |i| i + 1)) .max() .unwrap_or(0) } /// The minimum number of wires required to use this gate. fn min_wires(&self, config: CircuitConfig) -> usize { self.constraints(config) .into_iter() .map(|c| c.max_wire_input_index().map_or(0, |i| i + 1)) .max() .unwrap_or(0) } /// The maximum degree among this gate's constraint polynomials. fn degree(&self, config: CircuitConfig) -> usize { self.constraints(config) .into_iter() .map(|c| c.degree().to_usize().expect("degree too large")) .max() .unwrap_or(0) } } /// A wrapper around an `Rc` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs. #[derive(Clone)] pub struct GateRef(pub(crate) Rc>); impl GateRef { pub fn new>(gate: G) -> GateRef { GateRef(Rc::new(gate)) } } impl PartialEq for GateRef { fn eq(&self, other: &Self) -> bool { self.0.id() == other.0.id() } } impl Hash for GateRef { fn hash(&self, state: &mut H) { self.0.id().hash(state) } } impl Eq for GateRef {} /// A gate along with any constants used to configure it. pub struct GateInstance { pub gate_type: GateRef, pub constants: Vec, }