Require Import List.
  Export ListNotations.
  Require Import PeanoNat.
  Require Import Lia.

  Require Import general_export.

  Require Import GLS_export.

  Require Import UIGL_Def_measure.
  Require Import UIGL_Canopy.
  Require Import UIGL_LexSeq.
  Require Import UIGL_nodupseq.
  Require Import UIGL_irred_short.
  Require Import UIGL_braga.
  Require Import UIGL_UI_prelims.
  Require Import UIGL_UI_inter.
  Require Import UIGL_N_imp_UI.

  Theorem Diam_rec_UI_imp : s p X Y, (is_init s False) (critical_Seq s)
              GLS_prv (X,
        Diam (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) -->
        Diam (UI p (XBoxed_list (top_boxes (fst s)), []%list)) :: Y).
  Proof.
  intros.
  remember (list_conj (map (N p s) (Canopy (nodupseq (XBoxed_list (top_boxes (fst s)), []%list))))) as .
  remember (UI p (XBoxed_list (top_boxes (fst s)), []%list)) as .
  unfold Diam. unfold Neg.
  apply derI with (ps:=[((Box ( --> ) --> ) :: X, Box ( --> ) --> :: Y)]).
  apply ImpR. epose (ImpRRule_I _ _ [] X [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
  apply derI with (ps:=[(Box ( --> ) :: (Box ( --> ) --> ) :: X, :: Y)]).
  apply ImpR. epose (ImpRRule_I _ _ [] (Box ( --> ) --> :: X) [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
  apply derI with (ps:=[([Box ( --> )] X, Box ( --> ) :: :: Y);(Box ( --> ) :: :: X, :: Y)]).
  apply ImpL. epose (ImpLRule_I _ _ [Box ( --> )] X [] (Bot :: Y)). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
  2: apply derI with (ps:=[]) ; [apply BotL ; epose (BotLRule_I [Box ( --> )] X _) ; simpl in b ; apply b | apply dlNil].
  apply derI with (ps:=[(XBoxed_list (Box ( --> ) :: top_boxes X) [Box ( --> )], [ --> ])]).
  apply GLR. epose (@GLRRule_I _ _ _ []). simpl in g. apply g. 3: apply dlCons. 4: apply dlNil.
  intro. intros. inversion . exists ( --> ) ; rewrite ; auto. apply in_top_boxes in . destruct .
  destruct ; auto. destruct . destruct . exists x ; rewrite e ; auto.
  simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl.
  apply derI with (ps:=[([] :: --> :: Box ( --> ) :: XBoxed_list (top_boxes X) [Box ( --> )], [] :: [])]).
  apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
  apply derI with (ps:=[( :: Box ( --> ) :: XBoxed_list (top_boxes X) [Box ( --> )], [ ; ]);
  ( :: :: Box ( --> ) :: XBoxed_list (top_boxes X) [Box ( --> )], [])]).
  apply ImpL. epose (ImpLRule_I _ _ [] _ [] _). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
  2: apply derI with (ps:=[]) ; [apply BotL ; epose (BotLRule_I [] _ _) ; simpl in b ; apply b | apply dlNil].
  pose (@GLS_prv_list_wkn_L [] [] []). simpl in g.
  pose (@GLS_prv_list_wkn_R ( :: Box ( --> ) :: XBoxed_list (top_boxes X) [Box ( --> )]) [] []). simpl in .
  epose ( _ [Bot]). rewrite app_nil_r in . apply . Unshelve. clear .
  epose (g _ (Box ( --> ) :: XBoxed_list (top_boxes X) [Box ( --> )])).
  rewrite app_nil_r in . apply . Unshelve. clear g.
  apply ImpR_inv with (concl:=([], [ --> ])). subst.
  apply rec_UI_imp ; auto.
  epose (ImpRRule_I _ _ [] [] [] []). simpl in i. apply i.
  Qed.