我通过阅读“Certified Programming with Dependent Types”一书来学习 Coq,但我在理解forall
语法时遇到了麻烦。
作为一个例子,让我们考虑一下这种相互归纳的数据类型:(代码来自书中)
Inductive even_list : Set :=
| ENil : even_list
| ECons : nat -> odd_list -> even_list
with odd_list : Set :=
| OCons : nat -> even_list -> odd_list.
和这个相互递归的函数定义:
Fixpoint elength (el : even_list) : nat :=
match el with
| ENil => O
| ECons _ ol => S (olength ol)
end
with olength (ol : odd_list) : nat :=
match ol with
| OCons _ el => S (elength el)
end.
Fixpoint eapp (el1 el2 : even_list) : even_list :=
match el1 with
| ENil => el2
| ECons n ol => ECons n (oapp ol el2)
end
with oapp (ol : odd_list) (el : even_list) : odd_list :=
match ol with
| OCons n el' => OCons n (eapp el' el)
end.
我们生成了归纳方案:
Scheme even_list_mut := Induction for even_list Sort Prop
with odd_list_mut := Induction for odd_list Sort Prop.
现在我不明白的是,从even_list_mut
我可以看到它需要 3 个参数的类型:
even_list_mut
: forall (P : even_list -> Prop) (P0 : odd_list -> Prop),
P ENil ->
(forall (n : nat) (o : odd_list), P0 o -> P (ECons n o)) ->
(forall (n : nat) (e : even_list), P e -> P0 (OCons n e)) ->
forall e : even_list, P e
但为了应用它,我们需要为其提供两个参数,并将目标替换为 3 个前提(for和P ENil
case )。forall (n : nat) (o : odd_list), P0 o -> P (ECons n o)
forall (n : nat) (e : even_list), P e -> P0 (OCons n e)
所以它实际上得到了 5 个参数,而不是 3 个。
但是当我们想到这种类型时,这个想法就失败了:
fun el1 : even_list =>
forall el2 : even_list, elength (eapp el1 el2) = elength el1 + elength el2
: even_list -> Prop
和
fun el1 el2 : even_list => elength (eapp el1 el2) = elength el1 + elength el2
: even_list -> even_list -> Prop
谁能解释forall
语法是如何工作的?
谢谢,