(*************************************************************************)
(** * Type soundness *)
(*************************************************************************)
(*************************************************************************)
(** ** Preservation *)
(*************************************************************************)
(** *** Recommended Exercise [preservation]  Complete the proof of preservation.  In this proof, we proceed by induction on the given typing derivation.  The induction hypothesis has already been appropriately generalized by the given proof fragment.  Proof sketch: By induction on the typing derivation for [e].  - [typing_var] case: Variables don't step.  - [typing_abs] case: Abstractions don't step.  - [typing_app] case: By case analysis on how [e] steps. The [step_beta] case is interesting, since it follows by the substitution lemma.  The others follow directly from the induction hypotheses. *)
(* HINTS:  - Use [auto] and [eauto], especially with [;], to solve "uninteresting" subgoals.  - Use [inversion] to perform case analyses and to rule out impossible cases.  - In the [step_beta] subcase of the [typing_app] case:  -- Use [inversion] on a typing judgement to obtain a hypothesis about when the body of the abstraction is well-typed.  -- Use [subst_exp_intro] to rewrite the [open] operation into an [open] followed by a [subst].  You'll need to pick a fresh variable first.  *)

Lemma preservation : forall (E : ctx) e e' T,
typing E e T ->
step e e' ->
typing E e' T.