(* HINT for demo: To show the equality of the two sides below, use the tactics [unfold], which replaces a definition with its RHS and reduces it to head form, and [simpl], which reduces the term the rest of the way.  Then finish up with [auto].  *)
(*************************************************************************)
(*                                                                       *)
(*  Stretch break (5 mins)                                               *)
(*                                                                       *)
(*************************************************************************)
(*************************************************************************)
(** * Local closure *)
(*************************************************************************)
(** Recall that [exp] admits terms that contain unbound indices.  We say that a term is locally closed when no indices appearing in it are unbound.  The proposition [lc e] holds when an expression [e] is locally closed.  The inductive definition below formalizes local closure such that the resulting induction principle serves as the structural induction principle over (locally closed) expressions.  In particular, unlike induction for type [exp], there are no cases for bound variables.  Thus, the induction principle corresponds more closely to informal practice than the one arising from the definition of pre-terms. *)
Inductive lc : exp -> Prop :=
| lc_var : forall (x:atom),
lc x
| lc_abs : forall (x : atom) e t,
x `notin` fv e -> lc (open e x) ->
lc (abs t e)
| lc_app : forall e1 e2,
lc e1 -> lc e2 ->
lc (app e1 e2).
Hint Constructors lc.
(*************************************************************************)
(** Properties about basic operations *)
(*************************************************************************)
(** We also define a notation for [open_rec] to make stating some of the properties simpler. However, we don't need to use open_rec outside of this part of the tutorial so we make it a local notation, confined to this section. *)
Section BasicOperations.
Local Notation "{ k ~> u } t" := (open_rec k u t) (at level 67).
(** The first property we would like to show is the analogue to [subst_fresh]: index substitution has no effect for closed terms.  Here is an initial attempt at the proof. *)

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