证明助手是如何实现的?
How proof assistants are implemented?
证明助手的主要模块有哪些?
我只是想知道校对的内部逻辑。例如,有关此类助手的图形用户界面的主题,我不感兴趣。
有人向编译器提出了与我类似的问题:
https://softwareengineering.stackexchange.com/questions/165543/how-to-write-a-very-basic-compiler
我的担忧是相同的,但对于证明检查系统。
我不是这方面的专家(我只是这些系统的用户;我不担心太多它们的内部结构),这可能只是一个模糊的部分答案,但我知道的两种主要方法是:
- 使用 Curry–Howard 同构的依赖类型系统(例如 Coq、Lean、Agda)。语句只是类型,证明是具有该类型的术语,因此检查证明的有效性本质上只是类型检查术语的一种特殊情况。我不想对这种方法说太多,因为我对它了解不多,担心会出错。 Théo Winterhalter 在上面的评论中链接了一些内容,可能会提供有关此方法的更多背景信息。
- LCF 风格的定理证明(例如 Isabelle、HOL Light、HOL 4)。这里的定理(粗略地说)是实现语言中
thm
类型的不透明值。只有相对较小的“证明内核”才能创建这些 thm
值,并且系统的所有其他部分都与该证明内核交互。内核提供了一个由各种小函数组成的接口,这些函数实现了小的推理步骤,例如modus ponens(如果你有一个定理A ⟹ B
和一个定理A
,你可以得到定理B
)或者∀-引言(如果你有定理P x
对于一个固定变量x
,你可以得到定理∀x. P x
)等等内核还提供了一个用于定义新常量的接口。原则上,只要您可以相信这些函数忠实地实现了底层逻辑的基本推理步骤,您就可以相信您可以产生的任何 thm
值确实对应于您逻辑中的定理。对于 LCF 风格的证明者,实际证明是什么的答案有点难以回答,因为它们通常不构建证明项(例如 Isabelle 有它们,但默认情况下它们被禁用并且没有被广泛使用)。我认为可以说内核原语如何被调用的历史构成了证明,如果要记录它,它可以 – 原则上 – 在另一个系统中重播和检查.
在这两种情况下,我们的想法是您拥有一个您必须信任的内核(前者是类型检查器,后者是推理内核),然后您拥有一个由附加程序组成的大型生态系统提供更多便利层。但是,由于它们必须与内核交互才能实际产生定理,因此您不必相信该代码。
所有这些不同的系统都对系统的哪些部分在内核中,哪些部分不在内核中进行了各种权衡。总的来说,我认为可以公平地说依赖类型的系统往往比基于 LCF 的系统有更大的内核(例如 HOL Light 有一个特别小和简单的内核)。
我认为还有其他系统不属于这两个类别(例如 Mizar、ACL2、PVS、Metamath、NuPRL),但我不知道它们是如何实现的。
对于 LCF、HOL 和 Isabelle,您将在期刊文章“From LCF to Isabelle/HOL”中找到对您问题的详尽回答。 (它是开放访问。)
大多数依赖类型的系统,例如 Coq,也是 LCF 风格的定理证明器,如文章和 Eberl 的回答中所述。一个重要的区别是这样的演算包含完整的证明对象,因此 LCF 方法的 objective 之一——通过不存储证明来保存 space——被放弃了。不过,objective的稳健性还是达到了。
证明助手的主要模块有哪些?
我只是想知道校对的内部逻辑。例如,有关此类助手的图形用户界面的主题,我不感兴趣。
有人向编译器提出了与我类似的问题: https://softwareengineering.stackexchange.com/questions/165543/how-to-write-a-very-basic-compiler
我的担忧是相同的,但对于证明检查系统。
我不是这方面的专家(我只是这些系统的用户;我不担心太多它们的内部结构),这可能只是一个模糊的部分答案,但我知道的两种主要方法是:
- 使用 Curry–Howard 同构的依赖类型系统(例如 Coq、Lean、Agda)。语句只是类型,证明是具有该类型的术语,因此检查证明的有效性本质上只是类型检查术语的一种特殊情况。我不想对这种方法说太多,因为我对它了解不多,担心会出错。 Théo Winterhalter 在上面的评论中链接了一些内容,可能会提供有关此方法的更多背景信息。
- LCF 风格的定理证明(例如 Isabelle、HOL Light、HOL 4)。这里的定理(粗略地说)是实现语言中
thm
类型的不透明值。只有相对较小的“证明内核”才能创建这些thm
值,并且系统的所有其他部分都与该证明内核交互。内核提供了一个由各种小函数组成的接口,这些函数实现了小的推理步骤,例如modus ponens(如果你有一个定理A ⟹ B
和一个定理A
,你可以得到定理B
)或者∀-引言(如果你有定理P x
对于一个固定变量x
,你可以得到定理∀x. P x
)等等内核还提供了一个用于定义新常量的接口。原则上,只要您可以相信这些函数忠实地实现了底层逻辑的基本推理步骤,您就可以相信您可以产生的任何thm
值确实对应于您逻辑中的定理。对于 LCF 风格的证明者,实际证明是什么的答案有点难以回答,因为它们通常不构建证明项(例如 Isabelle 有它们,但默认情况下它们被禁用并且没有被广泛使用)。我认为可以说内核原语如何被调用的历史构成了证明,如果要记录它,它可以 – 原则上 – 在另一个系统中重播和检查.
在这两种情况下,我们的想法是您拥有一个您必须信任的内核(前者是类型检查器,后者是推理内核),然后您拥有一个由附加程序组成的大型生态系统提供更多便利层。但是,由于它们必须与内核交互才能实际产生定理,因此您不必相信该代码。
所有这些不同的系统都对系统的哪些部分在内核中,哪些部分不在内核中进行了各种权衡。总的来说,我认为可以公平地说依赖类型的系统往往比基于 LCF 的系统有更大的内核(例如 HOL Light 有一个特别小和简单的内核)。
我认为还有其他系统不属于这两个类别(例如 Mizar、ACL2、PVS、Metamath、NuPRL),但我不知道它们是如何实现的。
对于 LCF、HOL 和 Isabelle,您将在期刊文章“From LCF to Isabelle/HOL”中找到对您问题的详尽回答。 (它是开放访问。)
大多数依赖类型的系统,例如 Coq,也是 LCF 风格的定理证明器,如文章和 Eberl 的回答中所述。一个重要的区别是这样的演算包含完整的证明对象,因此 LCF 方法的 objective 之一——通过不存储证明来保存 space——被放弃了。不过,objective的稳健性还是达到了。