13.5 Pattern-matching on inductive objects involving local definitions

If local definitions occur in the type of a constructor, then there are two ways to match on this constructor. Either the local definitions are skipped and matching is done only on the true arguments of the constructors, or the bindings for local definitions can also be caught in the matching.

Example.

Coq < Inductive list : nat -> Set :=
Coq < | nil : (list O)
Coq < | cons : (n:nat)[m:=(mult (2) n)](list m)->(list (S (S m))).

In the next example, the local definition is not caught.

Coq < Fixpoint length [n; l:(list n)] : nat :=
Coq <   Cases l of
Coq <      nil => O
Coq <   | (cons n l0) => (S (length (mult (2) n) l0))
Coq <   end.
length is recursively defined

But in this example, it is.

Coq < Fixpoint length' [n; l:(list n)] : nat :=
Coq <   Cases l of
Coq <      nil => O
Coq <   | (cons _ m l0) => (S (length' m l0))
Coq <   end.
length' is recursively defined

Remark: for a given matching clause, either none of the local definitions or all of them can be caught.