(** Here we are stuck. We don't know that [x0] is not in the free variables of [u].  The solution is to change the *definition* of local closure so that we get a different induction principle.  Currently, in the [lc_abs] case, we show that an abstraction is locally closed by showing that the body is locally closed after it has been opened with one particular variable.  << | lc_abs : forall (x : atom) e, x `notin` fv e -> lc (open e x) -> lc (abs e) >>  Therefore, our induction hypothesis in this case only applies to that variable. From the hypothesis list in the [lc_abs] case:  x0 : atom, IHHe : lc ([x ~> u]open e x0)  The problem is that we don't have any assumptions about [x0]. It could very well be equal to [x].  A stronger induction principle provides an IH that applies to many variables. In that case, we could pick one that is "fresh enough". To do so, we need to revise the above definition of lc and replace the type of lc_abs with this one:  << | lc_abs_c : forall L e, (forall x:atom, x `notin` L -> lc (open e x)) -> lc (abs e) >>  This rule says that to show that an abstraction is locally closed, we need to show that the body is closed, after it has been opened by any atom [x], *except* those in some set [L]. With this rule, the IH in this proof is now:  H0 : forall x0 : atom, x0 `notin` L -> lc ([x ~> u]open e x0)  Below, lc_c is the local closure judgment revised to use this new rule in the abs case. We call this "cofinite quantification" because the IH applies to an infinite number of atoms [x0], except those in some finite set [L].  Changing the rule in this way does not change what terms are locally closed.  (For more details about cofinite-quantification see: "Engineering Formal Metatheory", Aydemir, Chargu'eraud, Pierce, Pollack, Weirich. POPL 2008.)  *)
Inductive lc_c : exp -> Prop :=
| lc_var_c : forall (x:atom),
lc_c x
| lc_abs_c : forall (L : atoms) e T,
(forall x : atom, x `notin` L -> lc_c (open e x)) ->
lc_c (abs T e)
| lc_app_c : forall e1 e2,
lc_c e1 ->
lc_c e2 ->
lc_c (app e1 e2).
Hint Constructors lc_c.
(* Reintroduce notation for [open_rec] so that we can reprove properties about it and the new version of lc_c. *)
Section CofiniteQuantification.
Local Notation "{ k ~> u } t" := (open_rec k u t) (at level 67).
(* With this new definition, we can almost use the same proof for [open_rec_lc], we only need one change. We need to add the line [pick fresh x for L.]  immediately before the use of [apply open_rec_lc_core].  This tactic, defined in [Metatheory], introduces a new atom [x] that is known not to be in the set [L]. *)

(* Specifications: *)
Lemma open_rec_lc_c : forall k u e,
lc_c e ->
e = {k ~> u} e.
Lemma open_rec_lc_c : forall k u e,
lc_c e ->
e = {k ~> u} e.