ListP t
e ListI t
são isomórficos: eles têm exatamente os mesmos construtores.
<prompt>Coq < 12 || 0 < </prompt>Check (NilP, NilI).
(NilP, NilI)
: (forall t : Type, ListP t) *
(forall t : Type, ListI t)
<prompt>Coq < 13 || 0 < </prompt>Check (ConsP, ConsI).
(ConsP, ConsI)
: (forall t : Type, t -> ListP t -> ListP t) *
(forall t : Type, t -> ListI t -> ListI t)
No entanto, Coq gera diferentes princípios de indução.
<prompt>Coq < 14 || 0 < </prompt>Check (ListP_ind, ListI_ind).
(ListP_ind, ListI_ind)
: (forall (t : Type) (P : ListP t -> Prop),
P (NilP t) ->
(forall (t0 : t) (l : ListP t), P l -> P (ConsP t t0 l)) ->
forall l : ListP t, P l) *
(forall P : forall T : Type, ListI T -> Prop,
(forall t : Type, P t (NilI t)) ->
(forall (t : Type) (t0 : t) (l : ListI t),
P t l -> P t (ConsI t t0 l)) ->
forall (T : Type) (l : ListI T), P T l)
O princípio de indução de ListI
requer que a propriedade seja paramétrica no tipo de elemento ( P : forall T, ListI T -> Prop
) enquanto o princípio de indução de ListP
pode ser instanciado em qualquer tipo t
( P : ListP t -> Prop
). Esta é uma fraqueza do front-end da Coq, na medida em que não é inteligente em relação a tipos recursivos não uniformes; você pode definir manualmente o mesmo princípio de indução (o typechecker o aceita, o que não surpreende, pois é ListP_ind
transformado pelo óbvio isomorfismo entre ListP
e ListI
).
A forma paramétrica ListP
é mais simples e fácil de usar pronta para uso. O ListI
formulário pode generalizar para recursão não uniforme, onde os parâmetros nas chamadas recursivas não são os originais. Consulte Polimorfismo e tipos de dados indutivos para obter um exemplo.
Eu também achei o seguinte bastante útil, especialmente os comentários:
http://homotopytypetheory.org/2011/04/10/just-kidding-understanding-identity-elimination-in-homotopy-type-theory/
fonte