(*************************************************************************)
(** * Free variables *)
(*************************************************************************)
(** The function [fv], defined below, calculates the set of free variables in an expression.  Because we are using a locally nameless representation, where bound variables are represented as indices, any name we see is a free variable of a term.  In particular, this makes the [abs] case simple. *)
Fixpoint fv (e : exp) {struct e} : atoms :=
match e with
| bvar i => empty
| fvar x => singleton x
| abs t e1 => fv e1
| app e1 e2 => (fv e1) `union` (fv e2)
end.
(** The type [atoms] represents a finite set of elements of type [atom].  The notation for infix union is defined in the Metatheory library. *)

(* Demo [fsetdec]  The tactic [fsetdec] solves a certain class of propositions involving finite sets. See the documentation in [FSetWeakDecide] for a full specification. *)
Lemma fsetdec_demo : forall (x :atom) (S : atoms),
x `in` (singleton x `union` S).