44
55use crate :: { DefaultCoef , Poly , expr_to_var} ;
66use baa:: BitVecOps ;
7+ use bit_set:: BitSet ;
78use patronus:: expr:: {
8- Context , DenseExprSet , Expr , ExprRef , ExprSet , ForEachChild , count_expr_uses, traversal,
9+ Context , DenseExprMetaData , DenseExprSet , Expr , ExprMap , ExprRef , ExprSet , ForEachChild ,
10+ count_expr_uses, traversal,
911} ;
1012use polysub:: { Coef , Mod , PhaseOptPolynom , VarIndex } ;
1113use rustc_hash:: FxHashSet ;
@@ -20,6 +22,10 @@ pub fn backwards_sub(
2022 todo : Vec < ( VarIndex , ExprRef ) > ,
2123 spec : Poly ,
2224) -> Poly {
25+ let root_vars: Vec < _ > = todo. iter ( ) . map ( |( v, _) | * v) . collect ( ) ;
26+ let root_exprs: Vec < _ > = todo. iter ( ) . map ( |( _, e) | * e) . collect ( ) ;
27+ let root_uses = analyze_uses ( ctx, & root_exprs) ;
28+
2329 // empirically, it looks like we should not use a stack
2430 let mut todo: VecDeque < _ > = todo. into ( ) ;
2531 let mut spec: PolyOpt = spec. into ( ) ;
@@ -33,15 +39,22 @@ pub fn backwards_sub(
3339 let mut seen = DenseExprSet :: default ( ) ;
3440
3541 while !todo. is_empty ( ) {
36- let min_idx = try_exhaustive ( ctx, input_vars, & spec, todo. iter ( ) . cloned ( ) ) ;
42+ let min_idx = try_exhaustive ( ctx, input_vars, & spec, todo. iter ( ) . cloned ( ) , & root_uses ) ;
3743 let ( output_var, gate) = todo. swap_remove_back ( min_idx) . unwrap ( ) ;
3844
3945 // chose variable to replace
4046 //let (output_var, gate) = todo.pop_back().unwrap();
4147
4248 replaced. push ( output_var) ;
49+ let gate_uses = & root_uses[ gate] ;
50+ let num_output_uses = gate_uses. len ( ) ;
51+ let output_use_str = gate_uses
52+ . iter ( )
53+ . map ( |ii| format ! ( "{}" , root_vars[ ii] ) )
54+ . collect :: < Vec < _ > > ( )
55+ . join ( ", " ) ;
4356 println ! (
44- "{output_var} {:?}: {}, {}" ,
57+ "{output_var} ({output_use_str}) {:?}: {}, {}" ,
4558 & ctx[ gate] ,
4659 todo. len( ) + 1 ,
4760 spec. size( )
@@ -154,20 +167,30 @@ fn try_exhaustive(
154167 input_vars : & FxHashSet < VarIndex > ,
155168 spec : & PolyOpt ,
156169 todo : impl Iterator < Item = ( VarIndex , ExprRef ) > ,
170+ root_uses : & impl ExprMap < BitSet > ,
157171) -> usize {
158172 let sizes: Vec < _ > = todo
159173 . enumerate ( )
160174 . map ( |( ii, ( output_var, gate) ) | {
161175 let mut s = spec. clone ( ) ;
162176 replace_gate ( ctx, input_vars, & mut s, output_var, gate) ;
163- s. size ( )
177+ ( s. size ( ) , root_uses [ gate ] . len ( ) )
164178 } )
165179 . collect ( ) ;
166- let min = sizes. iter ( ) . cloned ( ) . min ( ) . unwrap ( ) ;
167- let max = sizes. iter ( ) . cloned ( ) . max ( ) . unwrap ( ) ;
168- let first_min = sizes. iter ( ) . position ( |s| * s == min) . unwrap ( ) ;
169- println ! ( "{} -> {min}/{max}" , spec. size( ) ) ;
170- first_min
180+ let min = sizes. iter ( ) . map ( |( s, _) | * s) . min ( ) . unwrap ( ) ;
181+ let max = sizes. iter ( ) . map ( |( s, _) | * s) . max ( ) . unwrap ( ) ;
182+ let all_mins: Vec < _ > = sizes. iter ( ) . filter ( |( s, _) | * s == min) . collect ( ) ;
183+ let lowest_min_use = all_mins. iter ( ) . map ( |( _, u) | * u) . min ( ) . unwrap ( ) ;
184+ let min_with_lowest_use = sizes
185+ . iter ( )
186+ . position ( |( s, u) | * s == min && * u == lowest_min_use)
187+ . unwrap ( ) ;
188+ println ! (
189+ "{} -> {min}/{max}, {} mins, lowest use: {lowest_min_use}" ,
190+ spec. size( ) ,
191+ all_mins. len( )
192+ ) ;
193+ min_with_lowest_use
171194}
172195
173196/// tries to build the gate-level polynomial from the bottom up.
@@ -230,3 +253,18 @@ pub fn build_gate_polynomial(
230253 }
231254 } )
232255}
256+
257+ /// Calculates for each expression which root depends on it.
258+ fn analyze_uses ( ctx : & Context , roots : & [ ExprRef ] ) -> impl ExprMap < BitSet > {
259+ let mut out = DenseExprMetaData :: < BitSet > :: default ( ) ;
260+
261+ for ( ii, & root) in roots. iter ( ) . enumerate ( ) {
262+ let mut id = BitSet :: new ( ) ;
263+ id. insert ( ii) ;
264+ traversal:: bottom_up ( ctx, root, |_, e, _| {
265+ out[ e] . union_with ( & id) ;
266+ } )
267+ }
268+
269+ out
270+ }
0 commit comments