Require Import List.
Export ListNotations.
Require Import PeanoNat.
Require Import Lia.
Require Import String.
Require Import general_export.
Require Import KS_export.
Require Import UIK_Def_measure.
Require Import UIK_Canopy.
Require Import UIK_irred_short.
Require Import UIK_basics.
Require Import UIK_braga.
Section Prop_Subform.
(* This is copied from the Craig interpolation file. Make a syntax file for interpolations. *)
Fixpoint propvar_subform (A : MPropF) : list MPropF :=
match A with
| Var p => (Var p) :: nil
| Bot => nil
| Imp B C => (propvar_subform B) ++ ( propvar_subform C)
| Box B => ( propvar_subform B)
end.
Fixpoint propvar_subform_list (l : list MPropF) : list MPropF :=
match l with
| nil => nil
| A :: t => (propvar_subform A) ++ (propvar_subform_list t)
end.
(* Lemmas about propvar_subform_list. *)
Lemma propvar_subform_list_app: forall l0 l1,
propvar_subform_list (l0 ++ l1) = (propvar_subform_list l0) ++ (propvar_subform_list l1).
Proof.
induction l0.
- simpl. auto.
- intros. simpl. rewrite (IHl0). rewrite <- app_assoc ; auto.
Qed.
Lemma propvar_subform_list_unboxed_list : forall l A, In A (propvar_subform_list (unboxed_list l)) -> In A (propvar_subform_list l).
Proof.
induction l.
- auto.
- simpl. intros. apply in_app_or in H. destruct H. apply in_or_app ; left. destruct a ; auto.
apply in_or_app ; auto.
Qed.
Lemma propvar_subform_list_nobox_gen_ext : forall l0 l1, nobox_gen_ext l0 l1 ->
(forall A, In A (propvar_subform_list l0) -> In A (propvar_subform_list l1)).
Proof.
intros l0 l1 H. induction H ; auto.
- simpl ; intros. apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto.
- simpl ; intros. apply in_or_app ; auto.
Qed.
Lemma propvar_subform_list_top_boxes : forall l A, In A (propvar_subform_list (top_boxes l)) -> In A (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. destruct a ; simpl in H ; auto. 1-2: apply in_or_app ; apply IHl in H ; auto.
apply in_or_app ; apply in_app_or in H ; destruct H ; simpl ; auto.
Qed.
Lemma propvar_subform_list_conj : forall l A,
In A (propvar_subform (list_conj l)) -> In A (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
apply in_app_or in H. apply in_or_app. destruct H ; auto.
Qed.
Lemma propvar_subform_list_disj : forall l A,
In A (propvar_subform (list_disj l)) -> In A (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
apply in_app_or in H. apply in_or_app. destruct H ; auto.
Qed.
Lemma propvar_subform_list_witness : forall l A,
In A (propvar_subform_list l) -> (exists B, In B l /\ In A (propvar_subform B)).
Proof.
induction l ; simpl ; intros ; auto. inversion H. apply in_app_or in H. destruct H.
exists a ; auto. apply IHl in H. destruct H. exists x ; firstorder.
Qed.
Lemma propvar_subform_list_witnessT : forall l A,
InT A (propvar_subform_list l) -> (existsT2 B, (InT B l) * (InT A (propvar_subform B))).
Proof.
induction l ; simpl ; intros ; auto. inversion H. apply InT_app_or in H. destruct H.
exists a ; auto. split ; auto. apply InT_eq. apply IHl in i. destruct i. exists x ; firstorder. apply InT_cons ; auto.
Qed.
Lemma propvar_subform_list_Canopy : forall s ir A,
In ir (Canopy s) ->
In A (propvar_subform_list (fst ir ++ snd ir)) ->
In A (propvar_subform_list (fst s ++ snd s)).
Proof.
intros s ; induction on s as IHs with measure (n_imp_subformS s).
intros. remember (finite_ImpRules_premises_of_S s) as H1.
destruct H1. destruct x.
- assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH1.
simpl. auto. rewrite H1 in H. inversion H. subst. auto. inversion H2.
- apply In_InT_seqs in H. apply fold_Canopy in H. destruct H ; subst ; auto.
destruct s0. destruct p0. unfold inv_prems in i. destruct (finite_ImpRules_premises_of_S s).
simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1. apply p0 in i1.
apply IHs with (y:=x0) in H0. 3: apply InT_In ; auto.
destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. simpl in H0.
repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; apply in_app_or in H ; destruct H ; auto.
right ; apply in_or_app ; right ; auto.
inversion i1 ; subst. simpl. inversion i ; subst. simpl in H0.
repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
inversion H1 ; subst. 2: inversion H2. simpl in H0.
repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; auto.
right ; apply in_or_app ; right ; apply in_or_app ; right ; auto.
destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. unfold n_imp_subformS ; simpl.
repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
inversion i1. subst. inversion i ; subst. unfold n_imp_subformS ; simpl.
repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
inversion H1. subst. 2: inversion H2. unfold n_imp_subformS ; simpl.
repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
Qed.
Lemma propvar_subform_list_restr_list_prop : forall l p q, In # q (propvar_subform_list (restr_list_prop p l)) ->
((q <> p) * (In # q (propvar_subform_list l))).
Proof.
induction l ; simpl ; intros ; auto. unfold restr_list_prop in H. destruct a as [n | | |]; simpl ; simpl in H ; auto.
destruct (eq_dec_form (# p) (# n)) ; subst. apply IHl in H. destruct H ; auto.
simpl in H. destruct H ; subst ; auto. split ; auto. rewrite H in n0. destruct (string_dec p q) ; subst; auto.
all: apply IHl in H ; destruct H ; auto.
all: split ; auto. all: apply in_or_app ; auto.
Qed.
Lemma In_list_prop_LF: forall l A, In A (list_prop_LF l) -> ((existsT2 q, A = # q) * In A l).
Proof.
induction l ; simpl ; intros ; auto. inversion H. apply In_InT in H. apply InT_app_or in H.
destruct H. destruct a as [n | | |]; simpl in i ; inversion i ; subst ; auto. split ; [exists n ; auto | auto]. inversion H0.
apply InT_In in i ; apply IHl in i ; auto. destruct i ; split ; auto.
Qed.
Lemma list_prop_LF_propvar_subform_list : forall l q, In # q (list_prop_LF l) -> In # q (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. apply in_app_or in H ; destruct H ; auto. apply in_or_app ; left. destruct a ; simpl ; simpl in H ; try firstorder.
apply in_or_app ; right ; apply IHl in H ; auto.
Qed.
Lemma In_list_In_list_prop_LF : forall l P, In # P l -> In # P (list_prop_LF l).
Proof.
induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
Qed.
Lemma In_list_In_propvar_subform_list : forall l P, In # P l -> In # P (propvar_subform_list l).
Proof.
induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
Qed.
End Prop_Subform.
Section Diam_help.
Lemma In_unboxed_list : forall l A, In A (unboxed_list (top_boxes l)) -> (exists B, In B (top_boxes l) /\ B = Box A).
Proof.
induction l ; intros ; auto. simpl in H. exfalso ; auto. destruct a ; simpl ; simpl in H ; auto.
destruct H ; subst. exists (Box A) ; auto.
apply IHl in H. destruct H. firstorder.
Qed.
Lemma unboxed_list_In : forall l A, In (Box A) (top_boxes l) -> In A (unboxed_list (top_boxes l)).
Proof.
induction l ; simpl ; intros ; auto. destruct a ; simpl ; simpl in H ; auto. destruct H. inversion H ; subst. auto.
apply IHl in H ; auto.
Qed.
Lemma unboxed_list_In_unfold : forall l A, (exists B, In B (top_boxes l) /\ B = Box A) -> In A (unboxed_list (top_boxes l)).
Proof.
induction l ; simpl ; intros ; auto. destruct H. destruct H ; auto.
destruct a ; simpl ; simpl in H ; auto. destruct H. destruct H. subst. destruct H.
inversion H ; subst ; auto. right. apply unboxed_list_In ; auto.
Qed.
Lemma remove_list_decr_in: forall [l2 l1 l3 l4: list MPropF], NoDup l4 -> NoDup l3 ->
incl l1 l2 -> incl l3 l4 -> length (remove_list l2 l4) < length (remove_list l1 l3) ->
(exists A : MPropF, In A l2 /\ (In A l1 -> False)).
Proof.
induction l2 ; simpl.
- intros. destruct l1. simpl. simpl in H3. exfalso. pose (NoDup_incl_length H0 H2). simpl in l. lia.
exfalso. pose (H1 m). simpl in i ; apply i ; auto.
- intros. destruct (In_dec l2 a).
+ assert (incl l1 l2). intro. intros. apply H1 in H4. inversion H4 ; subst ; auto.
pose (In_remove_list_remove_redund _ l4 _ i). rewrite e in H3.
pose (IHl2 _ _ _ H H0 H4 H2 H3). destruct e0. destruct H5. exists x ; split ; auto.
+ destruct (In_dec l1 a).
* destruct (In_dec l4 a).
-- destruct (In_dec l3 a).
++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) (remove eq_dec_form a l3))).
rewrite <- In_remove_list_remove_redund with (a:=a). rewrite permut_remove_remove_list.
pose (permut_remove_remove_list a (remove eq_dec_form a l1) l3). rewrite <- e.
pose (redund_remove_remove_list a l1 l3). rewrite e0. rewrite permut_remove_remove_list. auto. auto.
assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
assert (J1: NoDup (remove eq_dec_form a l3)). apply remove_preserv_NoDup ; auto.
assert (J2: incl (remove eq_dec_form a l3) (remove eq_dec_form a l4)). intro. intros.
apply in_remove in H6. destruct H6. apply in_in_remove ; auto.
rewrite H5 in H3. rewrite permut_remove_remove_list in H3.
pose (IHl2 (remove eq_dec_form a l1) _ _ J0 J1 H4 J2 H3). destruct e. destruct H6.
exists x ; split ; auto. intro. apply H7. apply in_in_remove ; auto. intro ; subst. auto.
++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
rewrite permut_remove_remove_list in H3.
assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
assert (J1: incl l3 (remove eq_dec_form a l4)). intro. intros. apply in_in_remove ; auto.
intro ; subst ; auto.
assert (J:length (remove_list l2 (remove eq_dec_form a l4)) < length (remove_list (remove eq_dec_form a l1) l3)).
assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) l3)).
pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e.
symmetry in e. rewrite notin_remove in e. auto.
1-2: intro ; apply In_remove_list_In_list in H5 ; auto. rewrite H5 in H3. auto.
pose (IHl2 (remove eq_dec_form a l1) _ _ J0 H0 H4 J1 J). destruct e. destruct H5.
exists x ; split ; auto. intro. apply H6. apply in_in_remove ; auto. intro ; subst. auto.
-- assert (In a l3 -> False). intro. apply n0 ; auto. rewrite permut_remove_remove_list in H3.
rewrite notin_remove in H3 ; auto.
assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H5. destruct H5.
apply H1 in H5. inversion H5 ; subst ; auto. exfalso ; apply H6 ; auto.
assert (length (remove_list l2 l4) < length (remove_list (remove eq_dec_form a l1) l3)).
pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e. rewrite e. rewrite notin_remove ; auto.
intro. apply In_remove_list_In_list in H6 ; auto. intro. apply In_remove_list_In_list in H6 ; auto.
pose (IHl2 (remove eq_dec_form a l1) _ _ H H0 H5 H2 H6). destruct e. destruct H7.
exists x ; split ; auto. intro. apply H8. apply in_in_remove ; auto. intro ; subst. auto.
* exists a ; split ; auto.
Qed.
End Diam_help.
Section list_conj_disj_properties.
Lemma AndL : forall s A B, KS_prv (A :: B :: fst s, snd s) -> KS_prv (And A B :: fst s, snd s).
Proof.
intros. unfold And. unfold Neg.
apply derI with (ps:=[([] ++ fst s, [] ++ (A --> B --> Bot) :: snd s); ([] ++ Bot :: fst s, [] ++ snd s)]).
apply ImpL. assert (((A --> B --> Bot) --> Bot :: fst s, snd s) = ([] ++ (A --> B --> Bot) --> Bot :: fst s, snd s)). auto.
rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
apply derI with (ps:=[([] ++ A :: fst s, [] ++ B --> Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
apply dlCons. 2: apply dlNil. apply derI with (ps:=[([A] ++ B :: fst s, [] ++ Bot :: snd s)]).
assert (([] ++ A :: fst s, [] ++ B --> Bot :: snd s) = ([A] ++ fst s, [] ++ B --> Bot :: snd s)). auto. rewrite H.
apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R Bot ([A] ++ B :: fst s, [] ++ snd s) ([A] ++ B :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
apply dlNil.
Qed.
Lemma AndR : forall s A B, KS_prv (fst s, A :: snd s) -> KS_prv (fst s, B :: snd s) -> KS_prv (fst s, And A B :: snd s).
Proof.
intros. unfold And. unfold Neg.
apply derI with (ps:=[([] ++ A --> B --> Bot :: fst s, [] ++ Bot :: snd s)]).
apply ImpR. assert ((fst s, (A --> B --> Bot) --> Bot :: snd s) = ([] ++ fst s, [] ++ (A --> B --> Bot) --> Bot :: snd s)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([] ++ fst s, [] ++ A :: Bot :: snd s);([] ++ B --> Bot :: fst s, [] ++ Bot :: snd s)]). apply ImpL.
apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R Bot ([] ++ fst s, [A] ++ snd s) ([] ++ fst s, [A] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto.
apply derI with (ps:=[([] ++ fst s, [] ++ B :: Bot :: snd s);([] ++ Bot :: fst s, [] ++ Bot :: snd s)]). apply ImpL.
apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
assert (J0: derrec_height X0 = derrec_height X0). auto.
assert (J1: wkn_R Bot ([] ++ fst s, [B] ++ snd s) ([] ++ fst s, [B] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X0 J0 _ _ J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
apply dlNil.
Qed.
Lemma list_conj_wkn_L : forall l s A, InT A l -> KS_prv (A :: fst s, snd s) -> KS_prv (list_conj l :: fst s, snd s).
Proof.
induction l.
- intros. inversion H.
- intros. inversion H ; subst.
* simpl. apply AndL.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_L (list_conj l) (A :: fst s, snd s) (A :: list_conj l :: fst s, snd s)).
assert (A :: fst s = [A] ++ fst s). auto. rewrite H0.
assert (A :: list_conj l :: fst s = [A] ++ list_conj l :: fst s). auto. rewrite H1. apply wkn_LI.
pose (KS_wkn_L _ _ X J0 _ _ J1). destruct s0. auto.
* simpl. apply IHl in X ; auto.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_L a (list_conj l :: fst s, snd s) (a :: list_conj l :: fst s, snd s)).
assert (a :: list_conj l :: fst s = [] ++ a :: list_conj l :: fst s). auto. rewrite H0.
assert ((list_conj l :: fst s,snd s) = ([] ++ list_conj l :: fst s,snd s)). auto. rewrite H2. apply wkn_LI.
pose (KS_wkn_L _ _ X J0 _ _ J1). destruct s0. apply AndL ; auto.
Qed.
Lemma list_conj_R : forall l s, (forall A, InT A l -> KS_prv (fst s, A :: snd s)) -> KS_prv (fst s, list_conj l :: snd s).
Proof.
induction l.
- intros. simpl. unfold Top.
apply derI with (ps:=[([] ++ Bot :: fst s, [] ++ Bot :: snd s)]).
apply ImpR. assert ((fst s, Bot --> Bot :: snd s) = ([] ++ fst s, [] ++ Bot --> Bot :: snd s)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL.
apply BotLRule_I. apply dlNil.
- intros. simpl. apply AndR.
* apply X. apply InT_eq.
* simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
Qed.
Lemma OrL : forall s A B, KS_prv (A :: fst s, snd s) -> KS_prv (B :: fst s, snd s) -> KS_prv (Or A B :: fst s, snd s).
Proof.
intros. unfold Or. unfold Neg.
apply derI with (ps:=[([] ++ fst s, [] ++ (A --> Bot) :: snd s); ([] ++ B :: fst s, [] ++ snd s)]).
apply ImpL. assert (((A --> Bot) --> B :: fst s, snd s) = ([] ++ (A --> Bot) --> B :: fst s, snd s)). auto.
rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
apply derI with (ps:=[([] ++ A :: fst s, [] ++ Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
apply dlCons. 2: apply dlNil.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R Bot (A :: fst s, [] ++ snd s) (A :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto. auto.
Qed.
Lemma OrR : forall s A B, KS_prv (fst s, A :: B :: snd s) -> KS_prv (fst s, Or A B :: snd s).
Proof.
intros. unfold Or. unfold Neg.
apply derI with (ps:=[([] ++ (A --> Bot) :: fst s, [] ++ B :: snd s)]).
apply ImpR. assert ((fst s, (A --> Bot) --> B :: snd s) = (fst s, [] ++ (A --> Bot) --> B :: snd s)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([] ++ fst s, [] ++ A :: B :: snd s);([] ++ Bot :: fst s, [] ++ B :: snd s)]).
apply ImpL. apply ImpLRule_I.
apply dlCons. 2: apply dlCons. 3: apply dlNil. simpl ; auto.
apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
Qed.
Lemma list_disj_L : forall l s, (forall A, InT A l -> KS_prv (A :: fst s, snd s)) -> KS_prv (list_disj l :: fst s, snd s).
Proof.
induction l.
- intros. simpl. apply derI with (ps:=[]). apply BotL. assert ((Bot :: fst s, snd s) = ([] ++ Bot :: fst s, snd s)). auto.
rewrite H. apply BotLRule_I. apply dlNil.
- intros. simpl. apply OrL.
* apply X. apply InT_eq.
* simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
Qed.
Lemma list_disj_wkn_R : forall l s A, InT A l -> KS_prv (fst s, A :: snd s) -> KS_prv (fst s, list_disj l :: snd s).
Proof.
induction l.
- intros. inversion H.
- intros. inversion H ; subst.
* simpl. apply OrR.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R (list_disj l) (fst s, A :: snd s) (fst s, A :: list_disj l :: snd s)).
assert (A :: snd s = [A] ++ snd s). auto. rewrite H0.
assert (A :: list_disj l :: snd s = [A] ++ list_disj l :: snd s). auto. rewrite H1. apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto.
* simpl. apply IHl in X ; auto.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R a (fst s, list_disj l :: snd s) (fst s, a :: list_disj l :: snd s)).
assert (a :: list_disj l :: snd s = [] ++ a :: list_disj l :: snd s). auto. rewrite H0.
assert ((fst s, list_disj l :: snd s) = (fst s, [] ++ list_disj l :: snd s)). auto. rewrite H2. apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. apply OrR ; auto.
Qed.
Lemma DiamL_lim : forall A BΓ Γ0 Δ, (is_Boxed_list BΓ) ->
(nobox_gen_ext BΓ Γ0) ->
(KS_prv (A :: unboxed_list BΓ, [])) ->
(KS_prv (Diam A :: Γ0, Δ)).
Proof.
intros. unfold Diam. unfold Neg.
apply derI with (ps:=[([] ++ Γ0, [] ++ Box (A --> Bot) :: Δ);([] ++ Bot :: Γ0, [] ++ Δ)]).
apply ImpL. assert ((Box (A --> Bot) --> Bot :: Γ0, Δ) = ([] ++ Box (A --> Bot) --> Bot :: Γ0, [] ++ Δ)). auto.
rewrite H0. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
2: apply derI with (ps:=[]) ; try apply dlNil ; try apply BotL ; apply BotLRule_I.
apply derI with (ps:=[(unboxed_list BΓ, [A --> Bot])]).
apply KR. apply KRRule_I ; auto. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([] ++ A :: unboxed_list BΓ, [] ++ Bot :: [])]).
apply ImpR. assert ((unboxed_list BΓ, [A --> Bot]) = ([] ++ unboxed_list BΓ, [] ++ A --> Bot :: [])). auto.
rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
assert (J0: derrec_height X0 = derrec_height X0) ; auto.
assert (J3: wkn_R Bot (A :: unboxed_list BΓ, []%list) (A :: unboxed_list BΓ, [Bot])).
assert ((A :: unboxed_list BΓ, @nil MPropF) = (A :: unboxed_list BΓ, [] ++ [])).
rewrite app_nil_r. auto. rewrite H0.
assert ((A :: unboxed_list BΓ, [Bot]) = (A :: unboxed_list BΓ, [] ++ Bot :: [])). auto. rewrite H1.
apply wkn_RI. pose (KS_wkn_R _ _ X0 J0 _ _ J3). destruct s. simpl. auto.
Qed.
Lemma nobox_top_boxes : forall l, nobox_gen_ext (top_boxes l) l.
Proof.
induction l ; simpl ; auto. apply univ_gen_ext_nil. destruct a.
1-3: apply univ_gen_ext_extra ; auto ; intro ; inversion X ; inversion H.
apply univ_gen_ext_cons ; auto.
Qed.
Lemma is_init_Canopy : forall s, is_init s -> (forall leaf, InT leaf (Canopy s) -> is_init leaf).
Proof.
intros s ; induction on s as IHs with measure (n_imp_subformS s).
intros. apply fold_Canopy in H. destruct H ; subst ; auto.
destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
apply p in i1. destruct i1.
- inversion i1 ; subst. inversion i ; subst. 2: inversion H0.
assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
lia. apply IHs with (leaf:=leaf) in J0 ; auto.
unfold is_init. destruct X.
left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ A :: Γ1)). apply InT_or_app.
assert (InT (# P) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
assert (InT (# P) (Δ0 ++ B :: Δ1)). apply InT_or_app.
assert (InT (# P) (Δ0 ++ A --> B :: Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. inversion i3 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
rewrite e0. apply IdPRule_I.
right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ A :: Γ1)). apply InT_or_app.
assert (InT (Bot) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
- inversion i1 ; subst. inversion i ; subst. 2: inversion H0. 3: inversion H1.
assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
lia. apply IHs with (leaf:=leaf) in J0 ; auto.
unfold is_init. destruct X.
left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ Γ1)). apply InT_or_app.
assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. inversion i3 ; subst. inversion H2. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
assert (InT (# P) (Δ0 ++ A :: Δ1)). apply InT_or_app.
assert (InT (# P) (Δ0 ++ Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
rewrite e0. apply IdPRule_I.
right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ Γ1)). apply InT_or_app.
assert (InT (Bot) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. inversion i2 ; subst. inversion H1. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
lia. subst. apply IHs with (leaf:=leaf) in J0 ; auto.
unfold is_init. destruct X.
left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ B :: Γ1)). apply InT_or_app.
assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
destruct H1 ; auto. inversion i3 ; subst. inversion H3. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e.
apply IdPRule_I.
right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ B :: Γ1)). apply InT_or_app.
assert (InT (Bot) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
destruct H1 ; auto. inversion i2 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e. apply BotLRule_I.
Qed.
Lemma TopR : forall X Y0 Y1, KS_prv (X, Y0 ++ Top :: Y1).
Proof.
intros. unfold Top. apply derI with (ps:=[([] ++ Bot :: X, Y0 ++ Bot :: Y1)]).
apply ImpR. assert ((X, Y0 ++ Bot --> Bot :: Y1) = ([] ++ X, Y0 ++ Bot --> Bot :: Y1)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]).
apply BotL. apply BotLRule_I. apply dlNil.
Qed.
Lemma TopL_remove : forall Y X0 X1, KS_prv (X0 ++ Top :: X1, Y) -> KS_prv (X0 ++ X1, Y).
Proof.
intros. assert (Y= [] ++ Y). auto. rewrite H. rewrite H in X. apply KS_cut_adm with (A:=Top) ; auto.
apply TopR.
Qed.
Theorem is_init_UI_equiv_Top : forall s, is_init s -> forall p X Y0 Y1, KS_prv (X, Y0 ++ Top --> (UI p s) :: Y1).
Proof.
intros. destruct (critical_Seq_dec s).
- assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
pose (@GUI_inv_critic_init p s (UI p s) J0 c X). rewrite <- e.
apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ Top :: Y1)]).
apply ImpR. epose (ImpRRule_I _ _ []). simpl in i ; apply i.
apply dlCons. 2: apply dlNil. apply TopR.
- assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
assert (J1: Gimap (GUI p) (Canopy s) (map (UI p) (Canopy s))). apply Gimap_map. intros.
apply UI_GUI ; auto.
pose (@GUI_inv_not_critic p s (UI p s) (map (UI p) (Canopy s)) J0 f J1). rewrite <- e.
apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ list_conj (map (UI p) (Canopy s)) :: Y1)]).
apply ImpR. epose (ImpRRule_I _ _ []). simpl in i ; apply i. apply dlCons. 2: apply dlNil. simpl.
apply KS_adm_list_exch_R with (s:=(Top :: X0, list_conj (map (UI p) (Canopy s)) :: Y0 ++ Y1)).
pose (list_conj_R (map (UI p) (Canopy s)) (Top :: X0, Y0 ++ Y1)). apply k. clear k.
intros. simpl. apply InT_map_iff in H. destruct H. destruct p0. subst.
assert (J2: GUI p x (UI p x)). apply UI_GUI ; auto.
assert (J3: critical_Seq x). apply Canopy_critical in i ; auto.
assert (J4: is_init x). apply is_init_Canopy in i ; auto.
pose (@GUI_inv_critic_init p x (UI p x) J2 J3 J4). rewrite <- e0. epose (TopR _ [] _). simpl in k ; apply k.
epose (list_exch_RI _ [] [_] Y0 [] _). simpl in l. apply l.
Qed.
Theorem is_init_UI : forall s, is_init s -> forall p X Y0 Y1, KS_prv (X, Y0 ++ UI p s :: Y1).
Proof.
intros. eapply is_init_UI_equiv_Top in X. apply ImpR_inv with (prem:=([] ++ Top :: X0, Y0 ++ UI p s :: Y1)) in X.
apply TopL_remove in X. simpl in X ; auto. assert ((X0, Y0 ++ Top --> UI p s :: Y1) = ([] ++ X0, Y0 ++ Top --> UI p s :: Y1)).
auto. rewrite H. apply ImpRRule_I.
Qed.
End list_conj_disj_properties.
Section Canopy_lems.
Lemma inv_prems_measure : forall s0 s1, InT s1 (inv_prems s0) -> (measure s1 < measure s0).
Proof.
intros. unfold inv_prems in H. apply InT_flatten_list_InT_elem in H.
destruct H. destruct p. destruct (finite_ImpRules_premises_of_S s0). simpl in i0.
apply p in i0. destruct i0 ; inversion i0 ; subst. inversion i ; subst. unfold measure ; simpl.
repeat rewrite size_LF_dist_app ; simpl ; lia. inversion H0. inversion i ; subst.
unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H0 ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H1.
Qed.
Lemma Canopy_measure: forall s0 s1, InT s1 (Canopy s0) -> ((s0 = s1) + (measure s1 < measure s0)).
Proof.
intros s ; induction on s as IHs with measure (measure s).
intros. remember (finite_ImpRules_premises_of_S s) as H0. destruct H0. destruct x.
- left. assert (Canopy s = [s]). apply irred_nil. unfold inv_prems ; rewrite <- HeqH0 ; auto.
rewrite H0 in H. inversion H ; subst ; auto. inversion H2.
- apply fold_Canopy in H. destruct H ; auto. right. destruct s0. destruct p0. apply IHs in i0.
destruct i0 ; subst ; auto. apply inv_prems_measure in i ; auto. apply inv_prems_measure in i. lia.
unfold inv_prems in i. apply InT_flatten_list_InT_elem in i.
destruct i. destruct p0. rewrite <- HeqH0 in i1. simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
inversion i. subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H0. inversion i ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H0 ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H1.
Qed.
End Canopy_lems.
Export ListNotations.
Require Import PeanoNat.
Require Import Lia.
Require Import String.
Require Import general_export.
Require Import KS_export.
Require Import UIK_Def_measure.
Require Import UIK_Canopy.
Require Import UIK_irred_short.
Require Import UIK_basics.
Require Import UIK_braga.
Section Prop_Subform.
(* This is copied from the Craig interpolation file. Make a syntax file for interpolations. *)
Fixpoint propvar_subform (A : MPropF) : list MPropF :=
match A with
| Var p => (Var p) :: nil
| Bot => nil
| Imp B C => (propvar_subform B) ++ ( propvar_subform C)
| Box B => ( propvar_subform B)
end.
Fixpoint propvar_subform_list (l : list MPropF) : list MPropF :=
match l with
| nil => nil
| A :: t => (propvar_subform A) ++ (propvar_subform_list t)
end.
(* Lemmas about propvar_subform_list. *)
Lemma propvar_subform_list_app: forall l0 l1,
propvar_subform_list (l0 ++ l1) = (propvar_subform_list l0) ++ (propvar_subform_list l1).
Proof.
induction l0.
- simpl. auto.
- intros. simpl. rewrite (IHl0). rewrite <- app_assoc ; auto.
Qed.
Lemma propvar_subform_list_unboxed_list : forall l A, In A (propvar_subform_list (unboxed_list l)) -> In A (propvar_subform_list l).
Proof.
induction l.
- auto.
- simpl. intros. apply in_app_or in H. destruct H. apply in_or_app ; left. destruct a ; auto.
apply in_or_app ; auto.
Qed.
Lemma propvar_subform_list_nobox_gen_ext : forall l0 l1, nobox_gen_ext l0 l1 ->
(forall A, In A (propvar_subform_list l0) -> In A (propvar_subform_list l1)).
Proof.
intros l0 l1 H. induction H ; auto.
- simpl ; intros. apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto.
- simpl ; intros. apply in_or_app ; auto.
Qed.
Lemma propvar_subform_list_top_boxes : forall l A, In A (propvar_subform_list (top_boxes l)) -> In A (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. destruct a ; simpl in H ; auto. 1-2: apply in_or_app ; apply IHl in H ; auto.
apply in_or_app ; apply in_app_or in H ; destruct H ; simpl ; auto.
Qed.
Lemma propvar_subform_list_conj : forall l A,
In A (propvar_subform (list_conj l)) -> In A (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
apply in_app_or in H. apply in_or_app. destruct H ; auto.
Qed.
Lemma propvar_subform_list_disj : forall l A,
In A (propvar_subform (list_disj l)) -> In A (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. repeat rewrite app_nil_r in H.
apply in_app_or in H. apply in_or_app. destruct H ; auto.
Qed.
Lemma propvar_subform_list_witness : forall l A,
In A (propvar_subform_list l) -> (exists B, In B l /\ In A (propvar_subform B)).
Proof.
induction l ; simpl ; intros ; auto. inversion H. apply in_app_or in H. destruct H.
exists a ; auto. apply IHl in H. destruct H. exists x ; firstorder.
Qed.
Lemma propvar_subform_list_witnessT : forall l A,
InT A (propvar_subform_list l) -> (existsT2 B, (InT B l) * (InT A (propvar_subform B))).
Proof.
induction l ; simpl ; intros ; auto. inversion H. apply InT_app_or in H. destruct H.
exists a ; auto. split ; auto. apply InT_eq. apply IHl in i. destruct i. exists x ; firstorder. apply InT_cons ; auto.
Qed.
Lemma propvar_subform_list_Canopy : forall s ir A,
In ir (Canopy s) ->
In A (propvar_subform_list (fst ir ++ snd ir)) ->
In A (propvar_subform_list (fst s ++ snd s)).
Proof.
intros s ; induction on s as IHs with measure (n_imp_subformS s).
intros. remember (finite_ImpRules_premises_of_S s) as H1.
destruct H1. destruct x.
- assert (Canopy s = [s]). apply irred_nil. unfold inv_prems. rewrite <- HeqH1.
simpl. auto. rewrite H1 in H. inversion H. subst. auto. inversion H2.
- apply In_InT_seqs in H. apply fold_Canopy in H. destruct H ; subst ; auto.
destruct s0. destruct p0. unfold inv_prems in i. destruct (finite_ImpRules_premises_of_S s).
simpl in i. apply InT_flatten_list_InT_elem in i. destruct i. destruct p1. apply p0 in i1.
apply IHs with (y:=x0) in H0. 3: apply InT_In ; auto.
destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. simpl in H0.
repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; apply in_app_or in H ; destruct H ; auto.
right ; apply in_or_app ; right ; auto.
inversion i1 ; subst. simpl. inversion i ; subst. simpl in H0.
repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; right ; apply in_or_app ; right ; apply in_or_app ; auto.
inversion H1 ; subst. 2: inversion H2. simpl in H0.
repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
repeat rewrite propvar_subform_list_app in H0. repeat rewrite propvar_subform_list_app.
simpl in H0. simpl. repeat rewrite <- app_assoc in H0. repeat rewrite <- app_assoc.
apply in_or_app. apply in_app_or in H0 ; destruct H0 ; auto. right. apply in_or_app.
apply in_app_or in H ; destruct H ; auto. right ; apply in_or_app ; auto.
apply in_app_or in H ; destruct H ; auto. right. apply in_or_app ; right ; apply in_or_app ; auto.
right ; apply in_or_app ; right ; apply in_or_app ; right ; auto.
destruct i1. inversion i1 ; subst. simpl. inversion i ; subst. 2: inversion H1. unfold n_imp_subformS ; simpl.
repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
inversion i1. subst. inversion i ; subst. unfold n_imp_subformS ; simpl.
repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
inversion H1. subst. 2: inversion H2. unfold n_imp_subformS ; simpl.
repeat rewrite n_imp_subformLF_dist_app ; simpl ; repeat rewrite n_imp_subformLF_dist_app. lia.
Qed.
Lemma propvar_subform_list_restr_list_prop : forall l p q, In # q (propvar_subform_list (restr_list_prop p l)) ->
((q <> p) * (In # q (propvar_subform_list l))).
Proof.
induction l ; simpl ; intros ; auto. unfold restr_list_prop in H. destruct a as [n | | |]; simpl ; simpl in H ; auto.
destruct (eq_dec_form (# p) (# n)) ; subst. apply IHl in H. destruct H ; auto.
simpl in H. destruct H ; subst ; auto. split ; auto. rewrite H in n0. destruct (string_dec p q) ; subst; auto.
all: apply IHl in H ; destruct H ; auto.
all: split ; auto. all: apply in_or_app ; auto.
Qed.
Lemma In_list_prop_LF: forall l A, In A (list_prop_LF l) -> ((existsT2 q, A = # q) * In A l).
Proof.
induction l ; simpl ; intros ; auto. inversion H. apply In_InT in H. apply InT_app_or in H.
destruct H. destruct a as [n | | |]; simpl in i ; inversion i ; subst ; auto. split ; [exists n ; auto | auto]. inversion H0.
apply InT_In in i ; apply IHl in i ; auto. destruct i ; split ; auto.
Qed.
Lemma list_prop_LF_propvar_subform_list : forall l q, In # q (list_prop_LF l) -> In # q (propvar_subform_list l).
Proof.
induction l ; simpl ; intros ; auto. apply in_app_or in H ; destruct H ; auto. apply in_or_app ; left. destruct a ; simpl ; simpl in H ; try firstorder.
apply in_or_app ; right ; apply IHl in H ; auto.
Qed.
Lemma In_list_In_list_prop_LF : forall l P, In # P l -> In # P (list_prop_LF l).
Proof.
induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
Qed.
Lemma In_list_In_propvar_subform_list : forall l P, In # P l -> In # P (propvar_subform_list l).
Proof.
induction l ; simpl ; subst ; auto. intros. destruct H. subst ; simpl ; auto. apply in_or_app; right ; auto.
Qed.
End Prop_Subform.
Section Diam_help.
Lemma In_unboxed_list : forall l A, In A (unboxed_list (top_boxes l)) -> (exists B, In B (top_boxes l) /\ B = Box A).
Proof.
induction l ; intros ; auto. simpl in H. exfalso ; auto. destruct a ; simpl ; simpl in H ; auto.
destruct H ; subst. exists (Box A) ; auto.
apply IHl in H. destruct H. firstorder.
Qed.
Lemma unboxed_list_In : forall l A, In (Box A) (top_boxes l) -> In A (unboxed_list (top_boxes l)).
Proof.
induction l ; simpl ; intros ; auto. destruct a ; simpl ; simpl in H ; auto. destruct H. inversion H ; subst. auto.
apply IHl in H ; auto.
Qed.
Lemma unboxed_list_In_unfold : forall l A, (exists B, In B (top_boxes l) /\ B = Box A) -> In A (unboxed_list (top_boxes l)).
Proof.
induction l ; simpl ; intros ; auto. destruct H. destruct H ; auto.
destruct a ; simpl ; simpl in H ; auto. destruct H. destruct H. subst. destruct H.
inversion H ; subst ; auto. right. apply unboxed_list_In ; auto.
Qed.
Lemma remove_list_decr_in: forall [l2 l1 l3 l4: list MPropF], NoDup l4 -> NoDup l3 ->
incl l1 l2 -> incl l3 l4 -> length (remove_list l2 l4) < length (remove_list l1 l3) ->
(exists A : MPropF, In A l2 /\ (In A l1 -> False)).
Proof.
induction l2 ; simpl.
- intros. destruct l1. simpl. simpl in H3. exfalso. pose (NoDup_incl_length H0 H2). simpl in l. lia.
exfalso. pose (H1 m). simpl in i ; apply i ; auto.
- intros. destruct (In_dec l2 a).
+ assert (incl l1 l2). intro. intros. apply H1 in H4. inversion H4 ; subst ; auto.
pose (In_remove_list_remove_redund _ l4 _ i). rewrite e in H3.
pose (IHl2 _ _ _ H H0 H4 H2 H3). destruct e0. destruct H5. exists x ; split ; auto.
+ destruct (In_dec l1 a).
* destruct (In_dec l4 a).
-- destruct (In_dec l3 a).
++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) (remove eq_dec_form a l3))).
rewrite <- In_remove_list_remove_redund with (a:=a). rewrite permut_remove_remove_list.
pose (permut_remove_remove_list a (remove eq_dec_form a l1) l3). rewrite <- e.
pose (redund_remove_remove_list a l1 l3). rewrite e0. rewrite permut_remove_remove_list. auto. auto.
assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
assert (J1: NoDup (remove eq_dec_form a l3)). apply remove_preserv_NoDup ; auto.
assert (J2: incl (remove eq_dec_form a l3) (remove eq_dec_form a l4)). intro. intros.
apply in_remove in H6. destruct H6. apply in_in_remove ; auto.
rewrite H5 in H3. rewrite permut_remove_remove_list in H3.
pose (IHl2 (remove eq_dec_form a l1) _ _ J0 J1 H4 J2 H3). destruct e. destruct H6.
exists x ; split ; auto. intro. apply H7. apply in_in_remove ; auto. intro ; subst. auto.
++ assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H4. destruct H4.
apply H1 in H4. inversion H4 ; subst ; auto. exfalso ; apply H5 ; auto.
rewrite permut_remove_remove_list in H3.
assert (J0: NoDup (remove eq_dec_form a l4)). apply remove_preserv_NoDup ; auto.
assert (J1: incl l3 (remove eq_dec_form a l4)). intro. intros. apply in_in_remove ; auto.
intro ; subst ; auto.
assert (J:length (remove_list l2 (remove eq_dec_form a l4)) < length (remove_list (remove eq_dec_form a l1) l3)).
assert ((remove_list l1 l3) = (remove_list (remove eq_dec_form a l1) l3)).
pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e.
symmetry in e. rewrite notin_remove in e. auto.
1-2: intro ; apply In_remove_list_In_list in H5 ; auto. rewrite H5 in H3. auto.
pose (IHl2 (remove eq_dec_form a l1) _ _ J0 H0 H4 J1 J). destruct e. destruct H5.
exists x ; split ; auto. intro. apply H6. apply in_in_remove ; auto. intro ; subst. auto.
-- assert (In a l3 -> False). intro. apply n0 ; auto. rewrite permut_remove_remove_list in H3.
rewrite notin_remove in H3 ; auto.
assert (incl (remove eq_dec_form a l1) l2). intro. intros. apply in_remove in H5. destruct H5.
apply H1 in H5. inversion H5 ; subst ; auto. exfalso ; apply H6 ; auto.
assert (length (remove_list l2 l4) < length (remove_list (remove eq_dec_form a l1) l3)).
pose (redund_remove_remove_list a l1 l3). rewrite notin_remove in e. rewrite e. rewrite notin_remove ; auto.
intro. apply In_remove_list_In_list in H6 ; auto. intro. apply In_remove_list_In_list in H6 ; auto.
pose (IHl2 (remove eq_dec_form a l1) _ _ H H0 H5 H2 H6). destruct e. destruct H7.
exists x ; split ; auto. intro. apply H8. apply in_in_remove ; auto. intro ; subst. auto.
* exists a ; split ; auto.
Qed.
End Diam_help.
Section list_conj_disj_properties.
Lemma AndL : forall s A B, KS_prv (A :: B :: fst s, snd s) -> KS_prv (And A B :: fst s, snd s).
Proof.
intros. unfold And. unfold Neg.
apply derI with (ps:=[([] ++ fst s, [] ++ (A --> B --> Bot) :: snd s); ([] ++ Bot :: fst s, [] ++ snd s)]).
apply ImpL. assert (((A --> B --> Bot) --> Bot :: fst s, snd s) = ([] ++ (A --> B --> Bot) --> Bot :: fst s, snd s)). auto.
rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
apply derI with (ps:=[([] ++ A :: fst s, [] ++ B --> Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
apply dlCons. 2: apply dlNil. apply derI with (ps:=[([A] ++ B :: fst s, [] ++ Bot :: snd s)]).
assert (([] ++ A :: fst s, [] ++ B --> Bot :: snd s) = ([A] ++ fst s, [] ++ B --> Bot :: snd s)). auto. rewrite H.
apply ImpR. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R Bot ([A] ++ B :: fst s, [] ++ snd s) ([A] ++ B :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
apply dlNil.
Qed.
Lemma AndR : forall s A B, KS_prv (fst s, A :: snd s) -> KS_prv (fst s, B :: snd s) -> KS_prv (fst s, And A B :: snd s).
Proof.
intros. unfold And. unfold Neg.
apply derI with (ps:=[([] ++ A --> B --> Bot :: fst s, [] ++ Bot :: snd s)]).
apply ImpR. assert ((fst s, (A --> B --> Bot) --> Bot :: snd s) = ([] ++ fst s, [] ++ (A --> B --> Bot) --> Bot :: snd s)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([] ++ fst s, [] ++ A :: Bot :: snd s);([] ++ B --> Bot :: fst s, [] ++ Bot :: snd s)]). apply ImpL.
apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R Bot ([] ++ fst s, [A] ++ snd s) ([] ++ fst s, [A] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto.
apply derI with (ps:=[([] ++ fst s, [] ++ B :: Bot :: snd s);([] ++ Bot :: fst s, [] ++ Bot :: snd s)]). apply ImpL.
apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
assert (J0: derrec_height X0 = derrec_height X0). auto.
assert (J1: wkn_R Bot ([] ++ fst s, [B] ++ snd s) ([] ++ fst s, [B] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X0 J0 _ _ J1). destruct s0. auto. apply derI with (ps:=[]). apply BotL. apply BotLRule_I.
apply dlNil.
Qed.
Lemma list_conj_wkn_L : forall l s A, InT A l -> KS_prv (A :: fst s, snd s) -> KS_prv (list_conj l :: fst s, snd s).
Proof.
induction l.
- intros. inversion H.
- intros. inversion H ; subst.
* simpl. apply AndL.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_L (list_conj l) (A :: fst s, snd s) (A :: list_conj l :: fst s, snd s)).
assert (A :: fst s = [A] ++ fst s). auto. rewrite H0.
assert (A :: list_conj l :: fst s = [A] ++ list_conj l :: fst s). auto. rewrite H1. apply wkn_LI.
pose (KS_wkn_L _ _ X J0 _ _ J1). destruct s0. auto.
* simpl. apply IHl in X ; auto.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_L a (list_conj l :: fst s, snd s) (a :: list_conj l :: fst s, snd s)).
assert (a :: list_conj l :: fst s = [] ++ a :: list_conj l :: fst s). auto. rewrite H0.
assert ((list_conj l :: fst s,snd s) = ([] ++ list_conj l :: fst s,snd s)). auto. rewrite H2. apply wkn_LI.
pose (KS_wkn_L _ _ X J0 _ _ J1). destruct s0. apply AndL ; auto.
Qed.
Lemma list_conj_R : forall l s, (forall A, InT A l -> KS_prv (fst s, A :: snd s)) -> KS_prv (fst s, list_conj l :: snd s).
Proof.
induction l.
- intros. simpl. unfold Top.
apply derI with (ps:=[([] ++ Bot :: fst s, [] ++ Bot :: snd s)]).
apply ImpR. assert ((fst s, Bot --> Bot :: snd s) = ([] ++ fst s, [] ++ Bot --> Bot :: snd s)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]). apply BotL.
apply BotLRule_I. apply dlNil.
- intros. simpl. apply AndR.
* apply X. apply InT_eq.
* simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
Qed.
Lemma OrL : forall s A B, KS_prv (A :: fst s, snd s) -> KS_prv (B :: fst s, snd s) -> KS_prv (Or A B :: fst s, snd s).
Proof.
intros. unfold Or. unfold Neg.
apply derI with (ps:=[([] ++ fst s, [] ++ (A --> Bot) :: snd s); ([] ++ B :: fst s, [] ++ snd s)]).
apply ImpL. assert (((A --> Bot) --> B :: fst s, snd s) = ([] ++ (A --> Bot) --> B :: fst s, snd s)). auto.
rewrite H. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
apply derI with (ps:=[([] ++ A :: fst s, [] ++ Bot :: snd s)]). apply ImpR. apply ImpRRule_I.
apply dlCons. 2: apply dlNil.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R Bot (A :: fst s, [] ++ snd s) (A :: fst s, [] ++ Bot :: snd s)). apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto. auto.
Qed.
Lemma OrR : forall s A B, KS_prv (fst s, A :: B :: snd s) -> KS_prv (fst s, Or A B :: snd s).
Proof.
intros. unfold Or. unfold Neg.
apply derI with (ps:=[([] ++ (A --> Bot) :: fst s, [] ++ B :: snd s)]).
apply ImpR. assert ((fst s, (A --> Bot) --> B :: snd s) = (fst s, [] ++ (A --> Bot) --> B :: snd s)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([] ++ fst s, [] ++ A :: B :: snd s);([] ++ Bot :: fst s, [] ++ B :: snd s)]).
apply ImpL. apply ImpLRule_I.
apply dlCons. 2: apply dlCons. 3: apply dlNil. simpl ; auto.
apply derI with (ps:=[]). apply BotL. apply BotLRule_I. apply dlNil.
Qed.
Lemma list_disj_L : forall l s, (forall A, InT A l -> KS_prv (A :: fst s, snd s)) -> KS_prv (list_disj l :: fst s, snd s).
Proof.
induction l.
- intros. simpl. apply derI with (ps:=[]). apply BotL. assert ((Bot :: fst s, snd s) = ([] ++ Bot :: fst s, snd s)). auto.
rewrite H. apply BotLRule_I. apply dlNil.
- intros. simpl. apply OrL.
* apply X. apply InT_eq.
* simpl. apply IHl. intros. apply X. apply InT_cons ; auto.
Qed.
Lemma list_disj_wkn_R : forall l s A, InT A l -> KS_prv (fst s, A :: snd s) -> KS_prv (fst s, list_disj l :: snd s).
Proof.
induction l.
- intros. inversion H.
- intros. inversion H ; subst.
* simpl. apply OrR.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R (list_disj l) (fst s, A :: snd s) (fst s, A :: list_disj l :: snd s)).
assert (A :: snd s = [A] ++ snd s). auto. rewrite H0.
assert (A :: list_disj l :: snd s = [A] ++ list_disj l :: snd s). auto. rewrite H1. apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. auto.
* simpl. apply IHl in X ; auto.
assert (J0: derrec_height X = derrec_height X). auto.
assert (J1: wkn_R a (fst s, list_disj l :: snd s) (fst s, a :: list_disj l :: snd s)).
assert (a :: list_disj l :: snd s = [] ++ a :: list_disj l :: snd s). auto. rewrite H0.
assert ((fst s, list_disj l :: snd s) = (fst s, [] ++ list_disj l :: snd s)). auto. rewrite H2. apply wkn_RI.
pose (KS_wkn_R _ _ X J0 _ _ J1). destruct s0. apply OrR ; auto.
Qed.
Lemma DiamL_lim : forall A BΓ Γ0 Δ, (is_Boxed_list BΓ) ->
(nobox_gen_ext BΓ Γ0) ->
(KS_prv (A :: unboxed_list BΓ, [])) ->
(KS_prv (Diam A :: Γ0, Δ)).
Proof.
intros. unfold Diam. unfold Neg.
apply derI with (ps:=[([] ++ Γ0, [] ++ Box (A --> Bot) :: Δ);([] ++ Bot :: Γ0, [] ++ Δ)]).
apply ImpL. assert ((Box (A --> Bot) --> Bot :: Γ0, Δ) = ([] ++ Box (A --> Bot) --> Bot :: Γ0, [] ++ Δ)). auto.
rewrite H0. apply ImpLRule_I. apply dlCons. 2: apply dlCons. 3: apply dlNil.
2: apply derI with (ps:=[]) ; try apply dlNil ; try apply BotL ; apply BotLRule_I.
apply derI with (ps:=[(unboxed_list BΓ, [A --> Bot])]).
apply KR. apply KRRule_I ; auto. apply dlCons. 2: apply dlNil.
apply derI with (ps:=[([] ++ A :: unboxed_list BΓ, [] ++ Bot :: [])]).
apply ImpR. assert ((unboxed_list BΓ, [A --> Bot]) = ([] ++ unboxed_list BΓ, [] ++ A --> Bot :: [])). auto.
rewrite H0. apply ImpRRule_I. apply dlCons. 2: apply dlNil.
assert (J0: derrec_height X0 = derrec_height X0) ; auto.
assert (J3: wkn_R Bot (A :: unboxed_list BΓ, []%list) (A :: unboxed_list BΓ, [Bot])).
assert ((A :: unboxed_list BΓ, @nil MPropF) = (A :: unboxed_list BΓ, [] ++ [])).
rewrite app_nil_r. auto. rewrite H0.
assert ((A :: unboxed_list BΓ, [Bot]) = (A :: unboxed_list BΓ, [] ++ Bot :: [])). auto. rewrite H1.
apply wkn_RI. pose (KS_wkn_R _ _ X0 J0 _ _ J3). destruct s. simpl. auto.
Qed.
Lemma nobox_top_boxes : forall l, nobox_gen_ext (top_boxes l) l.
Proof.
induction l ; simpl ; auto. apply univ_gen_ext_nil. destruct a.
1-3: apply univ_gen_ext_extra ; auto ; intro ; inversion X ; inversion H.
apply univ_gen_ext_cons ; auto.
Qed.
Lemma is_init_Canopy : forall s, is_init s -> (forall leaf, InT leaf (Canopy s) -> is_init leaf).
Proof.
intros s ; induction on s as IHs with measure (n_imp_subformS s).
intros. apply fold_Canopy in H. destruct H ; subst ; auto.
destruct s0 ; destruct p. unfold inv_prems in i. apply InT_flatten_list_InT_elem in i. destruct i.
destruct p. destruct (finite_ImpRules_premises_of_S s). simpl in i1. subst.
apply p in i1. destruct i1.
- inversion i1 ; subst. inversion i ; subst. 2: inversion H0.
assert (J0: n_imp_subformS (Γ0 ++ A :: Γ1, Δ0 ++ B :: Δ1) < n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A --> B :: Δ1)).
unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
lia. apply IHs with (leaf:=leaf) in J0 ; auto.
unfold is_init. destruct X.
left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ A :: Γ1)). apply InT_or_app.
assert (InT (# P) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
assert (InT (# P) (Δ0 ++ B :: Δ1)). apply InT_or_app.
assert (InT (# P) (Δ0 ++ A --> B :: Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. inversion i3 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
rewrite e0. apply IdPRule_I.
right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ A :: Γ1)). apply InT_or_app.
assert (InT (Bot) (Γ0 ++ Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
- inversion i1 ; subst. inversion i ; subst. 2: inversion H0. 3: inversion H1.
assert (J0: n_imp_subformS (Γ0 ++ Γ1, Δ0 ++ A :: Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
lia. apply IHs with (leaf:=leaf) in J0 ; auto.
unfold is_init. destruct X.
left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ Γ1)). apply InT_or_app.
assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. inversion i3 ; subst. inversion H2. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e.
assert (InT (# P) (Δ0 ++ A :: Δ1)). apply InT_or_app.
assert (InT (# P) (Δ0 ++ Δ1)). rewrite <- H1. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. right ; apply InT_cons ; auto. apply InT_split in H0. destruct H0. destruct s.
rewrite e0. apply IdPRule_I.
right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ Γ1)). apply InT_or_app.
assert (InT (Bot) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H0.
destruct H0 ; auto. inversion i2 ; subst. inversion H1. auto. apply InT_split in H0. destruct H0. destruct s. rewrite e. apply BotLRule_I.
assert (J0: n_imp_subformS (Γ0 ++ B :: Γ1, Δ0 ++ Δ1) < n_imp_subformS (Γ0 ++ A --> B :: Γ1, Δ0 ++ Δ1)).
unfold n_imp_subformS. simpl. repeat rewrite n_imp_subformLF_dist_app. simpl ; repeat rewrite n_imp_subformLF_dist_app.
lia. subst. apply IHs with (leaf:=leaf) in J0 ; auto.
unfold is_init. destruct X.
left. inversion i2 ; subst. assert (InT (# P) (Γ0 ++ B :: Γ1)). apply InT_or_app.
assert (InT (# P) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
destruct H1 ; auto. inversion i3 ; subst. inversion H3. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e.
apply IdPRule_I.
right. inversion b ; subst. assert (InT (Bot) (Γ0 ++ B :: Γ1)). apply InT_or_app.
assert (InT (Bot) (Γ0 ++ A --> B :: Γ1)). rewrite <- H. apply InT_or_app ; right ;apply InT_eq. apply InT_app_or in H1.
destruct H1 ; auto. inversion i2 ; subst. inversion H2. right ; apply InT_cons ; auto. apply InT_split in H1. destruct H1. destruct s. rewrite e. apply BotLRule_I.
Qed.
Lemma TopR : forall X Y0 Y1, KS_prv (X, Y0 ++ Top :: Y1).
Proof.
intros. unfold Top. apply derI with (ps:=[([] ++ Bot :: X, Y0 ++ Bot :: Y1)]).
apply ImpR. assert ((X, Y0 ++ Bot --> Bot :: Y1) = ([] ++ X, Y0 ++ Bot --> Bot :: Y1)). auto.
rewrite H. apply ImpRRule_I. apply dlCons. 2: apply dlNil. apply derI with (ps:=[]).
apply BotL. apply BotLRule_I. apply dlNil.
Qed.
Lemma TopL_remove : forall Y X0 X1, KS_prv (X0 ++ Top :: X1, Y) -> KS_prv (X0 ++ X1, Y).
Proof.
intros. assert (Y= [] ++ Y). auto. rewrite H. rewrite H in X. apply KS_cut_adm with (A:=Top) ; auto.
apply TopR.
Qed.
Theorem is_init_UI_equiv_Top : forall s, is_init s -> forall p X Y0 Y1, KS_prv (X, Y0 ++ Top --> (UI p s) :: Y1).
Proof.
intros. destruct (critical_Seq_dec s).
- assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
pose (@GUI_inv_critic_init p s (UI p s) J0 c X). rewrite <- e.
apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ Top :: Y1)]).
apply ImpR. epose (ImpRRule_I _ _ []). simpl in i ; apply i.
apply dlCons. 2: apply dlNil. apply TopR.
- assert (J0: GUI p s (UI p s)). apply UI_GUI ; auto.
assert (J1: Gimap (GUI p) (Canopy s) (map (UI p) (Canopy s))). apply Gimap_map. intros.
apply UI_GUI ; auto.
pose (@GUI_inv_not_critic p s (UI p s) (map (UI p) (Canopy s)) J0 f J1). rewrite <- e.
apply derI with (ps:=[([] ++ Top :: X0, Y0 ++ list_conj (map (UI p) (Canopy s)) :: Y1)]).
apply ImpR. epose (ImpRRule_I _ _ []). simpl in i ; apply i. apply dlCons. 2: apply dlNil. simpl.
apply KS_adm_list_exch_R with (s:=(Top :: X0, list_conj (map (UI p) (Canopy s)) :: Y0 ++ Y1)).
pose (list_conj_R (map (UI p) (Canopy s)) (Top :: X0, Y0 ++ Y1)). apply k. clear k.
intros. simpl. apply InT_map_iff in H. destruct H. destruct p0. subst.
assert (J2: GUI p x (UI p x)). apply UI_GUI ; auto.
assert (J3: critical_Seq x). apply Canopy_critical in i ; auto.
assert (J4: is_init x). apply is_init_Canopy in i ; auto.
pose (@GUI_inv_critic_init p x (UI p x) J2 J3 J4). rewrite <- e0. epose (TopR _ [] _). simpl in k ; apply k.
epose (list_exch_RI _ [] [_] Y0 [] _). simpl in l. apply l.
Qed.
Theorem is_init_UI : forall s, is_init s -> forall p X Y0 Y1, KS_prv (X, Y0 ++ UI p s :: Y1).
Proof.
intros. eapply is_init_UI_equiv_Top in X. apply ImpR_inv with (prem:=([] ++ Top :: X0, Y0 ++ UI p s :: Y1)) in X.
apply TopL_remove in X. simpl in X ; auto. assert ((X0, Y0 ++ Top --> UI p s :: Y1) = ([] ++ X0, Y0 ++ Top --> UI p s :: Y1)).
auto. rewrite H. apply ImpRRule_I.
Qed.
End list_conj_disj_properties.
Section Canopy_lems.
Lemma inv_prems_measure : forall s0 s1, InT s1 (inv_prems s0) -> (measure s1 < measure s0).
Proof.
intros. unfold inv_prems in H. apply InT_flatten_list_InT_elem in H.
destruct H. destruct p. destruct (finite_ImpRules_premises_of_S s0). simpl in i0.
apply p in i0. destruct i0 ; inversion i0 ; subst. inversion i ; subst. unfold measure ; simpl.
repeat rewrite size_LF_dist_app ; simpl ; lia. inversion H0. inversion i ; subst.
unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H0 ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H1.
Qed.
Lemma Canopy_measure: forall s0 s1, InT s1 (Canopy s0) -> ((s0 = s1) + (measure s1 < measure s0)).
Proof.
intros s ; induction on s as IHs with measure (measure s).
intros. remember (finite_ImpRules_premises_of_S s) as H0. destruct H0. destruct x.
- left. assert (Canopy s = [s]). apply irred_nil. unfold inv_prems ; rewrite <- HeqH0 ; auto.
rewrite H0 in H. inversion H ; subst ; auto. inversion H2.
- apply fold_Canopy in H. destruct H ; auto. right. destruct s0. destruct p0. apply IHs in i0.
destruct i0 ; subst ; auto. apply inv_prems_measure in i ; auto. apply inv_prems_measure in i. lia.
unfold inv_prems in i. apply InT_flatten_list_InT_elem in i.
destruct i. destruct p0. rewrite <- HeqH0 in i1. simpl in i1. apply p in i1. destruct i1 ; inversion i1 ; subst.
inversion i. subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H0. inversion i ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H0 ; subst. unfold measure ; simpl ; repeat rewrite size_LF_dist_app ; simpl ; lia.
inversion H1.
Qed.
End Canopy_lems.