gpt4 book ai didi

recursion - Coq 无法计算由 Fix 定义的有根据的,但如果由 Program Fixpoint 定义则可以

转载 作者:行者123 更新时间:2023-12-01 19:47:56 25 4
gpt4 key购买 nike

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

扩展欧几里得算法适用于整数,所以我需要一些整数上有充分根据的关系。我尝试使用 Zwf 中的关系,但没有成功(我需要查看更多示例)。我认为使用 Z.abs_nat 函数将 Z 映射到 nat 会更容易,然后只需使用 Nat.lt 作为关系。我们的 friend 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. 结尾。好吧,还有一些不透明的东西,但是什么呢?如果 是一个库定义,那么我认为在我的代码中重新定义它并不酷。

看来我的问题与 this 有关。 , this 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' 中没有的?以及如何使 euclid 发挥作用?

最佳答案

Okey, something else is opaque, but what?

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

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

And how to make euclids work?

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

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

就是这样!修复 lt_wf_on_Z 后,其余代码即可正常工作。

关于recursion - Coq 无法计算由 Fix 定义的有根据的,但如果由 Program Fixpoint 定义则可以,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49846632/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com