Module red_one := ext_red_one invert.Module red := ext_red invert.(* -------------------------------------------------------------------------------- *)

Ltac try_refl :=
  try match goal with
      | [ P2 : Par _ _ _ ?b |- _ ] =>
        exists b; assert (lc_tm b); try eapply Par_lc2; eauto; try split; eauto; fail
      end.(*
Ltac invert_syntactic_equality :=
  match goal with
      | [ H : a_UAbs _ _ = a_UAbs _ _ |- _ ] =>
        inversion H; subst; clear H
      | [ H : a_Pi _ _ _ = a_Pi _ _ _ |- _ ] =>
        inversion H; subst; clear H
      | [ H : a_UCAbs _ = a_UCAbs _ |- _ ] =>
        inversion H; subst; clear H
      | [ H : a_App _ _ _ = _ _ _ |- _ ] =>
        inversion H; subst; clear H
      | [ H : a_CApp _ _  = a_CApp _ _ |- _ ] =>
        inversion H; subst; clear H
      | [ H : a_Fam _ = a_Fam _ |- _ ] =>
        inversion H; subst; clear H
      | [ H : a_CPi _ _ = a_CPi _ _ |- _ ] =>
        inversion H; subst; clear H
  end.
*)
Ltac invert_equality :=
  match goal with
  | [ H : _ = _ |- _ ] =>
    inversion H
  end.Ltac try_refl_left :=
  try match goal with
      | [ P2 : Par _ _ ?b ?b |- exists cc:tm, Par ?S ?D ?b cc /\ Par ?S ?D ?a2 cc ] =>
        exists a2; assert (lc_tm a2); try eapply Par_lc2; eauto; try split; eauto; fail
      end.Ltac try_refl_right :=
  try match goal with
      | [ P2 : Par _ _ ?b ?b |- exists cc:tm, Par ?S ?D ?a2 cc /\ Par ?S ?D ?b cc ] =>
        exists a2; assert (lc_tm a2); try eapply Par_lc2; eauto; try split; eauto; fail
      end.Ltac invert_erased :=
    match goal with
    | [ H : erased_tm ?a |- _ ] => inversion H; subst; clear H
    end.(* Find prove that the result of Par is erased, and then invert that *)
  Ltac invert_erased_tm b :=
        let h0 := fresh in
        match goal with
          [ h : Par ?G ?D ?a b, h1: erased_tm ?a |- _ ] =>
          assert (h0 : erased_tm b);
          [ eapply (Par_erased_tm h); eauto | inversion h0; subst]
        end.write (@co_subst_co_tm_intro x a); auto; rewrite h1;
        simpl; destruct (@eq_dec tmvar _ x x); try done;
        rewrite co_subst_co_tm_fresh_eq; auto
      end.


       (* Rewrite a goal of the form
            ... (a'0 ^ b'0) ...
          To
            ... (b . b'0) ...
          and try to solve it, give eta-assn Y2 *)
      Ltac eta_case a'0 Y2 :=
         let x:= fresh in
         pick fresh x;
         rewrite (tm_subst_tm_tm_intro x a'0); auto;
         rewrite Y2; auto; simpl;
         rewrite (tm_subst_tm_tm_fresh_eq); auto;
         destruct eq_dec; try done;
         eauto; clear x.



Ltac i

(* Specifications: *)
rewrite fv_co_co_tm_open_tm_wrt_co_lower. eauto.
H2 : Good S D,
Proof.
(* ---------------------------------------------------------------------- *)