【问题标题】:Coq can't compute well-founded defined with Fix, but can if defined with Program FixpointCoq 不能计算用 Fix 定义的有根据,但如果用 Program Fixpoint 定义则可以
【发布时间】:2018-04-15 20:47:29
【问题描述】:

作为通过有根据的关系理解递归的练习,我决定实现扩展欧几里得算法。

扩展欧几里得算法适用于整数,所以我需要一些 关于整数的有根据的关系。我尝试使用Zwf 中的关系,但没有奏效(我需要查看更多示例)。我决定使用Z.abs_nat 函数将Z 映射到nat 会更容易,然后只需使用Nat.lt 作为关系。我们的朋友wf_inverse_image 来帮助我。所以这就是我所做的:

Require Import ZArith Coq.ZArith.Znumtheory.
Require Import Wellfounded.

Definition fabs := (fun x => Z.abs_nat (Z.abs x)). (* (Z.abs x) is a involutive nice guy to help me in the future *) 
Definition myR (x y : Z) := (fabs x < fabs y)%nat.
Definition lt_wf_on_Z := (wf_inverse_image Z nat lt fabs) lt_wf.

扩展欧几里得算法是这样的:

Definition euclids_type (a : Z) := forall b : Z, Z * Z * Z.

Definition euclids_rec : (forall x : Z, (forall y : Z,(myR y x) -> euclids_type y) -> euclids_type x).
  unfold myR, fabs.
  refine (fun a rec b => if (Z_eq_dec a 0) then (b, 0, 1)
                      else let '(g, s, t) :=  rec (b mod a ) _ a 
                           in (g, t - (b / a) * s, s)
                      ).
apply Zabs_nat_lt. split. apply Z.abs_nonneg. apply Z.mod_bound_abs. assumption.
Defined.

Definition euclids := Fix lt_wf_on_Z _ euclids_rec. 

现在让我们看看它是否有效:

Compute (euclids 240 46). (* Computation takes a long time and results in a huge term *)

我知道如果某些定义不透明,可能会发生这种情况,但是我所有的定义都以Defined. 结尾。好吧,其他东西是不透明的,但是什么? 如果是一个库定义,那么我认为在我的代码中重新定义它不会很酷。

看来我的问题与thisthis otherthis too 有关。

我决定试一试Program Fixpoint,因为我从未使用过它。我惊讶地发现我可以复制和粘贴我的程序。

Program Fixpoint euclids' (a b: Z) {measure (Z.abs_nat (Z.abs a))} : Z * Z * Z :=
  if Z.eq_dec a 0 then (b, 0, 1)
  else let '(g, s, t) := euclids' (b mod a) a in
       (g, t - (b / a) * s, s).
Next Obligation.
apply Zabs_nat_lt. split. apply Z.abs_nonneg. apply Z.mod_bound_abs. assumption. 
Defined.

更令人惊讶的是,它运行良好:

Compute (euclids' 240 46). (* fast computation gives me (2, -9, 47): Z * Z * Z *)

euclids 中什么是不透明的,而 euclids' 中没有? 以及如何使euclids 工作?

【问题讨论】:

  • Program Fixpoint 使用Wf.Fix_sub(您使用Fix),它使用计算值来确定递归,(forall y : {y | myR y x}, euclids_type (proj1_sig y)) 而不是(forall y : Z,(myR y x) -&gt; euclids_type y)。这可能与它有关。

标签: recursion coq totality


【解决方案1】:

好吧,其他东西是不透明的,但是什么?

wf_inverse_image 是不透明的,它所依赖的引理也是如此:Acc_lemmaAcc_inverse_image。如果你让这三个透明euclids会计算。

充分发现的证据基本上是您进行结构递归的参数,因此它必须是透明的。

以及如何使euclids 工作?

幸运的是,您不必自行推出上述标准定义的透明版本,因为 well_founded_ltof 引理在 Coq.Arith.Wf_nat 中已经是透明的,因此我们可以重复使用它:

Lemma lt_wf_on_Z : well_founded myR.
Proof. exact (well_founded_ltof Z fabs). Defined.

就是这样!修复 lt_wf_on_Z 后,其余代码就可以工作了。

【讨论】:

  • 您是如何发现wf_inverse_image 是不透明的?碰巧你知道,或者你检查了我所有的定义和他们所依赖的定义?只是询问是否会再次发生这种情况。
  • 你可以像这样询问 Coq:About wf_inverse_image.(它会告诉你标识符是透明还是不透明)或 Print Opaque Dependencies wf_inverse_image.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
相关资源
最近更新 更多