mpri-funcprog-project/coq/MyList.v
2017-10-05 17:57:33 +02:00

125 lines
2.8 KiB
Coq

Require Import List.
Require Import MyTactics.
(* A few random additions to the [List] module, which is woefully incomplete. *)
(* -------------------------------------------------------------------------- *)
Lemma rev_cons_app:
forall {A} (x : A) xs ys,
rev (x :: xs) ++ ys = rev xs ++ x :: ys.
Proof.
intros. simpl. rewrite <- app_assoc. reflexivity.
Qed.
(* -------------------------------------------------------------------------- *)
Lemma length_nil:
forall A,
length (@nil A) = 0.
Proof.
reflexivity.
Qed.
Lemma length_cons:
forall A (x : A) xs,
length (x :: xs) = 1 + length xs.
Proof.
reflexivity.
Qed.
Hint Rewrite length_nil length_cons app_length map_length : length.
Ltac length :=
autorewrite with length in *;
try omega.
(* -------------------------------------------------------------------------- *)
(* We have [app_nth1] and [app_nth2], but the following lemma, which can be
viewed as a special case of [app_nth2], is missing. *)
Lemma app_nth:
forall {A} (xs ys : list A) x n,
n = length xs ->
nth n (xs ++ ys) x = nth 0 ys x.
Proof.
intros.
rewrite app_nth2 by omega.
replace (n - length xs) with 0 by omega.
reflexivity.
Qed.
(* -------------------------------------------------------------------------- *)
(* [rev_nats n] is the semi-open interval (n, 0], counted down. *)
(* It could also be defined as [rev (seq 0 n)], but a direct definition
is easier to work with, as it is immediately amenable to proofs by
induction. *)
Fixpoint rev_nats (n : nat) : list nat :=
match n with
| 0 =>
nil
| S n =>
n :: rev_nats n
end.
(* [nats n] is the semi-open interval [0, n), counted up. *)
Definition nats (n : nat) : list nat :=
seq 0 n.
(* These sequences have length [n]. *)
Lemma length_rev_nats:
forall n,
length (rev_nats n) = n.
Proof.
induction n; intros; simpl; [| rewrite IHn ]; eauto.
Qed.
Lemma length_nats:
forall n,
length (nats n) = n.
Proof.
unfold nats. intros. eauto using seq_length.
Qed.
(* -------------------------------------------------------------------------- *)
(* A few basic lemmas about [Forall]. *)
Lemma Forall_map:
forall A B (f : A -> B) (P : B -> Prop) xs,
Forall (fun x => P (f x)) xs ->
Forall P (map f xs).
Proof.
induction 1; intros; subst; simpl; econstructor; eauto.
Qed.
Lemma Forall_app:
forall A (P : A -> Prop) xs ys,
Forall P xs ->
Forall P ys ->
Forall P (xs ++ ys).
Proof.
induction 1; intros; subst; simpl; eauto.
Qed.
Lemma Forall_rev:
forall A (P : A -> Prop) xs,
Forall P xs ->
Forall P (rev xs).
Proof.
induction 1; intros; subst; simpl; eauto using Forall_app.
Qed.
Lemma Forall_seq:
forall (P : nat -> Prop) len start,
(forall i, start <= i < start + len -> P i) ->
Forall P (seq start len).
Proof.
induction len; intros; simpl; econstructor; eauto with omega.
Qed.