use std::hash::{Hash, Hasher}; use std::sync::Arc; use crate::circuit_builder::CircuitBuilder; use crate::field::field::Field; use crate::generator::WitnessGenerator; use crate::target::Target; use crate::vars::{EvaluationTargets, EvaluationVars}; /// A custom gate. pub trait Gate: 'static + Send + Sync { fn id(&self) -> String; fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec; fn eval_unfiltered_recursively( &self, builder: &mut CircuitBuilder, vars: EvaluationTargets, ) -> Vec; fn eval_filtered(&self, vars: EvaluationVars) -> Vec { // TODO: Filter self.eval_unfiltered(vars) } fn eval_filtered_recursively( &self, builder: &mut CircuitBuilder, vars: EvaluationTargets, ) -> Vec { // TODO: Filter self.eval_unfiltered_recursively(builder, vars) } fn generators( &self, gate_index: usize, local_constants: &[F], ) -> Vec>>; /// The number of wires used by this gate. fn num_wires(&self) -> usize; /// The number of constants used by this gate. fn num_constants(&self) -> usize; /// The maximum degree among this gate's constraint polynomials. fn degree(&self) -> usize; fn num_constraints(&self) -> usize; } /// A wrapper around an `Rc` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs. #[derive(Clone)] pub struct GateRef(pub(crate) Arc>); impl GateRef { pub fn new>(gate: G) -> GateRef { GateRef(Arc::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, }