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. *)
(** At this point there are two problems.  Our goal is about substitution for index [S k] in term [e], while our induction hypothesis IHLC only tells use about index [k] in term [open e x].  To solve the first problem, we generalize our IH over all [k]. That way, when [k] is incremented in the [abs] case, it will still apply.  Below, we use the tactic [generalize dependent] to generalize over [k] before using induction. *)
(** At this point we are still stuck because the IH concerns [open e x] instead of [e]. The result that we need is that if an index substitution has no effect for an opened term, then it has no effect for the raw term (as long as we are *not* substituting for [0], hence [S k] below). << open e x = {S k ~> u}(open e x)  -> e = {S k ~> u} e >> In other words, expanding the definition of open: << {0 ~> x}e = {S k ~> u}({0 ~> x} e)  -> e = {S k ~> u} e >> Of course, to prove this result, we must generalize [0] and [S k] to be any pair of inequal numbers to get a strong enough induction hypothesis for the [abs] case. *)
(* Take-home Exercise: We've proven the above lemma very explicitly, so that you can step through it slowly to see how it works. However, with automation, it is possible to give a *much* shorter proof. Reprove this lemma on your own to see how compact you can make it. *)

(* SOLUTION *)
Lemma open_rec_lc_core_automated : forall e j v i u,
i <> j ->
{j ~> v} e = {i ~> u} ({j ~> v} e) ->
e = {i ~> u} e.