/// Get free variables of a term
Get free variables of a term
Get free variables of a term
fn fv<'a>(&mut self, source: &'a TaggedTerm) -> HashSet<Id> {
        use self::Term::*;
        match *source.body() {
            Term::Lit(_) => HashSet::new(),
            Var(ref v) => {
                let mut hs = HashSet::new();
                hs.insert(v.to_owned());
                return hs;
            }
            List(ref lst) |
            Block(ref lst) |
            ApplyDir(_, ref lst) => {
                lst.iter().fold(HashSet::new(), |mut res, v| {
                    res.extend(self.fv(v.deref()));
                    res
                })
            }
            // The new binding name should not be visible
            // in binding value.
            Let(ref var, ref val, ref exp) => {
                let mut res = self.fv(exp.deref());
                res.remove(&var.name());
                res.extend(&self.fv(val.deref()));
                res
            }
            MakeCls(ref var, ref cls, ref exp) => {
                let mut r = self.fv(exp.deref());
                r.extend(cls.deref().fv());
                r.remove(&var.name());
                r
            }
            ApplyCls(ref n, ref args) => {
                let mut r = args.iter().fold(HashSet::new(), |mut res, v| {
                    res.extend(self.fv(v.deref()));
                    res
                });
                r.extend(self.fv(n.deref()));
                r
            }
            Binary(_, ref lhs, ref rhs) => {
                let mut r = self.fv(lhs.deref());
                r.extend(self.fv(rhs.deref()));
                r
            }
            Unary(_, ref e) => self.fv(e.deref()),
            If(ref c, ref t, ref f) => {
                let mut r = self.fv(c.deref());
                r.extend(self.fv(t.deref()));
                r.extend(self.fv(f.deref()));
                r
            }
        }
    }
fn fv < ' a > ( & mut self , source : & ' a TaggedTerm ) -> HashSet < Id > { use self :: Term :: * ; match * source . body ( ) { Term :: Lit ( _ ) => HashSet :: new ( ) , Var ( ref v ) => { let mut hs = HashSet :: new ( ) ; hs . insert ( v . to_owned ( ) ) ; return hs ; } List ( ref lst ) | Block ( ref lst ) | ApplyDir ( _ , ref lst ) => { lst . iter ( ) . fold ( HashSet :: new ( ) , | mut res , v | { res . extend ( self . fv ( v . deref ( ) ) ) ; res } ) } // The new binding name should not be visible // in binding value. Let ( ref var , ref val , ref exp ) => { let mut res = self . fv ( exp . deref ( ) ) ; res . remove ( & var . name ( ) ) ; res . extend ( & self . fv ( val . deref ( ) ) ) ; res } MakeCls ( ref var , ref cls , ref exp ) => { let mut r = self . fv ( exp . deref ( ) ) ; r . extend ( cls . deref ( ) . fv ( ) ) ; r . remove ( & var . name ( ) ) ; r } ApplyCls ( ref n , ref args ) => { let mut r = args . iter ( ) . fold ( HashSet :: new ( ) , | mut res , v | { res . extend ( self . fv ( v . deref ( ) ) ) ; res } ) ; r . extend ( self . fv ( n . deref ( ) ) ) ; r } Binary ( _ , ref lhs , ref rhs ) => { let mut r = self . fv ( lhs . deref ( ) ) ; r . extend ( self . fv ( rhs . deref ( ) ) ) ; r } Unary ( _ , ref e ) => self . fv ( e . deref ( ) ) , If ( ref c , ref t , ref f ) => { let mut r = self . fv ( c . deref ( ) ) ; r . extend ( self . fv ( t . deref ( ) ) ) ; r . extend ( self . fv ( f . deref ( ) ) ) ; r } } }
Get free variables of a term
Get free variables of a term
&mut self
source
&'a TaggedTerm