LOGIC:用于逻辑研究的Coq库与新鲜寄存器自动机双模拟检查
新鲜寄存器自动机的即时双模拟检查
在相关研究中,实现了一个新鲜名称生成器
GEN(a) = νb.¯ab.GEN(a)
,并将其与栈并行组合,以测试工具对并行性的响应。然而,工具超时时间明显提前,即对于更小的栈就会超时。瓶颈在于向新鲜寄存器自动机(FRAs)的转换,因为工具需要计算π - 演算进程的完整(符号化)标记迁移系统(LTS),不过最终输入到FRA双模拟检查器的自动机并不比普通栈的自动机大很多。
LOGIC库简介
LOGIC是一个用于形式化逻辑研究的Coq库,涵盖逻辑应用和逻辑元理论。对于应用场景,用户可以将从LOGIC导出的规则和高效证明自动化策略应用到基于程序逻辑的验证项目中。在元理论方面,借助LOGIC,用户能轻松为经典/直觉主义命题逻辑、分离逻辑和模态逻辑等进行标准的可靠性证明或亨金式完全性证明。
研究背景
定理证明器如Coq和Isabelle已用于形式化复杂的数学证明,包括许多重要的逻辑定理。形式化逻辑(特别是程序逻辑)在程序验证工具中广泛应用,以确保大型软件系统的安全性。但目前缺乏一个系统、基础且形式化的通用逻辑研究库。LOGIC旨在提供这样一个基础库,实现以下目标:
- 提供基础库,以便在此基础上形式化更高级的结果,并复用证明以得出类似结论。
- 导出有用的证明规则和证明自动化策略,用于不同程序验证项目中的断言蕴含证明。
- 使用单一“生态系统”实现上述两个目标。
面临挑战
- 统一形式化不同逻辑及其元理论 :不同逻辑研究虽有共同的技术符号和定义,但细微设置差异带来诸多证明工程问题。例如,不同逻辑研究可能选择不同的原始连接词,统一不同的语义定义并非易事;不同逻辑可能选择不同的原始判断,如希尔伯特系统和相继式演算对可证明性和可推导性的定义不同,如何为它们形式化一个统一理论并不明确。此外,形式化统一的亨金式完全性证明尤其困难,不同证明构建规范模型的方式不同,不同语义的模型具有不同的附加结构,这些差异导致亨金式完全性证明细节不同。
- 生成高效证明自动化策略 :为保证通用性,LOGIC中的证明需针对不同语言和证明系统进行参数化,但这种参数化设置通常会给证明构造带来显著开销。
Coq定理证明器背景
Coq是一个定理证明器,其逻辑对象用归纳构造演算编写。这种底层形式语言允许用户定义高阶函数和陈述高阶命题,即可以对函数、谓词甚至高阶函数/谓词进行量化。
Coq中的类型类是一种特殊的高阶对象,常用于形式化抽象结构,如群、偏序等。例如,群G通常定义为一个元组
(XG, +G, -G, 0G)
,其中XG是基础集合,+G是一个满足结合律的二元函数,-G是逆函数,0G是单位元。将群定义为类型类,在不引起歧义的情况下,用户可以省略G以简化表达。
此外,Coq还提供了模块系统,方便用户组织大型开发并进行大规模抽象。具体来说,模块是定义和证明的集合,模块签名是一组定理陈述,函子是从假设(由模块签名表示)到结论(由另一个签名表示)的推导。
高阶逻辑系统和模块系统是Coq模块化开发的两个关键基础设施。使用类型类的推导是针对参数化实例的形式化Coq证明,而函子不是Coq证明,而是证明生成器。
LOGIC库概述
LOGIC的主要目标是复用定义和证明,根据用户需求自动生成逻辑库,并为逻辑构造提供灵活选项。例如,对于具有连接词
→
、
¬
、
∨
的命题逻辑,可以采用不同的构造方式:
- 遵循Elliott Mendelson的方法,将
→
和
¬
作为原始连接词,定义
p ∨ q ≜ ¬p → q
。
- 采用Ebbinghaus等人的方法,将
¬
、
∨
作为原始连接词,定义
p → q ≜ ¬p ∨ q
。
证明系统也可以有多种构造方式。通常用
⊢ ϕ
表示 ϕ 可证明,
Φ ⊢ ϕ
表示 ϕ 可从命题集合 Φ 推导得出。当 ϕ 可从单个命题 ψ 推导时,写作
ψ ⊢ ϕ
。希望通过选择其中任何一个作为原始判断,推导出其他判断。
虽然可以使用不同模块和类型类来构造不同逻辑的参数化定义和证明,但这种方法存在缺点:
- 用户需要熟悉整个框架才能完成构造,需深入了解设计细节以找到每个参数的合适占位符,并选择满足需求的类。
- 证明规则的构造性证明会带来较大开销。例如,定义一个模型
Definition model : Type := A * B * C
,为其构建分离逻辑时,需要实例化多个类,如
Join
、
Unit
、
SepAlg
、
UnitJoin
等。在实例化过程中,隐式参数会导致构造规模不可接受地增大,若需实例化更多类,内存占用可能呈指数级增长。
为解决上述问题,设计了一个自动化逻辑生成器。该生成器接受用户指定的配置,集成所需的类项,并提供逻辑构造的接口。用户无需了解整个类系统的工作原理,只需编写配置并实现原始项,即可通过接口组合使用系统,导出所需的定义和证明,避免了搜索正确类和手动构造证明项的繁琐工作。此外,在大多数程序验证应用中,通常使用单一逻辑,其语法和证明规则在整个过程中保持不变。由于逻辑生成器在使用过程中已经完成了类型类的组合,无需重新构造逻辑,从而节省了时间和内存,解决了开销问题。
参数化定义和证明
为解决逻辑应用场景的多样性问题,将类型类分为四层,并根据其应用做出不同的设计选择:
1.
语言层
:定义逻辑语言的基础。
2.
连接词和判断层
:
- 为了支持同一逻辑语言的多种构造方式,分别用不同的类型类定义语言和连接词。例如,对于连接词
→
、
¬
、
∨
,可以有不同的原始连接词选择。定义了类型类
Language
来表示语言,以及
OrLanguage
、
AndLanguage
、
ImpLanguage
等类型类来表示连接词。“
OrLanguage L
” 并不假设析取是原始连接词,它可以是原始连接词或派生连接词。为了推理连接词之间的推导关系,引入了反射类,如
OrDefImpNeg
。
- 除了基于表达式的连接词,LOGIC还包含不依赖于表达式的代数结构,它们在 “模型层” 工作,直接展示模型之间的关系,常用于为表达式推导更高级的连接词。例如,代数结构
join
“
⊕
” 常用于定义分离合取 “
∗
”。
- LOGIC支持7种命题连接词和常量(
∧
、
∨
、
→
、
↔
、
¬
、
⊤
和
⊥
)、分离逻辑连接词和模态逻辑中的模态词,以及用于定义直觉主义命题逻辑、分离逻辑和模态逻辑语义的代数结构。
- 此外,LOGIC还包含形式化判断的类型类,以类似的方式构建。例如,
provable
是命题表达式的元逻辑属性,其Coq类型为
expr -> Prop
,还定义了逻辑等价,对不同应用很有用。
3.
证明规则层
:后续将详细介绍证明规则的形式化。
4.
可靠性和完全性层
:后续将阐述如何在LOGIC中证明逻辑的可靠性和完全性。
类型类示例
以下是一些类型类的示例代码:
Class MendelsonLanguage := {
expr : Type;
negp : expr -> expr;
impp : expr -> expr -> expr;
}.
Definition Mendelsonorp := fun p q => ¬p → q.
Class EbbinghausLanguage := {
expr : Type;
negp : expr -> expr;
orp : expr -> expr -> expr;
}.
Definition Ebbinghausimpp := fun p q => ¬p ∨ q.
Class Language := { expr : Type }.
Class OrLanguage (L : Language) := {orp : expr -> expr -> expr }.
Class AndLanguage (L : Language) := {andp : expr -> expr -> expr }.
Class ImpLanguage (L : Language) := {impp : expr -> expr -> expr }.
Class OrDefImpNeg (L : Language) {_ : ImpLanguage L} {_ : OrLanguage L} {_ : NegLanguage L} :=
{impp_negp2orp : for any ϕ ψ, ϕ ∨ ψ = ¬ϕ → ψ }.
Class Join (worlds : Type) : Type :=
join : worlds -> worlds -> worlds -> Prop.
Class SepconLanguage (L : Language) : Type :=
{ sepcon : expr -> expr -> expr }.
Instance worldsL := BuildLanguage (worlds -> Prop).
Class SepconDefJoin {SepconL : SepconLanguage worldsL } :=
{
join2sepcon : ϕ ∗ ψ = fun w => exists w1 w2, ⊕(w1, w2, w) and ϕ w1 and ψ w2
}.
总结
LOGIC库通过分层的类型类设计和自动化逻辑生成器,解决了统一形式化不同逻辑及其元理论和生成高效证明自动化策略的挑战,为逻辑研究和程序验证提供了强大的支持。后续将继续介绍证明规则、可靠性和完全性的形式化等内容。
逻辑构造方式对比
| 构造方式 | 原始连接词选择 | 定义示例 |
|---|---|---|
| Mendelson方法 |
→
和
¬
|
p ∨ q ≜ ¬p → q
|
| Ebbinghaus方法 |
¬
和
∨
|
p → q ≜ ¬p ∨ q
|
类型类分层结构
graph LR
A[语言层] --> B[连接词和判断层]
B --> C[证明规则层]
C --> D[可靠性和完全性层]
LOGIC:用于逻辑研究的Coq库与新鲜寄存器自动机双模拟检查
连接词与判断的深入分析
在连接词和判断的设计中,类型类的使用提供了极大的灵活性。例如,对于不同的逻辑语言,我们可以通过不同类型类的组合来实现。
我们来看连接词的类型类,以下代码展示了部分连接词的类型类定义:
Class Language := { expr : Type }.
Class OrLanguage (L : Language) := {orp : expr -> expr -> expr }.
Class AndLanguage (L : Language) := {andp : expr -> expr -> expr }.
Class ImpLanguage (L : Language) := {impp : expr -> expr -> expr }.
这些类型类并不关心连接词是原始的还是派生的,只关注其存在和类型。通过这种方式,我们可以方便地对不同逻辑语言中的连接词进行推理。
对于判断,如可证明性
provable
,它是一个元逻辑属性,其Coq类型为
expr -> Prop
。我们可以通过定义不同的类型类来表示不同的判断,从而实现对逻辑推理的形式化。
连接词推导关系的处理
为了处理连接词之间的推导关系,引入了反射类。例如
OrDefImpNeg
类:
Class OrDefImpNeg (L : Language) {_ : ImpLanguage L} {_ : OrLanguage L} {_ : NegLanguage L} :=
{impp_negp2orp : for any ϕ ψ, ϕ ∨ ψ = ¬ϕ → ψ }.
这个类表示了在特定语言中,析取和蕴含、否定之间的推导关系。通过这种方式,我们可以在LOGIC中对连接词的推导进行形式化的推理。
代数结构与连接词的关联
LOGIC中的代数结构在连接词的定义和推导中起到了重要作用。以分离合取为例,代数结构
join
“
⊕
” 与分离合取 “
∗
” 之间的关系通过以下类型类和实例体现:
Class Join (worlds : Type) : Type :=
join : worlds -> worlds -> worlds -> Prop.
Class SepconLanguage (L : Language) : Type :=
{ sepcon : expr -> expr -> expr }.
Instance worldsL := BuildLanguage (worlds -> Prop).
Class SepconDefJoin {SepconL : SepconLanguage worldsL } :=
{
join2sepcon : ϕ ∗ ψ = fun w => exists w1 w2, ⊕(w1, w2, w) and ϕ w1 and ψ w2
}.
join
代数结构直接展示了模型之间的关系,通过它可以为表达式推导分离合取这一高级连接词。这种方式使得我们可以将逻辑连接词和模型的代数结构统一在一个类型类系统中。
证明规则的形式化
在证明规则的形式化方面,我们基于前面构建的类型类系统进行设计。虽然文中未详细给出证明规则的具体代码,但可以想象,我们可以根据不同的逻辑语言和连接词的定义,来制定相应的证明规则。例如,对于蕴含连接词
→
,可以有如下的证明规则:
-
前提
:已知
ϕ
可证明,且
ϕ → ψ
可证明。
-
结论
:
ψ
可证明。
我们可以将这样的证明规则用类型类和函数的形式在Coq中进行形式化,从而实现对逻辑推理的自动化。
可靠性和完全性的证明
可靠性和完全性是逻辑研究中的重要概念。在LOGIC中,我们可以基于前面的参数化定义和证明规则,对逻辑的可靠性和完全性进行证明。
-
可靠性证明
:需要证明逻辑系统中的所有可证明命题在语义上都是真的。这意味着我们需要建立逻辑系统的语法和语义之间的联系,通过对证明规则的分析,确保每个证明步骤都能保持语义的正确性。
-
完全性证明
:要证明所有在语义上为真的命题在逻辑系统中都是可证明的。这通常涉及到构建规范模型等复杂的操作,由于不同逻辑的规范模型构建方式不同,所以完全性证明是一个具有挑战性的任务。
应用场景与优势
LOGIC库在程序验证等领域具有广泛的应用场景。在程序验证中,我们通常需要对程序的正确性进行证明,而LOGIC提供的逻辑推理和证明自动化功能可以大大简化这一过程。
-
复用性
:通过参数化定义和证明,我们可以在不同的逻辑系统中复用相同的代码和证明方法,提高开发效率。
-
灵活性
:支持多种逻辑语言和连接词的构造方式,用户可以根据自己的需求选择合适的逻辑系统。
-
自动化
:逻辑生成器的存在使得用户无需手动构造复杂的证明项,只需编写配置并实现原始项,即可自动生成所需的逻辑库。
总结
LOGIC库通过分层的类型类设计、自动化逻辑生成器以及对连接词、判断、证明规则、可靠性和完全性的形式化处理,为逻辑研究和程序验证提供了一个强大而灵活的工具。它解决了统一形式化不同逻辑及其元理论和生成高效证明自动化策略的问题,具有广泛的应用前景。
关键特性总结
| 特性 | 描述 |
|---|---|
| 类型类分层 | 将类型类分为语言、连接词和判断、证明规则、可靠性和完全性四层,提供清晰的结构 |
| 连接词灵活性 | 支持多种连接词的构造和推导关系的处理 |
| 代数结构关联 | 将逻辑连接词和模型的代数结构统一在一个类型类系统中 |
| 逻辑生成器 | 自动化生成逻辑库,减少用户的工作量 |
| 可靠性和完全性证明 | 支持对逻辑系统的可靠性和完全性进行证明 |
整体流程
graph LR
A[用户配置] --> B[逻辑生成器]
B --> C[类型类组合]
C --> D[生成逻辑库]
D --> E[程序验证应用]
F[连接词定义] --> G[证明规则制定]
G --> H[可靠性和完全性证明]
H --> E
通过以上的分析,我们可以看到LOGIC库在逻辑研究和程序验证中的重要作用,它为我们提供了一个高效、灵活且可复用的逻辑开发平台。
超级会员免费看

被折叠的 条评论
为什么被折叠?



