Proof with auto.
intros z e1 e2 He1 He2.
induction He1; simpl; auto;
try solve [
econstructor;
try instantiate (1 := L `union` singleton z);
intros;
try rewrite subst_ee_open_ee_var;
try rewrite subst_ee_open_te_var;
instantiate;
auto
].
Case "expr_var".
destruct (x == z)...
Qed.
(* *********************************************************************** *)
(** * #<a name="body"></a># Properties of [body_e] *)
(** The two kinds of facts we need about [body_e] are the following: - How to use it to derive that terms are locally closed. - How to derive it from the facts that terms are locally closed.  Since we use it only in the context of [exp_let] and [exp_sum] (see the definition of reduction), those two constructors are the only ones we consider below. *)

(* Specifications: *)
Lemma expr_let_from_body : forall e1 e2,
expr e1 ->
body_e e2 ->
expr (exp_let e1 e2).
Lemma body_from_expr_let : forall e1 e2,
expr (exp_let e1 e2) ->
body_e e2.
Lemma expr_case_from_body : forall e1 e2 e3,
expr e1 ->
body_e e2 ->
body_e e3 ->
expr (exp_case e1 e2 e3).
Lemma body_inl_from_expr_case : forall e1 e2 e3,
expr (exp_case e1 e2 e3) ->
body_e e2.
Lemma body_inr_from_expr_case : forall e1 e2 e3,
expr (exp_case e1 e2 e3) ->
body_e e3.
Lemma open_ee_body_e : forall e1 e2,
body_e e1 -> expr e2 -> expr (open_ee e1 e2).