ListsWorking with Structured Data
Inductive natprod : Type :=
| pair (n1 n2 : nat).
| pair (n1 n2 : nat).
We define extraction functions by pattern matching.
Definition fst (p : natprod) : nat :=
match p with
| pair x y ⇒ x
end.
Definition snd (p : natprod) : nat :=
match p with
| pair x y ⇒ y
end.
match p with
| pair x y ⇒ x
end.
Definition snd (p : natprod) : nat :=
match p with
| pair x y ⇒ y
end.
Notation "( x , y )" := (pair x y).
The new pair notation can be used both in expressions and in
pattern matches.
Compute (fst (3,5)).
Definition fst' (p : natprod) : nat :=
match p with
| (x,y) ⇒ x
end.
Definition snd' (p : natprod) : nat :=
match p with
| (x,y) ⇒ y
end.
Definition swap_pair (p : natprod) : natprod :=
match p with
| (x,y) ⇒ (y,x)
end.
Definition fst' (p : natprod) : nat :=
match p with
| (x,y) ⇒ x
end.
Definition snd' (p : natprod) : nat :=
match p with
| (x,y) ⇒ y
end.
Definition swap_pair (p : natprod) : natprod :=
match p with
| (x,y) ⇒ (y,x)
end.
Inductive natlist : Type :=
| nil
| cons (n : nat) (l : natlist).
Definition mylist := cons 1 (cons 2 (cons 3 nil)).
| nil
| cons (n : nat) (l : natlist).
Definition mylist := cons 1 (cons 2 (cons 3 nil)).
Notation "x :: l" := (cons x l)
(at level 60, right associativity).
Notation "[ ]" := nil.
Notation "[ x ; .. ; y ]" := (cons x .. (cons y nil) ..).
(at level 60, right associativity).
Notation "[ ]" := nil.
Notation "[ x ; .. ; y ]" := (cons x .. (cons y nil) ..).
Now these all mean exactly the same thing:
Definition mylist1 := 1 :: (2 :: (3 :: nil)).
Definition mylist2 := 1 :: 2 :: 3 :: nil.
Definition mylist3 := [1;2;3].
Definition mylist2 := 1 :: 2 :: 3 :: nil.
Definition mylist3 := [1;2;3].
Fixpoint repeat (n count : nat) : natlist :=
match count with
| O ⇒ nil
| S count' ⇒ n :: (repeat n count')
end.
match count with
| O ⇒ nil
| S count' ⇒ n :: (repeat n count')
end.
Fixpoint length (l:natlist) : nat :=
match l with
| nil ⇒ O
| h :: t ⇒ S (length t)
end.
Fixpoint app (l1 l2 : natlist) : natlist :=
match l1 with
| nil ⇒ l2
| h :: t ⇒ h :: (app t l2)
end.
Notation "x ++ y" := (app x y)
(right associativity, at level 60).
Definition hd (default:nat) (l:natlist) : nat :=
match l with
| nil ⇒ default
| h :: t ⇒ h
end.
Definition tl (l:natlist) : natlist :=
match l with
| nil ⇒ nil
| h :: t ⇒ t
end.
Theorem nil_app : ∀l:natlist,
[] ++ l = l.
Proof. reflexivity. Qed.
[] ++ l = l.
Proof. reflexivity. Qed.
Theorem tl_length_pred : ∀l:natlist,
pred (length l) = length (tl l).
Proof.
intros l. destruct l as [| n l'].
- (* l = nil *)
reflexivity.
- (* l = cons n l' *)
reflexivity. Qed.
pred (length l) = length (tl l).
Proof.
intros l. destruct l as [| n l'].
- (* l = nil *)
reflexivity.
- (* l = cons n l' *)
reflexivity. Qed.
Usually, though, interesting theorems about lists require
induction for their proofs.
Induction on Lists
Theorem app_assoc : ∀l1 l2 l3 : natlist,
(l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).
Proof.
intros l1 l2 l3. induction l1 as [| n l1' IHl1'].
- (* l1 = nil *)
reflexivity.
- (* l1 = cons n l1' *)
simpl. rewrite → IHl1'. reflexivity. Qed.
(l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).
Proof.
intros l1 l2 l3. induction l1 as [| n l1' IHl1'].
- (* l1 = nil *)
reflexivity.
- (* l1 = cons n l1' *)
simpl. rewrite → IHl1'. reflexivity. Qed.
Fixpoint rev (l:natlist) : natlist :=
match l with
| nil ⇒ nil
| h :: t ⇒ rev t ++ [h]
end.
match l with
| nil ⇒ nil
| h :: t ⇒ rev t ++ [h]
end.
Theorem rev_length_firsttry : ∀l : natlist,
length (rev l) = length l.
Proof.
intros l. induction l as [| n l' IHl'].
- (* l = nil *)
reflexivity.
- (* l = n :: l' *)
simpl.
rewrite <- IHl'.
Abort.
length (rev l) = length l.
Proof.
intros l. induction l as [| n l' IHl'].
- (* l = nil *)
reflexivity.
- (* l = n :: l' *)
simpl.
rewrite <- IHl'.
Abort.
Theorem app_length : ∀l1 l2 : natlist,
length (l1 ++ l2) = (length l1) + (length l2).
Proof.
(* WORK IN CLASS *) Admitted.
Theorem rev_length : ∀l : natlist,
length (rev l) = length l.
Proof.
intros l. induction l as [| n l' IHl'].
- (* l = nil *)
reflexivity.
- (* l = cons *)
simpl. rewrite → app_length.
simpl. rewrite → IHl'. rewrite plus_comm.
reflexivity.
Qed.
Inductive natoption : Type :=
| Some (n : nat)
| None.
Fixpoint nth_error (l:natlist) (n:nat) : natoption :=
match l with
| nil ⇒ None
| a :: l' ⇒ match n =? O with
| true ⇒ Some a
| false ⇒ nth_error l' (pred n)
end
end.
Fixpoint nth_error' (l:natlist) (n:nat) : natoption :=
match l with
| nil ⇒ None
| a :: l' ⇒ if n =? O then Some a
else nth_error' l' (pred n)
end.
match l with
| nil ⇒ None
| a :: l' ⇒ if n =? O then Some a
else nth_error' l' (pred n)
end.