fn find_free_vars_rec(expr: &Expr,
                      bindings: &mut BoundVarN,
                      free: &mut HashSet<Var>) {
  match *expr {
    Expr::Const(_) => (),
    Expr::Var(ref var) => {
      if !bindings.contains_key(var) {
        // Found a free var.
        free.insert(var.clone());
      }
    }
    Expr::Lam(ref var, ref ty, ref body) => {
      {
        find_free_vars_rec(ty, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter += 1;
      }
      {
        find_free_vars_rec(body, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter -= 1;
      }
    }
    Expr::Pi(ref var, ref ty, ref body) => {
      {
        find_free_vars_rec(ty, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter += 1;
      }
      {
        find_free_vars_rec(body, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter -= 1;
      }
    }
    Expr::App(ref f, ref arg) => {
      {
        find_free_vars_rec(f, bindings, free);
      }
      {
        find_free_vars_rec(arg, bindings, free);
      }
    }
  }
}
/// Finds all free variables in the given expression.
Finds all free variables in the given expression.
Finds all free variables in the given expression .
fn find_free_vars_rec(expr: &Expr,
                      bindings: &mut BoundVarN,
                      free: &mut HashSet<Var>) {
  match *expr {
    Expr::Const(_) => (),
    Expr::Var(ref var) => {
      if !bindings.contains_key(var) {
        // Found a free var.
        free.insert(var.clone());
      }
    }
    Expr::Lam(ref var, ref ty, ref body) => {
      {
        find_free_vars_rec(ty, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter += 1;
      }
      {
        find_free_vars_rec(body, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter -= 1;
      }
    }
    Expr::Pi(ref var, ref ty, ref body) => {
      {
        find_free_vars_rec(ty, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter += 1;
      }
      {
        find_free_vars_rec(body, bindings, free);
      }
      {
        let counter = bindings.entry(var.clone()).or_insert(0);
        *counter -= 1;
      }
    }
    Expr::App(ref f, ref arg) => {
      {
        find_free_vars_rec(f, bindings, free);
      }
      {
        find_free_vars_rec(arg, bindings, free);
      }
    }
  }
}
fn find_free_vars_rec ( expr : & Expr , bindings : & mut BoundVarN , free : & mut HashSet < Var > ) { match * expr { Expr :: Const ( _ ) => ( ) , Expr :: Var ( ref var ) => { if ! bindings . contains_key ( var ) { // Found a free var. free . insert ( var . clone ( ) ) ; } } Expr :: Lam ( ref var , ref ty , ref body ) => { { find_free_vars_rec ( ty , bindings , free ) ; } { let counter = bindings . entry ( var . clone ( ) ) . or_insert ( 0 ) ; * counter += 1 ; } { find_free_vars_rec ( body , bindings , free ) ; } { let counter = bindings . entry ( var . clone ( ) ) . or_insert ( 0 ) ; * counter -= 1 ; } } Expr :: Pi ( ref var , ref ty , ref body ) => { { find_free_vars_rec ( ty , bindings , free ) ; } { let counter = bindings . entry ( var . clone ( ) ) . or_insert ( 0 ) ; * counter += 1 ; } { find_free_vars_rec ( body , bindings , free ) ; } { let counter = bindings . entry ( var . clone ( ) ) . or_insert ( 0 ) ; * counter -= 1 ; } } Expr :: App ( ref f , ref arg ) => { { find_free_vars_rec ( f , bindings , free ) ; } { find_free_vars_rec ( arg , bindings , free ) ; } } } }
Finds all free variables in the given expression.
Finds all free variables in the given expression .
expr
&Expr
bindings
&mut BoundVarN
free
&mut HashSet<Var>
expr
&Expr
bindings
&mut BoundVarN
free
&mut HashSet<Var>