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.