1010
1111use std:: collections:: BTreeMap ;
1212use std:: iter;
13+ use std:: marker:: PhantomData ;
1314
1415use ff:: Field ;
1516use group:: { Group , GroupEncoding } ;
@@ -27,9 +28,9 @@ mod ops;
2728///
2829/// Used to reference scalars in sparse linear combinations.
2930#[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
30- pub struct ScalarVar ( usize ) ;
31+ pub struct ScalarVar < G > ( usize , PhantomData < G > ) ;
3132
32- impl ScalarVar {
33+ impl < G > ScalarVar < G > {
3334 pub fn index ( & self ) -> usize {
3435 self . 0
3536 }
@@ -39,34 +40,33 @@ impl ScalarVar {
3940///
4041/// Used to reference group elements in sparse linear combinations.
4142#[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
42- pub struct GroupVar ( usize ) ;
43+ pub struct GroupVar < G > ( usize , PhantomData < G > ) ;
4344
44- impl GroupVar {
45+ impl < G > GroupVar < G > {
4546 pub fn index ( & self ) -> usize {
4647 self . 0
4748 }
4849}
4950
5051/// A term in a linear combination, representing `scalar * elem`.
51- #[ derive( Copy , Clone , Debug ) ]
52- pub struct Term {
53- scalar : ScalarVar ,
54- elem : GroupVar ,
52+ #[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
53+ pub struct Term < G > {
54+ scalar : ScalarVar < G > ,
55+ elem : GroupVar < G > ,
5556}
5657
57- impl From < ( ScalarVar , GroupVar ) > for Term {
58- fn from ( ( scalar, elem) : ( ScalarVar , GroupVar ) ) -> Self {
58+ impl < G > From < ( ScalarVar < G > , GroupVar < G > ) > for Term < G > {
59+ fn from ( ( scalar, elem) : ( ScalarVar < G > , GroupVar < G > ) ) -> Self {
5960 Self { scalar, elem }
6061 }
6162}
6263
63- impl < F : Field > From < ( ScalarVar , GroupVar ) > for Weighted < Term , F > {
64- fn from ( pair : ( ScalarVar , GroupVar ) ) -> Self {
64+ impl < G : Group > From < ( ScalarVar < G > , GroupVar < G > ) > for Weighted < Term < G > , G :: Scalar > {
65+ fn from ( pair : ( ScalarVar < G > , GroupVar < G > ) ) -> Self {
6566 Term :: from ( pair) . into ( )
6667 }
6768}
6869
69- // TODO: Should this be generic over the field instead of the group?
7070#[ derive( Copy , Clone , Debug ) ]
7171pub struct Weighted < T , F > {
7272 pub term : T ,
@@ -97,49 +97,25 @@ impl<T> Sum<T> {
9797macro_rules! impl_from_for_sum {
9898 ( $( $type: ty) ,+) => {
9999 $(
100- impl <T : Into <$type>> From <T > for Sum <$type> {
101- fn from( value: T ) -> Self {
102- Sum ( vec![ value. into( ) ] )
103- }
104- }
105-
106- impl <T : Into <$type>> From <Vec <T >> for Sum <$type> {
107- fn from( terms: Vec <T >) -> Self {
108- Self :: from_iter( terms)
109- }
110- }
111-
112- impl <T : Into <$type>, const N : usize > From <[ T ; N ] > for Sum <$type> {
113- fn from( terms: [ T ; N ] ) -> Self {
114- Self :: from_iter( terms)
115- }
116- }
117-
118- impl <T : Into <$type>> FromIterator <T > for Sum <$type> {
119- fn from_iter<I : IntoIterator <Item = T >>( iter: I ) -> Self {
120- Self ( iter. into_iter( ) . map( |x| x. into( ) ) . collect( ) )
121- }
122- }
123-
124- impl <F , T : Into <Weighted <$type, F >>> From <T > for Sum <Weighted <$type, F >> {
100+ impl <G : Group , T : Into <$type>> From <T > for Sum <$type> {
125101 fn from( value: T ) -> Self {
126102 Sum ( vec![ value. into( ) ] )
127103 }
128104 }
129105
130- impl <F , T : Into <Weighted < $type, F >>> From <Vec <T >> for Sum <Weighted < $type, F > > {
106+ impl <G : Group , T : Into <$type>> From <Vec <T >> for Sum <$type> {
131107 fn from( terms: Vec <T >) -> Self {
132108 Self :: from_iter( terms)
133109 }
134110 }
135111
136- impl <F , T : Into <Weighted < $type, F >> , const N : usize > From <[ T ; N ] > for Sum <Weighted < $type, F > > {
112+ impl <G : Group , T : Into <$type> , const N : usize > From <[ T ; N ] > for Sum <$type> {
137113 fn from( terms: [ T ; N ] ) -> Self {
138114 Self :: from_iter( terms)
139115 }
140116 }
141117
142- impl <F , T : Into <Weighted < $type, F >>> FromIterator <T > for Sum <Weighted < $type, F > > {
118+ impl <G : Group , T : Into <$type>> FromIterator <T > for Sum <$type> {
143119 fn from_iter<I : IntoIterator <Item = T >>( iter: I ) -> Self {
144120 Self ( iter. into_iter( ) . map( |x| x. into( ) ) . collect( ) )
145121 }
@@ -148,7 +124,14 @@ macro_rules! impl_from_for_sum {
148124 } ;
149125}
150126
151- impl_from_for_sum ! ( ScalarVar , GroupVar , Term ) ;
127+ impl_from_for_sum ! (
128+ ScalarVar <G >,
129+ GroupVar <G >,
130+ Term <G >,
131+ Weighted <ScalarVar <G >, G :: Scalar >,
132+ Weighted <GroupVar <G >, G :: Scalar >,
133+ Weighted <Term <G >, G :: Scalar >
134+ ) ;
152135
153136impl < T , F : Field > From < Sum < T > > for Sum < Weighted < T , F > > {
154137 fn from ( sum : Sum < T > ) -> Self {
@@ -164,7 +147,7 @@ impl<T, F: Field> From<Sum<T>> for Sum<Weighted<T, F>> {
164147/// where `s_i` are scalars (referenced by `scalar_vars`) and `P_i` are group elements (referenced by `element_vars`).
165148///
166149/// The indices refer to external lists managed by the containing LinearMap.
167- pub type LinearCombination < G > = Sum < Weighted < Term , <G as Group >:: Scalar > > ;
150+ pub type LinearCombination < G > = Sum < Weighted < Term < G > , <G as Group >:: Scalar > > ;
168151
169152/// Ordered mapping of [GroupVar] to group elements assignments.
170153#[ derive( Clone , Debug ) ]
@@ -181,7 +164,7 @@ impl<G: Group> GroupMap<G> {
181164 /// # Panics
182165 ///
183166 /// Panics if the given assignment conflicts with the existing assignment.
184- pub fn assign_element ( & mut self , var : GroupVar , element : G ) {
167+ pub fn assign_element ( & mut self , var : GroupVar < G > , element : G ) {
185168 if self . 0 . len ( ) <= var. 0 {
186169 self . 0 . resize ( var. 0 + 1 , None ) ;
187170 } else if let Some ( assignment) = self . 0 [ var. 0 ] {
@@ -202,7 +185,7 @@ impl<G: Group> GroupMap<G> {
202185 /// # Panics
203186 ///
204187 /// Panics if the collection contains two conflicting assignments for the same variable.
205- pub fn assign_elements ( & mut self , assignments : impl IntoIterator < Item = ( GroupVar , G ) > ) {
188+ pub fn assign_elements ( & mut self , assignments : impl IntoIterator < Item = ( GroupVar < G > , G ) > ) {
206189 for ( var, elem) in assignments. into_iter ( ) {
207190 self . assign_element ( var, elem) ;
208191 }
@@ -211,26 +194,28 @@ impl<G: Group> GroupMap<G> {
211194 /// Get the element value assigned to the given point var.
212195 ///
213196 /// Returns [`Error::UnassignedGroupVar`] if a value is not assigned.
214- pub fn get ( & self , var : GroupVar ) -> Result < G , Error > {
215- self . 0 [ var. 0 ] . ok_or ( Error :: UnassignedGroupVar { var } )
197+ pub fn get ( & self , var : GroupVar < G > ) -> Result < G , Error > {
198+ self . 0 [ var. 0 ] . ok_or ( Error :: UnassignedGroupVar {
199+ var_debug : format ! ( "{var:?}" ) ,
200+ } )
216201 }
217202
218203 /// Iterate over the assigned variable and group element pairs in this mapping.
219204 // NOTE: Not implemented as `IntoIterator` for now because doing so requires explicitly
220205 // defining an iterator type, See https://github.com/rust-lang/rust/issues/63063
221206 #[ allow( clippy:: should_implement_trait) ]
222- pub fn into_iter ( self ) -> impl Iterator < Item = ( GroupVar , Option < G > ) > {
207+ pub fn into_iter ( self ) -> impl Iterator < Item = ( GroupVar < G > , Option < G > ) > {
223208 self . 0
224209 . into_iter ( )
225210 . enumerate ( )
226- . map ( |( i, x) | ( GroupVar ( i) , x) )
211+ . map ( |( i, x) | ( GroupVar ( i, PhantomData ) , x) )
227212 }
228213
229- pub fn iter ( & self ) -> impl Iterator < Item = ( GroupVar , Option < & G > ) > {
214+ pub fn iter ( & self ) -> impl Iterator < Item = ( GroupVar < G > , Option < & G > ) > {
230215 self . 0
231216 . iter ( )
232217 . enumerate ( )
233- . map ( |( i, opt) | ( GroupVar ( i) , opt. as_ref ( ) ) )
218+ . map ( |( i, opt) | ( GroupVar ( i, PhantomData ) , opt. as_ref ( ) ) )
234219 }
235220}
236221
@@ -240,8 +225,8 @@ impl<G> Default for GroupMap<G> {
240225 }
241226}
242227
243- impl < G : Group > FromIterator < ( GroupVar , G ) > for GroupMap < G > {
244- fn from_iter < T : IntoIterator < Item = ( GroupVar , G ) > > ( iter : T ) -> Self {
228+ impl < G : Group > FromIterator < ( GroupVar < G > , G ) > for GroupMap < G > {
229+ fn from_iter < T : IntoIterator < Item = ( GroupVar < G > , G ) > > ( iter : T ) -> Self {
245230 iter. into_iter ( )
246231 . fold ( Self :: default ( ) , |mut instance, ( var, val) | {
247232 instance. assign_element ( var, val) ;
@@ -361,7 +346,7 @@ where
361346 /// The underlying linear map describing the structure of the statement.
362347 pub linear_map : LinearMap < G > ,
363348 /// Indices pointing to elements representing the "target" images for each constraint.
364- pub image : Vec < GroupVar > ,
349+ pub image : Vec < GroupVar < G > > ,
365350}
366351
367352impl < G > LinearRelation < G >
@@ -388,7 +373,7 @@ where
388373 /// # Parameters
389374 /// - `lhs`: The image group element variable (left-hand side of the equation).
390375 /// - `rhs`: A slice of `(ScalarVar, GroupVar)` pairs representing the linear combination on the right-hand side.
391- pub fn append_equation ( & mut self , lhs : GroupVar , rhs : impl Into < LinearCombination < G > > ) {
376+ pub fn append_equation ( & mut self , lhs : GroupVar < G > , rhs : impl Into < LinearCombination < G > > ) {
392377 self . linear_map . append ( rhs. into ( ) ) ;
393378 self . image . push ( lhs) ;
394379 }
@@ -399,16 +384,16 @@ where
399384 /// # Parameters
400385 /// - `lhs`: The image group element variable (left-hand side of the equation).
401386 /// - `rhs`: A slice of `(ScalarVar, GroupVar)` pairs representing the linear combination on the right-hand side.
402- pub fn allocate_eq ( & mut self , rhs : impl Into < LinearCombination < G > > ) -> GroupVar {
387+ pub fn allocate_eq ( & mut self , rhs : impl Into < LinearCombination < G > > ) -> GroupVar < G > {
403388 let var = self . allocate_element ( ) ;
404389 self . append_equation ( var, rhs) ;
405390 var
406391 }
407392
408393 /// Allocates a scalar variable for use in the morphism.
409- pub fn allocate_scalar ( & mut self ) -> ScalarVar {
394+ pub fn allocate_scalar ( & mut self ) -> ScalarVar < G > {
410395 self . linear_map . num_scalars += 1 ;
411- ScalarVar ( self . linear_map . num_scalars - 1 )
396+ ScalarVar ( self . linear_map . num_scalars - 1 , PhantomData )
412397 }
413398
414399 /// Allocates space for `N` new scalar variables.
@@ -425,18 +410,18 @@ where
425410 /// let [var_x, var_y] = morphism.allocate_scalars();
426411 /// let vars = morphism.allocate_scalars::<10>();
427412 /// ```
428- pub fn allocate_scalars < const N : usize > ( & mut self ) -> [ ScalarVar ; N ] {
429- let mut vars = [ ScalarVar ( usize:: MAX ) ; N ] ;
413+ pub fn allocate_scalars < const N : usize > ( & mut self ) -> [ ScalarVar < G > ; N ] {
414+ let mut vars = [ ScalarVar ( usize:: MAX , PhantomData ) ; N ] ;
430415 for var in vars. iter_mut ( ) {
431416 * var = self . allocate_scalar ( ) ;
432417 }
433418 vars
434419 }
435420
436421 /// Allocates a point variable (group element) for use in the morphism.
437- pub fn allocate_element ( & mut self ) -> GroupVar {
422+ pub fn allocate_element ( & mut self ) -> GroupVar < G > {
438423 self . linear_map . num_elements += 1 ;
439- GroupVar ( self . linear_map . num_elements - 1 )
424+ GroupVar ( self . linear_map . num_elements - 1 , PhantomData )
440425 }
441426
442427 /// Allocates `N` point variables (group elements) for use in the morphism.
@@ -453,8 +438,8 @@ where
453438 /// let [var_g, var_h] = morphism.allocate_elements();
454439 /// let vars = morphism.allocate_elements::<10>();
455440 /// ```
456- pub fn allocate_elements < const N : usize > ( & mut self ) -> [ GroupVar ; N ] {
457- let mut vars = [ GroupVar ( usize:: MAX ) ; N ] ;
441+ pub fn allocate_elements < const N : usize > ( & mut self ) -> [ GroupVar < G > ; N ] {
442+ let mut vars = [ GroupVar ( usize:: MAX , PhantomData ) ; N ] ;
458443 for var in vars. iter_mut ( ) {
459444 * var = self . allocate_element ( ) ;
460445 }
@@ -471,7 +456,7 @@ where
471456 /// # Panics
472457 ///
473458 /// Panics if the given assignment conflicts with the existing assignment.
474- pub fn set_element ( & mut self , var : GroupVar , element : G ) {
459+ pub fn set_element ( & mut self , var : GroupVar < G > , element : G ) {
475460 self . linear_map . group_elements . assign_element ( var, element)
476461 }
477462
@@ -484,7 +469,7 @@ where
484469 /// # Panics
485470 ///
486471 /// Panics if the collection contains two conflicting assignments for the same variable.
487- pub fn set_elements ( & mut self , assignments : impl IntoIterator < Item = ( GroupVar , G ) > ) {
472+ pub fn set_elements ( & mut self , assignments : impl IntoIterator < Item = ( GroupVar < G > , G ) > ) {
488473 self . linear_map . group_elements . assign_elements ( assignments)
489474 }
490475
@@ -606,7 +591,7 @@ where
606591 // implement Hash or Ord.
607592 let mut remapping = BTreeMap :: < usize , Vec < ( G :: Scalar , u32 ) > > :: new ( ) ;
608593 let mut group_var_remap_index = 0u32 ;
609- let mut remap_var = |var : GroupVar , weight : G :: Scalar | -> u32 {
594+ let mut remap_var = |var : GroupVar < G > , weight : G :: Scalar | -> u32 {
610595 let entry = remapping. entry ( var. 0 ) . or_default ( ) ;
611596
612597 // If the (weight, group_var) pair has already been assigned an index, use it.
0 commit comments