pub fn action(&self, relation: &mut MirRelationExpr) -> Result<(), TransformError> {
        if let MirRelationExpr::Union { base, inputs } = relation {
            // Compares a union branch against the remaining branches in the union
            // with opposite sign until it finds a branch that cancels the given one
            // and returns its position.
            let matching_negation = |input: &MirRelationExpr,
                                     sign: bool,
                                     inputs: &[MirRelationExpr],
                                     input_signs: &[bool],
                                     start_idx: usize|
             -> Option<usize> {
                for i in start_idx..inputs.len() {
                    // Only compare branches with opposite signs
                    if sign != input_signs[i] {
                        if let BranchCmp::Inverse = Self::compare_branches(input, &inputs[i]) {
                            return Some(i);
                        }
                    }
                }
                None
            };

            let base_sign = Self::branch_sign(base);
            let input_signs = inputs.iter().map(Self::branch_sign).collect_vec();

            // Compare branches if there is at least a negated branch
            if std::iter::once(&base_sign).chain(&input_signs).any(|x| *x) {
                if let Some(j) = matching_negation(&*base, base_sign, inputs, &input_signs, 0) {
                    let relation_typ = base.typ();
                    **base = MirRelationExpr::constant(vec![], relation_typ.clone());
                    inputs[j] = MirRelationExpr::constant(vec![], relation_typ);
                }

                for i in 0..inputs.len() {
                    if let Some(j) =
                        matching_negation(&inputs[i], input_signs[i], inputs, &input_signs, i + 1)
                    {
                        let relation_typ = inputs[i].typ();
                        inputs[i] = MirRelationExpr::constant(vec![], relation_typ.clone());
                        inputs[j] = MirRelationExpr::constant(vec![], relation_typ);
                    }
                }
            }
        }
        Ok(())
    }
/// Detects an input being unioned with its negation and cancels them out
Detects an input being unioned with its negation and cancels them out
Detects an input being unioned with its negation and cancels them out
pub fn action(&self, relation: &mut MirRelationExpr) -> Result<(), TransformError> {
        if let MirRelationExpr::Union { base, inputs } = relation {
            // Compares a union branch against the remaining branches in the union
            // with opposite sign until it finds a branch that cancels the given one
            // and returns its position.
            let matching_negation = |input: &MirRelationExpr,
                                     sign: bool,
                                     inputs: &[MirRelationExpr],
                                     input_signs: &[bool],
                                     start_idx: usize|
             -> Option<usize> {
                for i in start_idx..inputs.len() {
                    // Only compare branches with opposite signs
                    if sign != input_signs[i] {
                        if let BranchCmp::Inverse = Self::compare_branches(input, &inputs[i]) {
                            return Some(i);
                        }
                    }
                }
                None
            };
            let base_sign = Self::branch_sign(base);
            let input_signs = inputs.iter().map(Self::branch_sign).collect_vec();
            // Compare branches if there is at least a negated branch
            if std::iter::once(&base_sign).chain(&input_signs).any(|x| *x) {
                if let Some(j) = matching_negation(&*base, base_sign, inputs, &input_signs, 0) {
                    let relation_typ = base.typ();
                    **base = MirRelationExpr::constant(vec![], relation_typ.clone());
                    inputs[j] = MirRelationExpr::constant(vec![], relation_typ);
                }
                for i in 0..inputs.len() {
                    if let Some(j) =
                        matching_negation(&inputs[i], input_signs[i], inputs, &input_signs, i + 1)
                    {
                        let relation_typ = inputs[i].typ();
                        inputs[i] = MirRelationExpr::constant(vec![], relation_typ.clone());
                        inputs[j] = MirRelationExpr::constant(vec![], relation_typ);
                    }
                }
            }
        }
        Ok(())
    }
pub fn action ( & self , relation : & mut MirRelationExpr ) -> Result < ( ) , TransformError > { if let MirRelationExpr :: Union { base , inputs } = relation { // Compares a union branch against the remaining branches in the union // with opposite sign until it finds a branch that cancels the given one // and returns its position. let matching_negation = | input : & MirRelationExpr , sign : bool , inputs : & [ MirRelationExpr ] , input_signs : & [ bool ] , start_idx : usize | -> Option < usize > { for i in start_idx .. inputs . len ( ) { // Only compare branches with opposite signs if sign != input_signs [ i ] { if let BranchCmp :: Inverse = Self :: compare_branches ( input , & inputs [ i ] ) { return Some ( i ) ; } } } None } ; let base_sign = Self :: branch_sign ( base ) ; let input_signs = inputs . iter ( ) . map ( Self :: branch_sign ) . collect_vec ( ) ; // Compare branches if there is at least a negated branch if std :: iter :: once ( & base_sign ) . chain ( & input_signs ) . any ( | x | * x ) { if let Some ( j ) = matching_negation ( & * base , base_sign , inputs , & input_signs , 0 ) { let relation_typ = base . typ ( ) ; * * base = MirRelationExpr :: constant ( vec ! [ ] , relation_typ . clone ( ) ) ; inputs [ j ] = MirRelationExpr :: constant ( vec ! [ ] , relation_typ ) ; } for i in 0 .. inputs . len ( ) { if let Some ( j ) = matching_negation ( & inputs [ i ] , input_signs [ i ] , inputs , & input_signs , i + 1 ) { let relation_typ = inputs [ i ] . typ ( ) ; inputs [ i ] = MirRelationExpr :: constant ( vec ! [ ] , relation_typ . clone ( ) ) ; inputs [ j ] = MirRelationExpr :: constant ( vec ! [ ] , relation_typ ) ; } } } } Ok ( ( ) ) }
Detects an input being unioned with its negation and cancels them out
Detects an input being unioned with its negation and cancels them out
&self
relation
&mut MirRelationExpr
&self
relation
&mut MirRelationExpr