G4iSLt.G4iSLT_exch_prelims5
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_exch_prelims1.
Lemma SLR_app_list_exchL : forall s se ps,
(@list_exch_L s se) ->
(SLRRule [ps] s) ->
(existsT2 pse,
(SLRRule [pse] se) *
(@list_exch_L ps pse)).
Proof.
intros s se ps exch RA. inversion RA. inversion exch. subst. inversion H ; subst.
exists (unBoxed_list Γ0 ++ unBoxed_list Γ3 ++ unBoxed_list Γ2 ++ unBoxed_list Γ1 ++ unBoxed_list Γ4 ++ [Box A], A). split.
- pose (@SLRRule_I A (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4)). repeat rewrite unBox_app_distrib in s ; repeat rewrite <- app_assoc in s ; auto.
- repeat rewrite unBox_app_distrib ; repeat rewrite <- app_assoc. apply list_exch_LI.
Qed.
Lemma AndImpL_app_list_exchL : forall s se ps,
(@list_exch_L s se) ->
(AndImpLRule [ps] s) ->
(existsT2 pse, (AndImpLRule [pse] se) *
(@list_exch_L ps pse)).
Proof.
intros s se ps exch RA. inversion RA. subst. inversion exch. subst. symmetry in H0.
apply app2_find_hole in H0. destruct H0. repeat destruct s ; destruct p ; subst.
- destruct Γ3.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists (Γ0 ++ A → B → C :: Γ1, D). repeat split. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ0 ++ A → B → C :: Γ5 ++ Γ6, D). repeat split. apply list_exch_L_id. }
* simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ A → B → C :: Γ4 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5) (Γ4 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ4) [] Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ Γ4 ++ A → B → C :: Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5 ++ Γ4) (Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ3) Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
- destruct x.
+ simpl in e0. subst. simpl. destruct Γ3.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. subst. simpl. rewrite <- e0. exists ((Γ0 ++ []) ++ A → B → C :: Γ1, D). repeat split. rewrite <- app_assoc. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ A → B → C :: Γ4 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5) (Γ4 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ4) [] Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* simpl in e0. inversion e0. subst. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ Γ4 ++ A → B → C :: Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5 ++ Γ4) (Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ3) Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ A → B → C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat rewrite <- app_assoc. repeat split.
pose (list_exch_LI (Γ0 ++ A → B → C :: x) Γ3 Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ3) ++ A → B → C :: Γ1, D). repeat split. 2: apply list_exch_L_id. rewrite app_assoc. apply AndImpLRule_I. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ Γ3 ++ Γ6, D). repeat split.
pose (list_exch_LI Γ2 Γ3 [] (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5) ++ A → B → C :: Γ4 ++ Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5) (Γ4 ++ Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 (A → B → C :: Γ4) Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
+ apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ4 ++ Γ3) ++ A → B → C :: Γ1, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ4 ++ Γ3) Γ1). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 [] Γ4 (A → B → C :: Γ1) D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ3 ++ Γ4) (Γ5 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 Γ4 (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ A → B → C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply AndImpLRule_I. }
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ A → B → C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply AndImpLRule_I. }
{ destruct x0.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ Γ4 ++ Γ3 ++ A → B → C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply AndImpLRule_I.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ x) ++ A → B → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ x) (x0 ++ Γ4 ++ Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 Γ4 (x ++ A → B → C :: x0) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* destruct x.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x0 ++ Γ3 ++ A → B → C :: Γ1, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ x0 ++ Γ3) Γ1). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 [] x0 (A → B → C :: Γ1) D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ x0 ++ Γ3 ++ Γ6, D). repeat split.
pose (list_exch_LI Γ2 Γ3 x0 (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
{ simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5 ++ x0) ++ A → B → C :: x ++ Γ3 ++ Γ6, D). split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5 ++ x0) (x ++ Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 (x0 ++ A → B → C :: x) Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
+ destruct x0.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ A → B → C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply AndImpLRule_I. apply list_exch_L_id.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ x ++ Γ6, D). repeat split.
pose (list_exch_LI Γ2 x [] (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
{ simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5) ++ A → B → C :: Γ4 ++ x ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5) (Γ4 ++ x ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 x (A → B → C :: Γ4) Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ A → B → C :: x0 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5 ++ Γ4 ++ x) (x0 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 (x ++ A → B → C :: x0) Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
Qed.
Lemma OrImpL_app_list_exchL : forall s se ps,
(@list_exch_L s se) ->
(OrImpLRule [ps] s) ->
(existsT2 pse, (OrImpLRule [pse] se) *
((@list_exch_L ps pse) + (existsT2 pse1, (@list_exch_L ps pse1) * (@list_exch_L pse1 pse)))).
Proof.
intros s se ps exch RA. inversion RA. subst. inversion exch. subst. symmetry in H0.
apply app2_find_hole in H0. destruct H0. repeat destruct s ; destruct p ; subst.
- destruct Γ4.
+ simpl in e0. subst. simpl. destruct Γ5.
* simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists (Γ0 ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto. left. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ0 ++ A → C :: Γ6 ++ B → C :: Γ7, D). repeat split. left. apply list_exch_L_id.
- exists (Γ0 ++ A → C :: (Γ6 ++ x0) ++ B → C :: Γ2, D). repeat split. 2: left. 2: apply list_exch_L_id.
assert (Γ0 ++ (A ∨ B) → C :: Γ6 ++ x0 ++ Γ2 =Γ0 ++ (A ∨ B) → C :: (Γ6 ++ x0) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I.
- exists (Γ0 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7, D). repeat split. 2: left. 2: apply list_exch_L_id. repeat rewrite <- app_assoc.
apply OrImpLRule_I. }
* simpl in e0. inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists (Γ0 ++ Γ6 ++ (A→ C :: Γ5) ++ B→ C :: Γ7, D) . repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ5 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ5 ++ [B → C]) [] Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6) ++ A→ C :: Γ5 ++ B→ C :: Γ7, D). split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ5 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ5) [] Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6) ++ A → C :: (Γ5 ++ x1) ++ B → C :: Γ2, D). split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) (Γ5 ++ x1) Γ2). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ5) [] Γ6 (x1 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ x0 ++ x1) ++ A → C :: Γ5 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x0 ++ x1) Γ5 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
exists (Γ0 ++ x1++ A → C :: (Γ5 ++ x0) ++ B → C :: Γ7, D). repeat split.
pose (list_exch_LI Γ0 [] (A → C :: Γ5 ++ x0 ++ [B → C]) x1 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (x1 ++ A → C :: Γ5) x0 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ1 (x0 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl ; rewrite <- app_assoc in o ; simpl in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ1 ++ B → C :: x0) [] Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
+ inversion e0. subst. symmetry in H1. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
exists (Γ0 ++ Γ5 ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7, D). repeat split.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ [B → C]) Γ5 (Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (Γ5 ++ A → C :: Γ1 ++ [B → C]) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 (x0 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ Γ5 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ6 ++ Γ7, D). repeat split.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ B → C :: x0) Γ5 (Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (Γ5 ++ A → C :: Γ1 ++ B → C :: x0) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
* symmetry in e1. apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ0 ++ Γ6 ++ x0) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ x0) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ x0 ++ A → C :: Γ4 ++ B → C :: Γ6 ++ Γ7, D). split.
pose (list_exch_LI Γ0 [] (A → C :: Γ4) x0 (B → C :: Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (x0 ++ A → C :: Γ4 ++ [B → C]) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6 ++ x0 ++ x1) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ x0 ++ x1) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ A → C :: Γ4 ++ B → C :: x0 ++ x1 ++ Γ6 ++ Γ7, D). split.
pose (list_exch_LI (Γ0 ++ A → C :: Γ4) x0 [B → C] [] (x1 ++ Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4 ++ [B → C]) (x0 ++ x1) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6 ++ Γ5) ++ A→ C :: Γ4 ++ B→ C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: (Γ4 ++ x0) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) (Γ4 ++ x0) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (x0 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ x1 ++ x0 ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x1 ++ x0 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists ((Γ0 ++ A → C :: Γ4 ++ Γ5 ++ x1) ++ [] ++ x0 ++ [B → C] ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI (Γ0 ++ A → C :: Γ4 ++ Γ5 ++ x1) [] [B → C] x0 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 (x1 ++ x0) (B → C :: Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
- destruct x ; simpl in e0 ; subst ; repeat rewrite <- app_assoc ; simpl.
* destruct Γ4.
+ simpl in e0. subst. simpl. destruct Γ5.
{ simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists (Γ0 ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto. left. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ0 ++ A → C :: Γ1 ++ B → C :: Γ2, D). repeat split. left. apply list_exch_L_id.
- exists (Γ0 ++ A → C :: Γ1 ++ B → C :: x ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left. apply list_exch_L_id.
- exists (Γ0 ++ A → C :: (Γ6 ++ x) ++ B → C :: Γ2, D). repeat split. 2: left. 2: apply list_exch_L_id.
assert (Γ0 ++ (A ∨ B) → C :: Γ6 ++ x ++ Γ2 =Γ0 ++ (A ∨ B) → C :: (Γ6 ++ x) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. } }
{ simpl in e0. inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ0 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: Γ7, D) . repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ1 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ [B → C]) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: x ++ Γ7, D). split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ1 (x ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ B → C :: x) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6) ++ A → C :: Γ5 ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ5 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ5) Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6) ++ A → C :: (Γ5 ++ x0) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) (Γ5 ++ x0) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ5) Γ6 (x0 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ x ++ x0) ++ A → C :: Γ5 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x ++ x0) Γ5 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ x0 ++ A → C :: (Γ5 ++ x) ++ B → C :: Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ5 ++ x ++ [B → C]) [] x0 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (x0 ++ A → C :: Γ5) [] x (B → C :: Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. } }
+ inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ1 ++ [B → C]) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: x ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 (x ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ1 ++ B → C :: x) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ [] ++ Γ5 ++ (A → C :: Γ4) ++ B → C :: Γ6 ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ4) [] Γ5 (B → C :: Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (Γ5 ++ A → C :: Γ4 ++ [B → C]) [] Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: (Γ4 ++ x) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) (Γ4 ++ x) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (x ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
* exists ((Γ0 ++ x0 ++ x ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x0 ++ x ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ x0 ++ Γ5 ++ (A → C :: Γ4) ++ B → C :: x ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 x0 (B → C :: x ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI (Γ0 ++ x0) [] (Γ5 ++ A → C :: Γ4 ++ [B → C]) x Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6 ++ x ++ x0) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ x ++ x0) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ Γ6 ++ (x ++ B → C :: x0) ++ (A → C :: Γ4) ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ4) (x ++ B → C :: x0) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI (Γ0 ++ Γ6 ++ x) [B → C] (x0 ++ A → C :: Γ4) [] Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
* inversion e0 ; subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+ exists (Γ0 ++ A → C :: (Γ1 ++ Γ6 ++ Γ5) ++ B → C :: Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (Γ1 ++ Γ6 ++ Γ5) (Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: Γ1) (B → C :: Γ4) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ exists (Γ0 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ6 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat split. repeat rewrite <- app_assoc. apply OrImpLRule_I. left.
pose (list_exch_LI (Γ0 ++ A → C :: Γ1 ++ B → C :: x0) Γ4 Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
{ exists (Γ0 ++ A → C :: (x ++ Γ6) ++ B → C :: Γ5 ++ Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6) (Γ5 ++ Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 (B → C :: Γ5) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5) ++ B → C :: Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5) (Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 (Γ5 ++ [B → C]) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
+ exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5 ++ Γ4) ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5 ++ Γ4) Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 Γ5 Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5 ++ Γ4 ++ x1) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 Γ5 Γ6 (x1 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ exists (Γ0 ++ A → C :: (x ++ x0) ++ B → C :: x1 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ x0) (x1 ++ Γ5 ++ Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 Γ5 (x0 ++ B → C :: x1) Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists (Γ0 ++ A → C :: (x ++ Γ6 ++ x1) ++ B → C :: x0 ++ Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ x1) (x0 ++ Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 (x1 ++ B → C :: x0) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5 ++ x0) ++ B → C :: x1 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5 ++ x0) (x1 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) (x0 ++ B → C :: x1) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
(* STOPPED CLEANING PROOF HERE. *)
- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
* destruct Γ5.
+ simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ3 ++ A → C :: (Γ1 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ1 ++ Γ4 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ1 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (A → C :: Γ1) ++ [] ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert (Γ3 ++ A → C :: (Γ1 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ [] ++ (A → C :: Γ1) ++ Γ4 ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ4 ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left.
assert (Γ3 ++ Γ4 ++ A → C :: Γ1 ++ B → C :: x ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ1 ++ B → C :: x) ++ [] ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ4 ++ Γ7 = Γ3 ++ [] ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: (Γ6 ++ Γ4 ++ x) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ Γ4 ++ x ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ Γ4 ++ x) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ6 ++ x) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (A → C :: Γ6) ++ [] ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ Γ4 ++ x) ++ B → C :: Γ2 = Γ3 ++ [] ++ (A → C :: Γ6) ++ Γ4 ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
+ simpl in e0. inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ3 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: Γ4 ++ Γ7, D) . repeat split. 2: left.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ1) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto. rewrite H.
apply OrImpLRule_I.
assert ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ1 ++ [B → C]) ++ Γ6 ++ Γ7). repeat rewrite <- app_assoc.
simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ [B → C]) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc.
simpl. repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ exists ((Γ3 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: x ++ Γ4 ++ Γ7, D). split. 2: left.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ1 ++ x) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ x ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto.
simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply OrImpLRule_I.
assert ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: x ++ Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x ++ Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4) ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ5) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ Γ4) ++ Γ7). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ5 ++ Γ6) ++ B → C :: Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ5) ++ Γ6 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4) ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ Γ4 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ5) ++ Γ4 ++ x1 ++ Γ2 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ Γ4 ++ x1) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ5 ++ Γ6 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (A → C :: Γ5) ++ Γ6 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ Γ4 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ x ++ x1) ++ A → C :: Γ5 ++ B → C :: Γ4 ++ Γ7, D). repeat split.
assert (Γ3 ++ (x ++ x1) ++ ((A ∨ B) → C :: Γ5) ++ Γ4 ++ Γ7 = (Γ3 ++ x ++ x1) ++ (A ∨ B) → C :: Γ5 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. right. exists (Γ3 ++ (x ++ B → C :: x1) ++ (A → C :: Γ5) ++ Γ4 ++ Γ7, D). split.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ5 ++ x) ++ B → C :: x1 ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ5) ++ (x ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x ++ B → C :: x1) ++ (A → C :: Γ5) ++ Γ4 ++ Γ7 = (Γ3 ++ x) ++ [B → C] ++ (x1 ++ A → C :: Γ5) ++ [] ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x ++ x1) ++ A → C :: Γ5 ++ B → C :: Γ4 ++ Γ7 = (Γ3 ++ x) ++ [] ++ (x1 ++ A → C :: Γ5) ++ [B → C] ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
* apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+ simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists ((Γ3 ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ Γ5 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ5 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ [] ++ Γ5 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert ((Γ3 ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ5 ++ [] ++ Γ4 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ3 ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ1 ++ Γ5 ++ Γ4 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ1 ++ Γ5 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (A → C :: Γ1) ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert (Γ3 ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ1) ++ Γ5 ++ Γ4 ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left.
assert (Γ3 ++ Γ4 ++ Γ5 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7 = Γ3 ++ Γ4 ++ Γ5 ++ (A → C :: Γ1 ++ B → C :: x0) ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ5 ++ Γ4 ++ Γ7 = Γ3 ++ (A → C :: Γ1 ++ B → C :: x0) ++ Γ5 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: (Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ Γ5 ++ Γ4 ++ x0 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5) ++ A → C :: (Γ6 ++ x0) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (A → C :: Γ6) ++ x0 ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ6) ++ Γ5 ++ Γ4 ++ x0 ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
+ subst. apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D) . repeat split. 2: left.
assert (Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ6 ++ Γ5 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto. rewrite H.
apply OrImpLRule_I. repeat rewrite <- app_assoc ; apply list_exch_LI. }
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split. 2: left.
assert (Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ x0 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. repeat rewrite <- app_assoc ; apply list_exch_LI. }
{ destruct x0 ; simpl in e0 ; inversion e0 ; subst.
- repeat rewrite <- app_assoc ; simpl. exists ((Γ3 ++ x ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ x ++ Γ5 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ x ++ Γ5 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H0. apply OrImpLRule_I. left. repeat rewrite <- app_assoc ; apply list_exch_LI.
- apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+ exists((Γ3 ++ x) ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (x ++ (A ∨ B) → C :: Γ1) ++ Γ5 ++ Γ4 ++ Γ2 = (Γ3 ++ x) ++ (A ∨ B) → C :: (Γ1 ++ Γ5 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (x ++ A → C :: Γ1) ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x) ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ (x ++ A → C :: Γ1) ++ Γ5 ++ Γ4 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat split.
assert (Γ3 ++ (x ++ (A ∨ B) → C :: Γ1 ++ x1) ++ Γ5 ++ Γ4 ++ Γ7 = (Γ3 ++ x) ++ (A ∨ B) → C :: Γ1 ++ x1 ++ Γ5 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto.
simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ7 = Γ3 ++ Γ4 ++ Γ5 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ5 ++ Γ4 ++ Γ7 = Γ3 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ5 ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ5 ++ Γ4 ++ x1 ++ Γ2 = (Γ3 ++ x) ++ (A ∨ B) → C :: (x0 ++ Γ5 ++ Γ4 ++ x1) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (x ++ A → C :: x0) ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ Γ4 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
+ destruct x ; simpl in e0 ; inversion e0 ; subst.
{ destruct Γ6.
- simpl in e0. subst. simpl in H0. simpl. repeat rewrite <- app_assoc. simpl.
exists ((Γ3 ++ x0 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ x0 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ x0 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ [] ++ x0 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert ((Γ3 ++ x0 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ x0 ++ [] ++ Γ4 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H1. apply list_exch_LI.
- simpl in e0. inversion e0. clear H0. subst. simpl. repeat rewrite <- app_assoc. simpl.
apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+ exists (Γ3 ++ A → C :: (Γ1 ++ x0 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ1 ++ x0 ++ Γ4 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ1 ++ x0 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ x0 ++ (A → C :: Γ1) ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert (Γ3 ++ A → C :: (Γ1 ++ x0 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ1) ++ x0 ++ Γ4 ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI.
+ exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ x0 ++ Γ4 ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: Γ1 ++ B → C :: x ++ Γ7 = Γ3 ++ Γ4 ++ x0 ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ x0 ++ Γ4 ++ Γ7 = Γ3 ++ (A → C :: Γ1 ++ B → C :: x) ++ x0 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
+ exists (Γ3 ++ A → C :: (Γ6 ++ x0 ++ Γ4 ++ x) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ x0 ++ Γ4 ++ x ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ x0 ++ Γ4 ++ x) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: (Γ6 ++ x) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ x0 ++ (A → C :: Γ6) ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ x0 ++ Γ4 ++ x) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ6) ++ x0 ++ Γ4 ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
{ apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ4 ++ Γ7, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: Γ1) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: Γ1 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: Γ1 ++ [B → C]) ++ Γ6 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: Γ1 ++ [B → C]) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ4 ++ Γ7, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: Γ1 ++ x1) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: Γ1 ++ x1 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ6 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
+ exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4) ++ B → C :: Γ7, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: x) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: (x ++ Γ4) ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: (x ++ Γ6) ++ B → C :: Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: x) ++ Γ6 ++ B → C :: Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4) ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: x) ++ Γ4 ++ B → C :: Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4 ++ x2) ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: x) ++ Γ4 ++ x2 ++ Γ2 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: (x ++ Γ4 ++ x2) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: (x ++ Γ6 ++ x2) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: x) ++ Γ6 ++ x2 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4 ++ x2) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: x) ++ Γ4 ++ x2 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ x1 ++ x2 ++ x0) ++ A → C :: x ++ B → C :: Γ4 ++ Γ7, D). split ;auto.
assert (Γ3 ++ (x1 ++ x2) ++ (x0 ++ (A ∨ B) → C :: x) ++ Γ4 ++ Γ7 = (Γ3 ++ x1 ++ x2 ++ x0) ++ (A ∨ B) → C :: x ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ (x1 ++ B → C :: x2) ++ (x0 ++ A → C :: x) ++ Γ4 ++ Γ7, D). split.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: (x ++ x1) ++ B → C :: x2 ++ Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: x) ++ (x1 ++ B → C :: x2) ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x1 ++ B → C :: x2) ++ (x0 ++ A → C :: x) ++ Γ4 ++ Γ7 = (Γ3 ++ x1) ++ [B → C] ++ (x2 ++ x0 ++ A → C :: x) ++ [] ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ x1 ++ x2 ++ x0) ++ A → C :: x ++ B → C :: Γ4 ++ Γ7 = (Γ3 ++ x1) ++ [] ++ (x2 ++ x0 ++ A → C :: x) ++ [B → C] ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
* destruct x0 ; simpl in e0 ; inversion e0 ; subst.
+ destruct Γ5 ; simpl in e0 ; inversion e0 ; subst.
{ destruct Γ6.
- simpl in H1. subst. repeat rewrite <- app_assoc. simpl.
exists ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ x ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ x) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left. repeat rewrite <- app_assoc. apply list_exch_L_id.
- simpl in H1. inversion H1. subst. apply app2_find_hole in H3. destruct H3. repeat destruct s ; destruct p ; subst.
* repeat rewrite <- app_assoc. simpl. exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ2, D). repeat split. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ x ++ (A → C :: Γ1 ++ [B → C]) ++ [] ++ Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ2 = Γ3 ++ [] ++ (A → C :: Γ1 ++ [B → C]) ++ x ++ Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H2. apply list_exch_LI.
* repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7, D). repeat split. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7 = Γ3 ++ x ++ (A → C :: Γ1 ++ B → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7 = Γ3 ++ [] ++ (A → C :: Γ1 ++ B → C :: x0) ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H2. apply list_exch_LI.
* repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
exists (Γ3 ++ A → C :: (Γ6 ++ x ++ x0) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ x ++ x0 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ x ++ x0) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ6 ++ x0 ++ B → C :: Γ2 = Γ3 ++ x ++ (A → C :: Γ6) ++ [] ++ x0 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ x ++ x0) ++ B → C :: Γ2 = Γ3 ++ [] ++ (A → C :: Γ6) ++ x ++ x0 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H2. apply list_exch_LI. }
{ apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
- repeat rewrite <- app_assoc. simpl. exists ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x ++ Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ1 ++ x ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ x ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ x ++ (A → C :: Γ1 ++ [B → C]) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ [B → C]) ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
- repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
exists ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ1 ++ x0 ++ x ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ x0 ++ x ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ6 ++ Γ7 = Γ3 ++ x ++(A → C :: Γ1 ++ B → C :: x0) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ B → C :: x0) ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
- repeat rewrite <- app_assoc. simpl. apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
* exists ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ x) ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ5 ++ x ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ x) ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ5 ++ Γ6 ++ B → C :: Γ7 = Γ3 ++ x ++ (A → C :: Γ5) ++ Γ6 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ x) ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ x ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
* exists ((Γ3 ++ Γ6) ++ A→ C :: (Γ5 ++ x ++ x1) ++ B→ C :: Γ2, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ5 ++ x ++ x1 ++ Γ2 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ x ++ x1) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ5 ++ (Γ6 ++ x1) ++ B → C :: Γ2 = Γ3 ++ x ++ (A → C :: Γ5) ++ Γ6 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ x ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ x ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
* exists ((Γ3 ++ x0 ++ x1) ++ A → C :: Γ5 ++ B → C :: x ++ Γ7, D). repeat split.
assert (Γ3 ++ (x0 ++ x1) ++ (A ∨ B) → C :: Γ5 ++ x ++ Γ7 = (Γ3 ++ x0 ++ x1) ++ (A ∨ B) → C :: Γ5 ++ x ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ (x0 ++ B → C :: x1) ++ (A → C :: Γ5) ++ x ++ Γ7, D). split.
assert (Γ3 ++ x ++ A → C :: Γ5 ++ x0 ++ B → C :: x1 ++ Γ7 = Γ3 ++ x ++ (A → C :: Γ5) ++ (x0 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x0 ++ B → C :: x1) ++ (A → C :: Γ5) ++ x ++ Γ7 = (Γ3 ++ x0) ++ [B → C] ++ (x1 ++ A → C :: Γ5) ++ [] ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x0 ++ x1) ++ A → C :: Γ5 ++ B → C :: x ++ Γ7 = (Γ3 ++ x0) ++ [] ++ (x1 ++ A → C :: Γ5) ++ [B → C] ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI. }
+ apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: Γ1) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: Γ1 ++ Γ7). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ5 ++ Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: Γ1 ++ [B → C]) ++ Γ5 ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: Γ1 ++ [B → C]) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: Γ1 ++ x1) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: Γ1 ++ x1 ++ Γ7). repeat rewrite <- app_assoc. auto.
simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ5 ++ Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ5 ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ7 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ Γ6 ++ (Γ5 ++ [B → C]) ++ (x ++ A → C :: x0) ++ Γ7, D). split.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5) ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ (Γ5 ++ [B → C]) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ Γ6 ++ (Γ5 ++ [B → C]) ++ (x ++ A → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5) ++ [B → C] ++ (x ++ A → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = (Γ3 ++ Γ6 ++ Γ5) ++ [] ++ (x ++ A → C :: x0) ++ [B → C] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
* exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ6) ++ B → C :: Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ Γ6 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: x0) ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
* exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ x1 ++ Γ2 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: (x0 ++ x1) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ6 ++ x1) ++ B → C :: Γ2 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ Γ6 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: x0) ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
* exists ((Γ3 ++ x2 ++ x1 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ (x2 ++ x1) ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ x2 ++ x1 ++ Γ5 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ (x2 ++ B → C :: x1) ++ Γ5 ++ (x ++ A → C :: x0) ++ Γ7, D). split.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ x2) ++ B → C :: x1 ++ Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ (x2 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x2 ++ B → C :: x1) ++ Γ5 ++ (x ++ A → C :: x0) ++ Γ7 = (Γ3 ++ x2) ++ [B → C] ++ (x1 ++ Γ5 ++ x ++ A → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x2 ++ x1 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = (Γ3 ++ x2) ++ [] ++ (x1 ++ Γ5 ++ x ++ A → C :: x0) ++ [B → C] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ Γ6 ++ x1 ++ x2 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (x1 ++ x2) ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ x1 ++ x2 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists(Γ3 ++ Γ6 ++ (x1 ++ B → C :: x2) ++ (x ++ A → C :: x0) ++ Γ7, D). split.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: x2 ++ Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ (x1 ++ B → C :: x2) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ Γ6 ++ (x1 ++ B → C :: x2) ++ (x ++ A → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ x1) ++ [B → C] ++ (x2 ++ x ++ A → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x1 ++ x2 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = (Γ3 ++ Γ6 ++ x1) ++ [] ++ (x2 ++ x ++ A → C :: x0) ++ [B → C] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
Qed.
Lemma ImpImpL_app_list_exchL : forall s se ps1 ps2,
(@list_exch_L s se) ->
(ImpImpLRule [ps1;ps2] s) ->
(existsT2 pse1 pse2,
(ImpImpLRule [pse1;pse2] se) *
(@list_exch_L ps1 pse1) *
(@list_exch_L ps2 pse2)).
Proof.
intros s se ps1 ps2 exch RA. inversion RA. subst. inversion exch. subst. symmetry in H0.
apply app2_find_hole in H0. destruct H0. repeat destruct s ; destruct p ; subst.
- destruct Γ3.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists (Γ0 ++ B → C :: Γ1, A → B). exists (Γ0 ++ C :: Γ1, D). repeat split ; try apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ0 ++ B → C :: Γ5 ++ Γ6, A → B). exists (Γ0 ++ C :: Γ5 ++ Γ6, D). repeat split ; try apply list_exch_L_id. }
* simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ B → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ ((A → B) → C :: Γ4) ++ Γ6 = (Γ0 ++ Γ5) ++ (A → B) → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (B → C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ B → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ Γ4 ++ ((A → B) → C :: Γ3) ++ Γ6 =( Γ0 ++ Γ5 ++ Γ4) ++ (A → B) → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (B → C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (B → C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
- destruct x.
+ simpl in e0. subst. simpl. destruct Γ3.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. subst. simpl. rewrite <- e0. exists ((Γ0 ++ []) ++ B → C :: Γ1, A → B). exists ((Γ0 ++ []) ++ C :: Γ1, D). repeat split ; rewrite <- app_assoc ; simpl ; try apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ B → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ (A → B) → C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ (A → B) → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (B → C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* simpl in e0. inversion e0. subst. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ B → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ Γ4 ++ (A → B) → C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ (A → B) → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (B → C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (B → C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ B → C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, A → B). exists (Γ0 ++ C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat rewrite <- app_assoc. repeat split.
assert (Γ0 ++ B → C :: x ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ0 ++ B → C :: x) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ B → C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ0 ++ B → C :: x) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: x ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ0 ++ C :: x) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ0 ++ C :: x) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ3) ++ B → C :: Γ1, A → B). exists ((Γ2 ++ Γ3) ++ C :: Γ1, D). repeat split ; try apply list_exch_L_id. rewrite app_assoc.
apply ImpImpLRule_I. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ B → C :: Γ5 ++ Γ3 ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ Γ3 ++ Γ6, D). repeat split.
assert ((Γ2 ++ Γ3) ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ (B → C :: Γ5) ++ [] ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3) ++ C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ (C :: Γ5) ++ [] ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ Γ3 ++ Γ6, A → B). exists ((Γ2 ++ Γ5) ++ C :: Γ4 ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ ((A → B) → C :: Γ4) ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5) ++ (A → B) → C :: Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert ((Γ2 ++ Γ3) ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (B → C :: Γ4) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3) ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ C :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (C :: Γ4) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
+ apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ4 ++ Γ3) ++ B → C :: Γ1, A → B). exists ((Γ2 ++ Γ4 ++ Γ3) ++ C :: Γ1, D). repeat split.
assert (Γ2 ++ Γ4 ++ Γ3 ++ (A → B) → C :: Γ1 = (Γ2 ++ Γ4 ++ Γ3) ++ (A → B) → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ B → C :: Γ1 = Γ2 ++ Γ3 ++ Γ4 ++ [] ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ4 ++ Γ3) ++ B → C :: Γ1 = Γ2 ++ [] ++ Γ4 ++ Γ3 ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ C :: Γ1 = Γ2 ++ Γ3 ++ Γ4 ++ [] ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ4 ++ Γ3) ++ C :: Γ1 = Γ2 ++ [] ++ Γ4 ++ Γ3 ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ B → C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (B → C :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (C :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ B → C :: Γ1, A → B). exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply ImpImpLRule_I. }
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ B → C :: Γ1, A → B). exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply ImpImpLRule_I. }
{ destruct x0.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ Γ4 ++ Γ3 ++ B → C :: Γ1, A → B). exists (Γ2 ++ x ++ Γ4 ++ Γ3 ++ C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply ImpImpLRule_I.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ x) ++ B → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6, A → B). exists ((Γ2 ++ x) ++ C :: x0 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ x ++ (A → B) → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ (A → B) → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert (Γ2 ++ Γ3 ++ Γ4 ++ x ++ B → C :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ B → C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ x) ++ B → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ B → C :: x0) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ Γ3 ++ Γ4 ++ x ++ C :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ x) ++ C :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ C :: x0) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* destruct x.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x0 ++ Γ3 ++ B → C :: Γ1, A → B). exists (Γ2 ++ x0 ++ Γ3 ++ C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply ImpImpLRule_I.
assert (Γ2 ++ Γ3 ++ x0 ++ B → C :: Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ x0 ++ Γ3 ++ B → C :: Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ Γ3 ++ x0 ++ C :: Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ x0 ++ Γ3 ++ C :: Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ B → C :: Γ5 ++ x0 ++ Γ3 ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ x0 ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ3 ++ x0 ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ x0 ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ x0 ++ Γ3 ++ Γ6 = Γ2 ++ (B → C :: Γ5) ++ x0 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ Γ3 ++ x0 ++ C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ x0 ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ x0 ++ Γ3 ++ Γ6 = Γ2 ++ (C :: Γ5) ++ x0 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5 ++ x0) ++ B → C :: x ++ Γ3 ++ Γ6, A → B). exists ((Γ2 ++ Γ5 ++ x0) ++ C :: x ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ (x0 ++ (A → B) → C :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ x0) ++ (A → B) → C :: x ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert ((Γ2 ++ Γ3 ++ x0) ++ B → C :: x ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ B → C :: x) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ x0) ++ B → C :: x ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (x0 ++ B → C :: x) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3 ++ x0) ++ C :: x ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ C :: x) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ x0) ++ C :: x ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (x0 ++ C :: x) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
+ destruct x0.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ B → C :: Γ1, A → B). exists (Γ2 ++ x ++ C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply ImpImpLRule_I. apply list_exch_L_id. apply list_exch_L_id.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ B → C :: Γ5 ++ x ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ x ++ Γ6, D). repeat split.
assert (Γ2 ++ x ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ x ++ Γ6 = Γ2 ++( B → C :: Γ5) ++ [] ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ x ++ C :: Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ x ++ Γ6 = Γ2 ++(C :: Γ5) ++ [] ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ x ++ Γ6, A → B). exists ((Γ2 ++ Γ5) ++ C :: Γ4 ++ x ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ (A → B) → C :: Γ4 ++ x ++ Γ6 = (Γ2 ++ Γ5) ++ (A → B) → C :: Γ4 ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert (Γ2 ++ x ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ x ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ x ++ Γ6 = Γ2 ++ Γ5 ++ (B → C :: Γ4) ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ x ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ x ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ C :: Γ4 ++ x ++ Γ6 = Γ2 ++ Γ5 ++ (C :: Γ4) ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ B → C :: x0 ++ Γ6, A → B). exists ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ C :: x0 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ Γ4 ++ x ++ (A → B) → C :: x0 ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4 ++ x) ++ (A → B) → C :: x0 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert (Γ2 ++ x ++ B → C :: x0 ++ Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ (x ++ B → C :: x0) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ B → C :: x0 ++ Γ6 = Γ2 ++ Γ5 ++ Γ4 ++ (x ++ B → C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ x ++ C :: x0 ++ Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ (x ++ C :: x0) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ C :: x0 ++ Γ6 = Γ2 ++ Γ5 ++ Γ4 ++ (x ++ C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
Qed.
Export ListNotations.
Require Import PeanoNat.
Require Import Lia.
Require Import general_export.
Require Import G4iSLT_calc.
Require Import G4iSLT_list_lems.
Require Import G4iSLT_exch_prelims1.
Lemma SLR_app_list_exchL : forall s se ps,
(@list_exch_L s se) ->
(SLRRule [ps] s) ->
(existsT2 pse,
(SLRRule [pse] se) *
(@list_exch_L ps pse)).
Proof.
intros s se ps exch RA. inversion RA. inversion exch. subst. inversion H ; subst.
exists (unBoxed_list Γ0 ++ unBoxed_list Γ3 ++ unBoxed_list Γ2 ++ unBoxed_list Γ1 ++ unBoxed_list Γ4 ++ [Box A], A). split.
- pose (@SLRRule_I A (Γ0 ++ Γ3 ++ Γ2 ++ Γ1 ++ Γ4)). repeat rewrite unBox_app_distrib in s ; repeat rewrite <- app_assoc in s ; auto.
- repeat rewrite unBox_app_distrib ; repeat rewrite <- app_assoc. apply list_exch_LI.
Qed.
Lemma AndImpL_app_list_exchL : forall s se ps,
(@list_exch_L s se) ->
(AndImpLRule [ps] s) ->
(existsT2 pse, (AndImpLRule [pse] se) *
(@list_exch_L ps pse)).
Proof.
intros s se ps exch RA. inversion RA. subst. inversion exch. subst. symmetry in H0.
apply app2_find_hole in H0. destruct H0. repeat destruct s ; destruct p ; subst.
- destruct Γ3.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists (Γ0 ++ A → B → C :: Γ1, D). repeat split. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ0 ++ A → B → C :: Γ5 ++ Γ6, D). repeat split. apply list_exch_L_id. }
* simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ A → B → C :: Γ4 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5) (Γ4 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ4) [] Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ Γ4 ++ A → B → C :: Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5 ++ Γ4) (Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ3) Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
- destruct x.
+ simpl in e0. subst. simpl. destruct Γ3.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. subst. simpl. rewrite <- e0. exists ((Γ0 ++ []) ++ A → B → C :: Γ1, D). repeat split. rewrite <- app_assoc. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ A → B → C :: Γ4 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5) (Γ4 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ4) [] Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* simpl in e0. inversion e0. subst. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ Γ4 ++ A → B → C :: Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ0 ++ Γ5 ++ Γ4) (Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ0 (A → B → C :: Γ3) Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ A → B → C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat rewrite <- app_assoc. repeat split.
pose (list_exch_LI (Γ0 ++ A → B → C :: x) Γ3 Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ3) ++ A → B → C :: Γ1, D). repeat split. 2: apply list_exch_L_id. rewrite app_assoc. apply AndImpLRule_I. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ Γ3 ++ Γ6, D). repeat split.
pose (list_exch_LI Γ2 Γ3 [] (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5) ++ A → B → C :: Γ4 ++ Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5) (Γ4 ++ Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 (A → B → C :: Γ4) Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
+ apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ4 ++ Γ3) ++ A → B → C :: Γ1, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ4 ++ Γ3) Γ1). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 [] Γ4 (A → B → C :: Γ1) D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ3 ++ Γ4) (Γ5 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 Γ4 (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ A → B → C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply AndImpLRule_I. }
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ A → B → C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply AndImpLRule_I. }
{ destruct x0.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ Γ4 ++ Γ3 ++ A → B → C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply AndImpLRule_I.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ x) ++ A → B → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ x) (x0 ++ Γ4 ++ Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 Γ4 (x ++ A → B → C :: x0) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* destruct x.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x0 ++ Γ3 ++ A → B → C :: Γ1, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ x0 ++ Γ3) Γ1). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 [] x0 (A → B → C :: Γ1) D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ x0 ++ Γ3 ++ Γ6, D). repeat split.
pose (list_exch_LI Γ2 Γ3 x0 (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
{ simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5 ++ x0) ++ A → B → C :: x ++ Γ3 ++ Γ6, D). split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5 ++ x0) (x ++ Γ3 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 Γ3 (x0 ++ A → B → C :: x) Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
+ destruct x0.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ A → B → C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply AndImpLRule_I. apply list_exch_L_id.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ A → B → C :: Γ5 ++ x ++ Γ6, D). repeat split.
pose (list_exch_LI Γ2 x [] (A → B → C :: Γ5) Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
{ simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5) ++ A → B → C :: Γ4 ++ x ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5) (Γ4 ++ x ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 x (A → B → C :: Γ4) Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto. }
* simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ A → B → C :: x0 ++ Γ6, D). repeat split.
pose (AndImpLRule_I A B C D (Γ2 ++ Γ5 ++ Γ4 ++ x) (x0 ++ Γ6)). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in a ; simpl in a ; auto.
pose (list_exch_LI Γ2 (x ++ A → B → C :: x0) Γ4 Γ5 Γ6 D). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in l ; simpl in l ; auto.
Qed.
Lemma OrImpL_app_list_exchL : forall s se ps,
(@list_exch_L s se) ->
(OrImpLRule [ps] s) ->
(existsT2 pse, (OrImpLRule [pse] se) *
((@list_exch_L ps pse) + (existsT2 pse1, (@list_exch_L ps pse1) * (@list_exch_L pse1 pse)))).
Proof.
intros s se ps exch RA. inversion RA. subst. inversion exch. subst. symmetry in H0.
apply app2_find_hole in H0. destruct H0. repeat destruct s ; destruct p ; subst.
- destruct Γ4.
+ simpl in e0. subst. simpl. destruct Γ5.
* simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists (Γ0 ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto. left. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ0 ++ A → C :: Γ6 ++ B → C :: Γ7, D). repeat split. left. apply list_exch_L_id.
- exists (Γ0 ++ A → C :: (Γ6 ++ x0) ++ B → C :: Γ2, D). repeat split. 2: left. 2: apply list_exch_L_id.
assert (Γ0 ++ (A ∨ B) → C :: Γ6 ++ x0 ++ Γ2 =Γ0 ++ (A ∨ B) → C :: (Γ6 ++ x0) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I.
- exists (Γ0 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7, D). repeat split. 2: left. 2: apply list_exch_L_id. repeat rewrite <- app_assoc.
apply OrImpLRule_I. }
* simpl in e0. inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists (Γ0 ++ Γ6 ++ (A→ C :: Γ5) ++ B→ C :: Γ7, D) . repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ5 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ5 ++ [B → C]) [] Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6) ++ A→ C :: Γ5 ++ B→ C :: Γ7, D). split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ5 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ5) [] Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6) ++ A → C :: (Γ5 ++ x1) ++ B → C :: Γ2, D). split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) (Γ5 ++ x1) Γ2). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ5) [] Γ6 (x1 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ x0 ++ x1) ++ A → C :: Γ5 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x0 ++ x1) Γ5 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
exists (Γ0 ++ x1++ A → C :: (Γ5 ++ x0) ++ B → C :: Γ7, D). repeat split.
pose (list_exch_LI Γ0 [] (A → C :: Γ5 ++ x0 ++ [B → C]) x1 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (x1 ++ A → C :: Γ5) x0 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ1 (x0 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl ; rewrite <- app_assoc in o ; simpl in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ1 ++ B → C :: x0) [] Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
+ inversion e0. subst. symmetry in H1. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 Γ7). repeat rewrite <- app_assoc ; simpl ; repeat rewrite <- app_assoc in o ; simpl in o ; auto.
exists (Γ0 ++ Γ5 ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7, D). repeat split.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ [B → C]) Γ5 (Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (Γ5 ++ A → C :: Γ1 ++ [B → C]) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 (x0 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ Γ5 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ6 ++ Γ7, D). repeat split.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ B → C :: x0) Γ5 (Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (Γ5 ++ A → C :: Γ1 ++ B → C :: x0) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
* symmetry in e1. apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ0 ++ Γ6 ++ x0) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ x0) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ x0 ++ A → C :: Γ4 ++ B → C :: Γ6 ++ Γ7, D). split.
pose (list_exch_LI Γ0 [] (A → C :: Γ4) x0 (B → C :: Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 [] (x0 ++ A → C :: Γ4 ++ [B → C]) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6 ++ x0 ++ x1) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ x0 ++ x1) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ A → C :: Γ4 ++ B → C :: x0 ++ x1 ++ Γ6 ++ Γ7, D). split.
pose (list_exch_LI (Γ0 ++ A → C :: Γ4) x0 [B → C] [] (x1 ++ Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4 ++ [B → C]) (x0 ++ x1) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6 ++ Γ5) ++ A→ C :: Γ4 ++ B→ C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: (Γ4 ++ x0) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) (Γ4 ++ x0) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (x0 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ x1 ++ x0 ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x1 ++ x0 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists ((Γ0 ++ A → C :: Γ4 ++ Γ5 ++ x1) ++ [] ++ x0 ++ [B → C] ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI (Γ0 ++ A → C :: Γ4 ++ Γ5 ++ x1) [] [B → C] x0 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 (x1 ++ x0) (B → C :: Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
- destruct x ; simpl in e0 ; subst ; repeat rewrite <- app_assoc ; simpl.
* destruct Γ4.
+ simpl in e0. subst. simpl. destruct Γ5.
{ simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists (Γ0 ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto. left. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ0 ++ A → C :: Γ1 ++ B → C :: Γ2, D). repeat split. left. apply list_exch_L_id.
- exists (Γ0 ++ A → C :: Γ1 ++ B → C :: x ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left. apply list_exch_L_id.
- exists (Γ0 ++ A → C :: (Γ6 ++ x) ++ B → C :: Γ2, D). repeat split. 2: left. 2: apply list_exch_L_id.
assert (Γ0 ++ (A ∨ B) → C :: Γ6 ++ x ++ Γ2 =Γ0 ++ (A ∨ B) → C :: (Γ6 ++ x) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. } }
{ simpl in e0. inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ0 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: Γ7, D) . repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ1 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ [B → C]) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: x ++ Γ7, D). split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ1 (x ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ1 ++ B → C :: x) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6) ++ A → C :: Γ5 ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) Γ5 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ5) Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6) ++ A → C :: (Γ5 ++ x0) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6) (Γ5 ++ x0) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 [] (A → C :: Γ5) Γ6 (x0 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ x ++ x0) ++ A → C :: Γ5 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x ++ x0) Γ5 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ x0 ++ A → C :: (Γ5 ++ x) ++ B → C :: Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ5 ++ x ++ [B → C]) [] x0 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (x0 ++ A → C :: Γ5) [] x (B → C :: Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. } }
+ inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ1 ++ [B → C]) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: x ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ1 (x ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ1 ++ B → C :: x) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ [] ++ Γ5 ++ (A → C :: Γ4) ++ B → C :: Γ6 ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ4) [] Γ5 (B → C :: Γ6 ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI Γ0 (Γ5 ++ A → C :: Γ4 ++ [B → C]) [] Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
* exists ((Γ0 ++ Γ6 ++ Γ5) ++ A → C :: (Γ4 ++ x) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ Γ5) (Γ4 ++ x) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 Γ6 (x ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
* exists ((Γ0 ++ x0 ++ x ++ Γ5) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ x0 ++ x ++ Γ5) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ x0 ++ Γ5 ++ (A → C :: Γ4) ++ B → C :: x ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ4) Γ5 x0 (B → C :: x ++ Γ7) D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI (Γ0 ++ x0) [] (Γ5 ++ A → C :: Γ4 ++ [B → C]) x Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists ((Γ0 ++ Γ6 ++ x ++ x0) ++ A → C :: Γ4 ++ B → C :: Γ7, D). repeat split. 2: right.
pose (OrImpLRule_I A B C D (Γ0 ++ Γ6 ++ x ++ x0) Γ4 Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; rewrite <- app_assoc in o) ; auto.
exists (Γ0 ++ Γ6 ++ (x ++ B → C :: x0) ++ (A → C :: Γ4) ++ Γ7, D). repeat split ; simpl.
pose (list_exch_LI Γ0 (A → C :: Γ4) (x ++ B → C :: x0) Γ6 Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto.
pose (list_exch_LI (Γ0 ++ Γ6 ++ x) [B → C] (x0 ++ A → C :: Γ4) [] Γ7 D). repeat (simpl ; rewrite <- app_assoc ; simpl) ; repeat (simpl in l ; rewrite <- app_assoc in l ; simpl in l) ; auto. }
* inversion e0 ; subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+ exists (Γ0 ++ A → C :: (Γ1 ++ Γ6 ++ Γ5) ++ B → C :: Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (Γ1 ++ Γ6 ++ Γ5) (Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: Γ1) (B → C :: Γ4) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ exists (Γ0 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ6 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat split. repeat rewrite <- app_assoc. apply OrImpLRule_I. left.
pose (list_exch_LI (Γ0 ++ A → C :: Γ1 ++ B → C :: x0) Γ4 Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
{ exists (Γ0 ++ A → C :: (x ++ Γ6) ++ B → C :: Γ5 ++ Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6) (Γ5 ++ Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 (B → C :: Γ5) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5) ++ B → C :: Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5) (Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 (Γ5 ++ [B → C]) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
+ exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5 ++ Γ4) ++ B → C :: Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5 ++ Γ4) Γ7). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 Γ5 Γ6 (B → C :: Γ7) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5 ++ Γ4 ++ x1) Γ2). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 Γ5 Γ6 (x1 ++ B → C :: Γ2) D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
+ exists (Γ0 ++ A → C :: (x ++ x0) ++ B → C :: x1 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ x0) (x1 ++ Γ5 ++ Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 Γ5 (x0 ++ B → C :: x1) Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto.
- exists (Γ0 ++ A → C :: (x ++ Γ6 ++ x1) ++ B → C :: x0 ++ Γ4 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ x1) (x0 ++ Γ4 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) Γ4 (x1 ++ B → C :: x0) Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
{ exists (Γ0 ++ A → C :: (x ++ Γ6 ++ Γ5 ++ x0) ++ B → C :: x1 ++ Γ7, D). repeat split. 2: left.
pose (OrImpLRule_I A B C D Γ0 (x ++ Γ6 ++ Γ5 ++ x0) (x1 ++ Γ7)). repeat (simpl ; rewrite <- app_assoc) ; repeat (simpl in o ; repeat rewrite <- app_assoc in o) ; auto.
pose (list_exch_LI (Γ0 ++ A → C :: x) (x0 ++ B → C :: x1) Γ5 Γ6 Γ7 D). repeat rewrite <- app_assoc ; simpl ; repeat (repeat rewrite <- app_assoc in l ; simpl in l) ; auto. }
(* STOPPED CLEANING PROOF HERE. *)
- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
* destruct Γ5.
+ simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left. apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ3 ++ A → C :: (Γ1 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ1 ++ Γ4 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ1 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (A → C :: Γ1) ++ [] ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert (Γ3 ++ A → C :: (Γ1 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ [] ++ (A → C :: Γ1) ++ Γ4 ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ4 ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left.
assert (Γ3 ++ Γ4 ++ A → C :: Γ1 ++ B → C :: x ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ1 ++ B → C :: x) ++ [] ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ4 ++ Γ7 = Γ3 ++ [] ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: (Γ6 ++ Γ4 ++ x) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ Γ4 ++ x ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ Γ4 ++ x) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ6 ++ x) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (A → C :: Γ6) ++ [] ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ Γ4 ++ x) ++ B → C :: Γ2 = Γ3 ++ [] ++ (A → C :: Γ6) ++ Γ4 ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
+ simpl in e0. inversion e0. subst. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ3 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: Γ4 ++ Γ7, D) . repeat split. 2: left.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ1) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto. rewrite H.
apply OrImpLRule_I.
assert ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ1 ++ [B → C]) ++ Γ6 ++ Γ7). repeat rewrite <- app_assoc.
simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ [B → C]) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc.
simpl. repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ exists ((Γ3 ++ Γ6) ++ A→ C :: Γ1 ++ B→ C :: x ++ Γ4 ++ Γ7, D). split. 2: left.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ1 ++ x) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ x ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto.
simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply OrImpLRule_I.
assert ((Γ3 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: x ++ Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x ++ Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4) ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ5) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ Γ4) ++ Γ7). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ5 ++ Γ6) ++ B → C :: Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ5) ++ Γ6 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4) ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ Γ4 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ Γ6 ++ ((A ∨ B) → C :: Γ5) ++ Γ4 ++ x1 ++ Γ2 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ Γ4 ++ x1) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ5 ++ Γ6 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (A → C :: Γ5) ++ Γ6 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ Γ4 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ x ++ x1) ++ A → C :: Γ5 ++ B → C :: Γ4 ++ Γ7, D). repeat split.
assert (Γ3 ++ (x ++ x1) ++ ((A ∨ B) → C :: Γ5) ++ Γ4 ++ Γ7 = (Γ3 ++ x ++ x1) ++ (A ∨ B) → C :: Γ5 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. right. exists (Γ3 ++ (x ++ B → C :: x1) ++ (A → C :: Γ5) ++ Γ4 ++ Γ7, D). split.
assert ((Γ3 ++ Γ4) ++ A → C :: (Γ5 ++ x) ++ B → C :: x1 ++ Γ7 = Γ3 ++ Γ4 ++ (A → C :: Γ5) ++ (x ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x ++ B → C :: x1) ++ (A → C :: Γ5) ++ Γ4 ++ Γ7 = (Γ3 ++ x) ++ [B → C] ++ (x1 ++ A → C :: Γ5) ++ [] ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x ++ x1) ++ A → C :: Γ5 ++ B → C :: Γ4 ++ Γ7 = (Γ3 ++ x) ++ [] ++ (x1 ++ A → C :: Γ5) ++ [B → C] ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
* apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+ simpl in e0. simpl. destruct Γ6.
{ simpl in e0. subst. simpl. exists ((Γ3 ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ Γ5 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ5 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ [] ++ Γ5 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert ((Γ3 ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ5 ++ [] ++ Γ4 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. simpl. apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists (Γ3 ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ1 ++ Γ5 ++ Γ4 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ1 ++ Γ5 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (A → C :: Γ1) ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert (Γ3 ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ1) ++ Γ5 ++ Γ4 ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left.
assert (Γ3 ++ Γ4 ++ Γ5 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7 = Γ3 ++ Γ4 ++ Γ5 ++ (A → C :: Γ1 ++ B → C :: x0) ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ5 ++ Γ4 ++ Γ7 = Γ3 ++ (A → C :: Γ1 ++ B → C :: x0) ++ Γ5 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- exists (Γ3 ++ A → C :: (Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ Γ5 ++ Γ4 ++ x0 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5) ++ A → C :: (Γ6 ++ x0) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (A → C :: Γ6) ++ x0 ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ6) ++ Γ5 ++ Γ4 ++ x0 ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
+ subst. apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D) . repeat split. 2: left.
assert (Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ6 ++ Γ5 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto. rewrite H.
apply OrImpLRule_I. repeat rewrite <- app_assoc ; apply list_exch_LI. }
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split. 2: left.
assert (Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ x0 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ Γ6 ++ Γ5 ++ Γ4 ++ x0) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. repeat rewrite <- app_assoc ; apply list_exch_LI. }
{ destruct x0 ; simpl in e0 ; inversion e0 ; subst.
- repeat rewrite <- app_assoc ; simpl. exists ((Γ3 ++ x ++ Γ5 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ x ++ Γ5 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ x ++ Γ5 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H0. apply OrImpLRule_I. left. repeat rewrite <- app_assoc ; apply list_exch_LI.
- apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
+ exists((Γ3 ++ x) ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (x ++ (A ∨ B) → C :: Γ1) ++ Γ5 ++ Γ4 ++ Γ2 = (Γ3 ++ x) ++ (A ∨ B) → C :: (Γ1 ++ Γ5 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (x ++ A → C :: Γ1) ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x) ++ A → C :: (Γ1 ++ Γ5 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ (x ++ A → C :: Γ1) ++ Γ5 ++ Γ4 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ5 ++ Γ4 ++ Γ7, D). repeat split.
assert (Γ3 ++ (x ++ (A ∨ B) → C :: Γ1 ++ x1) ++ Γ5 ++ Γ4 ++ Γ7 = (Γ3 ++ x) ++ (A ∨ B) → C :: Γ1 ++ x1 ++ Γ5 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. auto.
simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ7 = Γ3 ++ Γ4 ++ Γ5 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ5 ++ Γ4 ++ Γ7 = Γ3 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ5 ++ Γ4 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ5 ++ Γ4 ++ x1 ++ Γ2 = (Γ3 ++ x) ++ (A ∨ B) → C :: (x0 ++ Γ5 ++ Γ4 ++ x1) ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ Γ5 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ Γ5 ++ (x ++ A → C :: x0) ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ4 ++ x1) ++ B → C :: Γ2 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ Γ4 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
+ destruct x ; simpl in e0 ; inversion e0 ; subst.
{ destruct Γ6.
- simpl in e0. subst. simpl in H0. simpl. repeat rewrite <- app_assoc. simpl.
exists ((Γ3 ++ x0 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ x0 ++ Γ4 ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ x0 ++ Γ4) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ [] ++ x0 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert ((Γ3 ++ x0 ++ Γ4) ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ x0 ++ [] ++ Γ4 ++ A → C :: Γ1 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H1. apply list_exch_LI.
- simpl in e0. inversion e0. clear H0. subst. simpl. repeat rewrite <- app_assoc. simpl.
apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
+ exists (Γ3 ++ A → C :: (Γ1 ++ x0 ++ Γ4) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ1 ++ x0 ++ Γ4 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ1 ++ x0 ++ Γ4) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ x0 ++ (A → C :: Γ1) ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H.
assert (Γ3 ++ A → C :: (Γ1 ++ x0 ++ Γ4) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ1) ++ x0 ++ Γ4 ++ (B → C :: Γ2)). repeat rewrite <- app_assoc ; auto.
rewrite H0. apply list_exch_LI.
+ exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ x0 ++ Γ4 ++ Γ7, D). repeat rewrite <- app_assoc. repeat split. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: Γ1 ++ B → C :: x ++ Γ7 = Γ3 ++ Γ4 ++ x0 ++ (A → C :: Γ1 ++ B → C :: x) ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ x0 ++ Γ4 ++ Γ7 = Γ3 ++ (A → C :: Γ1 ++ B → C :: x) ++ x0 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
+ exists (Γ3 ++ A → C :: (Γ6 ++ x0 ++ Γ4 ++ x) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ x0 ++ Γ4 ++ x ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ x0 ++ Γ4 ++ x) ++ Γ2). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ Γ4 ++ x0 ++ A → C :: (Γ6 ++ x) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ x0 ++ (A → C :: Γ6) ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ x0 ++ Γ4 ++ x) ++ B → C :: Γ2 = Γ3 ++ (A → C :: Γ6) ++ x0 ++ Γ4 ++ x ++ B → C :: Γ2). repeat rewrite <- app_assoc. simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
{ apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
- exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ4 ++ Γ7, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: Γ1) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: Γ1 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: Γ1 ++ [B → C]) ++ Γ6 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: Γ1 ++ [B → C]) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ4 ++ Γ7, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: Γ1 ++ x1) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: Γ1 ++ x1 ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ6 ++ Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ6 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ4 ++ Γ7 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
+ exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4) ++ B → C :: Γ7, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: x) ++ Γ4 ++ Γ7 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: (x ++ Γ4) ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: (x ++ Γ6) ++ B → C :: Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: x) ++ Γ6 ++ B → C :: Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4) ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: x) ++ Γ4 ++ B → C :: Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4 ++ x2) ++ B → C :: Γ2, D). split ;auto.
assert (Γ3 ++ Γ6 ++ (x0 ++ (A ∨ B) → C :: x) ++ Γ4 ++ x2 ++ Γ2 = (Γ3 ++ Γ6 ++ x0) ++ (A ∨ B) → C :: (x ++ Γ4 ++ x2) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: (x ++ Γ6 ++ x2) ++ B → C :: Γ2 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: x) ++ Γ6 ++ x2 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x0) ++ A → C :: (x ++ Γ4 ++ x2) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ (x0 ++ A → C :: x) ++ Γ4 ++ x2 ++ B → C :: Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI.
+ exists ((Γ3 ++ x1 ++ x2 ++ x0) ++ A → C :: x ++ B → C :: Γ4 ++ Γ7, D). split ;auto.
assert (Γ3 ++ (x1 ++ x2) ++ (x0 ++ (A ∨ B) → C :: x) ++ Γ4 ++ Γ7 = (Γ3 ++ x1 ++ x2 ++ x0) ++ (A ∨ B) → C :: x ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ (x1 ++ B → C :: x2) ++ (x0 ++ A → C :: x) ++ Γ4 ++ Γ7, D). split.
assert ((Γ3 ++ Γ4 ++ x0) ++ A → C :: (x ++ x1) ++ B → C :: x2 ++ Γ7 = Γ3 ++ Γ4 ++ (x0 ++ A → C :: x) ++ (x1 ++ B → C :: x2) ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x1 ++ B → C :: x2) ++ (x0 ++ A → C :: x) ++ Γ4 ++ Γ7 = (Γ3 ++ x1) ++ [B → C] ++ (x2 ++ x0 ++ A → C :: x) ++ [] ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H.
assert ((Γ3 ++ x1 ++ x2 ++ x0) ++ A → C :: x ++ B → C :: Γ4 ++ Γ7 = (Γ3 ++ x1) ++ [] ++ (x2 ++ x0 ++ A → C :: x) ++ [B → C] ++ Γ4 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H0. apply list_exch_LI. }
* destruct x0 ; simpl in e0 ; inversion e0 ; subst.
+ destruct Γ5 ; simpl in e0 ; inversion e0 ; subst.
{ destruct Γ6.
- simpl in H1. subst. repeat rewrite <- app_assoc. simpl.
exists ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ x ++ (A ∨ B) → C :: Γ1 ++ Γ2 = (Γ3 ++ x) ++ (A ∨ B) → C :: Γ1 ++ Γ2). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left. repeat rewrite <- app_assoc. apply list_exch_L_id.
- simpl in H1. inversion H1. subst. apply app2_find_hole in H3. destruct H3. repeat destruct s ; destruct p ; subst.
* repeat rewrite <- app_assoc. simpl. exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ2, D). repeat split. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: Γ2 = Γ3 ++ x ++ (A → C :: Γ1 ++ [B → C]) ++ [] ++ Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x ++ Γ2 = Γ3 ++ [] ++ (A → C :: Γ1 ++ [B → C]) ++ x ++ Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H2. apply list_exch_LI.
* repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
exists (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7, D). repeat split. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ7 = Γ3 ++ x ++ (A → C :: Γ1 ++ B → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ3 ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7 = Γ3 ++ [] ++ (A → C :: Γ1 ++ B → C :: x0) ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H2. apply list_exch_LI.
* repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
exists (Γ3 ++ A → C :: (Γ6 ++ x ++ x0) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ (A ∨ B) → C :: Γ6 ++ x ++ x0 ++ Γ2 = Γ3 ++ (A ∨ B) → C :: (Γ6 ++ x ++ x0) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ6 ++ x0 ++ B → C :: Γ2 = Γ3 ++ x ++ (A → C :: Γ6) ++ [] ++ x0 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ3 ++ A → C :: (Γ6 ++ x ++ x0) ++ B → C :: Γ2 = Γ3 ++ [] ++ (A → C :: Γ6) ++ x ++ x0 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H2. apply list_exch_LI. }
{ apply app2_find_hole in H2. destruct H2. repeat destruct s ; destruct p ; subst.
- repeat rewrite <- app_assoc. simpl. exists ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x ++ Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ1 ++ x ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ x ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ x ++ (A → C :: Γ1 ++ [B → C]) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ [B → C]) ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
- repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc.
exists ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ1 ++ x0 ++ x ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: Γ1 ++ x0 ++ x ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ1 ++ B → C :: x0 ++ Γ6 ++ Γ7 = Γ3 ++ x ++(A → C :: Γ1 ++ B → C :: x0) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: Γ1 ++ B → C :: x0 ++ x ++ Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ1 ++ B → C :: x0) ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
- repeat rewrite <- app_assoc. simpl. apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
* exists ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ x) ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ5 ++ x ++ Γ7 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ x) ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ5 ++ Γ6 ++ B → C :: Γ7 = Γ3 ++ x ++ (A → C :: Γ5) ++ Γ6 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ x) ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ x ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
* exists ((Γ3 ++ Γ6) ++ A→ C :: (Γ5 ++ x ++ x1) ++ B→ C :: Γ2, D). repeat split.
assert (Γ3 ++ Γ6 ++ (A ∨ B) → C :: Γ5 ++ x ++ x1 ++ Γ2 = (Γ3 ++ Γ6) ++ (A ∨ B) → C :: (Γ5 ++ x ++ x1) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert (Γ3 ++ x ++ A → C :: Γ5 ++ (Γ6 ++ x1) ++ B → C :: Γ2 = Γ3 ++ x ++ (A → C :: Γ5) ++ Γ6 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6) ++ A → C :: (Γ5 ++ x ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ (A → C :: Γ5) ++ x ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI.
* exists ((Γ3 ++ x0 ++ x1) ++ A → C :: Γ5 ++ B → C :: x ++ Γ7, D). repeat split.
assert (Γ3 ++ (x0 ++ x1) ++ (A ∨ B) → C :: Γ5 ++ x ++ Γ7 = (Γ3 ++ x0 ++ x1) ++ (A ∨ B) → C :: Γ5 ++ x ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ (x0 ++ B → C :: x1) ++ (A → C :: Γ5) ++ x ++ Γ7, D). split.
assert (Γ3 ++ x ++ A → C :: Γ5 ++ x0 ++ B → C :: x1 ++ Γ7 = Γ3 ++ x ++ (A → C :: Γ5) ++ (x0 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x0 ++ B → C :: x1) ++ (A → C :: Γ5) ++ x ++ Γ7 = (Γ3 ++ x0) ++ [B → C] ++ (x1 ++ A → C :: Γ5) ++ [] ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x0 ++ x1) ++ A → C :: Γ5 ++ B → C :: x ++ Γ7 = (Γ3 ++ x0) ++ [] ++ (x1 ++ A → C :: Γ5) ++ [B → C] ++ x ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H1. apply list_exch_LI. }
+ apply app2_find_hole in H1. destruct H1. repeat destruct s ; destruct p ; subst.
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: Γ1) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: Γ1 ++ Γ7). repeat rewrite <- app_assoc. auto.
rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ5 ++ Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: Γ1 ++ [B → C]) ++ Γ5 ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: Γ1 ++ [B → C]) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
{ exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: Γ1 ++ x1) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: Γ1 ++ x1 ++ Γ7). repeat rewrite <- app_assoc. auto.
simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ5 ++ Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ5 ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: Γ1 ++ B → C :: x1 ++ Γ7 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: Γ1 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
{ apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
- exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ Γ6 ++ (Γ5 ++ [B → C]) ++ (x ++ A → C :: x0) ++ Γ7, D). split.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5) ++ B → C :: Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ (Γ5 ++ [B → C]) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ Γ6 ++ (Γ5 ++ [B → C]) ++ (x ++ A → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5) ++ [B → C] ++ (x ++ A → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = (Γ3 ++ Γ6 ++ Γ5) ++ [] ++ (x ++ A → C :: x0) ++ [B → C] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- apply app2_find_hole in e1. destruct e1. repeat destruct s ; destruct p ; subst.
* exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ6) ++ B → C :: Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ Γ6 ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: x0) ++ B → C :: Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
* exists ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: Γ2, D). repeat split.
assert (Γ3 ++ Γ6 ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ x1 ++ Γ2 = (Γ3 ++ Γ6 ++ Γ5 ++ x) ++ (A ∨ B) → C :: (x0 ++ x1) ++ Γ2). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. left.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ Γ6 ++ x1) ++ B → C :: Γ2 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ Γ6 ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ Γ5 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: Γ2 = Γ3 ++ Γ6 ++ Γ5 ++ (x ++ A → C :: x0) ++ x1 ++ B → C :: Γ2).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
* exists ((Γ3 ++ x2 ++ x1 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ (x2 ++ x1) ++ Γ5 ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ x2 ++ x1 ++ Γ5 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists (Γ3 ++ (x2 ++ B → C :: x1) ++ Γ5 ++ (x ++ A → C :: x0) ++ Γ7, D). split.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ Γ5 ++ x2) ++ B → C :: x1 ++ Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ Γ5 ++ (x2 ++ B → C :: x1) ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ (x2 ++ B → C :: x1) ++ Γ5 ++ (x ++ A → C :: x0) ++ Γ7 = (Γ3 ++ x2) ++ [B → C] ++ (x1 ++ Γ5 ++ x ++ A → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ x2 ++ x1 ++ Γ5 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = (Γ3 ++ x2) ++ [] ++ (x1 ++ Γ5 ++ x ++ A → C :: x0) ++ [B → C] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI.
- exists ((Γ3 ++ Γ6 ++ x1 ++ x2 ++ x) ++ A → C :: x0 ++ B → C :: Γ7, D). repeat split.
assert (Γ3 ++ Γ6 ++ (x1 ++ x2) ++ (x ++ (A ∨ B) → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ x1 ++ x2 ++ x) ++ (A ∨ B) → C :: x0 ++ Γ7). repeat rewrite <- app_assoc ; simpl.
repeat rewrite <- app_assoc ; auto. rewrite H. apply OrImpLRule_I. right.
exists(Γ3 ++ Γ6 ++ (x1 ++ B → C :: x2) ++ (x ++ A → C :: x0) ++ Γ7, D). split.
assert ((Γ3 ++ x) ++ A → C :: (x0 ++ x1) ++ B → C :: x2 ++ Γ6 ++ Γ7 = Γ3 ++ (x ++ A → C :: x0) ++ (x1 ++ B → C :: x2) ++ Γ6 ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H. apply list_exch_LI.
assert (Γ3 ++ Γ6 ++ (x1 ++ B → C :: x2) ++ (x ++ A → C :: x0) ++ Γ7 = (Γ3 ++ Γ6 ++ x1) ++ [B → C] ++ (x2 ++ x ++ A → C :: x0) ++ [] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ3 ++ Γ6 ++ x1 ++ x2 ++ x) ++ A → C :: x0 ++ B → C :: Γ7 = (Γ3 ++ Γ6 ++ x1) ++ [] ++ (x2 ++ x ++ A → C :: x0) ++ [B → C] ++ Γ7).
repeat rewrite <- app_assoc. simpl. repeat rewrite <- app_assoc. auto. rewrite H0. apply list_exch_LI. }
Qed.
Lemma ImpImpL_app_list_exchL : forall s se ps1 ps2,
(@list_exch_L s se) ->
(ImpImpLRule [ps1;ps2] s) ->
(existsT2 pse1 pse2,
(ImpImpLRule [pse1;pse2] se) *
(@list_exch_L ps1 pse1) *
(@list_exch_L ps2 pse2)).
Proof.
intros s se ps1 ps2 exch RA. inversion RA. subst. inversion exch. subst. symmetry in H0.
apply app2_find_hole in H0. destruct H0. repeat destruct s ; destruct p ; subst.
- destruct Γ3.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists (Γ0 ++ B → C :: Γ1, A → B). exists (Γ0 ++ C :: Γ1, D). repeat split ; try apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ0 ++ B → C :: Γ5 ++ Γ6, A → B). exists (Γ0 ++ C :: Γ5 ++ Γ6, D). repeat split ; try apply list_exch_L_id. }
* simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ B → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ ((A → B) → C :: Γ4) ++ Γ6 = (Γ0 ++ Γ5) ++ (A → B) → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (B → C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ B → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ Γ4 ++ ((A → B) → C :: Γ3) ++ Γ6 =( Γ0 ++ Γ5 ++ Γ4) ++ (A → B) → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (B → C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (B → C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
- destruct x.
+ simpl in e0. subst. simpl. destruct Γ3.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. subst. simpl. rewrite <- e0. exists ((Γ0 ++ []) ++ B → C :: Γ1, A → B). exists ((Γ0 ++ []) ++ C :: Γ1, D). repeat split ; rewrite <- app_assoc ; simpl ; try apply list_exch_L_id. }
{ simpl in e0. inversion e0. subst. simpl. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ B → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ (A → B) → C :: Γ4 ++ Γ6 = (Γ0 ++ Γ5) ++ (A → B) → C :: Γ4 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ B → C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (B → C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ [] ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ C :: Γ4 ++ Γ6 = Γ0 ++ Γ5 ++ (C :: Γ4) ++ [] ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* simpl in e0. inversion e0. subst. rewrite <- app_assoc ; simpl. exists (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6, A → B). exists (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6, D). repeat split.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ B → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
assert (Γ0 ++ Γ5 ++ Γ4 ++ (A → B) → C :: Γ3 ++ Γ6 = (Γ0 ++ Γ5 ++ Γ4) ++ (A → B) → C :: Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H1.
apply ImpImpLRule_I.
assert (Γ0 ++ B → C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (B → C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ B → C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (B → C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = Γ0 ++ (C :: Γ3) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ Γ5 ++ Γ4 ++ C :: Γ3 ++ Γ6 = Γ0 ++ Γ5 ++ Γ4 ++ (C :: Γ3) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
+ simpl in e0. inversion e0. subst. exists (Γ0 ++ B → C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, A → B). exists (Γ0 ++ C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat rewrite <- app_assoc. repeat split.
assert (Γ0 ++ B → C :: x ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ0 ++ B → C :: x) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ B → C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ0 ++ B → C :: x) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ0 ++ C :: x ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6 = (Γ0 ++ C :: x) ++ Γ3 ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ0 ++ C :: x ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ0 ++ C :: x) ++ Γ5 ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
- apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
+ simpl in e0. subst. simpl. destruct Γ4.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ3) ++ B → C :: Γ1, A → B). exists ((Γ2 ++ Γ3) ++ C :: Γ1, D). repeat split ; try apply list_exch_L_id. rewrite app_assoc.
apply ImpImpLRule_I. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ B → C :: Γ5 ++ Γ3 ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ Γ3 ++ Γ6, D). repeat split.
assert ((Γ2 ++ Γ3) ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ (B → C :: Γ5) ++ [] ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3) ++ C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ [] ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ Γ3 ++ Γ6 = Γ2 ++ (C :: Γ5) ++ [] ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ Γ3 ++ Γ6, A → B). exists ((Γ2 ++ Γ5) ++ C :: Γ4 ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ ((A → B) → C :: Γ4) ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5) ++ (A → B) → C :: Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert ((Γ2 ++ Γ3) ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (B → C :: Γ4) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3) ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ C :: Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (C :: Γ4) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
+ apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
* simpl in e0. simpl. destruct Γ5.
{ simpl in e0. subst. simpl. exists ((Γ2 ++ Γ4 ++ Γ3) ++ B → C :: Γ1, A → B). exists ((Γ2 ++ Γ4 ++ Γ3) ++ C :: Γ1, D). repeat split.
assert (Γ2 ++ Γ4 ++ Γ3 ++ (A → B) → C :: Γ1 = (Γ2 ++ Γ4 ++ Γ3) ++ (A → B) → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ B → C :: Γ1 = Γ2 ++ Γ3 ++ Γ4 ++ [] ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ4 ++ Γ3) ++ B → C :: Γ1 = Γ2 ++ [] ++ Γ4 ++ Γ3 ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ C :: Γ1 = Γ2 ++ Γ3 ++ Γ4 ++ [] ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ4 ++ Γ3) ++ C :: Γ1 = Γ2 ++ [] ++ Γ4 ++ Γ3 ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. simpl. exists (Γ2 ++ B → C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (B → C :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3 ++ Γ4) ++ C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (C :: Γ5) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* apply app2_find_hole in e0. destruct e0. repeat destruct s ; destruct p ; subst.
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ B → C :: Γ1, A → B). exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply ImpImpLRule_I. }
{ repeat rewrite <- app_assoc. exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ B → C :: Γ1, A → B). exists (Γ2 ++ Γ5 ++ Γ4 ++ Γ3 ++ x0 ++ C :: Γ1, D). repeat split. repeat rewrite app_assoc. apply ImpImpLRule_I. }
{ destruct x0.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ Γ4 ++ Γ3 ++ B → C :: Γ1, A → B). exists (Γ2 ++ x ++ Γ4 ++ Γ3 ++ C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply ImpImpLRule_I.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ x) ++ B → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6, A → B). exists ((Γ2 ++ x) ++ C :: x0 ++ Γ4 ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ x ++ (A → B) → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = (Γ2 ++ x) ++ (A → B) → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert (Γ2 ++ Γ3 ++ Γ4 ++ x ++ B → C :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ B → C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ x) ++ B → C :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ B → C :: x0) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ Γ3 ++ Γ4 ++ x ++ C :: x0 ++ Γ6 = Γ2 ++ Γ3 ++ Γ4 ++ (x ++ C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ x) ++ C :: x0 ++ Γ4 ++ Γ3 ++ Γ6 = Γ2 ++ (x ++ C :: x0) ++ Γ4 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* destruct x.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x0 ++ Γ3 ++ B → C :: Γ1, A → B). exists (Γ2 ++ x0 ++ Γ3 ++ C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply ImpImpLRule_I.
assert (Γ2 ++ Γ3 ++ x0 ++ B → C :: Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ x0 ++ Γ3 ++ B → C :: Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ B → C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ Γ3 ++ x0 ++ C :: Γ1 = Γ2 ++ Γ3 ++ [] ++ x0 ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ x0 ++ Γ3 ++ C :: Γ1 = Γ2 ++ x0 ++ [] ++ Γ3 ++ C :: Γ1). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ B → C :: Γ5 ++ x0 ++ Γ3 ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ x0 ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ3 ++ x0 ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ x0 ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ x0 ++ Γ3 ++ Γ6 = Γ2 ++ (B → C :: Γ5) ++ x0 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ Γ3 ++ x0 ++ C :: Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ x0 ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ x0 ++ Γ3 ++ Γ6 = Γ2 ++ (C :: Γ5) ++ x0 ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. exists ((Γ2 ++ Γ5 ++ x0) ++ B → C :: x ++ Γ3 ++ Γ6, A → B). exists ((Γ2 ++ Γ5 ++ x0) ++ C :: x ++ Γ3 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ (x0 ++ (A → B) → C :: x) ++ Γ3 ++ Γ6 = (Γ2 ++ Γ5 ++ x0) ++ (A → B) → C :: x ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert ((Γ2 ++ Γ3 ++ x0) ++ B → C :: x ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ B → C :: x) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ x0) ++ B → C :: x ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (x0 ++ B → C :: x) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert ((Γ2 ++ Γ3 ++ x0) ++ C :: x ++ Γ5 ++ Γ6 = Γ2 ++ Γ3 ++ (x0 ++ C :: x) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ x0) ++ C :: x ++ Γ3 ++ Γ6 = Γ2 ++ Γ5 ++ (x0 ++ C :: x) ++ Γ3 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
+ destruct x0.
* simpl in e0. simpl. destruct Γ4.
{ simpl in e0. destruct Γ5.
- simpl in e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ x ++ B → C :: Γ1, A → B). exists (Γ2 ++ x ++ C :: Γ1, D). repeat split.
repeat rewrite app_assoc. apply ImpImpLRule_I. apply list_exch_L_id. apply list_exch_L_id.
- simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists (Γ2 ++ B → C :: Γ5 ++ x ++ Γ6, A → B). exists (Γ2 ++ C :: Γ5 ++ x ++ Γ6, D). repeat split.
assert (Γ2 ++ x ++ B → C :: Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ (B → C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ B → C :: Γ5 ++ x ++ Γ6 = Γ2 ++( B → C :: Γ5) ++ [] ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ x ++ C :: Γ5 ++ Γ6 = Γ2 ++ x ++ [] ++ (C :: Γ5) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert (Γ2 ++ C :: Γ5 ++ x ++ Γ6 = Γ2 ++(C :: Γ5) ++ [] ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
{ simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ x ++ Γ6, A → B). exists ((Γ2 ++ Γ5) ++ C :: Γ4 ++ x ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ (A → B) → C :: Γ4 ++ x ++ Γ6 = (Γ2 ++ Γ5) ++ (A → B) → C :: Γ4 ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert (Γ2 ++ x ++ B → C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ x ++ (B → C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ B → C :: Γ4 ++ x ++ Γ6 = Γ2 ++ Γ5 ++ (B → C :: Γ4) ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ x ++ C :: Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ x ++ (C :: Γ4) ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5) ++ C :: Γ4 ++ x ++ Γ6 = Γ2 ++ Γ5 ++ (C :: Γ4) ++ x ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI. }
* simpl in e0. inversion e0. subst. repeat rewrite <- app_assoc. simpl. exists ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ B → C :: x0 ++ Γ6, A → B). exists ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ C :: x0 ++ Γ6, D). repeat split.
assert (Γ2 ++ Γ5 ++ Γ4 ++ x ++ (A → B) → C :: x0 ++ Γ6 = (Γ2 ++ Γ5 ++ Γ4 ++ x) ++ (A → B) → C :: x0 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
apply ImpImpLRule_I.
assert (Γ2 ++ x ++ B → C :: x0 ++ Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ (x ++ B → C :: x0) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ B → C :: x0 ++ Γ6 = Γ2 ++ Γ5 ++ Γ4 ++ (x ++ B → C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
assert (Γ2 ++ x ++ C :: x0 ++ Γ4 ++ Γ5 ++ Γ6 = Γ2 ++ (x ++ C :: x0) ++ Γ4 ++ Γ5 ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H.
assert ((Γ2 ++ Γ5 ++ Γ4 ++ x) ++ C :: x0 ++ Γ6 = Γ2 ++ Γ5 ++ Γ4 ++ (x ++ C :: x0) ++ Γ6). repeat rewrite <- app_assoc. auto. rewrite H0.
apply list_exch_LI.
Qed.