When I am trying to prove a theorem about a recursive function (see below), I end up at a reducible expression
(fix picksome L H := match A with .... end) L1 H1 = RHS
I would like to expand the match
expression, but Coq refuses. Doing simpl
just expands the right hand side into an unreadable mess. Why is Coq not able to finish the proof with simpl; reflexivity
, and how should instruct Coq to expand precisely the redex, and finish the proof ?
The function is a recursive function pick
that takes a list nat
and takes the first nat
called a
, drops the following a
items from the list, and recurses on the remaining list. I.e.
pick [2;3;4;0;1;3])=[2; 0; 1]
The theorem I'm trying to prove is that the function 'does nothing' on lists that only contains zeroes. Here is the development that leads up to the problem:
Require Import Arith.
Require Import List.
Import ListNotations.
Fixpoint drop {T} n (l:list T) :=
match n,l with
| S n', cons _ l' => drop n' l'
| O, _ => l
| _, _ => nil
end.
The first lemma:
Lemma drop_lemma_le : forall {T} n (l:list T), length (drop n l) <= (length l).
Proof.
intros; generalize n; induction l; intros; destruct n0; try reflexivity;
apply le_S; apply IHl.
Defined.
Second lemma:
Lemma picksome_term: forall l l' (a :nat),
l = a::l' -> Acc lt (length l) -> Acc lt (length (drop a l')).
Proof.
intros; apply H0; rewrite H; simpl; apply le_lt_n_Sm; apply drop_lemma_le.
Defined.
A few more definitions:
Fixpoint picksome (l:list nat) (H : Acc lt (length l)) {struct H}: list nat :=
match l as m return l=m -> _ with
| nil => fun _ => nil
| cons a l' => fun Hl =>
cons a (picksome (drop a l')
(picksome_term _ _ _ Hl H))
end
(eq_refl _).
Definition pick (l:list nat) : list nat := picksome l (lt_wf (length l)).
Inductive zerolist : list nat -> Prop :=
| znil : zerolist nil
| hzlist : forall l, zerolist l -> zerolist (O::l).
Now, we can prove our theorem if we have the lemma H
:
Theorem pickzero': (forall k, pick (0::k) = 0::pick k) ->
forall l, zerolist l -> pick l = l.
Proof.
intros H l H0; induction H0; [ | rewrite H; rewrite IHzerolist]; reflexivity.
Qed.
(* but trying to prove the lemma *)
Lemma pickzero_lemma : forall k, pick (0::k) = 0::pick k.
induction k; try reflexivity.
unfold pick at 1.
unfold picksome.
This is the goal and context:
a : nat
k : list nat
IHk : pick (0 :: k) = 0 :: pick k
============================
(fix picksome (l : list nat) (H : Acc lt (length l)) {struct H} :
list nat :=
match l as m return (l = m -> list nat) with
| [] => fun _ : l = [] => []
| a0 :: l' =>
fun Hl : l = a0 :: l' =>
a0 :: picksome (drop a0 l') (picksome_term l l' a0 Hl H)
end eq_refl) (0 :: a :: k) (lt_wf (length (0 :: a :: k))) =
0 :: pick (a :: k)