@@ -108,40 +108,42 @@ mod tests {
108108 }
109109 }
110110
111- /// Test rule: removes any literal "1" regardless of parent type (wildcard rule)
112- struct RemoveOneLiteralRule ;
111+ /// Test rule: remove identity 0 + x -> x without matching parent directly (equiv to above).
112+ struct AddZeroRuleAnyParent ;
113113
114- impl ParentReduceRule < Literal , AnyParent , RuleContext > for RemoveOneLiteralRule {
114+ impl ParentReduceRule < Literal , AnyParent , RuleContext > for AddZeroRuleAnyParent {
115115 fn reduce_parent (
116116 & self ,
117117 expr : & ExpressionView < Literal > ,
118- parent : & Expression , // ← Untyped! AnyParent gives us &Expression
118+ parent : & Expression ,
119119 child_idx : usize ,
120120 _ctx : & RuleContext ,
121121 ) -> VortexResult < Option < Expression > > {
122- // Check if this literal is 1
123- let one_scalar = Scalar :: from ( 1i32 ) ;
124- if expr. data ( ) != & one_scalar {
122+ // Only apply if the parent is an Add operation
123+ let Some ( parent) = parent. as_opt :: < Binary > ( ) else {
124+ return Ok ( None ) ;
125+ } ;
126+ if parent. operator ( ) != Operator :: Add {
125127 return Ok ( None ) ;
126128 }
127129
128- // Return the OTHER child from the parent (works for any binary parent)
129- if parent . children ( ) . len ( ) == 2 {
130- let other_idx = if child_idx == 0 { 1 } else { 0 } ;
131- return Ok ( Some ( parent . child ( other_idx ) . clone ( ) ) ) ;
130+ // Check if this literal is zero
131+ let zero_scalar = Scalar :: from ( 0i32 ) ;
132+ if expr . data ( ) != & zero_scalar {
133+ return Ok ( None ) ;
132134 }
133135
134- Ok ( None )
136+ // Return the other child (not this zero)
137+ let other_idx = if child_idx == 0 { 1 } else { 0 } ;
138+ Ok ( Some ( parent. child ( other_idx) . clone ( ) ) )
135139 }
136140 }
137141
138142 #[ test]
139- fn test_add_zero_parent_rule_basic ( ) {
140- // Create a session and register the rule (specific parent: Binary)
143+ fn test_add_zero_with_specific_parent_rule ( ) {
141144 let mut session = ExprSession :: default ( ) ;
142145 session. register_parent_rule ( & Literal , & Binary , AddZeroRule ) ;
143146
144- // Test: 0 + x should simplify to x
145147 let x = col ( "x" ) ;
146148 let zero = lit ( 0 ) ;
147149 let expr = checked_add ( zero, x. clone ( ) ) ;
@@ -152,91 +154,31 @@ mod tests {
152154 }
153155
154156 #[ test]
155- fn test_add_zero_parent_rule_left ( ) {
157+ fn test_add_zero_with_any_parent_rule ( ) {
156158 let mut session = ExprSession :: default ( ) ;
157- session. register_parent_rule ( & Literal , & Binary , AddZeroRule ) ;
159+ session. register_any_parent_rule ( & Literal , AddZeroRuleAnyParent ) ;
158160
159- // Test: 0 + (0 + x) should simplify to 0 + x, then to x
160161 let x = col ( "x" ) ;
161162 let zero = lit ( 0 ) ;
162- let zero_plus_x = checked_add ( lit ( 0 ) , x. clone ( ) ) ;
163- let expr = checked_add ( zero, zero_plus_x) ;
164-
165- let result = simplify ( expr, & session) . unwrap ( ) ;
166-
167- assert_eq ! ( & result, & x) ;
168- }
169-
170- #[ test]
171- fn test_add_zero_parent_rule_right ( ) {
172- let mut session = ExprSession :: default ( ) ;
173- session. register_parent_rule ( & Literal , & Binary , AddZeroRule ) ;
174-
175- // Test: x + 0 should simplify to x
176- let x = col ( "x" ) ;
177- let zero = lit ( 0 ) ;
178- let expr = checked_add ( x. clone ( ) , zero) ;
163+ let expr = checked_add ( zero, x. clone ( ) ) ;
179164
180165 let result = simplify ( expr, & session) . unwrap ( ) ;
181166
182167 assert_eq ! ( & result, & x) ;
183168 }
184169
185170 #[ test]
186- fn test_add_zero_parent_rule_nested ( ) {
171+ fn test_add_zero_with_both_rules ( ) {
187172 let mut session = ExprSession :: default ( ) ;
188173 session. register_parent_rule ( & Literal , & Binary , AddZeroRule ) ;
174+ session. register_any_parent_rule ( & Literal , AddZeroRuleAnyParent ) ;
189175
190- // Test: (0 + x) + 0 should simplify to x
191176 let x = col ( "x" ) ;
192177 let zero = lit ( 0 ) ;
193- let zero_plus_x = checked_add ( lit ( 0 ) , x. clone ( ) ) ;
194- let expr = checked_add ( zero_plus_x, zero) ;
195-
196- let result = simplify ( expr, & session) . unwrap ( ) ;
197-
198- assert_eq ! ( & result, & x) ;
199- }
200-
201- #[ test]
202- fn test_any_parent_wildcard_rule ( ) {
203- // Test AnyParent - rule works with ANY parent type
204- let mut session = ExprSession :: default ( ) ;
205- session. register_any_parent_rule ( & Literal , RemoveOneLiteralRule ) ;
206-
207- // Test: x + 1 should simplify to x (works with Add)
208- let x = col ( "x" ) ;
209- let one = lit ( 1 ) ;
210- let expr = checked_add ( x. clone ( ) , one) ;
178+ let expr = checked_add ( zero, x. clone ( ) ) ;
211179
212180 let result = simplify ( expr, & session) . unwrap ( ) ;
213181
214182 assert_eq ! ( & result, & x) ;
215183 }
216-
217- #[ test]
218- fn test_specific_and_wildcard_rules_together ( ) {
219- // Test both specific and wildcard rules registered at the same time
220- let mut session = ExprSession :: default ( ) ;
221-
222- // Specific rule: removes 0 from Add operations only
223- session. register_parent_rule ( & Literal , & Binary , AddZeroRule ) ;
224-
225- // Wildcard rule: removes 1 from ANY operation
226- session. register_any_parent_rule ( & Literal , RemoveOneLiteralRule ) ;
227-
228- // Test 1: 0 + x -> x (specific rule applies)
229- let x = col ( "x" ) ;
230- let zero = lit ( 0 ) ;
231- let expr = checked_add ( zero, x. clone ( ) ) ;
232- let result = simplify ( expr, & session) . unwrap ( ) ;
233- assert_eq ! ( & result, & x) ;
234-
235- // Test 2: 1 + y -> y (wildcard rule applies)
236- let y = col ( "y" ) ;
237- let one = lit ( 1 ) ;
238- let expr = checked_add ( one, y. clone ( ) ) ;
239- let result = simplify ( expr, & session) . unwrap ( ) ;
240- assert_eq ! ( & result, & y) ;
241- }
242184}
0 commit comments