使用有效的递归(Acc lt(x-y))

时间:2014-11-26 15:44:18

标签: recursion coq well-formed

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来表明此功能实际终止?

1 个答案:

答案 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.