本文已参与「新人创作礼」活动,一起开启掘金创作之路。
形式化验证
- 为什么需要形式化验证?
- 因为这种证明方法可以在理论上寻找到程序中的错误,而这些错误可能不可复现、无法被测试所覆盖、或者只会发生一次等,比如1994年奔腾芯片的FDIV错误,除法运算会发生某种偏差,这个问题是在90亿次除法运算中才可能出现1次错误,或者一些其他的著名BUG:原来曾有过这么多BUG!哪个CPU最严重。我们没用办法通过简单的测试来找到这些BUG,但通过形式化的验证却可以找到哪里可能存在问题。
- 形式化验证的三个部分:
- 用于系统建模的框架
- 用于描述待验证性质的规范语言
- 用来确定系统描述是否满足规范的验证方法
- 根据证明的依据对形式化验证的分类
- 基于证明的处理中:系统描述一组公式Γ,他的规范是另一个公式ϕ,验证的方法就是试图找到Γ⊢ϕ的证明。
- 基于模型的处理中(本节笔记重点):系统由适当逻辑的模型M表示,规范也是另一个公式ϕ表示,验证方法则是由计算模型M是否满足ϕ构成(写作M⊨ϕ)。
- 根据验证的完全程度对形式化验证的分类
- 性质验证:规范描述系统的单一性质。
- 完全验证:规范描述的系统的全部性质。
模型检测(Model Checking)
- 时态逻辑(Temporal Logic)
- 思想:在一个模型中,公式的真与假不是静态的,而在命题逻辑或谓词逻辑中的确如此。
- 含义:时态逻辑的模型包含若干状态,而一个公式可以在某些状态下为真,在其他状态下为假。公式可以随系统的状态演化而改变其真值。
- 模型检测:模型检测是一种自动的、基于模型的、性质验证的处理方法。
- 模型检测也是基于时态逻辑的,在模型检测中,模型M是迁移系统,性质ϕ是是时态逻辑公式,为了验证一个系统满足一个性质,需要三步操作:
- 使用模型检测器的描述性语言对系统进行建模,得到一个模型M
- 使用模型检测器的规范语言对性质进行编码,禅师一个时态逻辑公式ϕ
- 以M和ϕ做输入,运行模型检测器
如果模型检测器M⊨ϕ的结果为假(或者no、false),大多数模型检测器会产生导致失败的系统行为轨迹,我们称这一操作为之为逆向追踪
- 模型检测就是对问题M,s⊨ϕ是否成立计算答案的过程,此处的ϕ是时态逻辑的一个公式,M是所考虑的一个适当模型,s是该模型的一个状态,⊨是满足关系。
线性时态逻辑(Linear-time Temporal Logic,简写为LTL)
- 定义:一种能表达时间概念的特殊时态逻辑。它将时间轴看成一个线性的状态序列,可以无限延伸到未来。常用来精确表示模型的动态语义。
- 计算路径(简称为路径):模型里的状态序列。因为未来是不确定的,有无数种可能,在模型中表示有无数条路径,代表未来不同的可能,任何一条路径都可能会是一条实际的路径(每一条路径都有可能发生,但只有一条路径会真正发生)。
- 命题原子公式:原子公式用p,q,r,p1,q1,r1...等符号表示,这些原子代表系统可能成立的事实,比如“打印机正在打印”,“进程1220被挂起”,或者“程序计数器上的值为6”。
- 原子集合:表示系统可能成立的全部事实,用Atoms表示,比如p,q的所有组合:Atoms={∅,{p},{q},{p,q}}
LTL语法
ϕ::=⊥∣⊤∣p∣(¬ϕ)∣(ϕ∧ϕ)∣(ϕ∨ϕ)∣(ϕ→ϕ)∣(Xϕ)∣(Fϕ)∣(Gϕ)∣(ϕUϕ)∣(ϕWϕ)∣(ϕRϕ)
上述公式表示,如果ϕ是LTL公式,则¬ϕ,(ϕ∧ϕ),(Gϕ)⋯也是LTL公式,同时⊥∣⊤∣p也是LTL公式。其中,p是取自原子集合Atoms的任意命题原子
LTL语义
-
迁移系统:M={S,→,L},S是一个状态集合;→是迁移关系(这个迁移关系表示S上的二元关系),使得每个属于S的s中(也就是s∈S),有某个s′满足s→s′(这个s′∈S);标记函数L→P(Atoms)
- 迁移系统简称为模型 ,一个模型有状态集S,关系→(描述的是系统如何从一个状态转向另一个状态),以及每个状态s伴随有原子命题的集合L(s)。我们用P(Atoms)表示Atoms的幂集,也叫做原子描述集。
- 幂集范例:对于状态集S={p,q},则他的幂集P(Atoms)={∅,{p},{q},{p,q}}
- 用有向图表示一个有限迁移系统M的所有信息,图的结点包含了在该状态下为真的所有原子命题。
- 模型范例:M有三个状态s0,s1,s2,状态之间仅有的可能迁移是s0→s1,s0→s2,s1→s0,s1→s2,s2→s2,若L(s0)={p,q},L(s1)={q,r},L(s2)={r},则将模型的信息浓缩到状态图中为:

在上述状态图中,状态r是一个死锁状态,他的下一个状态永远只能是自身
-
无限路径:模型M={S,→,L}中的一条路径是S中状态的无限序列s1,s2,s3,⋯,对每个i⩾1,都有si→si+1,则我们可以将该路径写为π=s1→s2→s3→⋯,我们用πi表示从第i个状态开始的后缀,比如π3=s3→s4→⋯
- 将上面的模型范例里的系统展开成一个从特定状态开始的所有计算路径的无限树为:

-
设M={S,→,L}是一个模型,π=s1→s2→s3→⋯是M中地一条路径,路径π与LTL公式满足关系定义如下:
- π⊨⊤
- π⊭⊥
⊤表示总为真的事实,⊥表示总为假的事实
- π⊨p当且仅当p∈L(s1)
- π⊨ϕ1∧ϕ2当且仅当π⊨ϕ1且π⊨ϕ2
- π⊨ϕ1∨ϕ2当且仅当π⊨ϕ1或π⊨ϕ2
- π⊨ϕ1→ϕ2当且仅当只要π⊨ϕ1就有π⊨ϕ2
- π⊨X ϕ当且仅当π2⊨ϕ
- π⊨X ϕ表示路径从第二个状态开始满足LTL公式ϕ
- ϕ是原子集内的某个原子命题,也是一个LTL公式,在路径中也叫做状态;X ϕ表示这个原子命题的下一个状态;π2表示从路径π上的第二个状态开始的路径
- π⊨G ϕ当且仅当对所有i⩾1,πi⊨ϕ
- π⊨F ϕ当且仅存在某个i⩾1使得,πi⊨ϕ
- π⊨ϕ Uψ当且仅当存在某个i⩾1,使得πi⊨ψ并且对所有j=1,⋯,i−1,有πi⊨ϕ
- π⊨ϕ Wψ当且仅当存在某个i⩾1,使得πi⊨ψ且对所有的j=1,⋯,i−1,有πi⊨ϕ,或者对所有k⩾1,有πk⊨ψ
- π⊨ϕ R ψ当且仅当或者存在某个i⩾1,使得πi⊨ψ且对所有j=1,⋯,i,有πi⊨ψ;或者对所有k⩾1,有πk⊨ψ
π⊨ϕ R ψ还可以表述为:当且仅当或者∃i≥0使得πi⊨ϕ且对于每个j≤i都有πj⊨ψ,或者对于所有的k≥0都有πk⊨ψ
-
状态满足公式:设M=(S,→,L)是一个模型,s∈S,ϕ是一个LTL公式,若对从s出发的每条路π都有π⊨ϕ,则称状态s满足ϕ,记作M,s⊨ϕ,或s⊨ϕ
-
范例:
对于上面的Kripke结构,有如下结论:
- s0⊨(p∧q),¬r,Xr
s0这个状态满足三个条件:
- (p \wedge q):$$s_0状态上有原子命题p和q
- \neg r:$$s_0状态上没有原子命题r
- X r:$$s_0状态的下一个结点有原子命题r
- s0⊭X(q∧r)
s0的下一个状态不一定满足包含原子命题q和r。因为s0的下一个状态如果是s2的话,只包含原子命题r而不包含原子命题q,如果s0的下一个状态如果是s1的话才包含原子命题q和r
- s0⊨G¬(p∧r)
s0这个状态满足未来所有状态不同时包含原子命题p和r。因为s0以后可能要迁移到s1、s2或迁移回s0,而这三个状态均不同时包含原子命题p和r,所以s0这个状态满足未来所有状态不同时包含原子命题p和r
- s2⊨Gr
s2状态满足未来所有状态全部包含原子命题r
- s⊨F(¬q∧r)→FGr
s状态满足,如果未来的状态不含原子命题q但包含原子命题r,则未来全部状态都包含原子命题r。因为不含原子命题q但包含原子命题r的状态只有s2,s2的下一个状态永远只能是s2,s2也只包含原子命题r,所以未来全部状态都包含原子命题r
语义等价
- 定义:设ϕ,ψ是 LTL 公式, 若对于所有的模型M以及M中的所有的路π都有π⊨ψ当且仅当π⊨ψ,则称ϕ与ψ是语义等价的, 记作ϕ≡ψ
- 语义等价等价刻画:设ϕ,ψ是 LTL 公式,它们是语义等价的,当且仅当若对于所有的模型M以及M中的所有的状态s都有s⊨ϕ当且仅当s⊨ψ
- 等价性质:
- 对偶性:
- Gϕ≡¬F¬ϕ
- Fϕ≡¬G¬ϕ
- ϕUψ≡¬(¬ϕR¬ψ)
- ϕRψ≡¬(¬ϕU¬ψ)
- Xϕ≡¬X¬ϕ
- 分配性:
- F(ϕ∨ψ)≡Fϕ∨Fψ
- G(ϕ∧ψ)≡Fϕ∧Fψ
- 连接词相互定义
- Fϕ≡⊤Uϕ
- Gϕ≡⊥Rϕ
- ϕRψ≡ψU(ϕ∧ψ)∨Gψ