fn divide()

in checker/src/abstract_value.rs [2463:2511]


    fn divide(&self, other: Rc<AbstractValue>) -> Rc<AbstractValue> {
        match (&self.expression, &other.expression) {
            (_, Expression::CompileTimeConstant(ConstantDomain::U128(c1))) if *c1 == 1 => {
                return self.clone();
            }
            // [(x * y) / x] -> y
            // [(x * y) / y] -> x
            (Expression::Mul { left: x, right: y }, _) => {
                if x.eq(&other) {
                    return y.clone();
                } else if y.eq(&other) {
                    return x.clone();
                }
            }
            (
                Expression::Cast {
                    operand,
                    target_type,
                },
                Expression::CompileTimeConstant(ConstantDomain::U128(c2)),
            ) => {
                if let Expression::Mul { left: x, right: y } = &operand.expression {
                    if x.eq(&other) {
                        // [((x * y) as target_type) / x] -> y as target_type
                        return y.cast(*target_type);
                    } else if y.eq(&other) {
                        // [((x * y) as target_type) / y] -> x as target_type
                        return x.cast(*target_type);
                    } else {
                        // [((c1 * y) as t) / c2] -> ((c1 / c2) * y) as t if c1 >= c2 and c1 % c2 == 0
                        if let Expression::CompileTimeConstant(ConstantDomain::U128(c1)) =
                            &x.expression
                        {
                            if *c1 > *c2 && *c1 % *c2 == 0 {
                                return x.divide(other).multiply(y.clone()).cast(*target_type);
                            }
                        }
                    }
                }
            }
            _ => (),
        }
        self.try_to_constant_fold_and_distribute_binary_op(
            other,
            ConstantDomain::div,
            Self::divide,
            |l, r| AbstractValue::make_binary(l, r, |left, right| Expression::Div { left, right }),
        )
    }