你如何查找 Coq 证明策略的定义或实现?
How do you lookup the definition or implementation of Coq proof tactics?
我在看this:
Theorem eq_add_1 : forall n m,
n + m == 1 -> n == 1 /\ m == 0 \/ n == 0 /\ m == 1.
Proof.
intros n m. rewrite one_succ. intro H.
assert (H1 : exists p, n + m == S p) by now exists 0.
apply eq_add_succ in H1. destruct H1 as [[n' H1] | [m' H1]].
left. rewrite H1 in H; rewrite add_succ_l in H; apply succ_inj in H.
apply eq_add_0 in H. destruct H as [H2 H3]; rewrite H2 in H1; now split.
right. rewrite H1 in H; rewrite add_succ_r in H; apply succ_inj in H.
apply eq_add_0 in H. destruct H as [H2 H3]; rewrite H3 in H1; now split.
Qed.
我如何找到 intros
或 destruct
之类的东西 确切 的意思,比如查找一个实现(或者,如果不可能,一个定义)?有什么方法可以有效地做到这一点?
原始战术和 user-defined 战术的答案不同。但是,您显示的证明脚本几乎没有使用 user-defined 策略,除了 now
,它是 easy
策略的符号。
如果您不确定一种策略是否原始,请尝试两种策略;检查手册可能是最简单的第一步。
对于user-defined战术。
对于定义为 Ltac foo args := body.
的策略,您可以使用 Print Ltac foo
(例如 Print Ltac easy.
)。 AFAIK,这不适用于 Tactic Notation.
定义的战术 在这两种情况下,我更喜欢查看来源(我通过 grep
找到)。
原始战术
有 Coq 参考手册 (https://coq.inria.fr/distrib/current/refman/coq-tacindex.html),它没有完整的规范,但通常是最接近的。它不是很容易访问,因此您应该首先参考许多 Coq 教程或介绍之一,例如软件基础。
有实际的 Coq 实现,但除非您是 Coq 实现者,否则这不是很有帮助。
正如 Blaisorblade 所提到的,很难准确理解战术在做什么,查看参考手册以了解如何使用它们会更容易。然而,在概念层面上,战术并没有那么复杂。通过 Curry-Howard correspondence,Coq 证明使用您用来编写常规程序的相同函数式语言来表示。 intros
或 destruct
等策略只是用这种语言编写程序的元程序。
例如,假设你需要证明A -> B
。这意味着你需要编写一个函数类型为A -> B
的程序。当你写 intros H.
时,Coq 构建了一个部分证明 fun (H : A) => ?
,其中 ?
表示一个应该具有类型 B
的洞。同理,destruct
在你的证明中添加一个match
表达式来做案例分析,并要求你为每个match
分支出示证明。随着您添加更多策略,您会不断填补这些漏洞,直到您拥有完整的证明。
Coq 的语言非常少,因此构建证明的策略只能做这么多:函数应用和抽象、构造函数、模式匹配等。原则上,可能只有一些策略,一个用于 Coq 中的每个句法结构,这将允许您构建 any 证明!我们不这样做的原因是直接使用这些核心构造太低级别,策略使用自动证明搜索、统一和其他功能来简化编写证明的过程。
我在看this:
Theorem eq_add_1 : forall n m,
n + m == 1 -> n == 1 /\ m == 0 \/ n == 0 /\ m == 1.
Proof.
intros n m. rewrite one_succ. intro H.
assert (H1 : exists p, n + m == S p) by now exists 0.
apply eq_add_succ in H1. destruct H1 as [[n' H1] | [m' H1]].
left. rewrite H1 in H; rewrite add_succ_l in H; apply succ_inj in H.
apply eq_add_0 in H. destruct H as [H2 H3]; rewrite H2 in H1; now split.
right. rewrite H1 in H; rewrite add_succ_r in H; apply succ_inj in H.
apply eq_add_0 in H. destruct H as [H2 H3]; rewrite H3 in H1; now split.
Qed.
我如何找到 intros
或 destruct
之类的东西 确切 的意思,比如查找一个实现(或者,如果不可能,一个定义)?有什么方法可以有效地做到这一点?
原始战术和 user-defined 战术的答案不同。但是,您显示的证明脚本几乎没有使用 user-defined 策略,除了 now
,它是 easy
策略的符号。
如果您不确定一种策略是否原始,请尝试两种策略;检查手册可能是最简单的第一步。
对于user-defined战术。
对于定义为 Ltac foo args := body.
的策略,您可以使用 Print Ltac foo
(例如 Print Ltac easy.
)。 AFAIK,这不适用于 Tactic Notation.
定义的战术 在这两种情况下,我更喜欢查看来源(我通过 grep
找到)。
原始战术
有 Coq 参考手册 (https://coq.inria.fr/distrib/current/refman/coq-tacindex.html),它没有完整的规范,但通常是最接近的。它不是很容易访问,因此您应该首先参考许多 Coq 教程或介绍之一,例如软件基础。
有实际的 Coq 实现,但除非您是 Coq 实现者,否则这不是很有帮助。
正如 Blaisorblade 所提到的,很难准确理解战术在做什么,查看参考手册以了解如何使用它们会更容易。然而,在概念层面上,战术并没有那么复杂。通过 Curry-Howard correspondence,Coq 证明使用您用来编写常规程序的相同函数式语言来表示。 intros
或 destruct
等策略只是用这种语言编写程序的元程序。
例如,假设你需要证明A -> B
。这意味着你需要编写一个函数类型为A -> B
的程序。当你写 intros H.
时,Coq 构建了一个部分证明 fun (H : A) => ?
,其中 ?
表示一个应该具有类型 B
的洞。同理,destruct
在你的证明中添加一个match
表达式来做案例分析,并要求你为每个match
分支出示证明。随着您添加更多策略,您会不断填补这些漏洞,直到您拥有完整的证明。
Coq 的语言非常少,因此构建证明的策略只能做这么多:函数应用和抽象、构造函数、模式匹配等。原则上,可能只有一些策略,一个用于 Coq 中的每个句法结构,这将允许您构建 any 证明!我们不这样做的原因是直接使用这些核心构造太低级别,策略使用自动证明搜索、统一和其他功能来简化编写证明的过程。