(** The hypotheses in the [typing_var_c] case include an environment [E0] that that has no relation to what we need to prove.  The missing fact we need is that [E0 = (G ++ E)].  The problem here arises from the fact that Coq's [induction] tactic let's us only prove something about all typing derivations. While it's clear to us that weakening applies to all typing derivations, it's not clear to Coq, because the environment is written using concatenation.  The [induction] tactic expects that all arguments to a judgement are variables.  So we see [E0] in the proof instead of [(G ++ E)].  The solution is to restate the lemma.  For example, we can prove  << forall E F E' e T, typing_c E' e T -> forall G, E' = G ++ E -> uniq (G ++ F ++ E) -> typing_c (G ++ F ++ E) e T. >>  The equality gets around the problem with Coq's [induction] tactic.  The placement of the [(forall G)] quantifier gives us a sufficiently strong induction hypothesis in the [typing_abs_c] case.  However, we prefer not to state the lemma in the way shown above, since it is not as readable as the original statement.  Instead, we use a tactic to introduce the equality within the proof itself. The tactic [(remember t as t')] replaces an object [t] with the identifier [t'] everywhere in the goal and introduces an equality [t' = t] into the context.  It is often combined with [generalize dependent], as illustrated below. *)
(** *** Exercise  See how we use [remember as] in the proof below for weakening. Then, complete the proof below.  HINTS:  - The [typing_var_c] case follows from [binds_weaken], the weakening lemma for the [binds] relation.  - The [typing_abs_c] case follows from the induction hypothesis, but the [apply] tactic may be unable to unify things as you might expect.  -- Recall the [pick fresh and apply] tactic.  -- In order to apply the induction hypothesis, use [rewrite_env] to reassociate the list operations.  -- After applying the induction hypothesis, use [simpl_env] to use [uniq_push].  -- Here, use [auto] to solve facts about finite sets of atoms, since it will simplify the [dom] function behind the scenes.  [fsetdec] does not work with the [dom] function.  - The [typing_app_c] case follows directly from the induction hypotheses. *)

(* Specifications: *)
Lemma typing_c_weakening_strengthened :  forall (E F G : env) e T,
typing_c (G ++ E) e T ->
uniq (G ++ F ++ E) ->
typing_c (G ++ F ++ E) e T.
Lemma typing_c_weakening_strengthened :  forall (E F G : env) e T,
typing_c (G ++ E) e T ->
uniq (G ++ F ++ E) ->
typing_c (G ++ F ++ E) e T.