vortex_expr/transform/
simplify.rs

1use vortex_error::VortexResult;
2
3use crate::transform::match_between::find_between;
4// use crate::transform::match_between::find_between;
5use crate::traversal::{MutNodeVisitor, Node, TransformResult};
6use crate::{ExprRef, GetItem, Pack};
7
8/// Simplifies an expression into an equivalent expression which is faster and easier to analyze.
9///
10/// If the scope dtype is known, see `simplify_typed` for a simplifier which uses dtype.
11pub fn simplify(e: ExprRef) -> VortexResult<ExprRef> {
12    let mut folder = Simplify;
13    let e = e.transform(&mut folder).map(|e| e.result)?;
14    Ok(find_between(e.clone()))
15}
16
17struct Simplify;
18
19impl MutNodeVisitor for Simplify {
20    type NodeTy = ExprRef;
21
22    fn visit_up(&mut self, node: Self::NodeTy) -> VortexResult<TransformResult<ExprRef>> {
23        // pack(l_1: e_1, ..., l_i: e_i, ..., l_n: e_n).get_item(l_i) = e_i where 0 <= i <= n
24        if let Some(get_item) = node.as_any().downcast_ref::<GetItem>() {
25            if let Some(pack) = get_item.child().as_any().downcast_ref::<Pack>() {
26                let expr = pack.field(get_item.field())?;
27                return Ok(TransformResult::yes(expr));
28            }
29        }
30        Ok(TransformResult::no(node))
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use crate::transform::simplify::simplify;
37    use crate::{get_item, lit, pack};
38
39    #[test]
40    fn test_simplify() {
41        let e = get_item("b", pack([("a", lit(1)), ("b", lit(2))]));
42        let e = simplify(e).unwrap();
43        assert_eq!(&e, &lit(2));
44    }
45}