I have fold_length defined like this:
Inductive list (X: Type) : Type :=
| nil : list X
| cons : X -> list X -> list X.
Arguments nil {X}.
Arguments cons {X} _ _.
Notation "x :: y" := (cons x y)
(at level 60, right associativity).
Notation "[ ]" := nil.
Fixpoint fold {X Y:Type} (f: X -> Y -> Y) (l:list X) (b:Y) : Y :=
match l with
| nil => b
| h :: t => f h (fold f t b)
end.
Definition fold_length {X : Type} (l : list X) : nat :=
fold (fun _ n => S n) l 0.
I have to prove a theorem and this is my code so far:
Theorem fold_length_correct : forall X (l : list X),
fold_length l = length l.
Proof.
intros X l.
induction l as [| n l' IHl'].
- simpl.
unfold fold_length.
simpl.
reflexivity.
- simpl.
unfold fold_length.
simpl.
Right now, my goal looks like this:
X : Type
n : X
l' : list X
IHl' : fold_length l' = length l'
============================
S (fold (fun (_ : X) (n0 : nat) => S n0) l' 0) = S (length l')
Now I want to convert the expression (fold (fun (_ : X) (n0 : nat) => S n0) l' 0) to fold_length l' using the definition of fold_length. Is there a way to do that in Coq (There seems to something named fold tactic in Coq. Can that achieve this.) ?
Also, is there a way to prove the above theorem without the usage of unfold and fold tactic ?
now rewrite <- IHl'or use an aux lemma:Lemma fold_lengthE {X : Type} (l : list X) : fold_right (fun _ n => S n) 0 l = fold_length l. Proof. now trivial. Qed.then rewrite using it. - ejgallegofoldcannot be used here ? - Sibifold? AFAICT it's not in the stdlib. Please provide a self-contained example (with the right imports & definitions). - gallaisfoldis usually not powerful enough to work well in most cases, YMMV, but usually one want to prevent unfolding itself instead of refolding. Controlling reduction is a bit complex in Coq, you can usesimplflags (see the manual) or deploy some other custom solution like mathcomp'snosimpl. - ejgallego