Library list_ex_answers
appending two lists by recursion over the first input list
Fixpoint append (l m : natlist) {struct l} : natlist :=
match l with
| nil => m
| cons x xs => cons x (append xs m)
end.
match l with
| nil => m
| cons x xs => cons x (append xs m)
end.
one of the following lemma's has a simple proof, without induction
which? why?
Lemma append_nil_r : forall l, append l nil = l.
Proof.
induction l.
- simpl. auto.
- simpl. rewrite IHl. auto.
Qed.
Lemma append_nil_l : forall l, append nil l = l.
Proof.
simpl.
auto.
Qed.
in the following lemma: think about what variable to do induction over
Lemma append_assoc : forall l k m ,
append l (append k m) = append (append l k) m.
Proof.
induction l.
- intros k m. simpl. auto.
- intros k m. simpl. rewrite IHl. auto.
Qed.
Fixpoint length (l : natlist) : nat :=
match l with
| nil => 0
| cons a k => S(length k)
end.
Lemma append_length : forall l m,
length (append l m) = length l + length m.
Proof.
Admitted.
append l (append k m) = append (append l k) m.
Proof.
induction l.
- intros k m. simpl. auto.
- intros k m. simpl. rewrite IHl. auto.
Qed.
Fixpoint length (l : natlist) : nat :=
match l with
| nil => 0
| cons a k => S(length k)
end.
Lemma append_length : forall l m,
length (append l m) = length l + length m.
Proof.
Admitted.
Exercise 1: define a function list_sum : natlist -> nat that sums up
all elements in a list
Fixpoint list_sum (l: natlist) {struct l} : nat :=
match l with
| nil => 0
| cons x xs => plus x (list_sum xs)
end.
match l with
| nil => 0
| cons x xs => plus x (list_sum xs)
end.
Exercise 2: define a function list_map :(nat->nat) -> natlist -> natlist
that applies a function f to all elements in a list
Fixpoint list_map (f : nat -> nat)(l: natlist) {struct l} : natlist :=
match l with
| nil => nil
| cons x xs => cons (f x) (list_map f xs)
end.
match l with
| nil => nil
| cons x xs => cons (f x) (list_map f xs)
end.
reversing a list, using append
Fixpoint reverse (l : natlist) : natlist :=
match l with
| nil => nil
| cons a k => append (reverse k) (cons a nil)
end.
Lemma reverse_append : forall l m,
reverse (append l m) = append (reverse m) (reverse l).
Proof.
intro l.
induction l.
- simpl. intro m.
rewrite append_nil_r. auto.
- intro m. simpl.
rewrite IHl.
rewrite append_assoc.
auto.
Qed.
Lemma reverse_length : forall l,
length l = length (reverse l).
Proof.
induction l.
- simpl;auto.
- simpl.
rewrite IHl.
simpl.
rewrite append_length.
simpl.
auto.
match l with
| nil => nil
| cons a k => append (reverse k) (cons a nil)
end.
Lemma reverse_append : forall l m,
reverse (append l m) = append (reverse m) (reverse l).
Proof.
intro l.
induction l.
- simpl. intro m.
rewrite append_nil_r. auto.
- intro m. simpl.
rewrite IHl.
rewrite append_assoc.
auto.
Qed.
Lemma reverse_length : forall l,
length l = length (reverse l).
Proof.
induction l.
- simpl;auto.
- simpl.
rewrite IHl.
simpl.
rewrite append_length.
simpl.
auto.
Alternative 1: First prove a separate
Lemma help : forall n: nat, S n = n + 1.
and then apply help
The shortest solution is to invoke lia, which add all kinds of automation regarding a.o. arithmetic
It is actually "not done" to Import such a file inside a proof: do it in at teh beginning of your file
Lemma help : forall n: nat, S n = n + 1.
and then apply help
The shortest solution is to invoke lia, which add all kinds of automation regarding a.o. arithmetic
It is actually "not done" to Import such a file inside a proof: do it in at teh beginning of your file
Alternative 2: reverse the lemma append_length
Axiom append_length' : forall l m,
length (append l m) = length m + length l.
Lemma reverse_length' : forall l,
length l = length (reverse l).
Proof.
induction l.
- simpl;auto.
- simpl.
rewrite IHl.
simpl.
rewrite append_length'.
simpl.
auto.
Qed.
Lemma reverse_double : forall l, reverse (reverse l) = l.
Proof.
intro l.
induction l.
- simpl. reflexivity.
- simpl.
rewrite reverse_append.
simpl.
rewrite IHl.
auto.
Qed.
length (append l m) = length m + length l.
Lemma reverse_length' : forall l,
length l = length (reverse l).
Proof.
induction l.
- simpl;auto.
- simpl.
rewrite IHl.
simpl.
rewrite append_length'.
simpl.
auto.
Qed.
Lemma reverse_double : forall l, reverse (reverse l) = l.
Proof.
intro l.
induction l.
- simpl. reflexivity.
- simpl.
rewrite reverse_append.
simpl.
rewrite IHl.
auto.
Qed.
Pretty printing of lists in the standard library
the list type is defined parametrically over the carrier type A
Check cons.
Check nil.
Definition example_list := cons 1 (cons 2 (cons 3 (cons 4 nil))).
Print example_list.
Check nil.
Definition example_list := cons 1 (cons 2 (cons 3 (cons 4 nil))).
Print example_list.
Rocq prints the list back in its own sugared notation
And there is notation for append
Here is how you compute with the Rocq functions