gpt4 book ai didi

coq - 在 Coq 中定义 Ackermann 时出错

转载 作者:行者123 更新时间:2023-12-04 03:59:28 24 4
gpt4 key购买 nike

我试图在 Coq 中定义 Ackermann-Peters 函数,但收到一条我不明白的错误消息。如您所见,我正在打包参数 a, b阿克曼一对 ab ;我提供了一个为参数定义排序函数的排序。然后我使用 Function定义阿克曼本身的形式,为它提供 ab 的排序函数论据。

Require Import Recdef.    
Definition ack_ordering (ab1 ab2 : nat * nat) :=
match (ab1, ab2) with
|((a1, b1), (a2, b2)) =>
(a1 > a2) \/ ((a1 = a2) /\ (b1 > b2))
end.
Function ack (ab : nat * nat) {wf ack_ordering} : nat :=
match ab with
| (0, b) => b + 1
| (a, 0) => ack (a-1, 1)
| (a, b) => ack (a-1, ack (a, b-1))
end.

我得到的是以下错误消息:

Error: No such section variable or assumption: ack.



我不确定是什么困扰着 Coq,但在互联网上搜索,我发现一个建议,使用通过排序或度量定义的递归函数可能会出现问题,其中递归调用发生在匹配中。但是,使用预测 fstsnd和一个 if-then-else生成了不同的错误消息。有人可以建议如何在 Coq 中定义 Ackermann 吗?

最佳答案

好像Function无法解决这个问题。然而,它的堂兄Program Fixpoint可以。

让我们先定义一些处理有根据的引理:

Require Import Coq.Program.Wf.
Require Import Coq.Arith.Arith.

Definition lexicographic_ordering (ab1 ab2 : nat * nat) : Prop :=
match ab1, ab2 with
| (a1, b1), (a2, b2) =>
(a1 < a2) \/ ((a1 = a2) /\ (b1 < b2))
end.

(* this is defined in stdlib, but unfortunately it is opaque *)
Lemma lt_wf_ind :
forall n (P:nat -> Prop), (forall n, (forall m, m < n -> P m) -> P n) -> P n.
Proof. intro p; intros; elim (lt_wf p); auto with arith. Defined.

(* this is defined in stdlib, but unfortunately it is opaque too *)
Lemma lt_wf_double_ind :
forall P:nat -> nat -> Prop,
(forall n m,
(forall p (q:nat), p < n -> P p q) ->
(forall p, p < m -> P n p) -> P n m) -> forall n m, P n m.
Proof.
intros P Hrec p. pattern p. apply lt_wf_ind.
intros n H q. pattern q. apply lt_wf_ind. auto.
Defined.

Lemma lexicographic_ordering_wf : well_founded lexicographic_ordering.
Proof.
intros (a, b); pattern a, b; apply lt_wf_double_ind.
intros m n H1 H2.
constructor; intros (m', n') [G | [-> G]].
- now apply H1.
- now apply H2.
Defined.

现在我们可以定义 Ackermann-Péter 函数:
Program Fixpoint ack (ab : nat * nat) {wf lexicographic_ordering ab} : nat :=
match ab with
| (0, b) => b + 1
| (S a, 0) => ack (a, 1)
| (S a, S b) => ack (a, ack (S a, b))
end.
Next Obligation.
inversion Heq_ab; subst. left; auto. Defined.
Next Obligation.
apply lexicographic_ordering_wf. Defined.

一些简单的测试证明我们可以使用 ack 进行计算:
Example test1 : ack (1, 2) = 4 := eq_refl.
Example test2 : ack (3, 4) = 125 := eq_refl. (* this may take several seconds *)

使用 Equations M. Sozeau 和 C. Mangin 的插件可以这样定义函数:
From Equations Require Import Equations Subterm.

Equations ack (p : nat * nat) : nat :=
ack p by rec p (lexprod _ _ lt lt) :=
ack (pair 0 n) := n + 1;
ack (pair (S m) 0) := ack (m, 1);
ack (pair (S m) (S n)) := ack (m, ack (S m, n)).

不幸的是,无法使用 ( , )由于 issue #81 对的符号.代码取自Equation 的测试套件: ack.v .

关于coq - 在 Coq 中定义 Ackermann 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10292421/

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