In order to ensure soundness, and to keep axioms like proof irrelevance admissible, Coq has an "elimination restriction" on inductive types in Prop
.
Consider, for example, the definition of the existential quantifier, reproduced here:
Inductive exT (A:Type) (P : A -> Prop) : Prop :=
exT_intro : forall (a:A), P a -> exT A P.
Arguments exT_intro {_} {_} _ _.
This quantifier can be eliminated into a Q : Prop
, as follows:
Definition elim_exT_Prop {T:Type} {P:T->Prop} (Q:Prop) :
(forall (a:T), P a -> Q) ->
(exT T P) -> Q :=
fun H Hex => match Hex with exT_intro w Hw => H w Hw end.
However, if we want Q
to have type Type
, this fails:
Fail
Definition elim_exT_Type {T:Type} {P:T->Prop} (Q:Type) :
(forall (a:T), P a -> Q) ->
(exT T P) -> Q :=
fun H Hex => match Hex with exT_intro _ _ w Hw => H w Hw end.
So far, so clear. There are exceptions to this "elimination restriction," namely:
- The type being eliminated has no constructor (
False
is the main example) - The type being eliminated has only one constructor, and all arguments of it themselves have type
Prop
(and P Q
is the other example, as is the well-founded recursion type)
This means that the following type, an existential quantifier quantifying over Prop
, is not subject to this restriction, i.e. is computational, i.e. can be eliminated into Type
:
Inductive exP (A:Prop) (P : A -> Prop) : Prop :=
exP_intro : forall (a:A), P a -> exP A P.
Arguments exP_intro {_} {_} _ _.
(* exP can be eliminated into Type *)
Definition elim_exP_Type {T:Prop} {P:T->Prop} (Q:Type) :
(forall (a:T), P a -> Q) ->
(exP T P) -> Q :=
fun H Hex => match Hex with exP_intro w Hw => H w Hw end.
However, if we take our old definition exP
, and instantiate it with a proposition, it can still not be eliminated:
Fail (* even though T has type **Prop** *)
Definition elim_exT_with_Prop_into_Type {T:Prop} {P:T->Prop} (Q:Type) :
(forall (a:T), P a -> Q) ->
(exT T P) -> Q :=
fun H Hex => match Hex with exT_intro _ _ w Hw => H w Hw end.
My question now is: Why is this? Does Coq's elimination restriction check not see that there is no computational content to be gained here?
If we do some extra work, we can define something of the above type, that even has the same reduction behavior:
Definition exT_to_exP {T:Prop} {P:T->Prop} : exT T P -> exP T P
:= elim_exT_Prop _ exP_intro.
Definition elim_exT_with_Prop_into_Type {T:Prop} {P:T->Prop} (Q:Type) :
(forall (a:T), P a -> Q) ->
(exT T P) -> Q := fun H Hex => elim_exP_Type _ H (exT_to_exP Hex).
Again, we can achieve this by doing a round-about way through something in Prop
. But why is that step necessary?
Thanks!
PS: I have called this restriction "elimination restriction" following the lecture notes by Prof. Smolka at Saarland University. Is this "the name" for this? Is there another one?