2023-10-25 07:22:47 -04:00
|
|
|
Require Import Nat.
|
|
|
|
Require Import PeanoNat.
|
|
|
|
Require Import List.
|
|
|
|
Import ListNotations.
|
|
|
|
|
2023-10-30 01:50:55 -04:00
|
|
|
Require Import Lia.
|
|
|
|
|
2023-10-25 07:22:47 -04:00
|
|
|
|
2023-10-29 16:10:19 -04:00
|
|
|
Definition subsequence (l s : list Type) :=
|
|
|
|
exists (l1: list Type) (l2 : list (list Type)),
|
2023-10-25 07:22:47 -04:00
|
|
|
length s = length l2
|
|
|
|
/\ l = l1 ++ flat_map (fun e => (fst e) :: (snd e)) (combine s l2).
|
|
|
|
|
2023-10-29 16:10:19 -04:00
|
|
|
Definition subsequence2 (l s : list Type) :=
|
2023-10-25 07:22:47 -04:00
|
|
|
exists (t: list bool),
|
|
|
|
length t = length l /\ s = map snd (filter fst (combine t l)).
|
|
|
|
|
2023-10-30 01:50:55 -04:00
|
|
|
(*
|
|
|
|
TODO: problème, les éléments de l ne sont pas uniques ; or
|
|
|
|
il doit pouvoir y avoir des différences dans la décision de les
|
|
|
|
prendre ou non
|
|
|
|
Definition subsequence3 (l s : list Type) :=
|
|
|
|
exists f, s = fst (partition f l).
|
|
|
|
*)
|
2023-10-29 16:10:19 -04:00
|
|
|
|
|
|
|
Theorem subsequence_nil_r : forall (l : list Type), subsequence l nil.
|
|
|
|
Proof.
|
2023-10-30 03:18:20 -04:00
|
|
|
intro l. exists l. exists nil. rewrite app_nil_r. split; easy.
|
2023-10-29 16:10:19 -04:00
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Theorem subsequence_nil_cons_r : forall (l: list Type) (a:Type),
|
|
|
|
~ subsequence nil (a::l).
|
|
|
|
Proof.
|
2023-10-30 03:18:20 -04:00
|
|
|
intros l a. unfold not. intro H.
|
2023-10-29 16:10:19 -04:00
|
|
|
destruct H. destruct H. destruct H.
|
|
|
|
destruct x. rewrite app_nil_l in H0.
|
|
|
|
destruct x0. apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
simpl in H0. apply nil_cons in H0. contradiction H0.
|
|
|
|
apply nil_cons in H0. contradiction H0.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Theorem subsequence2_nil_r : forall (l : list Type), subsequence2 l nil.
|
|
|
|
Proof.
|
2023-10-30 03:18:20 -04:00
|
|
|
intro l.
|
2023-10-29 16:10:19 -04:00
|
|
|
exists (repeat false (length l)). rewrite repeat_length.
|
|
|
|
split. easy.
|
|
|
|
induction l. reflexivity. simpl. assumption.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
Theorem subsequence2_nil_cons_r : forall (l: list Type) (a:Type),
|
|
|
|
~ subsequence2 nil (a::l).
|
|
|
|
Proof.
|
2023-10-30 03:18:20 -04:00
|
|
|
intros l a. unfold not. intro H. destruct H.
|
2023-10-29 16:10:19 -04:00
|
|
|
destruct H. assert (x = nil). destruct x. reflexivity.
|
|
|
|
apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
rewrite H1 in H0. symmetry in H0. apply nil_cons in H0. contradiction H0.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
2023-10-30 05:57:47 -04:00
|
|
|
Theorem subsequence_cons_l : forall (l s: list Type) (a: Type),
|
|
|
|
subsequence l s -> subsequence (a::l) s.
|
|
|
|
Proof.
|
|
|
|
intros l s a. intro H.
|
|
|
|
destruct H. destruct H. destruct H.
|
|
|
|
exists (a::x). exists x0. split. assumption.
|
|
|
|
rewrite H0. reflexivity.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
2023-10-30 01:50:55 -04:00
|
|
|
Theorem subsequence2_cons_l : forall (l s: list Type) (a: Type),
|
|
|
|
subsequence2 l s -> subsequence2 (a::l) s.
|
|
|
|
Proof.
|
2023-10-30 03:18:20 -04:00
|
|
|
intros l s a. intro H.
|
2023-10-30 01:50:55 -04:00
|
|
|
destruct H. destruct H. exists (false::x).
|
|
|
|
split. simpl. apply eq_S. assumption.
|
|
|
|
simpl. assumption.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
2023-10-30 05:57:47 -04:00
|
|
|
Theorem subsequence_cons_r : forall (l s: list Type) (a: Type),
|
|
|
|
subsequence l (a::s) -> subsequence l s.
|
|
|
|
Proof.
|
|
|
|
intros l s a. intro H. destruct H. destruct H. destruct H.
|
|
|
|
destruct x0. apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
exists (x++a::l0). exists x0. split. inversion H. reflexivity. rewrite H0.
|
|
|
|
rewrite <- app_assoc. apply app_inv_head_iff. simpl. reflexivity.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
2023-10-30 01:50:55 -04:00
|
|
|
Theorem subsequence2_cons_r : forall (l s: list Type) (a: Type),
|
|
|
|
subsequence2 l (a::s) -> subsequence2 l s.
|
|
|
|
Proof.
|
|
|
|
intro l. induction l. intros. apply subsequence2_nil_cons_r in H.
|
2023-10-30 03:18:20 -04:00
|
|
|
contradiction H. intros s a0 . intro H. destruct H. destruct H. destruct x.
|
2023-10-30 01:50:55 -04:00
|
|
|
symmetry in H0. apply nil_cons in H0. contradiction H0.
|
|
|
|
destruct b. simpl in H0. inversion H0.
|
2023-10-30 03:18:20 -04:00
|
|
|
exists (false::x). split; try rewrite <- H; reflexivity.
|
|
|
|
simpl in H0. apply subsequence2_cons_l. apply IHl with (a := a0).
|
2023-10-30 01:50:55 -04:00
|
|
|
unfold subsequence2. exists (x). split. inversion H.
|
|
|
|
reflexivity. assumption.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
2023-10-30 07:33:00 -04:00
|
|
|
Theorem subsequence_cons_eq : forall (l1 l2: list Type) (a: Type),
|
|
|
|
subsequence (a::l1) (a::l2) <-> subsequence l1 l2.
|
|
|
|
Proof.
|
|
|
|
intros l s a. split. intro H.
|
|
|
|
destruct H. destruct H. destruct H.
|
|
|
|
destruct x. destruct x0.
|
|
|
|
apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
simpl in H0. inversion H0. exists l0. exists x0.
|
|
|
|
inversion H. split; reflexivity.
|
|
|
|
destruct x0. simpl in H0.
|
|
|
|
apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
exists (x ++ (a::l0)). exists x0. inversion H. split. reflexivity.
|
|
|
|
inversion H0. rewrite <- app_assoc. apply app_inv_head_iff.
|
|
|
|
rewrite app_comm_cons. reflexivity.
|
|
|
|
|
|
|
|
intro H. destruct H. destruct H. destruct H.
|
|
|
|
exists nil. exists (x::x0). simpl. split. rewrite H. reflexivity.
|
|
|
|
rewrite H0. reflexivity.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-10-29 16:10:19 -04:00
|
|
|
Theorem subsequence2_cons_eq : forall (l1 l2: list Type) (a: Type),
|
|
|
|
subsequence2 (a::l1) (a::l2) <-> subsequence2 l1 l2.
|
|
|
|
Proof.
|
2023-10-30 02:48:09 -04:00
|
|
|
intros l s a. split. intro H. unfold subsequence2 in H.
|
|
|
|
destruct H. destruct H. destruct x. inversion H0.
|
2023-10-30 03:18:20 -04:00
|
|
|
destruct b. exists (x). split. inversion H. reflexivity. simpl in H0.
|
2023-10-30 02:48:09 -04:00
|
|
|
inversion H0. reflexivity. simpl in H0. inversion H.
|
|
|
|
assert (subsequence2 l (a::s)). exists x. split; assumption.
|
|
|
|
apply subsequence2_cons_r with (a := a). assumption.
|
2023-10-30 02:51:59 -04:00
|
|
|
intro H. destruct H. destruct H. exists (true :: x).
|
|
|
|
split. simpl. apply eq_S. assumption. simpl. rewrite H0. reflexivity.
|
|
|
|
Qed.
|
2023-10-30 02:48:09 -04:00
|
|
|
|
|
|
|
|
2023-10-30 02:51:59 -04:00
|
|
|
(*
|
2023-10-29 16:10:19 -04:00
|
|
|
assert (forall (l s: list Type) t,
|
|
|
|
s = map snd (filter fst (combine t l))
|
|
|
|
-> length t = length l
|
|
|
|
-> count_occ Bool.bool_dec t true = length s).
|
|
|
|
intros l s t.
|
|
|
|
|
|
|
|
generalize l s. induction t. intros l0 s0. intros J K.
|
|
|
|
simpl in J. rewrite J. reflexivity.
|
|
|
|
intros l0 s0. intros J K.
|
|
|
|
destruct a. destruct s0. destruct l0.
|
|
|
|
apply Nat.neq_succ_0 in K. contradiction K.
|
|
|
|
apply nil_cons in J. contradiction J. simpl. apply eq_S.
|
|
|
|
|
|
|
|
destruct l0.
|
|
|
|
apply Nat.neq_succ_0 in K. contradiction K.
|
|
|
|
|
|
|
|
apply IHt with (l := l0). inversion J. rewrite <- H1.
|
|
|
|
reflexivity. inversion K. reflexivity.
|
|
|
|
|
|
|
|
simpl. destruct l0.
|
|
|
|
apply Nat.neq_succ_0 in K. contradiction K.
|
|
|
|
|
|
|
|
apply IHt with (l := l0). inversion J. simpl.
|
|
|
|
reflexivity. inversion K. reflexivity.
|
2023-10-30 02:51:59 -04:00
|
|
|
*)
|
2023-10-30 01:50:55 -04:00
|
|
|
|
2023-10-29 16:10:19 -04:00
|
|
|
|
|
|
|
|
|
|
|
Theorem subsequence2_dec :
|
|
|
|
(forall x y : Type, {x = y} + {x <> y})
|
|
|
|
-> forall (l s : list Type), { subsequence2 l s } + { ~ subsequence2 l s }.
|
|
|
|
Proof.
|
|
|
|
intro H.
|
|
|
|
intros l. induction l. intro s. destruct s. left. apply subsequence2_nil_r.
|
|
|
|
right. apply subsequence2_nil_cons_r.
|
|
|
|
|
|
|
|
intro s. assert({subsequence2 l s} + {~ subsequence2 l s}). apply IHl.
|
|
|
|
destruct H0.
|
|
|
|
|
2023-10-30 05:30:22 -04:00
|
|
|
rewrite <- subsequence2_cons_eq with (a := a) in s0.
|
|
|
|
apply subsequence2_cons_r in s0. left. assumption.
|
2023-10-29 16:10:19 -04:00
|
|
|
|
2023-10-30 05:30:22 -04:00
|
|
|
destruct s. left. apply subsequence2_nil_r.
|
|
|
|
assert ({T=a}+{T<>a}). apply H. destruct H0. rewrite e.
|
|
|
|
destruct IHl with (s := s).
|
|
|
|
left. rewrite subsequence2_cons_eq. assumption.
|
|
|
|
right. rewrite subsequence2_cons_eq. assumption.
|
|
|
|
|
|
|
|
right. unfold not in n. unfold not. intro I.
|
|
|
|
destruct I. destruct H0. destruct x.
|
|
|
|
symmetry in H1. apply nil_cons in H1. contradiction H1.
|
|
|
|
destruct b.
|
|
|
|
inversion H1. rewrite H3 in n0. contradiction n0. reflexivity.
|
|
|
|
|
|
|
|
assert (subsequence2 l (T::s)). exists x. split.
|
|
|
|
inversion H0. reflexivity. assumption. apply n in H2. contradiction H2.
|
|
|
|
Qed.
|
2023-10-29 16:10:19 -04:00
|
|
|
|
|
|
|
|
2023-10-30 05:57:47 -04:00
|
|
|
Theorem subsequence_eq_def :
|
|
|
|
(forall x y : Type, {x = y} + {x <> y})
|
|
|
|
-> (forall l s, subsequence l s <-> subsequence2 l s).
|
2023-10-25 07:22:47 -04:00
|
|
|
Proof.
|
2023-10-30 05:57:47 -04:00
|
|
|
intro I. intro l. induction l.
|
2023-10-25 07:22:47 -04:00
|
|
|
(* first part of the induction *)
|
|
|
|
intro s. unfold subsequence. unfold subsequence2.
|
|
|
|
split. exists nil. split. reflexivity. simpl.
|
|
|
|
destruct H. destruct H. destruct H.
|
|
|
|
assert (x = nil). destruct x. reflexivity. simpl in H0.
|
|
|
|
apply nil_cons in H0. contradiction H0. rewrite H1 in H0.
|
|
|
|
simpl in H0. assert (combine s x0 = nil).
|
|
|
|
destruct (combine s x0). reflexivity. simpl in H0.
|
|
|
|
apply nil_cons in H0. contradiction H0.
|
|
|
|
destruct x0. destruct s. reflexivity. simpl in H.
|
|
|
|
apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
destruct s. reflexivity. simpl in H2.
|
|
|
|
symmetry in H2. apply nil_cons in H2. contradiction H2.
|
|
|
|
exists nil. exists nil. destruct s. simpl. easy.
|
|
|
|
destruct H. destruct H.
|
|
|
|
assert (x = nil). destruct x. reflexivity. simpl in H.
|
|
|
|
apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
rewrite H1 in H0. simpl in H0.
|
|
|
|
symmetry in H0. apply nil_cons in H0. contradiction H0.
|
|
|
|
(* second part of the induction *)
|
|
|
|
intro s. destruct s. unfold subsequence. unfold subsequence2. split.
|
|
|
|
exists (repeat false (S (length l))). rewrite repeat_length.
|
|
|
|
split. easy. simpl.
|
|
|
|
assert (forall u,
|
2023-10-29 16:10:19 -04:00
|
|
|
(nil: list Type)
|
2023-10-25 07:22:47 -04:00
|
|
|
= map snd (filter fst (combine (repeat false (length u)) u))).
|
|
|
|
intro u. induction u. reflexivity. simpl. assumption. apply H0.
|
|
|
|
exists (a::l). exists (nil). simpl. split; try rewrite app_nil_r; reflexivity.
|
2023-10-29 16:10:19 -04:00
|
|
|
(* deux cas : a = n ou non *)
|
2023-10-30 05:57:47 -04:00
|
|
|
assert ({a=T} + {a<>T}). apply I. destruct H.
|
|
|
|
rewrite e. rewrite subsequence2_cons_eq. rewrite <- IHl.
|
2023-10-30 07:34:36 -04:00
|
|
|
rewrite subsequence_cons_eq. split; intro; assumption.
|
2023-10-25 07:22:47 -04:00
|
|
|
|
2023-10-30 07:57:00 -04:00
|
|
|
split; intro H. apply subsequence2_cons_l. apply IHl.
|
|
|
|
destruct H. destruct H. destruct H.
|
|
|
|
destruct x. destruct x0.
|
|
|
|
apply PeanoNat.Nat.neq_succ_0 in H. contradiction H.
|
|
|
|
simpl in H0. inversion H0. rewrite H2 in n. contradiction n.
|
|
|
|
reflexivity. inversion H0.
|
|
|
|
exists x. exists x0. split. assumption.
|
|
|
|
reflexivity.
|
|
|
|
|
|
|
|
apply subsequence_cons_l. apply IHl.
|
|
|
|
destruct H. destruct H.
|
|
|
|
destruct x. simpl in H0.
|
|
|
|
symmetry in H0. apply nil_cons in H0. contradiction H0.
|
|
|
|
destruct b. simpl in H0. inversion H0. rewrite H2 in n.
|
|
|
|
contradiction n. reflexivity.
|
|
|
|
exists x. inversion H. inversion H0.
|
|
|
|
split; reflexivity.
|
|
|
|
Qed.
|
2023-10-25 07:22:47 -04:00
|
|
|
|
|
|
|
|
2023-10-30 08:00:05 -04:00
|
|
|
Theorem subsequence_dec :
|
|
|
|
(forall x y : Type, {x = y} + {x <> y})
|
|
|
|
-> forall (l s : list Type), { subsequence l s } + { ~ subsequence l s }.
|
|
|
|
Proof.
|
|
|
|
intro H. intros l s.
|
|
|
|
assert ({ subsequence2 l s } + { ~ subsequence2 l s }).
|
|
|
|
apply subsequence2_dec. assumption. destruct H0.
|
|
|
|
rewrite <- subsequence_eq_def in s0. left. assumption.
|
|
|
|
assumption. rewrite <- subsequence_eq_def in n. right. assumption.
|
|
|
|
assumption.
|
|
|
|
Qed.
|
2023-10-25 07:22:47 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example test1: subsequence [1;2;3;4;5] [1;3;5].
|
|
|
|
Proof.
|
|
|
|
unfold subsequence.
|
|
|
|
exists [].
|
|
|
|
exists [[2];[4];[]]. simpl. easy.
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
Example test2: subsequence [1;2;3;4;5] [2;4].
|
|
|
|
Proof.
|
|
|
|
unfold subsequence.
|
|
|
|
exists [1].
|
|
|
|
exists [[3];[5]]. simpl. easy.
|
|
|
|
Qed.
|