Module pres := fc_preservation wf weak subst e_subst.
(* Why does this cause so many messages? *)
Hint Resolve erased_tm_erase : erased.
Definition AnnGood G D := Good (erase_context G) D.
unfold AnnGood. simpl. unfold Good. unfold erased_context.
split. auto.
intros.
unfold binds in H. inversion H.
Qed.
(* --------- Paths infect the cannonical forms lemmas for functions --------- *)
Definition irrelevant G D (a : tm) :=
(forall x A, binds x (Tm A) G -> x `notin` fv_tm (erase a)) /\ AnnGood G D.
(* ------------------------------------- *)
(* This is proved in the preservation file. Lemma reduction_erasure : forall G a a', head_reduction G a a' -> reduction_in_one (erase a) (erase a') \/ erase a = erase a'. *)
(* ------------------------------------- *)
Inductive multi (rel : tm -> tm -> Prop) : tm -> tm -> Prop :=
| multi_refl : forall a, lc_tm a -> multi rel a a
| multi_step : forall a b c, rel a b -> multi rel b c -> multi rel a c.
(* ------------------------------------- *)
(* ------------------------------------- *)
(* ------------------------------------- *)
(* TODO: move elsewhere?  ext_consist for the first two? *)
(* ------------------------------------- *)
(* A specialized version of eauto that only uses the most common lc lemmas to cut down the search space. *)
Ltac eauto_lc := simpl; eauto using AnnTyping_lc1, Value_lc,
AnnDefEq_lc3, AnnPropWff_lc.

(* If an annotated term erases to a value, then it evaluates to a coerced value. *)
Lemma erased_Value_reduces_to_CoercedValue :
forall G a0 A,
AnnTyping G a0 A
-> AnnGood G (dom G) -> forall a, erase a0 = a -> Value a
-> exists av, multi (head_reduction G) a0 av /\ CoercedValue av /\ erase av = a.