G4iSLt.G4iSLT_remove_list
Require Import List.
Export ListNotations.
Require Import PeanoNat.
Require Import Lia.
Require Import existsT.
Require Import G4iSLT_calc.
Set Implicit Arguments.
Lemma In_dec : forall l (a : MPropF) , (In a l) + ((In a l) -> False).
Proof.
induction l.
- right. intro. destruct H.
- intro a0. pose (IHl a0). destruct s.
* left. apply in_cons. assumption.
* destruct (eq_dec_form a a0).
+ subst. left. apply in_eq.
+ right. intro. inversion H.
{ apply n. assumption. }
{ apply f. assumption. }
Qed.
(* Let us prove some lemmas about remove. *)
Lemma in_not_touched_remove : forall l1 (a0 a1 : MPropF),
In a0 l1 -> a0 <> a1 -> In a0 (remove eq_dec_form a1 l1).
Proof.
induction l1.
- intros. inversion H.
- intros. simpl. destruct (eq_dec_form a1 a).
* subst. apply IHl1. inversion H. exfalso. apply H0. auto. assumption. assumption.
* inversion H. subst. apply in_eq. apply in_cons. apply IHl1. assumption. assumption.
Qed.
Lemma remove_dist_app {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
forall (a : A) l1 l2, (@remove A eq_dec a (l1 ++ l2)) =
(@remove A eq_dec a l1) ++ (@remove A eq_dec a l2).
Proof.
intros a l1. induction l1.
- intro l2. rewrite app_nil_l. simpl. reflexivity.
- intro l2. simpl. destruct (eq_dec a a0).
* apply IHl1.
* simpl. rewrite IHl1. reflexivity.
Qed.
Lemma remove_not_in_anymore : forall l (A : MPropF),
(In A (remove eq_dec_form A l)) -> False.
Proof.
induction l.
- intros. simpl in H. inversion H.
- intros. simpl in H. destruct (eq_dec_form A a). subst. apply IHl in H. assumption.
inversion H. apply n. symmetry. assumption. apply IHl in H0. assumption.
Qed.
Lemma in_remove_in_init : forall l A B,
In A (remove eq_dec_form B l) -> In A l.
Proof.
induction l.
- intros. simpl. inversion H.
- intros. destruct (eq_dec_form A a). subst. apply in_eq. apply in_cons.
pose (IHl A B). apply i. simpl in H. destruct (eq_dec_form B a).
* subst. assumption.
* inversion H. exfalso. apply n. symmetry. assumption. assumption.
Qed.
Lemma remove_preserv_NoDup : forall l (A : MPropF), NoDup l -> NoDup (remove eq_dec_form A l).
Proof.
induction l.
- intros. simpl. apply NoDup_nil.
- intros. simpl. destruct (eq_dec_form A a).
* subst. apply IHl. inversion H. assumption.
* apply NoDup_cons. intro. apply in_remove_in_init in H0. inversion H. apply H3. assumption.
apply IHl. inversion H. assumption.
Qed.
Lemma NoDup_destr_split : forall l1 l2 (A : MPropF), NoDup (l1 ++ A :: l2) -> NoDup (l1 ++ l2).
Proof.
induction l1.
- intros. rewrite app_nil_l. rewrite app_nil_l in H. inversion H. assumption.
- intros. simpl. apply NoDup_cons. intro. inversion H. subst. apply H3. apply in_app_or in H0.
destruct H0. apply in_or_app. left. assumption. apply in_or_app. right. apply in_cons.
assumption. simpl in H. inversion H. subst. apply IHl1 with (A:=A). assumption.
Qed.
Lemma remove_le_length : forall l (A : MPropF), length (remove eq_dec_form A l) <= length l.
Proof.
induction l.
- intros. simpl. reflexivity.
- intros. simpl. destruct (eq_dec_form A a).
* subst. apply le_S. apply IHl.
* simpl. apply le_n_S. apply IHl.
Qed.
Lemma remove_In_smaller_length : forall l (A : MPropF),
In A l -> length (remove eq_dec_form A l) < length l.
Proof.
induction l.
- intros. inversion H.
- intros. simpl. destruct (eq_dec_form A a).
* subst. unfold lt. apply le_n_S. apply remove_le_length.
* simpl. rewrite <- Nat.succ_lt_mono. apply IHl. inversion H. subst. exfalso. apply n. auto.
assumption.
Qed.
Lemma double_remove {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
forall a l, (@remove A eq_dec a (@remove A eq_dec a l)) = (@remove A eq_dec a l).
Proof.
intros a l. induction l.
- simpl. reflexivity.
- simpl. destruct (eq_dec a a0).
* subst. apply IHl.
* simpl. destruct (eq_dec a a0).
+ exfalso. apply n. assumption.
+ rewrite IHl. reflexivity.
Qed.
Lemma permut_remove {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
forall a0 a1 l, (@remove A eq_dec a0 (@remove A eq_dec a1 l)) =
(@remove A eq_dec a1 (@remove A eq_dec a0 l)).
Proof.
intros a0 a1 l. induction l.
- simpl. reflexivity.
- simpl. destruct (eq_dec a1 a).
* subst. simpl. destruct (eq_dec a0 a).
+ subst. reflexivity.
+ simpl. destruct (eq_dec a a). apply IHl. exfalso. apply n0. reflexivity.
* simpl. destruct (eq_dec a0 a).
+ subst. assumption.
+ simpl. destruct (eq_dec a1 a). exfalso. apply n. assumption.
rewrite IHl. reflexivity.
Qed.
Lemma In_remove_diff : forall l (A B : MPropF), In A (remove eq_dec_form B l) -> A <> B.
Proof.
induction l ; intros.
- intro. simpl in H. assumption.
- simpl in H. destruct (eq_dec_form B a).
* subst. apply IHl. assumption.
* inversion H.
+ subst. intro. apply n. symmetry. assumption.
+ apply IHl. assumption.
Qed.
(* Now we define remove_list and prove some lemmas about it. *)
Fixpoint remove_list (l1 l2: list MPropF) : list MPropF :=
match l1 with
| [] => l2
| h1 :: t1 => remove eq_dec_form h1 (remove_list t1 l2)
end.
Lemma remove_list_of_nil : forall (l : list MPropF), remove_list l nil = nil.
Proof.
induction l.
- simpl. reflexivity.
- simpl. rewrite IHl. simpl. reflexivity.
Qed.
Lemma app_remove_list : forall (l1 l2 l3 : list MPropF),
remove_list (l1 ++ l2) l3 = remove_list l1 (remove_list l2 l3).
Proof.
induction l1.
- simpl. firstorder.
- induction l2.
* intro l3. rewrite app_nil_r. simpl. reflexivity.
* intro l3. simpl. pose (IHl1 (a0 :: l2) l3). simpl in e.
rewrite e. reflexivity.
Qed.
Lemma remove_list_preserv_NoDup : forall l1 l2, NoDup l2 -> NoDup (remove_list l1 l2).
Proof.
induction l1.
- intros. simpl. assumption.
- intros. simpl. apply IHl1 in H. apply remove_preserv_NoDup with (A:=a) in H.
assumption.
Qed.
Lemma remove_list_cont : forall l1 A, In A l1 -> (forall l2, In A (remove_list l1 l2) -> False).
Proof.
induction l1.
- intros. inversion H.
- intros. inversion H.
* subst. simpl in H0. apply remove_not_in_anymore in H0. assumption.
* simpl in H0. pose (IHl1 A H1 l2). apply f. apply in_remove_in_init with (B:= a). assumption.
Qed.
Lemma remove_list_dist_app : forall (l1 l2 l3 : list MPropF),
remove_list l1 (l2 ++ l3) = (remove_list l1 l2) ++ (remove_list l1 l3).
Proof.
induction l1.
- intros. simpl. reflexivity.
- simpl. intros. rewrite IHl1. simpl. rewrite remove_dist_app. reflexivity.
Qed.
Lemma permut_remove_remove_list : forall a (l1 l2 : list MPropF),
remove eq_dec_form a (remove_list l1 l2) =
remove_list l1 (remove eq_dec_form a l2).
Proof.
intros a l1. generalize dependent a. induction l1 ; simpl.
- reflexivity.
- intros. rewrite permut_remove. rewrite IHl1. reflexivity.
Qed.
Lemma swap_remove_list : forall (l1 l2 l3 : list MPropF),
remove_list (l1 ++ l2) l3 = remove_list (l2 ++ l1) l3.
Proof.
induction l1.
- intros. rewrite app_nil_l. rewrite app_nil_r. reflexivity.
- induction l2.
* rewrite app_nil_l. rewrite app_nil_r. reflexivity.
* intro l3. simpl. rewrite IHl1. simpl. rewrite permut_remove.
rewrite <- IHl2. simpl. rewrite IHl1. reflexivity.
Qed.
Lemma redund_remove_remove_list : forall a (l1 l2 : list MPropF),
remove eq_dec_form a (remove_list (remove eq_dec_form a l1) l2) =
remove eq_dec_form a (remove_list l1 l2).
Proof.
intro a. induction l1.
- intro l2. simpl. reflexivity.
- intro l2. simpl. destruct (eq_dec_form a a0).
* rewrite IHl1. subst. rewrite double_remove. reflexivity.
* simpl. rewrite permut_remove. rewrite IHl1. apply permut_remove.
Qed.
Lemma redund_remove : forall (l1 l2 l3 : list MPropF) a,
remove eq_dec_form a (remove_list l1 (remove_list (remove eq_dec_form a l2) l3)) =
remove eq_dec_form a (remove_list l1 (remove_list l2 l3)).
Proof.
intros. repeat rewrite <- app_remove_list. rewrite swap_remove_list.
rewrite app_remove_list. rewrite redund_remove_remove_list. rewrite <- app_remove_list.
rewrite swap_remove_list. reflexivity.
Qed.
Lemma redund_remove_list : forall (l1 l2 l3 : list MPropF),
remove_list l1 (remove_list (remove_list l1 l2) l3) = remove_list l1 (remove_list l2 l3).
Proof.
induction l1 ; intros ; simpl.
- reflexivity.
- rewrite redund_remove. rewrite IHl1. reflexivity.
Qed.
Lemma remove_list_in_single : forall l1 a, (In a l1) -> remove_list l1 [a] = nil.
Proof.
induction l1.
- intros. inversion H.
- intros. inversion H.
* subst. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form a0 a0).
apply remove_list_of_nil. exfalso. apply n. reflexivity.
* apply IHl1 in H0. simpl. rewrite H0. simpl. reflexivity.
Qed.
Lemma not_removed_remove_list : forall l2 l1 A, In A l2 -> (In A l1 -> False) -> In A (remove_list l1 l2).
Proof.
induction l2.
- intros. inversion H.
- induction l1.
* intros. simpl. assumption.
* intros. simpl. pose (in_not_touched_remove (remove_list l1 (a :: l2))). pose (i A).
pose (i0 a0). apply i1. apply IHl1. assumption. intro. apply H0. apply in_cons. assumption.
clear i1. clear i0. clear i. destruct (eq_dec_form A a0). intro. apply H0. subst. apply in_eq.
assumption.
Qed.
Lemma add_remove_list_preserve_NoDup : forall (l1 l2 : list MPropF),
NoDup l1 -> NoDup l2 -> NoDup (l1 ++ (remove_list l1 l2)).
Proof.
induction l1.
- intros. rewrite app_nil_l. simpl. assumption.
- intros. simpl. apply NoDup_cons.
* intro. apply in_app_or in H1. destruct H1. inversion H. apply H4. assumption.
apply remove_not_in_anymore in H1. assumption.
* rewrite permut_remove_remove_list. apply IHl1. inversion H. assumption.
apply remove_preserv_NoDup. assumption.
Qed.
Lemma remove_list_is_in : forall l1 l2 A, In A l1 -> In A (l2 ++ (remove_list l2 l1)).
Proof.
intros. pose (In_dec l2 A). destruct s.
- apply in_or_app. left. assumption.
- apply in_or_app. right. apply not_removed_remove_list ; assumption.
Qed.
Lemma In_remove_same : forall l1 l2 (A : MPropF), In A l1 ->
remove_list l1 (A :: l2) = remove_list l1 l2.
Proof.
induction l1.
- intros. inversion H.
- intros. inversion H.
* subst. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form A A).
rewrite permut_remove_remove_list. reflexivity. exfalso. apply n. reflexivity.
* simpl. pose (IHl1 l2 A H0). rewrite e. reflexivity.
Qed.
Lemma In_remove_length_same : forall l1 l2 (A : MPropF), In A l1 ->
length (remove_list l1 (A :: l2)) = length (remove_list l1 l2).
Proof.
intros. rewrite In_remove_same. reflexivity. assumption.
Qed.
Lemma length_le_remove_list : forall (l1 l2 : list MPropF), length (remove_list l1 l2) <= length l2.
Proof.
induction l1.
- intros. auto.
- intros. simpl. rewrite permut_remove_remove_list. pose (IHl1 (remove eq_dec_form a l2)).
apply Nat.le_trans with (m:=length (remove eq_dec_form a l2)). assumption.
apply remove_le_length.
Qed.
Lemma remove_list_singl_id_or_nil : forall l (A : MPropF), remove_list l [A] = nil \/ remove_list l [A] = [A].
Proof.
induction l.
- intros. right. auto.
- intros. pose (IHl A). destruct o. left. simpl. rewrite H. auto.
simpl. rewrite H. destruct (eq_dec_form A a).
* subst. left. simpl. destruct (eq_dec_form a a). reflexivity. exfalso. apply n.
reflexivity.
* right. simpl. destruct (eq_dec_form a A). exfalso. apply n. symmetry. assumption.
reflexivity.
Qed.
Lemma remove_list_non_empty_inter_smaller_length : forall l2 l1 (A : MPropF),
In A l1 -> In A l2 -> length (remove_list l1 l2) < length l2.
Proof.
induction l2.
- intros. inversion H0.
- intros. simpl. destruct (eq_dec_form A a).
* subst. rewrite In_remove_length_same. 2: assumption. unfold lt. apply le_n_S.
apply length_le_remove_list.
* inversion H0.
+ exfalso. apply n. symmetry. assumption.
+ assert (a :: l2 = [a] ++ l2). auto. rewrite H2. rewrite remove_list_dist_app.
rewrite app_length. pose (remove_list_singl_id_or_nil l1 a). destruct o.
rewrite H3. simpl. apply Nat.lt_lt_succ_r. apply IHl2 with (A:=A) ; assumption.
rewrite H3. simpl. rewrite <- Nat.succ_lt_mono. apply IHl2 with (A:=A) ; assumption.
Qed.
Lemma remove_list_delete_head : forall l1 l2 l3 A, remove_list (l1 ++ A :: l2) (A :: l3) = remove_list (l1 ++ A :: l2) l3.
Proof.
induction l1 ; intros ; simpl.
- rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form A A). symmetry. apply permut_remove_remove_list.
exfalso. apply n. reflexivity.
- rewrite IHl1. reflexivity.
Qed.
Lemma remove_list_delete_head_In : forall l1 l2 A, In A l1 -> remove_list l1 (A :: l2) = remove_list l1 l2.
Proof.
intros. pose (In_split A l1 H). destruct e. destruct H0. subst. apply remove_list_delete_head.
Qed.
Lemma remove_list_in_nil : forall l1 l2 l3 A,
remove_list l1 (l2 ++ A :: l3) = nil ->
(existsT2 l4 l5, l1 = l4 ++ A :: l5).
Proof.
induction l1.
- intros. simpl in H. destruct l2 ; inversion H.
- induction l2.
* intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a A).
+ subst. exists []. exists l1. auto.
+ pose (IHl1 [] (remove eq_dec_form a l3)). simpl in s. apply s in H. destruct H. destruct s0.
exists ([a] ++ x). exists x0. subst. auto.
* intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a a0).
+ subst. pose (IHl2 l3 A). apply s. rewrite <- permut_remove_remove_list in H. simpl. assumption.
+ pose (IHl1 [] (remove eq_dec_form a (l2 ++ A :: l3)) a0). pose (s H). repeat destruct s0.
subst. apply IHl2 with (l3:= l3). simpl. rewrite permut_remove_remove_list.
rewrite remove_list_delete_head in H. assumption.
Qed.
Lemma remove_list_is_nil : forall l1 l2, (remove_list l1 l2 = nil <-> (forall A, (In A l2) -> (In A l1))).
Proof.
induction l1.
- intro l2. split.
* intros. simpl in H. rewrite <- H. assumption.
* intros. simpl. destruct l2.
+ reflexivity.
+ exfalso. pose (H m). assert (In m (m :: l2)). apply in_eq. apply i in H0. inversion H0.
- induction l2.
* split.
+ intros. inversion H0.
+ intros. apply remove_list_of_nil.
* split.
+ intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a a0).
subst. inversion H0. subst. apply in_eq. rewrite <- permut_remove_remove_list in H. simpl in IHl2.
rewrite IHl2 in H. apply H in H1. destruct H1. subst. apply in_eq. apply in_cons. assumption.
inversion H0. subst. apply in_cons. pose (remove_list_in_nil l1 [] (remove eq_dec_form a l2) A).
simpl in s. apply s in H. destruct H. destruct s0. subst. apply in_or_app. right. apply in_eq.
apply IHl2. 2: assumption. simpl. rewrite permut_remove_remove_list.
pose (app_eq_nil (remove_list l1 [a0]) (remove_list l1 (remove eq_dec_form a l2))). simpl in a1.
assert (H2: remove_list l1 [a0] ++ remove_list l1 (remove eq_dec_form a l2) = []).
rewrite <- remove_list_dist_app. simpl. assumption. apply a1 in H2. destruct H2. assumption.
+ intros. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form a a0).
{ subst. rewrite <- permut_remove_remove_list. simpl in IHl2. rewrite IHl2. intros.
pose (H A). apply i. apply in_cons. assumption. }
{ assert (H1: (forall A : MPropF, In A l2 -> In A (a :: l1))). intros. apply H.
apply in_cons. assumption. apply IHl2 in H1.
assert (H2: a0 :: remove eq_dec_form a l2 = [a0] ++ remove eq_dec_form a l2). auto.
rewrite H2. rewrite remove_list_dist_app. clear H2. rewrite <- permut_remove_remove_list.
simpl in H1. rewrite H1. rewrite app_nil_r. apply remove_list_in_single. pose (H a0).
assert (H3: In a0 (a0 :: l2)). apply in_eq. apply i in H3. inversion H3. exfalso. apply n.
assumption. assumption. }
Qed.
Lemma remove_delete_origin : forall l1 l2 (A B : MPropF), (A <> B) ->
length (remove eq_dec_form A (l1 ++ B :: l2)) = S (length (remove eq_dec_form A (l1 ++ l2))).
Proof.
induction l1.
- intros. repeat rewrite app_nil_l. simpl. destruct (eq_dec_form A B). exfalso. apply H. assumption.
simpl. reflexivity.
- intros. simpl. destruct (eq_dec_form A a).
* apply IHl1. assumption.
* simpl. apply eq_S. apply IHl1. assumption.
Qed.
Lemma keep_list_delete_head_not_origin : forall l1 l2 l3 A, ((In A l1) -> False) ->
length (remove_list l1 (l2 ++ A :: l3)) = S (length (remove_list l1 (l2 ++ l3))).
Proof.
induction l1.
- intros. simpl. rewrite app_length. simpl. rewrite app_length. auto.
- intros. simpl. repeat rewrite remove_list_dist_app. assert (In A l1 -> False).
intro. apply H. apply in_cons. assumption. assert (A :: l3 = [A] ++ l3).
auto. rewrite H1. rewrite remove_list_dist_app. pose (remove_list_singl_id_or_nil l1 A).
destruct o. exfalso. rewrite remove_list_is_nil in H2. apply H0. apply H2.
apply in_eq. rewrite H2. apply remove_delete_origin. intro. apply H. subst. apply in_eq.
Qed.
Lemma keep_list_delete_head_not_In : forall l1 l2 A, ((In A l1) -> False) ->
length (remove_list l1 (A :: l2)) = S (length (remove_list l1 l2)).
Proof.
intros. pose (@keep_list_delete_head_not_origin l1 [] l2 A H). repeat rewrite app_nil_l in e.
assumption.
Qed.
Lemma In_remove_In_list : forall (A B : MPropF) l, In A (remove eq_dec_form B l) -> In A l.
Proof.
induction l ; intros.
- simpl in H. destruct H.
- simpl in H. destruct (eq_dec_form B a).
* subst. apply in_cons. apply IHl. assumption.
* inversion H.
+ subst. apply in_eq.
+ apply in_cons. apply IHl. assumption.
Qed.
Lemma In_remove_list_In_list : forall (A : MPropF) l1 l2, In A (remove_list l1 l2) -> In A l2.
Proof.
intro A. induction l1 ; intros.
- simpl in H. assumption.
- simpl in H. apply In_remove_In_list in H. apply IHl1. assumption.
Qed.
Lemma In_remove_list_In_list_not_In_remove_list : forall (A : MPropF) l1 l2,
In A (remove_list l1 l2) -> (In A l2 /\ ((In A l1) -> False)).
Proof.
intro A. induction l1 ; intros.
- simpl in H. split. assumption. intro. inversion H0.
- simpl in H. split. apply In_remove_In_list in H. apply IHl1. assumption. intro.
inversion H0.
* subst. apply remove_not_in_anymore in H. assumption.
* apply In_remove_In_list in H. apply IHl1 in H. destruct H. apply H2. assumption.
Qed.
Lemma remove_list_incr_decr3 : forall (l3 l2 l1 : list MPropF),
(incl l1 l2) ->
length (remove_list l2 l3) <= length (remove_list l1 l3).
Proof.
induction l3 ; intros.
- repeat rewrite remove_list_of_nil. auto.
- destruct (In_dec l2 a).
+ rewrite remove_list_delete_head_In. 2: assumption. destruct (In_dec l1 a).
* rewrite remove_list_delete_head_In. 2: assumption. apply IHl3 ; auto.
* rewrite keep_list_delete_head_not_In. 2: assumption. apply Nat.le_le_succ_r.
apply IHl3. assumption.
+ repeat rewrite keep_list_delete_head_not_In. apply le_n_S. apply IHl3 ; auto.
intro. apply f. apply H. assumption. assumption.
Qed.
Lemma remove_list_incr_decr1 : forall (l3 l1 l2: list MPropF),
(exists A, In A l2 /\ In A l3 /\ (In A l1 -> False)) ->
(incl l1 l2) ->
length (remove_list l2 l3) < length (remove_list l1 l3).
Proof.
induction l3.
- intros. destruct H. destruct H. destruct H1. exfalso. inversion H1.
- intros. destruct H. destruct H. destruct H1. destruct (eq_dec_form a x).
* subst. rewrite remove_list_delete_head_In. 2: assumption.
rewrite keep_list_delete_head_not_In. 2: assumption. unfold lt.
apply le_n_S. apply remove_list_incr_decr3. assumption.
* inversion H1. exfalso. apply n ; assumption.
assert (H4: exists A : MPropF, In A l2 /\ In A l3 /\ (In A l1 -> False)).
exists x. auto. apply IHl3 in H4. 2 : assumption. unfold lt.
destruct (In_dec l2 a).
+ rewrite remove_list_delete_head_In. 2: assumption. destruct (In_dec l1 a).
{ rewrite remove_list_delete_head_In. 2: assumption. apply H4. }
{ rewrite keep_list_delete_head_not_In. 2: assumption. apply le_n_S.
unfold lt in H4. apply Nat.lt_le_incl. assumption. }
+ rewrite keep_list_delete_head_not_In. 2: assumption. rewrite keep_list_delete_head_not_In.
unfold lt in H4. apply le_n_S. assumption. intro. apply f. apply H0. assumption.
Qed.
Lemma remove_list_incr_decr2 : forall (l4 l3 l1 : list MPropF),
(NoDup l4) ->
(NoDup l3) ->
(incl l4 l3) ->
length (remove_list l1 l4) <= length (remove_list l1 l3).
Proof.
induction l4.
- intros. rewrite remove_list_of_nil. simpl. apply le_0_n.
- intros. destruct (In_dec l1 a).
* rewrite remove_list_delete_head_In. 2: assumption. apply IHl4 ; try assumption.
inversion H. assumption. unfold incl. intros. apply H1. apply in_cons. assumption.
* rewrite keep_list_delete_head_not_In. 2: assumption. assert (H2: In a l3). apply H1.
apply in_eq. pose (in_split a l3 H2). repeat destruct e. destruct H3. rewrite H3.
rewrite keep_list_delete_head_not_origin. 2: assumption. apply le_n_S. apply IHl4.
inversion H. assumption. subst. apply NoDup_destr_split with (A:=a). assumption.
inversion H. unfold incl. intros. subst. assert (H9 : In a0 (a :: l4)). apply in_cons.
assumption. pose (H1 a0 H9). apply in_app_or in i. destruct i. apply in_or_app. left.
assumption. inversion H3. subst. exfalso. apply H6. assumption. apply in_or_app. right.
assumption.
Qed.
Lemma remove_list_incr_decr4 : forall (l4 l3 l1: list MPropF),
(NoDup l4) ->
(NoDup l3) ->
(incl l4 l3) ->
((incl l3 l4) -> False) ->
(exists A, (In A l3) /\ ((In A l1) -> False) /\ ((In A l4) -> False)) ->
length (remove_list l1 l4) < length (remove_list l1 l3).
Proof.
induction l4.
- intros. rewrite remove_list_of_nil. simpl. destruct H3. destruct H3. destruct H4. pose (In_split x l3 H3).
destruct e. destruct H6. subst. rewrite keep_list_delete_head_not_origin. 2: assumption.
apply Nat.lt_0_succ.
- intros. destruct (In_dec l1 a).
* rewrite remove_list_delete_head_In. 2: assumption. apply IHl4 ; try assumption.
inversion H. assumption. unfold incl. intros. apply H1. apply in_cons. assumption.
intro. apply H2. unfold incl. intros. apply in_cons. apply H4. assumption. destruct H3.
destruct H3. destruct H4. exists x. repeat split ; try assumption. intro. apply H5.
apply in_cons. assumption.
* rewrite keep_list_delete_head_not_In. 2: assumption. assert (In a l3). apply H1.
apply in_eq. pose (In_split a l3 H4). destruct e. destruct H5. subst.
rewrite keep_list_delete_head_not_origin. 2 : assumption. rewrite <- Nat.succ_lt_mono.
apply IHl4. inversion H. assumption. apply NoDup_destr_split with (A:=a). assumption.
unfold incl. intros. pose (H1 a0). assert (In a0 (a :: l4)). apply in_cons. assumption.
apply i in H6. apply in_app_or in H6. destruct H6. apply in_or_app. left. assumption.
inversion H6. subst. inversion H. exfalso. apply H9. assumption. apply in_or_app. right.
assumption. intro. apply H2. unfold incl. intros. apply in_app_or in H6. destruct H6.
apply in_cons. apply H5. apply in_or_app. left. assumption. inversion H6. subst. apply in_eq.
apply in_cons. apply H5. apply in_or_app. right. assumption.
destruct H3. destruct H3. destruct H5. exists x1. repeat split ; try assumption.
apply in_app_or in H3. destruct H3. apply in_or_app. left. assumption. inversion H3.
subst. exfalso. apply H6. apply in_eq. apply in_or_app. right. assumption.
intro. apply H6. apply in_cons. assumption.
Qed.
Lemma remove_list_incr_decr : forall (l1 l2 l3 l4 : list MPropF),
(NoDup l4) ->
(NoDup l3) ->
(exists A, In A l2 /\ In A l3 /\ (In A l1 -> False)) ->
(incl l1 l2) ->
(incl l4 l3) ->
length (remove_list l2 l4) < length (remove_list l1 l3).
Proof.
intros. unfold lt.
pose (remove_list_incr_decr2 l1 H H0 H3).
repeat destruct H1. destruct H4. destruct (In_dec l4 x).
- assert (H6: (exists A, In A l2 /\ In A l4 /\ (In A l1 -> False))).
exists x. repeat split ; assumption. pose (@remove_list_incr_decr1 l4 l1 l2 H6 H2).
unfold lt in l0. apply Nat.le_trans with (m:=length (remove_list l1 l4)) ; assumption.
- assert ((incl l3 l4) -> False). intros. apply f. apply H6. assumption.
assert ((exists A, (In A l3) /\ ((In A l1) -> False) /\ ((In A l4) -> False))). exists x. auto.
pose (@remove_list_incr_decr3 l4 l2 l1 H2). pose (@remove_list_incr_decr4 l4 l3 l1 H H0 H3 H6 H7).
unfold lt in l5. apply le_n_S in l0. lia.
Qed.
Lemma In_remove_list_remove_redund : forall l1 l2 a, In a l1 ->
remove eq_dec_form a (remove_list l1 l2) = remove_list l1 l2.
Proof.
induction l1.
- intros. inversion H.
- intros. simpl. inversion H.
* subst. rewrite double_remove. reflexivity.
* pose (IHl1 l2 a0 H0). rewrite permut_remove. rewrite e. reflexivity.
Qed.
Lemma In_matters_remove_list : forall l1 l2, (incl l1 l2 /\ incl l2 l1) -> (forall l0,
remove_list l1 l0 = remove_list l2 l0).
Proof.
induction l1.
- intros. destruct H. destruct l2. auto. unfold incl in H0. pose (H0 m). assert (In m (m :: l2)).
apply in_eq. apply i in H1. inversion H1.
- intros. destruct H. simpl. pose (H a). assert (In a (a :: l1)). apply in_eq. apply i in H1.
apply in_split in H1. destruct H1. destruct H1. subst. destruct (In_dec l1 a).
* rewrite In_remove_list_remove_redund. 2: assumption. apply IHl1. split. intro. intro.
apply H. apply in_cons. assumption. intro. intro. apply H0 in H1. inversion H1. subst.
assumption. assumption.
* rewrite swap_remove_list. simpl. rewrite <- redund_remove_remove_list with (l1:=(x0 ++ x)).
pose (IHl1 (remove eq_dec_form a (x0 ++ x))). rewrite e.
auto. split. intro. intro. apply in_not_touched_remove. assert (In a0 (a :: l1)). apply in_cons.
assumption. apply H in H2. apply in_app_or in H2. destruct H2. apply in_or_app. right. assumption.
inversion H2. subst. exfalso. apply f. assumption. apply in_or_app. left. assumption.
intro. subst. apply f. assumption. intro. intro. pose (In_remove_diff (x0 ++ x) H1).
pose (In_remove_In_list a0 a (x0 ++ x) H1). assert (In a0 (x ++ a :: x0)). apply in_app_or in i0.
destruct i0. apply in_or_app. right. apply in_cons. assumption. apply in_or_app. left. assumption.
apply H0 in H2. inversion H2. exfalso. apply n. symmetry. assumption. assumption.
Qed.
Export ListNotations.
Require Import PeanoNat.
Require Import Lia.
Require Import existsT.
Require Import G4iSLT_calc.
Set Implicit Arguments.
Lemma In_dec : forall l (a : MPropF) , (In a l) + ((In a l) -> False).
Proof.
induction l.
- right. intro. destruct H.
- intro a0. pose (IHl a0). destruct s.
* left. apply in_cons. assumption.
* destruct (eq_dec_form a a0).
+ subst. left. apply in_eq.
+ right. intro. inversion H.
{ apply n. assumption. }
{ apply f. assumption. }
Qed.
(* Let us prove some lemmas about remove. *)
Lemma in_not_touched_remove : forall l1 (a0 a1 : MPropF),
In a0 l1 -> a0 <> a1 -> In a0 (remove eq_dec_form a1 l1).
Proof.
induction l1.
- intros. inversion H.
- intros. simpl. destruct (eq_dec_form a1 a).
* subst. apply IHl1. inversion H. exfalso. apply H0. auto. assumption. assumption.
* inversion H. subst. apply in_eq. apply in_cons. apply IHl1. assumption. assumption.
Qed.
Lemma remove_dist_app {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
forall (a : A) l1 l2, (@remove A eq_dec a (l1 ++ l2)) =
(@remove A eq_dec a l1) ++ (@remove A eq_dec a l2).
Proof.
intros a l1. induction l1.
- intro l2. rewrite app_nil_l. simpl. reflexivity.
- intro l2. simpl. destruct (eq_dec a a0).
* apply IHl1.
* simpl. rewrite IHl1. reflexivity.
Qed.
Lemma remove_not_in_anymore : forall l (A : MPropF),
(In A (remove eq_dec_form A l)) -> False.
Proof.
induction l.
- intros. simpl in H. inversion H.
- intros. simpl in H. destruct (eq_dec_form A a). subst. apply IHl in H. assumption.
inversion H. apply n. symmetry. assumption. apply IHl in H0. assumption.
Qed.
Lemma in_remove_in_init : forall l A B,
In A (remove eq_dec_form B l) -> In A l.
Proof.
induction l.
- intros. simpl. inversion H.
- intros. destruct (eq_dec_form A a). subst. apply in_eq. apply in_cons.
pose (IHl A B). apply i. simpl in H. destruct (eq_dec_form B a).
* subst. assumption.
* inversion H. exfalso. apply n. symmetry. assumption. assumption.
Qed.
Lemma remove_preserv_NoDup : forall l (A : MPropF), NoDup l -> NoDup (remove eq_dec_form A l).
Proof.
induction l.
- intros. simpl. apply NoDup_nil.
- intros. simpl. destruct (eq_dec_form A a).
* subst. apply IHl. inversion H. assumption.
* apply NoDup_cons. intro. apply in_remove_in_init in H0. inversion H. apply H3. assumption.
apply IHl. inversion H. assumption.
Qed.
Lemma NoDup_destr_split : forall l1 l2 (A : MPropF), NoDup (l1 ++ A :: l2) -> NoDup (l1 ++ l2).
Proof.
induction l1.
- intros. rewrite app_nil_l. rewrite app_nil_l in H. inversion H. assumption.
- intros. simpl. apply NoDup_cons. intro. inversion H. subst. apply H3. apply in_app_or in H0.
destruct H0. apply in_or_app. left. assumption. apply in_or_app. right. apply in_cons.
assumption. simpl in H. inversion H. subst. apply IHl1 with (A:=A). assumption.
Qed.
Lemma remove_le_length : forall l (A : MPropF), length (remove eq_dec_form A l) <= length l.
Proof.
induction l.
- intros. simpl. reflexivity.
- intros. simpl. destruct (eq_dec_form A a).
* subst. apply le_S. apply IHl.
* simpl. apply le_n_S. apply IHl.
Qed.
Lemma remove_In_smaller_length : forall l (A : MPropF),
In A l -> length (remove eq_dec_form A l) < length l.
Proof.
induction l.
- intros. inversion H.
- intros. simpl. destruct (eq_dec_form A a).
* subst. unfold lt. apply le_n_S. apply remove_le_length.
* simpl. rewrite <- Nat.succ_lt_mono. apply IHl. inversion H. subst. exfalso. apply n. auto.
assumption.
Qed.
Lemma double_remove {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
forall a l, (@remove A eq_dec a (@remove A eq_dec a l)) = (@remove A eq_dec a l).
Proof.
intros a l. induction l.
- simpl. reflexivity.
- simpl. destruct (eq_dec a a0).
* subst. apply IHl.
* simpl. destruct (eq_dec a a0).
+ exfalso. apply n. assumption.
+ rewrite IHl. reflexivity.
Qed.
Lemma permut_remove {A : Type} (eq_dec : forall x y : A, {x = y} + {x <> y}) :
forall a0 a1 l, (@remove A eq_dec a0 (@remove A eq_dec a1 l)) =
(@remove A eq_dec a1 (@remove A eq_dec a0 l)).
Proof.
intros a0 a1 l. induction l.
- simpl. reflexivity.
- simpl. destruct (eq_dec a1 a).
* subst. simpl. destruct (eq_dec a0 a).
+ subst. reflexivity.
+ simpl. destruct (eq_dec a a). apply IHl. exfalso. apply n0. reflexivity.
* simpl. destruct (eq_dec a0 a).
+ subst. assumption.
+ simpl. destruct (eq_dec a1 a). exfalso. apply n. assumption.
rewrite IHl. reflexivity.
Qed.
Lemma In_remove_diff : forall l (A B : MPropF), In A (remove eq_dec_form B l) -> A <> B.
Proof.
induction l ; intros.
- intro. simpl in H. assumption.
- simpl in H. destruct (eq_dec_form B a).
* subst. apply IHl. assumption.
* inversion H.
+ subst. intro. apply n. symmetry. assumption.
+ apply IHl. assumption.
Qed.
(* Now we define remove_list and prove some lemmas about it. *)
Fixpoint remove_list (l1 l2: list MPropF) : list MPropF :=
match l1 with
| [] => l2
| h1 :: t1 => remove eq_dec_form h1 (remove_list t1 l2)
end.
Lemma remove_list_of_nil : forall (l : list MPropF), remove_list l nil = nil.
Proof.
induction l.
- simpl. reflexivity.
- simpl. rewrite IHl. simpl. reflexivity.
Qed.
Lemma app_remove_list : forall (l1 l2 l3 : list MPropF),
remove_list (l1 ++ l2) l3 = remove_list l1 (remove_list l2 l3).
Proof.
induction l1.
- simpl. firstorder.
- induction l2.
* intro l3. rewrite app_nil_r. simpl. reflexivity.
* intro l3. simpl. pose (IHl1 (a0 :: l2) l3). simpl in e.
rewrite e. reflexivity.
Qed.
Lemma remove_list_preserv_NoDup : forall l1 l2, NoDup l2 -> NoDup (remove_list l1 l2).
Proof.
induction l1.
- intros. simpl. assumption.
- intros. simpl. apply IHl1 in H. apply remove_preserv_NoDup with (A:=a) in H.
assumption.
Qed.
Lemma remove_list_cont : forall l1 A, In A l1 -> (forall l2, In A (remove_list l1 l2) -> False).
Proof.
induction l1.
- intros. inversion H.
- intros. inversion H.
* subst. simpl in H0. apply remove_not_in_anymore in H0. assumption.
* simpl in H0. pose (IHl1 A H1 l2). apply f. apply in_remove_in_init with (B:= a). assumption.
Qed.
Lemma remove_list_dist_app : forall (l1 l2 l3 : list MPropF),
remove_list l1 (l2 ++ l3) = (remove_list l1 l2) ++ (remove_list l1 l3).
Proof.
induction l1.
- intros. simpl. reflexivity.
- simpl. intros. rewrite IHl1. simpl. rewrite remove_dist_app. reflexivity.
Qed.
Lemma permut_remove_remove_list : forall a (l1 l2 : list MPropF),
remove eq_dec_form a (remove_list l1 l2) =
remove_list l1 (remove eq_dec_form a l2).
Proof.
intros a l1. generalize dependent a. induction l1 ; simpl.
- reflexivity.
- intros. rewrite permut_remove. rewrite IHl1. reflexivity.
Qed.
Lemma swap_remove_list : forall (l1 l2 l3 : list MPropF),
remove_list (l1 ++ l2) l3 = remove_list (l2 ++ l1) l3.
Proof.
induction l1.
- intros. rewrite app_nil_l. rewrite app_nil_r. reflexivity.
- induction l2.
* rewrite app_nil_l. rewrite app_nil_r. reflexivity.
* intro l3. simpl. rewrite IHl1. simpl. rewrite permut_remove.
rewrite <- IHl2. simpl. rewrite IHl1. reflexivity.
Qed.
Lemma redund_remove_remove_list : forall a (l1 l2 : list MPropF),
remove eq_dec_form a (remove_list (remove eq_dec_form a l1) l2) =
remove eq_dec_form a (remove_list l1 l2).
Proof.
intro a. induction l1.
- intro l2. simpl. reflexivity.
- intro l2. simpl. destruct (eq_dec_form a a0).
* rewrite IHl1. subst. rewrite double_remove. reflexivity.
* simpl. rewrite permut_remove. rewrite IHl1. apply permut_remove.
Qed.
Lemma redund_remove : forall (l1 l2 l3 : list MPropF) a,
remove eq_dec_form a (remove_list l1 (remove_list (remove eq_dec_form a l2) l3)) =
remove eq_dec_form a (remove_list l1 (remove_list l2 l3)).
Proof.
intros. repeat rewrite <- app_remove_list. rewrite swap_remove_list.
rewrite app_remove_list. rewrite redund_remove_remove_list. rewrite <- app_remove_list.
rewrite swap_remove_list. reflexivity.
Qed.
Lemma redund_remove_list : forall (l1 l2 l3 : list MPropF),
remove_list l1 (remove_list (remove_list l1 l2) l3) = remove_list l1 (remove_list l2 l3).
Proof.
induction l1 ; intros ; simpl.
- reflexivity.
- rewrite redund_remove. rewrite IHl1. reflexivity.
Qed.
Lemma remove_list_in_single : forall l1 a, (In a l1) -> remove_list l1 [a] = nil.
Proof.
induction l1.
- intros. inversion H.
- intros. inversion H.
* subst. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form a0 a0).
apply remove_list_of_nil. exfalso. apply n. reflexivity.
* apply IHl1 in H0. simpl. rewrite H0. simpl. reflexivity.
Qed.
Lemma not_removed_remove_list : forall l2 l1 A, In A l2 -> (In A l1 -> False) -> In A (remove_list l1 l2).
Proof.
induction l2.
- intros. inversion H.
- induction l1.
* intros. simpl. assumption.
* intros. simpl. pose (in_not_touched_remove (remove_list l1 (a :: l2))). pose (i A).
pose (i0 a0). apply i1. apply IHl1. assumption. intro. apply H0. apply in_cons. assumption.
clear i1. clear i0. clear i. destruct (eq_dec_form A a0). intro. apply H0. subst. apply in_eq.
assumption.
Qed.
Lemma add_remove_list_preserve_NoDup : forall (l1 l2 : list MPropF),
NoDup l1 -> NoDup l2 -> NoDup (l1 ++ (remove_list l1 l2)).
Proof.
induction l1.
- intros. rewrite app_nil_l. simpl. assumption.
- intros. simpl. apply NoDup_cons.
* intro. apply in_app_or in H1. destruct H1. inversion H. apply H4. assumption.
apply remove_not_in_anymore in H1. assumption.
* rewrite permut_remove_remove_list. apply IHl1. inversion H. assumption.
apply remove_preserv_NoDup. assumption.
Qed.
Lemma remove_list_is_in : forall l1 l2 A, In A l1 -> In A (l2 ++ (remove_list l2 l1)).
Proof.
intros. pose (In_dec l2 A). destruct s.
- apply in_or_app. left. assumption.
- apply in_or_app. right. apply not_removed_remove_list ; assumption.
Qed.
Lemma In_remove_same : forall l1 l2 (A : MPropF), In A l1 ->
remove_list l1 (A :: l2) = remove_list l1 l2.
Proof.
induction l1.
- intros. inversion H.
- intros. inversion H.
* subst. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form A A).
rewrite permut_remove_remove_list. reflexivity. exfalso. apply n. reflexivity.
* simpl. pose (IHl1 l2 A H0). rewrite e. reflexivity.
Qed.
Lemma In_remove_length_same : forall l1 l2 (A : MPropF), In A l1 ->
length (remove_list l1 (A :: l2)) = length (remove_list l1 l2).
Proof.
intros. rewrite In_remove_same. reflexivity. assumption.
Qed.
Lemma length_le_remove_list : forall (l1 l2 : list MPropF), length (remove_list l1 l2) <= length l2.
Proof.
induction l1.
- intros. auto.
- intros. simpl. rewrite permut_remove_remove_list. pose (IHl1 (remove eq_dec_form a l2)).
apply Nat.le_trans with (m:=length (remove eq_dec_form a l2)). assumption.
apply remove_le_length.
Qed.
Lemma remove_list_singl_id_or_nil : forall l (A : MPropF), remove_list l [A] = nil \/ remove_list l [A] = [A].
Proof.
induction l.
- intros. right. auto.
- intros. pose (IHl A). destruct o. left. simpl. rewrite H. auto.
simpl. rewrite H. destruct (eq_dec_form A a).
* subst. left. simpl. destruct (eq_dec_form a a). reflexivity. exfalso. apply n.
reflexivity.
* right. simpl. destruct (eq_dec_form a A). exfalso. apply n. symmetry. assumption.
reflexivity.
Qed.
Lemma remove_list_non_empty_inter_smaller_length : forall l2 l1 (A : MPropF),
In A l1 -> In A l2 -> length (remove_list l1 l2) < length l2.
Proof.
induction l2.
- intros. inversion H0.
- intros. simpl. destruct (eq_dec_form A a).
* subst. rewrite In_remove_length_same. 2: assumption. unfold lt. apply le_n_S.
apply length_le_remove_list.
* inversion H0.
+ exfalso. apply n. symmetry. assumption.
+ assert (a :: l2 = [a] ++ l2). auto. rewrite H2. rewrite remove_list_dist_app.
rewrite app_length. pose (remove_list_singl_id_or_nil l1 a). destruct o.
rewrite H3. simpl. apply Nat.lt_lt_succ_r. apply IHl2 with (A:=A) ; assumption.
rewrite H3. simpl. rewrite <- Nat.succ_lt_mono. apply IHl2 with (A:=A) ; assumption.
Qed.
Lemma remove_list_delete_head : forall l1 l2 l3 A, remove_list (l1 ++ A :: l2) (A :: l3) = remove_list (l1 ++ A :: l2) l3.
Proof.
induction l1 ; intros ; simpl.
- rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form A A). symmetry. apply permut_remove_remove_list.
exfalso. apply n. reflexivity.
- rewrite IHl1. reflexivity.
Qed.
Lemma remove_list_delete_head_In : forall l1 l2 A, In A l1 -> remove_list l1 (A :: l2) = remove_list l1 l2.
Proof.
intros. pose (In_split A l1 H). destruct e. destruct H0. subst. apply remove_list_delete_head.
Qed.
Lemma remove_list_in_nil : forall l1 l2 l3 A,
remove_list l1 (l2 ++ A :: l3) = nil ->
(existsT2 l4 l5, l1 = l4 ++ A :: l5).
Proof.
induction l1.
- intros. simpl in H. destruct l2 ; inversion H.
- induction l2.
* intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a A).
+ subst. exists []. exists l1. auto.
+ pose (IHl1 [] (remove eq_dec_form a l3)). simpl in s. apply s in H. destruct H. destruct s0.
exists ([a] ++ x). exists x0. subst. auto.
* intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a a0).
+ subst. pose (IHl2 l3 A). apply s. rewrite <- permut_remove_remove_list in H. simpl. assumption.
+ pose (IHl1 [] (remove eq_dec_form a (l2 ++ A :: l3)) a0). pose (s H). repeat destruct s0.
subst. apply IHl2 with (l3:= l3). simpl. rewrite permut_remove_remove_list.
rewrite remove_list_delete_head in H. assumption.
Qed.
Lemma remove_list_is_nil : forall l1 l2, (remove_list l1 l2 = nil <-> (forall A, (In A l2) -> (In A l1))).
Proof.
induction l1.
- intro l2. split.
* intros. simpl in H. rewrite <- H. assumption.
* intros. simpl. destruct l2.
+ reflexivity.
+ exfalso. pose (H m). assert (In m (m :: l2)). apply in_eq. apply i in H0. inversion H0.
- induction l2.
* split.
+ intros. inversion H0.
+ intros. apply remove_list_of_nil.
* split.
+ intros. simpl in H. rewrite permut_remove_remove_list in H. simpl in H. destruct (eq_dec_form a a0).
subst. inversion H0. subst. apply in_eq. rewrite <- permut_remove_remove_list in H. simpl in IHl2.
rewrite IHl2 in H. apply H in H1. destruct H1. subst. apply in_eq. apply in_cons. assumption.
inversion H0. subst. apply in_cons. pose (remove_list_in_nil l1 [] (remove eq_dec_form a l2) A).
simpl in s. apply s in H. destruct H. destruct s0. subst. apply in_or_app. right. apply in_eq.
apply IHl2. 2: assumption. simpl. rewrite permut_remove_remove_list.
pose (app_eq_nil (remove_list l1 [a0]) (remove_list l1 (remove eq_dec_form a l2))). simpl in a1.
assert (H2: remove_list l1 [a0] ++ remove_list l1 (remove eq_dec_form a l2) = []).
rewrite <- remove_list_dist_app. simpl. assumption. apply a1 in H2. destruct H2. assumption.
+ intros. simpl. rewrite permut_remove_remove_list. simpl. destruct (eq_dec_form a a0).
{ subst. rewrite <- permut_remove_remove_list. simpl in IHl2. rewrite IHl2. intros.
pose (H A). apply i. apply in_cons. assumption. }
{ assert (H1: (forall A : MPropF, In A l2 -> In A (a :: l1))). intros. apply H.
apply in_cons. assumption. apply IHl2 in H1.
assert (H2: a0 :: remove eq_dec_form a l2 = [a0] ++ remove eq_dec_form a l2). auto.
rewrite H2. rewrite remove_list_dist_app. clear H2. rewrite <- permut_remove_remove_list.
simpl in H1. rewrite H1. rewrite app_nil_r. apply remove_list_in_single. pose (H a0).
assert (H3: In a0 (a0 :: l2)). apply in_eq. apply i in H3. inversion H3. exfalso. apply n.
assumption. assumption. }
Qed.
Lemma remove_delete_origin : forall l1 l2 (A B : MPropF), (A <> B) ->
length (remove eq_dec_form A (l1 ++ B :: l2)) = S (length (remove eq_dec_form A (l1 ++ l2))).
Proof.
induction l1.
- intros. repeat rewrite app_nil_l. simpl. destruct (eq_dec_form A B). exfalso. apply H. assumption.
simpl. reflexivity.
- intros. simpl. destruct (eq_dec_form A a).
* apply IHl1. assumption.
* simpl. apply eq_S. apply IHl1. assumption.
Qed.
Lemma keep_list_delete_head_not_origin : forall l1 l2 l3 A, ((In A l1) -> False) ->
length (remove_list l1 (l2 ++ A :: l3)) = S (length (remove_list l1 (l2 ++ l3))).
Proof.
induction l1.
- intros. simpl. rewrite app_length. simpl. rewrite app_length. auto.
- intros. simpl. repeat rewrite remove_list_dist_app. assert (In A l1 -> False).
intro. apply H. apply in_cons. assumption. assert (A :: l3 = [A] ++ l3).
auto. rewrite H1. rewrite remove_list_dist_app. pose (remove_list_singl_id_or_nil l1 A).
destruct o. exfalso. rewrite remove_list_is_nil in H2. apply H0. apply H2.
apply in_eq. rewrite H2. apply remove_delete_origin. intro. apply H. subst. apply in_eq.
Qed.
Lemma keep_list_delete_head_not_In : forall l1 l2 A, ((In A l1) -> False) ->
length (remove_list l1 (A :: l2)) = S (length (remove_list l1 l2)).
Proof.
intros. pose (@keep_list_delete_head_not_origin l1 [] l2 A H). repeat rewrite app_nil_l in e.
assumption.
Qed.
Lemma In_remove_In_list : forall (A B : MPropF) l, In A (remove eq_dec_form B l) -> In A l.
Proof.
induction l ; intros.
- simpl in H. destruct H.
- simpl in H. destruct (eq_dec_form B a).
* subst. apply in_cons. apply IHl. assumption.
* inversion H.
+ subst. apply in_eq.
+ apply in_cons. apply IHl. assumption.
Qed.
Lemma In_remove_list_In_list : forall (A : MPropF) l1 l2, In A (remove_list l1 l2) -> In A l2.
Proof.
intro A. induction l1 ; intros.
- simpl in H. assumption.
- simpl in H. apply In_remove_In_list in H. apply IHl1. assumption.
Qed.
Lemma In_remove_list_In_list_not_In_remove_list : forall (A : MPropF) l1 l2,
In A (remove_list l1 l2) -> (In A l2 /\ ((In A l1) -> False)).
Proof.
intro A. induction l1 ; intros.
- simpl in H. split. assumption. intro. inversion H0.
- simpl in H. split. apply In_remove_In_list in H. apply IHl1. assumption. intro.
inversion H0.
* subst. apply remove_not_in_anymore in H. assumption.
* apply In_remove_In_list in H. apply IHl1 in H. destruct H. apply H2. assumption.
Qed.
Lemma remove_list_incr_decr3 : forall (l3 l2 l1 : list MPropF),
(incl l1 l2) ->
length (remove_list l2 l3) <= length (remove_list l1 l3).
Proof.
induction l3 ; intros.
- repeat rewrite remove_list_of_nil. auto.
- destruct (In_dec l2 a).
+ rewrite remove_list_delete_head_In. 2: assumption. destruct (In_dec l1 a).
* rewrite remove_list_delete_head_In. 2: assumption. apply IHl3 ; auto.
* rewrite keep_list_delete_head_not_In. 2: assumption. apply Nat.le_le_succ_r.
apply IHl3. assumption.
+ repeat rewrite keep_list_delete_head_not_In. apply le_n_S. apply IHl3 ; auto.
intro. apply f. apply H. assumption. assumption.
Qed.
Lemma remove_list_incr_decr1 : forall (l3 l1 l2: list MPropF),
(exists A, In A l2 /\ In A l3 /\ (In A l1 -> False)) ->
(incl l1 l2) ->
length (remove_list l2 l3) < length (remove_list l1 l3).
Proof.
induction l3.
- intros. destruct H. destruct H. destruct H1. exfalso. inversion H1.
- intros. destruct H. destruct H. destruct H1. destruct (eq_dec_form a x).
* subst. rewrite remove_list_delete_head_In. 2: assumption.
rewrite keep_list_delete_head_not_In. 2: assumption. unfold lt.
apply le_n_S. apply remove_list_incr_decr3. assumption.
* inversion H1. exfalso. apply n ; assumption.
assert (H4: exists A : MPropF, In A l2 /\ In A l3 /\ (In A l1 -> False)).
exists x. auto. apply IHl3 in H4. 2 : assumption. unfold lt.
destruct (In_dec l2 a).
+ rewrite remove_list_delete_head_In. 2: assumption. destruct (In_dec l1 a).
{ rewrite remove_list_delete_head_In. 2: assumption. apply H4. }
{ rewrite keep_list_delete_head_not_In. 2: assumption. apply le_n_S.
unfold lt in H4. apply Nat.lt_le_incl. assumption. }
+ rewrite keep_list_delete_head_not_In. 2: assumption. rewrite keep_list_delete_head_not_In.
unfold lt in H4. apply le_n_S. assumption. intro. apply f. apply H0. assumption.
Qed.
Lemma remove_list_incr_decr2 : forall (l4 l3 l1 : list MPropF),
(NoDup l4) ->
(NoDup l3) ->
(incl l4 l3) ->
length (remove_list l1 l4) <= length (remove_list l1 l3).
Proof.
induction l4.
- intros. rewrite remove_list_of_nil. simpl. apply le_0_n.
- intros. destruct (In_dec l1 a).
* rewrite remove_list_delete_head_In. 2: assumption. apply IHl4 ; try assumption.
inversion H. assumption. unfold incl. intros. apply H1. apply in_cons. assumption.
* rewrite keep_list_delete_head_not_In. 2: assumption. assert (H2: In a l3). apply H1.
apply in_eq. pose (in_split a l3 H2). repeat destruct e. destruct H3. rewrite H3.
rewrite keep_list_delete_head_not_origin. 2: assumption. apply le_n_S. apply IHl4.
inversion H. assumption. subst. apply NoDup_destr_split with (A:=a). assumption.
inversion H. unfold incl. intros. subst. assert (H9 : In a0 (a :: l4)). apply in_cons.
assumption. pose (H1 a0 H9). apply in_app_or in i. destruct i. apply in_or_app. left.
assumption. inversion H3. subst. exfalso. apply H6. assumption. apply in_or_app. right.
assumption.
Qed.
Lemma remove_list_incr_decr4 : forall (l4 l3 l1: list MPropF),
(NoDup l4) ->
(NoDup l3) ->
(incl l4 l3) ->
((incl l3 l4) -> False) ->
(exists A, (In A l3) /\ ((In A l1) -> False) /\ ((In A l4) -> False)) ->
length (remove_list l1 l4) < length (remove_list l1 l3).
Proof.
induction l4.
- intros. rewrite remove_list_of_nil. simpl. destruct H3. destruct H3. destruct H4. pose (In_split x l3 H3).
destruct e. destruct H6. subst. rewrite keep_list_delete_head_not_origin. 2: assumption.
apply Nat.lt_0_succ.
- intros. destruct (In_dec l1 a).
* rewrite remove_list_delete_head_In. 2: assumption. apply IHl4 ; try assumption.
inversion H. assumption. unfold incl. intros. apply H1. apply in_cons. assumption.
intro. apply H2. unfold incl. intros. apply in_cons. apply H4. assumption. destruct H3.
destruct H3. destruct H4. exists x. repeat split ; try assumption. intro. apply H5.
apply in_cons. assumption.
* rewrite keep_list_delete_head_not_In. 2: assumption. assert (In a l3). apply H1.
apply in_eq. pose (In_split a l3 H4). destruct e. destruct H5. subst.
rewrite keep_list_delete_head_not_origin. 2 : assumption. rewrite <- Nat.succ_lt_mono.
apply IHl4. inversion H. assumption. apply NoDup_destr_split with (A:=a). assumption.
unfold incl. intros. pose (H1 a0). assert (In a0 (a :: l4)). apply in_cons. assumption.
apply i in H6. apply in_app_or in H6. destruct H6. apply in_or_app. left. assumption.
inversion H6. subst. inversion H. exfalso. apply H9. assumption. apply in_or_app. right.
assumption. intro. apply H2. unfold incl. intros. apply in_app_or in H6. destruct H6.
apply in_cons. apply H5. apply in_or_app. left. assumption. inversion H6. subst. apply in_eq.
apply in_cons. apply H5. apply in_or_app. right. assumption.
destruct H3. destruct H3. destruct H5. exists x1. repeat split ; try assumption.
apply in_app_or in H3. destruct H3. apply in_or_app. left. assumption. inversion H3.
subst. exfalso. apply H6. apply in_eq. apply in_or_app. right. assumption.
intro. apply H6. apply in_cons. assumption.
Qed.
Lemma remove_list_incr_decr : forall (l1 l2 l3 l4 : list MPropF),
(NoDup l4) ->
(NoDup l3) ->
(exists A, In A l2 /\ In A l3 /\ (In A l1 -> False)) ->
(incl l1 l2) ->
(incl l4 l3) ->
length (remove_list l2 l4) < length (remove_list l1 l3).
Proof.
intros. unfold lt.
pose (remove_list_incr_decr2 l1 H H0 H3).
repeat destruct H1. destruct H4. destruct (In_dec l4 x).
- assert (H6: (exists A, In A l2 /\ In A l4 /\ (In A l1 -> False))).
exists x. repeat split ; assumption. pose (@remove_list_incr_decr1 l4 l1 l2 H6 H2).
unfold lt in l0. apply Nat.le_trans with (m:=length (remove_list l1 l4)) ; assumption.
- assert ((incl l3 l4) -> False). intros. apply f. apply H6. assumption.
assert ((exists A, (In A l3) /\ ((In A l1) -> False) /\ ((In A l4) -> False))). exists x. auto.
pose (@remove_list_incr_decr3 l4 l2 l1 H2). pose (@remove_list_incr_decr4 l4 l3 l1 H H0 H3 H6 H7).
unfold lt in l5. apply le_n_S in l0. lia.
Qed.
Lemma In_remove_list_remove_redund : forall l1 l2 a, In a l1 ->
remove eq_dec_form a (remove_list l1 l2) = remove_list l1 l2.
Proof.
induction l1.
- intros. inversion H.
- intros. simpl. inversion H.
* subst. rewrite double_remove. reflexivity.
* pose (IHl1 l2 a0 H0). rewrite permut_remove. rewrite e. reflexivity.
Qed.
Lemma In_matters_remove_list : forall l1 l2, (incl l1 l2 /\ incl l2 l1) -> (forall l0,
remove_list l1 l0 = remove_list l2 l0).
Proof.
induction l1.
- intros. destruct H. destruct l2. auto. unfold incl in H0. pose (H0 m). assert (In m (m :: l2)).
apply in_eq. apply i in H1. inversion H1.
- intros. destruct H. simpl. pose (H a). assert (In a (a :: l1)). apply in_eq. apply i in H1.
apply in_split in H1. destruct H1. destruct H1. subst. destruct (In_dec l1 a).
* rewrite In_remove_list_remove_redund. 2: assumption. apply IHl1. split. intro. intro.
apply H. apply in_cons. assumption. intro. intro. apply H0 in H1. inversion H1. subst.
assumption. assumption.
* rewrite swap_remove_list. simpl. rewrite <- redund_remove_remove_list with (l1:=(x0 ++ x)).
pose (IHl1 (remove eq_dec_form a (x0 ++ x))). rewrite e.
auto. split. intro. intro. apply in_not_touched_remove. assert (In a0 (a :: l1)). apply in_cons.
assumption. apply H in H2. apply in_app_or in H2. destruct H2. apply in_or_app. right. assumption.
inversion H2. subst. exfalso. apply f. assumption. apply in_or_app. left. assumption.
intro. subst. apply f. assumption. intro. intro. pose (In_remove_diff (x0 ++ x) H1).
pose (In_remove_In_list a0 a (x0 ++ x) H1). assert (In a0 (x ++ a :: x0)). apply in_app_or in i0.
destruct i0. apply in_or_app. right. apply in_cons. assumption. apply in_or_app. left. assumption.
apply H0 in H2. inversion H2. exfalso. apply n. symmetry. assumption. assumption.
Qed.