@@ -6,7 +6,7 @@ use baa::{BitVecOps, BitVecValue, BitVecValueRef};
66use patronus:: expr:: traversal:: TraversalCmd ;
77use patronus:: expr:: {
88 Context , DenseExprMetaData , Expr , ExprRef , ForEachChild , SerializableIrNode , Simplifier ,
9- SparseExprMap , TypeCheck , WidthInt , simplify_single_expression, traversal,
9+ SparseExprMap , TypeCheck , WidthInt , count_expr_uses , simplify_single_expression, traversal,
1010} ;
1111use polysub:: { Coef , Polynom , Term , VarIndex } ;
1212use rustc_hash:: { FxHashMap , FxHashSet } ;
@@ -44,9 +44,15 @@ pub fn simplify_word_level_equality(ctx: &mut Context, p: ScaEqualityProblem) ->
4444 . collect ( ) ;
4545
4646 // now we can perform backwards substitution
47- backwards_sub ( ctx, gate_outputs. into ( ) , spec) ;
47+ let result = backwards_sub ( ctx, gate_outputs. into ( ) , spec) ;
4848
49- todo ! ( "check the result of backwards substitution" )
49+ if result. is_zero ( ) {
50+ println ! ( "The SAME!" )
51+ } else {
52+ println ! ( "DIFFERENT: {result}" )
53+ }
54+
55+ None
5056}
5157
5258type DefaultCoef = polysub:: ArrayCoef < 8 > ;
@@ -68,15 +74,32 @@ fn var_to_expr(v: polysub::VarIndex) -> ExprRef {
6874 usize:: from ( v) . into ( )
6975}
7076
71- fn backwards_sub ( ctx : & Context , mut todo : VecDeque < ( VarIndex , ExprRef ) > , mut spec : Poly ) {
77+ fn is_gate ( expr : & Expr ) -> bool {
78+ matches ! (
79+ expr,
80+ Expr :: BVNot ( _, 1 ) | Expr :: BVAnd ( _, _, 1 ) | Expr :: BVOr ( _, _, 1 ) | Expr :: BVXor ( _, _, 1 )
81+ )
82+ }
83+
84+ fn backwards_sub ( ctx : & Context , mut todo : VecDeque < ( VarIndex , ExprRef ) > , mut spec : Poly ) -> Poly {
7285 let m = spec. get_mod ( ) ;
86+ println ! ( "MOD={m:?} ({} bits)" , m. bits( ) ) ;
7387 let one: DefaultCoef = Coef :: from_i64 ( 1 , m) ;
88+ println ! ( "one = {one:?}" ) ;
7489 let minus_one: DefaultCoef = Coef :: from_i64 ( -1 , m) ;
75- let mut on_todo = FxHashSet :: default ( ) ;
90+ println ! ( "minus_one = {minus_one:?}" ) ;
91+ // first, we count how often expressions are used
92+ let roots: Vec < _ > = todo. iter ( ) . map ( |( _, e) | * e) . collect ( ) ;
93+ let mut uses = count_expr_uses ( ctx, roots) ;
7694
7795 while let Some ( ( output_var, gate) ) = todo. pop_back ( ) {
78- println ! ( "{output_var}, {}" , expr_to_var( gate) == output_var) ;
79- on_todo. remove ( & gate) ;
96+ println ! (
97+ "{output_var}, {}, {:?} ({})" ,
98+ expr_to_var( gate) == output_var,
99+ & ctx[ gate] ,
100+ spec. size( )
101+ ) ;
102+
80103 let add_children = match ctx[ gate] . clone ( ) {
81104 Expr :: BVOr ( a, b, 1 ) => {
82105 // a || b = !(!a && !b)
@@ -86,12 +109,16 @@ fn backwards_sub(ctx: &Context, mut todo: VecDeque<(VarIndex, ExprRef)>, mut spe
86109 ( one. clone ( ) , vec ! [ x1] . into ( ) ) ,
87110 ( minus_one. clone ( ) , vec ! [ x0, x1] . into ( ) ) ,
88111 ] ;
112+ assert_ne ! ( gate, a) ;
113+ assert_ne ! ( gate, b) ;
89114 spec. replace_var ( output_var, & monoms) ;
90115 true
91116 }
92117 Expr :: BVAnd ( a, b, 1 ) => {
93118 let ( x0, x1) = exprs_to_vars_commutative ( a, b) ;
94119 let monoms = [ ( one. clone ( ) , vec ! [ x0, x1] . into ( ) ) ] ;
120+ assert_ne ! ( gate, a) ;
121+ assert_ne ! ( gate, b) ;
95122 spec. replace_var ( output_var, & monoms) ;
96123 true
97124 }
@@ -101,6 +128,7 @@ fn backwards_sub(ctx: &Context, mut todo: VecDeque<(VarIndex, ExprRef)>, mut spe
101128 ( one. clone ( ) , vec ! [ ] . into ( ) ) ,
102129 ( minus_one. clone ( ) , vec ! [ x0] . into ( ) ) ,
103130 ] ;
131+ assert_ne ! ( gate, a) ;
104132 spec. replace_var ( output_var, & monoms) ;
105133 true
106134 }
@@ -113,13 +141,18 @@ fn backwards_sub(ctx: &Context, mut todo: VecDeque<(VarIndex, ExprRef)>, mut spe
113141 } ;
114142 if add_children {
115143 ctx[ gate] . for_each_child ( |& e| {
116- if !on_todo. contains ( & e) {
117- on_todo. insert ( e) ;
144+ // reduce the use by one
145+ let prev_uses = uses[ e] ;
146+ assert ! ( prev_uses > 0 ) ;
147+ uses[ e] = prev_uses - 1 ;
148+ // did the use count just go down to zero?
149+ if prev_uses == 1 && is_gate ( & ctx[ e] ) {
118150 todo. push_front ( ( expr_to_var ( e) , e) ) ;
119151 }
120152 } ) ;
121153 }
122154 }
155+ spec
123156}
124157
125158fn poly_for_bv_expr ( ctx : & mut Context , e : ExprRef ) -> Poly {
0 commit comments