在A Tutorial on[Co-]Inductive Types in Coq上。 47,定义递归函数,其中每个递归步骤使用格式良好的命题来表明递归终止。
使用x
调用的函数使用x-y
y<>0
进行递归调用,因此它应该终止。
我无法在没有收到错误的情况下将其输入Coq。 Coq抱怨调用中的递归参数不较小,而教程声称它是如此。
我错过了什么?
我稍微重写了代码以缩短代码,但我也尝试了文章中的逐字定义。
首先,我们展示可以从x访问x-y
。
Require Import Omega.
Definition minus_decrease:
forall x y, Acc lt x -> x<>0 -> y<>0 -> Acc lt (x-y).
intros x y H Hx Hy.
case H; intro Ha; apply Ha.
omega.
Qed.
接下来,在尝试定义函数时,就像这样
Definition div_aux :=
fix div_aux (x y:nat) (H:Acc lt x) {struct H}: nat :=
match eq_nat_dec x 0 with
|left _ => 0
|right _ =>
match eq_nat_dec y 0 with
|left _ => 0
|right v => S (div_aux (x-y) y (minus_decrease x y H _ v))
end
end.
然后Coq拒绝,说
对div_aux的递归调用具有等于的主参数 “minus_decrease x y H?156 v”而不是“H”的子项。
注意div_aux x ...
如何使用div_aux (x-y) ...
递归调用自身,(minus_decrease ...)
返回Acc lt (x-y)
类型的字词
如何使用Acc
来表明此功能实际终止?
答案 0 :(得分:3)
错误似乎是我使用Qed.
而不是Defined.
结束了定义。以下工作。
Require Import Omega.
Definition minus_decrease: forall x y, Acc lt x -> x<>0 -> y<>0 -> Acc lt (x-y).
intros x y H Hx Hy.
case H; intro Ha; apply Ha.
omega.
Defined.
Fixpoint div_aux (x y:nat) (H:Acc lt x) {struct H}: nat.
Proof.
refine (if eq_nat_dec x 0
then 0
else if eq_nat_dec y 0
then y
else S (div_aux (x-y) y _)).
apply (minus_decrease _ _ H _H _H0).
Qed.