| Some programs and results about lists following CAML Manual |
Require Export PolyList.
Set Implicit Arguments.
Chapter Lists.
Variable A : Set.
| The null function |
Definition Isnil : (list A) -> Prop := [l:(list A)](nil A)=l.
Lemma Isnil_nil : (Isnil (nil A)).
Red; Auto.
Qed.
Hints Resolve Isnil_nil.
Lemma not_Isnil_cons : (a:A)(l:(list A))~(Isnil (cons a l)).
Unfold Isnil.
Intros; Discriminate.
Qed.
Hints Resolve Isnil_nil not_Isnil_cons.
Lemma Isnil_dec : (l:(list A)){(Isnil l)}+{~(Isnil l)}.
Intro l; Case l;Auto.
Qed.
| The Uncons function |
Lemma Uncons : (l:(list A)){a : A & { m: (list A) | (cons a m)=l}}+{Isnil l}.
Intro l; Case l.
Auto.
Intros a m; Intros; Left; Exists a; Exists m; Reflexivity.
Qed.
| The head function |
Lemma Hd : (l:(list A)){a : A | (EX m:(list A) |(cons a m)=l)}+{Isnil l}.
Intro l; Case l.
Auto.
Intros a m; Intros; Left; Exists a; Exists m; Reflexivity.
Qed.
Lemma Tl : (l:(list A)){m:(list A)| (EX a:A |(cons a m)=l)
\/ ((Isnil l) /\ (Isnil m)) }.
Intro l; Case l.
Exists (nil A); Auto.
Intros a m; Intros; Exists m; Left; Exists a; Reflexivity.
Qed.
| Length of lists |
Fixpoint Length_l [l:(list A)] : nat -> nat
:= [n:nat] Cases l of
nil => n
| (cons _ m) => (Length_l m (S n))
end.
Lemma Length_l_pf : (l:(list A))(n:nat){m:nat|(plus n (length l))=m}.
Induction l.
Intro n; Exists n; Simpl; Auto.
Intros a m lrec n; Elim (lrec (S n)); Simpl; Intros.
Exists x; Transitivity (S (plus n (length m))); Auto.
Qed.
Lemma Length : (l:(list A)){m:nat|(length l)=m}.
Intro l. Apply (Length_l_pf l O).
Qed.
| Members of lists |
Inductive In_spec [a:A] : (list A) -> Prop :=
| in_hd : (l:(list A))(In_spec a (cons a l))
| in_tl : (l:(list A))(b:A)(In a l)->(In_spec a (cons b l)).
Hints Resolve in_hd in_tl.
Hints Unfold In.
Hints Resolve in_cons.
Theorem In_In_spec : (a:A)(l:(list A))(In a l) <-> (In_spec a l).
Split.
Elim l; [ Intros; Contradiction
| Intros; Elim H0;
[ Intros; Rewrite H1; Auto
| Auto ]].
Intros; Elim H; Auto.
Qed.
Inductive AllS [P:A->Prop] : (list A) -> Prop
:= allS_nil : (AllS P (nil A))
| allS_cons : (a:A)(l:(list A))(P a)->(AllS P l)->(AllS P (cons a l)).
Hints Resolve allS_nil allS_cons.
Hypothesis eqA_dec : (a,b:A){a=b}+{~a=b}.
Fixpoint mem [a:A; l:(list A)] : bool :=
Cases l of
nil => false
| (cons b m) => if (eqA_dec a b) then [H]true else [H](mem a m)
end.
Hints Unfold In.
Lemma Mem : (a:A)(l:(list A)){(In a l)}+{(AllS [b:A]~b=a l)}.
Intros a l.
NewInduction l.
Auto.
Elim (eqA_dec a a0).
Auto.
Simpl. Elim IHl; Auto.
Qed.
| Index of elements |
Require Le.
Require Lt.
Inductive nth_spec : (list A)->nat->A->Prop :=
nth_spec_O : (a:A)(l:(list A))(nth_spec (cons a l) (S O) a)
| nth_spec_S : (n:nat)(a,b:A)(l:(list A))
(nth_spec l n a)->(nth_spec (cons b l) (S n) a).
Hints Resolve nth_spec_O nth_spec_S.
Inductive fst_nth_spec : (list A)->nat->A->Prop :=
fst_nth_O : (a:A)(l:(list A))(fst_nth_spec (cons a l) (S O) a)
| fst_nth_S : (n:nat)(a,b:A)(l:(list A))(~a=b)->
(fst_nth_spec l n a)->(fst_nth_spec (cons b l) (S n) a).
Hints Resolve fst_nth_O fst_nth_S.
Lemma fst_nth_nth : (l:(list A))(n:nat)(a:A)(fst_nth_spec l n a)->(nth_spec l n a).
Induction 1; Auto.
Qed.
Hints Immediate fst_nth_nth.
Lemma nth_lt_O : (l:(list A))(n:nat)(a:A)(nth_spec l n a)->(lt O n).
Induction 1; Auto.
Qed.
Lemma nth_le_length : (l:(list A))(n:nat)(a:A)(nth_spec l n a)->(le n (length l)).
Induction 1; Simpl; Auto with arith.
Qed.
Fixpoint Nth_func [l:(list A)] : nat -> (Exc A)
:= [n:nat] Cases l n of
(cons a _) (S O) => (value A a)
| (cons _ l') (S (S p)) => (Nth_func l' (S p))
| _ _ => Error
end.
Lemma Nth : (l:(list A))(n:nat)
{a:A|(nth_spec l n a)}+{(n=O)\/(lt (length l) n)}.
Induction l.
Intro n; Case n; Simpl; Auto with arith.
Intros; Case n; Simpl; Auto.
Intro n0; Case n0.
Left; Exists a; Auto.
Intro n1; Case (H (S n1)); Intro.
Case s; Intros b p; Left; Exists b; Auto.
Right; Case o; Intro.
Absurd (S n1)=O; Auto.
Auto with arith.
Save.
Lemma Item : (l:(list A))(n:nat){a:A|(nth_spec l (S n) a)}+{(le (length l) n)}.
Intros l n; Case (Nth l (S n)); Intro.
Case s; Intro a; Left; Exists a; Auto.
Right; Case o; Intro.
Absurd (S n)=O; Auto.
Auto with arith.
Save.
Require Minus.
Require DecBool.
Fixpoint index_p [a:A;l:(list A)] : nat -> (Exc nat) :=
Cases l of nil => [p]Error
| (cons b m) => [p](ifdec (eqA_dec a b) (Value p) (index_p a m (S p)))
end.
Lemma Index_p : (a:A)(l:(list A))(p:nat)
{n:nat|(fst_nth_spec l (minus (S n) p) a)}+{(AllS [b:A]~a=b l)}.
Induction l.
Auto.
Intros b m irec p.
Case (eqA_dec a b); Intro e.
Left; Exists p.
Case e; Elim minus_Sn_m; Trivial; Elim minus_n_n; Auto with arith.
Case (irec (S p)); Intro.
Case s; Intros n H; Left; Exists n; Auto with arith.
Elim minus_Sn_m; Auto with arith.
Apply lt_le_weak; Apply lt_O_minus_lt; Apply nth_lt_O with m a; Auto with arith.
Auto.
Save.
Lemma Index : (a:A)(l:(list A))
{n:nat|(fst_nth_spec l n a)}+{(AllS [b:A]~a=b l)}.
Intros a l; Case (Index_p a l (S O)); Auto.
Intros (n,P); Left; Exists n; Auto.
Rewrite (minus_n_O n); Trivial.
Save.
Section Find_sec.
Variable R,P : A -> Prop.
Inductive InR : (list A) -> Prop
:= inR_hd : (a:A)(l:(list A))(R a)->(InR (cons a l))
| inR_tl : (a:A)(l:(list A))(InR l)->(InR (cons a l)).
Hints Resolve inR_hd inR_tl.
Definition InR_inv :=
[l:(list A)]Cases l of
nil => False
| (cons b m) => (R b)\/(InR m)
end.
Lemma InR_INV : (l:(list A))(InR l)->(InR_inv l).
Induction 1; Simpl; Auto.
Save.
Lemma InR_cons_inv : (a:A)(l:(list A))(InR (cons a l))->((R a)\/(InR l)).
Intros a l H; Exact (InR_INV H).
Save.
Lemma InR_or_app : (l,m:(list A))((InR l)\/(InR m))->(InR (app l m)).
Induction 1.
Induction 1; Simpl; Auto.
Intro; Elim l; Simpl; Auto.
Save.
Lemma InR_app_or : (l,m:(list A))(InR (app l m))->((InR l)\/(InR m)).
Intros l m; Elim l; Simpl; Auto.
Intros b l' Hrec IAc; Elim (InR_cons_inv IAc);Auto.
Intros; Elim Hrec; Auto.
Save.
Hypothesis RS_dec : (a:A){(R a)}+{(P a)}.
Fixpoint find [l:(list A)] : (Exc A) :=
Cases l of nil => Error
| (cons a m) => (ifdec (RS_dec a) (Value a) (find m))
end.
Lemma Find : (l:(list A)){a:A | (In a l) & (R a)}+{(AllS P l)}.
Induction l; Auto.
Intros a m H.
Case H.
Intros (b,H1,H2); Left; Exists b; Auto.
Intro; Case (RS_dec a); Intro.
Left; Exists a; Auto.
Auto.
Save.
Variable B : Set.
Variable T : A -> B -> Prop.
Variable TS_dec : (a:A){c:B| (T a c)}+{(P a)}.
Fixpoint try_find [l:(list A)] : (Exc B) :=
Cases l of
nil => Error
| (cons a l1) =>
Cases (TS_dec a) of
(inleft (exist c _)) => (Value c)
| (inright _) => (try_find l1)
end
end.
Lemma Try_find : (l:(list A)){c:B|(EX a:A |(In a l) & (T a c))}+{(AllS P l)}.
Induction l.
Auto.
Intros a m H.
Case H.
Intros (b,H1); Left; Exists b.
Case H1; Intros a' H2 H3; Exists a'; Auto.
Intro; Case (TS_dec a); Intro.
Case s; Intros c H1; Left; Exists c.
Exists a; Auto.
Auto.
Save.
End Find_sec.
Section Assoc_sec.
Variable B : Set.
Fixpoint assoc [a:A;l:(list A*B)] : (Exc B) :=
Cases l of nil => Error
| (cons (a',b) m) => (ifdec (eqA_dec a a') (Value b) (assoc a m))
end.
Inductive AllS_assoc [P:A -> Prop]: (list A*B) -> Prop :=
allS_assoc_nil : (AllS_assoc P (nil A*B))
| allS_assoc_cons : (a:A)(b:B)(l:(list A*B))
(P a)->(AllS_assoc P l)->(AllS_assoc P (cons (a,b) l)).
Hints Resolve allS_assoc_nil allS_assoc_cons.
Lemma Assoc : (a:A)(l:(list A*B))(B+{(AllS_assoc [a':A]~(a=a') l)}).
Induction l; Auto.
Intros (a',b) m assrec.
Case (eqA_dec a a'); Intro.
Left; Exact b.
Case assrec.
Intro b'; Left; Exact b'.
Auto.
Save.
End Assoc_sec.
End Lists.
Hints Resolve Isnil_nil not_Isnil_cons in_hd in_tl in_cons allS_nil allS_cons
: datatypes.
Hints Immediate fst_nth_nth : datatypes.