pub fn keep_only(&self, only: &[SPPath]) -> Option<Predicate> {
        match &self {
            Predicate::AND(x) => {
                let mut new: Vec<_> = x.iter().flat_map(|p| p.keep_only(only)).collect();
                new.dedup();
                if new.len() == 0 {
                    None
                } else if new.len() == 1 {
                    Some(new[0].clone())
                } else {
                    Some(Predicate::AND(new))
                }
            }
            Predicate::OR(x) => {
                let mut new: Vec<_> = x.iter().flat_map(|p| p.keep_only(only)).collect();
                new.dedup();
                if new.len() == 0 {
                    None
                } else if new.len() == 1 {
                    Some(new[0].clone())
                } else {
                    Some(Predicate::OR(new))
                }
            }
            Predicate::XOR(x) => {
                let mut new: Vec<_> = x.iter().flat_map(|p| p.keep_only(only)).collect();
                new.dedup();
                if new.len() == 0 {
                    None
                } else if new.len() == 1 {
                    Some(new[0].clone())
                } else {
                    Some(Predicate::XOR(new))
                }
            }
            Predicate::NOT(x) => match x.keep_only(only) {
                Some(x) => Some(Predicate::NOT(Box::new(x))),
                None => None,
            },
            Predicate::TRUE => Some(Predicate::TRUE),
            Predicate::FALSE => Some(Predicate::FALSE),
            Predicate::EQ(x, y)
            | Predicate::NEQ(x, y)
            | Predicate::TON(x, y)
            | Predicate::TOFF(x, y)
            | Predicate::MEMBER(x, y) => {
                let remove_x = match x {
                    PredicateValue::SPValue(_) => false,
                    PredicateValue::SPPath(p, _) => !only.contains(p),
                };
                let remove_y = match y {
                    PredicateValue::SPValue(_) => false,
                    PredicateValue::SPPath(p, _) => !only.contains(p),
                };

                if remove_x || remove_y {
                    None
                } else {
                    Some(self.clone())
                }
            }
        }
    }
/// Recursively clean expression and keep only constants and allowed paths
Recursively clean expression and keep only constants and allowed paths
Recursively clean expression and keep only constants and allowed paths
pub fn keep_only(&self, only: &[SPPath]) -> Option<Predicate> {
        match &self {
            Predicate::AND(x) => {
                let mut new: Vec<_> = x.iter().flat_map(|p| p.keep_only(only)).collect();
                new.dedup();
                if new.len() == 0 {
                    None
                } else if new.len() == 1 {
                    Some(new[0].clone())
                } else {
                    Some(Predicate::AND(new))
                }
            }
            Predicate::OR(x) => {
                let mut new: Vec<_> = x.iter().flat_map(|p| p.keep_only(only)).collect();
                new.dedup();
                if new.len() == 0 {
                    None
                } else if new.len() == 1 {
                    Some(new[0].clone())
                } else {
                    Some(Predicate::OR(new))
                }
            }
            Predicate::XOR(x) => {
                let mut new: Vec<_> = x.iter().flat_map(|p| p.keep_only(only)).collect();
                new.dedup();
                if new.len() == 0 {
                    None
                } else if new.len() == 1 {
                    Some(new[0].clone())
                } else {
                    Some(Predicate::XOR(new))
                }
            }
            Predicate::NOT(x) => match x.keep_only(only) {
                Some(x) => Some(Predicate::NOT(Box::new(x))),
                None => None,
            },
            Predicate::TRUE => Some(Predicate::TRUE),
            Predicate::FALSE => Some(Predicate::FALSE),
            Predicate::EQ(x, y)
            | Predicate::NEQ(x, y)
            | Predicate::TON(x, y)
            | Predicate::TOFF(x, y)
            | Predicate::MEMBER(x, y) => {
                let remove_x = match x {
                    PredicateValue::SPValue(_) => false,
                    PredicateValue::SPPath(p, _) => !only.contains(p),
                };
                let remove_y = match y {
                    PredicateValue::SPValue(_) => false,
                    PredicateValue::SPPath(p, _) => !only.contains(p),
                };
                if remove_x || remove_y {
                    None
                } else {
                    Some(self.clone())
                }
            }
        }
    }
pub fn keep_only ( & self , only : & [ SPPath ] ) -> Option < Predicate > { match & self { Predicate :: AND ( x ) => { let mut new : Vec < _ > = x . iter ( ) . flat_map ( | p | p . keep_only ( only ) ) . collect ( ) ; new . dedup ( ) ; if new . len ( ) == 0 { None } else if new . len ( ) == 1 { Some ( new [ 0 ] . clone ( ) ) } else { Some ( Predicate :: AND ( new ) ) } } Predicate :: OR ( x ) => { let mut new : Vec < _ > = x . iter ( ) . flat_map ( | p | p . keep_only ( only ) ) . collect ( ) ; new . dedup ( ) ; if new . len ( ) == 0 { None } else if new . len ( ) == 1 { Some ( new [ 0 ] . clone ( ) ) } else { Some ( Predicate :: OR ( new ) ) } } Predicate :: XOR ( x ) => { let mut new : Vec < _ > = x . iter ( ) . flat_map ( | p | p . keep_only ( only ) ) . collect ( ) ; new . dedup ( ) ; if new . len ( ) == 0 { None } else if new . len ( ) == 1 { Some ( new [ 0 ] . clone ( ) ) } else { Some ( Predicate :: XOR ( new ) ) } } Predicate :: NOT ( x ) => match x . keep_only ( only ) { Some ( x ) => Some ( Predicate :: NOT ( Box :: new ( x ) ) ) , None => None , } , Predicate :: TRUE => Some ( Predicate :: TRUE ) , Predicate :: FALSE => Some ( Predicate :: FALSE ) , Predicate :: EQ ( x , y ) | Predicate :: NEQ ( x , y ) | Predicate :: TON ( x , y ) | Predicate :: TOFF ( x , y ) | Predicate :: MEMBER ( x , y ) => { let remove_x = match x { PredicateValue :: SPValue ( _ ) => false , PredicateValue :: SPPath ( p , _ ) => ! only . contains ( p ) , } ; let remove_y = match y { PredicateValue :: SPValue ( _ ) => false , PredicateValue :: SPPath ( p , _ ) => ! only . contains ( p ) , } ; if remove_x || remove_y { None } else { Some ( self . clone ( ) ) } } } }
Recursively clean expression and keep only constants and allowed paths
Recursively clean expression and keep only constants and allowed paths
&self
only
&[SPPath]