G4iSLt.G4iSLT_inv_ImpR

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

Require Import general_export.

Require Import G4iSLT_calc.
Require Import G4iSLT_list_lems.
Require Import G4iSLT_remove_list.
Require Import G4iSLT_dec.
Require Import G4iSLT_exch.
Require Import G4iSLT_wkn.
Require Import G4iSLT_adm_unBox_L.

Theorem ImpR_hpinv : (k : ) concl
        (D0 : derrec G4iSLT_rules (fun _ False) concl),
        k = (derrec_height )
          (( prem, ((ImpRRule [prem] concl)
           (D1 : derrec G4iSLT_rules (fun _ False) prem),
          derrec_height k))).
Proof.
assert (DersNilF: dersrec G4iSLT_rules (fun _ : Seq False) []).
apply dersrec_nil.
(* Setting up the strong induction on the height. *)
pose (strong_inductionT (fun (x:) (concl : Seq)
  (D0 : derrec G4iSLT_rules (fun _ : Seq False) concl),
x = derrec_height
(( prem, ((ImpRRule [prem] concl)
           (D1 : derrec G4iSLT_rules (fun _ False) prem),
          derrec_height x))))).
apply s. intros n IH. clear s.
(* Now we do the actual proof-theoretical work. *)
intros s . remember as . destruct .
(* D0 is a leaf *)
- destruct f.
(* D0 is ends with an application of rule *)
- intros hei. intros prem RA. inversion RA. subst.
  inversion g ; subst.
  (* IdP *)
  * inversion H.
  (* BotL *)
  * inversion H. subst. assert (InT () (Γ0 A :: Γ1)). assert (InT () (Γ0 Γ1)). rewrite . apply InT_or_app. right. apply InT_eq.
    apply InT_app_or in . destruct . apply InT_or_app. auto. apply InT_or_app. right.
    apply InT_cons. auto. apply InT_split in . destruct . destruct s. rewrite e.
    assert (BotLRule [] (x :: , B)). apply BotLRule_I. apply BotL in .
    pose (derI (rules:=G4iSLT_rules) (prems:=fun _ : Seq False) (ps:=[]) (x :: , B) DersNilF). exists .
    simpl. rewrite dersrec_height_nil. lia. reflexivity.
   (* AndR *)
  * inversion H.
  (* AndL *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d ). destruct s.
    pose (ImpRRule_I A B [] (Γ2 :: :: Γ3)). simpl in i.
    assert (: derrec_height x < S (dersrec_height d)). lia. assert (: derrec_height x = derrec_height x). reflexivity.
    pose (IH _ _ _ _ i). destruct s. pose (dlCons DersNilF).
    pose (AndLRule_I B (A :: Γ2) Γ3). simpl in a. apply AndL in a. pose (derI _ a ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
  (* OrR1 *)
  * inversion H.
  (* OrR2 *)
  * inversion H.
  (* OrL *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d ). repeat destruct s.
    pose (ImpRRule_I A B [] (Γ2 :: Γ3)). simpl in i. pose (ImpRRule_I A B [] (Γ2 :: Γ3)). simpl in .
    assert (: derrec_height x < S (dersrec_height d)). lia. assert (: derrec_height x = derrec_height x). reflexivity.
    pose (IH _ _ _ _ i). destruct s.
    assert (: derrec_height < S (dersrec_height d)). lia. assert (: derrec_height = derrec_height ). reflexivity.
    pose (IH _ _ _ _ ). destruct s. pose (dlCons DersNilF). pose (dlCons ).
    pose (OrLRule_I B (A :: Γ2) Γ3). simpl in o. apply OrL in o. pose (derI _ o ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
  (* ImpR *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d ). destruct s.
    assert (: derrec_height x = derrec_height x). auto.
    assert (: list_exch_L (Γ2 A :: Γ3, B) (A :: Γ0 Γ1, B)).
    rewrite . assert (A :: Γ2 Γ3 = [] [A] Γ2 [] Γ3). auto. rewrite .
    assert (Γ2 A :: Γ3 = [] [] Γ2 [A] Γ3). auto. rewrite . apply list_exch_LI.
    pose (G4iSLT_hpadm_list_exch_L (derrec_height x) (Γ2 A :: Γ3, B) x (A :: Γ0 Γ1, B) ).
    destruct s.
    assert (: derrec_height = derrec_height ). auto.
    assert (: list_exch_L (A :: Γ0 Γ1, B) (Γ0 A :: Γ1, B)).
    assert (A :: Γ0 Γ1 = [] [A] Γ0 [] Γ1). auto. rewrite .
    assert (Γ0 A :: Γ1 = [] [] Γ0 [A] Γ1). auto. rewrite . apply list_exch_LI.
    pose (G4iSLT_hpadm_list_exch_L (derrec_height ) (A :: Γ0 Γ1, B) (Γ0 A :: Γ1, B) ).
    destruct s. exists . lia.
  (* AtomImpL1 *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d ). destruct s.
    pose (ImpRRule_I A B [] (Γ2 # P :: Γ3 :: Γ4)). simpl in i.
    assert (: derrec_height x < S (dersrec_height d)). lia. assert (: derrec_height x = derrec_height x). reflexivity.
    pose (IH _ _ _ _ i). destruct s. pose (dlCons DersNilF).
    pose (AtomImpL1Rule_I P B (A :: Γ2) Γ3 Γ4). simpl in a. apply AtomImpL1 in a. pose (derI _ a ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
  (* AtomImpL2 *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d ). destruct s.
    pose (ImpRRule_I A B [] (Γ2 :: Γ3 # P :: Γ4)). simpl in i.
    assert (: derrec_height x < S (dersrec_height d)). lia. assert (: derrec_height x = derrec_height x). reflexivity.
    pose (IH _ _ _ _ i). destruct s. pose (dlCons DersNilF).
    pose (AtomImpL2Rule_I P B (A :: Γ2) Γ3 Γ4). simpl in a. apply AtomImpL2 in a. pose (derI _ a ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
 (* AndImpL *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d ). destruct s.
    pose (ImpRRule_I A B [] (Γ2 C :: Γ3)). simpl in i.
    assert (: derrec_height x < S (dersrec_height d)). lia. assert (: derrec_height x = derrec_height x). reflexivity.
    pose (IH _ _ _ _ i). destruct s. pose (dlCons DersNilF).
    pose (AndImpLRule_I C B (A :: Γ2) Γ3). simpl in a. apply AndImpL in a. pose (derI _ a ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
  (* OrImpL *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec_height (dersrec_height d) _ _ _ _ d ). destruct s.
    pose (ImpRRule_I A B [] (Γ2 C :: Γ3 C :: Γ4)). simpl in i.
    assert (: derrec_height x < S (dersrec_height d)). lia. assert (: derrec_height x = derrec_height x). reflexivity.
    pose (IH _ _ _ _ i). destruct s. pose (dlCons DersNilF).
    pose (OrImpLRule_I C B (A :: Γ2) Γ3 Γ4). simpl in o. apply OrImpL in o. pose (derI _ o ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
  (* ImpImpL *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d ). repeat destruct s.
    pose (ImpRRule_I A B [] (Γ2 C :: Γ3)). simpl in i.
    assert (: derrec_height < S (dersrec_height d)). lia. assert (: derrec_height = derrec_height ). reflexivity.
    pose (IH _ _ _ _ i). destruct s.
    assert (: derrec_height x = derrec_height x). auto.
    pose (wkn_LI A [] (Γ2 C :: Γ3) ( )). simpl in w.
    pose (G4iSLT_wkn_L x w). destruct s. pose (dlCons DersNilF). pose (dlCons ).
    pose (ImpImpLRule_I C B (A :: Γ2) Γ3). simpl in . apply ImpImpL in . pose (derI _ ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
  (* BoxImpL *)
  * inversion H. subst. simpl. assert (: dersrec_height d = dersrec_height d). reflexivity.
    pose (@dersrec_derrec2_height (dersrec_height d) _ _ _ _ _ d ). repeat destruct s.
    pose (ImpRRule_I A B [] (Γ2 :: Γ3)). simpl in i.
    assert (: derrec_height < S (dersrec_height d)). lia. assert (: derrec_height = derrec_height ). reflexivity.
    pose (IH _ _ _ _ i). destruct s.
    assert (: derrec_height x = derrec_height x). auto.
    pose (wkn_LI A [] (unBoxed_list Γ2 :: unBoxed_list Γ3 [Box ]) ). simpl in w.
    pose (G4iSLT_wkn_L x w). destruct s. pose (dlCons DersNilF).
    assert (BoxImpLRule [((unBox_formula A :: unBoxed_list Γ2) :: unBoxed_list Γ3 [Box ], ); ((A :: Γ2) :: Γ3, B)] ((A :: Γ2) Box :: Γ3, B)).
    pose (@BoxImpLRule_I B (A :: Γ2) Γ3). simpl in b ; simpl ; apply b.
    apply BoxImpL in . repeat rewrite app_assoc in . simpl in .
    pose (unBox_left_hpadm_gen A [] (unBoxed_list Γ2 :: unBoxed_list Γ3 [Box ]) ).
    simpl in s. destruct s. pose (dlCons ). pose (derI _ ).
    assert (: derrec_height = derrec_height ). auto.
    pose (list_exch_LI [] [A] [] Γ0 Γ1 B). simpl in . rewrite in .
    pose (G4iSLT_hpadm_list_exch_L _ _ _ ). destruct s. exists . simpl in .
    rewrite dersrec_height_nil in . lia. auto.
  (* GLR *)
  * inversion H.
Qed.


Theorem ImpR_inv : concl prem, (derrec G4iSLT_rules (fun _ False) concl)
                                      (ImpRRule [prem] concl)
                                      (derrec G4iSLT_rules (fun _ False) prem).
Proof.
intros.
assert (: derrec_height X = derrec_height X). reflexivity.
pose (ImpR_hpinv _ _ X ). pose (s _ H). destruct . assumption.
Qed.