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 : forall 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 conj1.
remember (UI p (XBoxed_list (top_boxes (fst s)), []%list)) as conj2.
unfold Diam. unfold Neg.
apply derI with (ps:=[((Box (conj1 --> ⊥) --> ⊥) :: X, Box (conj2 --> ⊥) --> ⊥ :: Y)]).
apply ImpR. epose (ImpRRule_I _ _ [] X [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[(Box (conj2 --> ⊥) :: (Box (conj1 --> ⊥) --> ⊥) :: X, ⊥ :: Y)]).
apply ImpR. epose (ImpRRule_I _ _ [] (Box (conj1 --> ⊥) --> ⊥ :: X) [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([Box (conj2 --> ⊥)] ++ X, Box (conj1 --> ⊥) :: ⊥ :: Y);(Box (conj2 --> ⊥) :: ⊥ :: X, ⊥ :: Y)]).
apply ImpL. epose (ImpLRule_I _ _ [Box (conj2 --> ⊥)] 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 (conj2 --> ⊥)] X _) ; simpl in b ; apply b | apply dlNil].
apply derI with (ps:=[(XBoxed_list (Box (conj2 --> ⊥) :: top_boxes X) ++ [Box (conj1 --> ⊥)], [conj1 --> ⊥])]).
apply GLR. epose (@GLRRule_I _ _ _ []). simpl in g. apply g. 3: apply dlCons. 4: apply dlNil.
intro. intros. inversion H1. exists (conj2 --> ⊥) ; rewrite <- H2 ; auto. apply in_top_boxes in H2. destruct H2.
destruct s0 ; auto. destruct s0. destruct p0. exists x ; rewrite <- e ; auto.
simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl.
apply derI with (ps:=[([] ++ conj1 :: conj2 --> ⊥ :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)], [] ++ ⊥ :: [])]).
apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
apply derI with (ps:=[(conj1 :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)], [conj2 ; ⊥]);
(conj1 :: ⊥ :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)], [⊥])]).
apply ImpL. epose (ImpLRule_I _ _ [conj1] _ [] _). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
2: apply derI with (ps:=[]) ; [apply BotL ; epose (BotLRule_I [conj1] _ _) ; simpl in b ; apply b | apply dlNil].
pose (@GLS_prv_list_wkn_L [conj1] [] [conj2]). simpl in g.
pose (@GLS_prv_list_wkn_R (conj1 :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)]) [conj2] []). simpl in g0.
epose (g0 _ [Bot]). rewrite app_nil_r in g1. apply g1. Unshelve. clear g0.
epose (g _ (Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)])).
rewrite app_nil_r in g0. apply g0. Unshelve. clear g.
apply ImpR_inv with (concl:=([], [conj1 --> conj2])). subst.
apply rec_UI_imp ; auto.
epose (ImpRRule_I _ _ [] [] [] []). simpl in i. apply i.
Qed.
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 : forall 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 conj1.
remember (UI p (XBoxed_list (top_boxes (fst s)), []%list)) as conj2.
unfold Diam. unfold Neg.
apply derI with (ps:=[((Box (conj1 --> ⊥) --> ⊥) :: X, Box (conj2 --> ⊥) --> ⊥ :: Y)]).
apply ImpR. epose (ImpRRule_I _ _ [] X [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[(Box (conj2 --> ⊥) :: (Box (conj1 --> ⊥) --> ⊥) :: X, ⊥ :: Y)]).
apply ImpR. epose (ImpRRule_I _ _ [] (Box (conj1 --> ⊥) --> ⊥ :: X) [] Y). simpl in i. apply i. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([Box (conj2 --> ⊥)] ++ X, Box (conj1 --> ⊥) :: ⊥ :: Y);(Box (conj2 --> ⊥) :: ⊥ :: X, ⊥ :: Y)]).
apply ImpL. epose (ImpLRule_I _ _ [Box (conj2 --> ⊥)] 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 (conj2 --> ⊥)] X _) ; simpl in b ; apply b | apply dlNil].
apply derI with (ps:=[(XBoxed_list (Box (conj2 --> ⊥) :: top_boxes X) ++ [Box (conj1 --> ⊥)], [conj1 --> ⊥])]).
apply GLR. epose (@GLRRule_I _ _ _ []). simpl in g. apply g. 3: apply dlCons. 4: apply dlNil.
intro. intros. inversion H1. exists (conj2 --> ⊥) ; rewrite <- H2 ; auto. apply in_top_boxes in H2. destruct H2.
destruct s0 ; auto. destruct s0. destruct p0. exists x ; rewrite <- e ; auto.
simpl. apply univ_gen_ext_cons. apply top_boxes_nobox_gen_ext. simpl.
apply derI with (ps:=[([] ++ conj1 :: conj2 --> ⊥ :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)], [] ++ ⊥ :: [])]).
apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil. simpl.
apply derI with (ps:=[(conj1 :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)], [conj2 ; ⊥]);
(conj1 :: ⊥ :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)], [⊥])]).
apply ImpL. epose (ImpLRule_I _ _ [conj1] _ [] _). simpl in i. apply i. apply dlCons. 2: apply dlCons. 3: apply dlNil.
2: apply derI with (ps:=[]) ; [apply BotL ; epose (BotLRule_I [conj1] _ _) ; simpl in b ; apply b | apply dlNil].
pose (@GLS_prv_list_wkn_L [conj1] [] [conj2]). simpl in g.
pose (@GLS_prv_list_wkn_R (conj1 :: Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)]) [conj2] []). simpl in g0.
epose (g0 _ [Bot]). rewrite app_nil_r in g1. apply g1. Unshelve. clear g0.
epose (g _ (Box (conj2 --> ⊥) :: XBoxed_list (top_boxes X) ++ [Box (conj1 --> ⊥)])).
rewrite app_nil_r in g0. apply g0. Unshelve. clear g.
apply ImpR_inv with (concl:=([], [conj1 --> conj2])). subst.
apply rec_UI_imp ; auto.
epose (ImpRRule_I _ _ [] [] [] []). simpl in i. apply i.
Qed.