### coq

#### Folding back after unfolding

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 ?

To answer your first question, yes, the fold tactic can be used here to replace the left side of the equality with S (fold_length l'). Usually, for a function f, fold f is not powerful enough to detect what it can fold. But if you specify the whole term, like here fold (fold_length l'), it works. Regarding your second question, note that tactics like reflexivity or assumption can conclude if the terms involved are equal up to some simplifications. Here, the base case of the induction can be just reflexivity. For the second case, assuming that fold is List.fold_right, simpl can surprisingly simplify without unfolding and you should not need unfold or fold here either.

### Related Links

How to prove binary commutavity with a different definition of bin?

Coq's mathematical proof language: Rewriting in if condition

Unfolding a proof term in Coq

Is it possible to rewrite the silly2 example from the Tactics chapter of the SF book using 'rewrite' instead of 'apply'?

How do Structures with Inheritance (:>) work in Coq?

How to understand Setoid definition of category?

Compatibility of impredicative Set and function extensionality

Combining two Coq hypotheses

Relationship between existential and universal quantifier in an inductive Coq definition

Simple inversion using custom inversion

forward_call with local variables

How can I rewrite “+ 1” (plus one) to “S” (succ) in Coq?

The reference “X” was not found in the current environment

Coq can't discriminate between constructors for dependently typed inductive proposition

Reduction of terms with fix. (Coq)

Casting types in coq