让我教你一个奇怪的技巧。它可能不是解决你所有问题的答案,但至少在概念上可以帮助你。
让我们为自然数实现加法,后者由以下方式给出:
Inductive nat : Set :=
| zero : nat
| suc : nat -> nat.
你可以尝试通过策略来写加法,但这种情况会发生。
Theorem plus' : nat -> nat -> nat.
Proof.
induction 1.
plus' < 2 subgoals
============================
nat -> nat
subgoal 2 is:
nat -> nat
你看不清自己在做什么。
关键是要更仔细地观察你正在做的事情。我们可以引入一个毫无必要的依赖类型,克隆nat
。
Inductive PLUS (x y : nat) : Set :=
| defPLUS : nat -> PLUS x y.
这里的想法是,
PLUS x y
表示 "计算
x + y
的方法"。我们需要一个投影函数,可以提取这种计算的结果。
Theorem usePLUS : forall x y, PLUS x y -> nat.
Proof.
induction 1.
exact n.
Defined.
现在我们已经准备好通过提供程序来编程。
Theorem mkPLUS : forall x y, PLUS x y.
Proof.
mkPLUS < 1 subgoal
============================
forall x y : nat, PLUS x y
目标的结论向我们展示了当前的左侧和上下文。在Agda中,C-c C-c
的类比是...
induction x.
mkPLUS < 2 subgoals
============================
forall y : nat, PLUS zero y
subgoal 2 is:
forall y : nat, PLUS (suc x) y
你可以看到它已经进行了案例分割!让我们去掉基本情况。
intros y.
exact (defPLUS zero y y).
调用PLUS的构造函数就像写一个方程式。想象在它的第三个参数前有一个=
符号。对于步进情况,我们需要进行递归调用。
intros y.
eapply (fun h => (defPLUS (suc x) y (suc (usePLUS x y h)))).
为了进行递归调用,我们使用所需参数调用
usePLUS
,这里是
x
和
y
,但我们对第三个参数进行抽象,即如何实际计算它的说明。最终目标只剩下这个子目标,实质上是终止检查。
mkPLUS < 1 subgoal
x : nat
IHx : forall y : nat, PLUS x y
y : nat
============================
PLUS x y
现在,您不再使用Coq的守卫检查,而是使用...
auto.
…这检查归纳假设覆盖递归调用。我们正在
该段文本是关于计算机科学中的递归程序设计方面的内容,其中提到了一种方法来检查归纳假设是否覆盖了递归调用。
Defined.
我们有一个工作者,但我们需要一个包装器。
Theorem plus : nat -> nat -> nat.
Proof.
intros x y.
exact (usePLUS x y (mkPLUS x y)).
Defined.
我们准备好了。
Eval compute in (plus (suc (suc zero)) (suc (suc zero))).
Coq < = suc (suc (suc (suc zero)))
: nat
您拥有一个交互式的构建工具。通过使类型更加详细,您可以将其优化以显示解决问题所需的相关细节。生成的证明脚本...
Theorem mkPLUS : forall x y, PLUS x y.
Proof.
induction x.
intros y.
exact (defPLUS zero y y).
intros y.
eapply (fun h => (defPLUS (suc x) y (suc (usePLUS x y h)))).
auto.
Defined.
...明确指出了它构建的程序。你可以看到它定义了加法。
如果你自动化这个程序构建过程,并添加一个界面来显示你正在构建的程序和关键的问题简化策略,那么你就得到了一个有趣的小型编程语言,叫做Epigram 1。
refine
(请参阅文档)。第二个要点可能会更困难,因为我认为当前的Coq IDE还无法使用类型信息,我猜想company-coq可能有助于第三个要点。 - ejgallegomatch
,你的意思是按 C-c C-c 键,对吗? - pigworker