菜单

szdxdxdx
szdxdxdx
发布于 2024-08-16 / 57 阅读
0
0

程序验证、模型检验

程序验证与模型检验

程序验证

基本概念

一个语言 A验证器 V 被定义为

A= \{ \ w \ | \ V \ \text{accepts} ⟨w,c⟩ \ \text{for some string} \ c \ \}

语言 A

在形式语言理论中,语言 A 是一个字符串集合

A 指定了什么样的输入字符串是“合法”的,它定义了一个问题或特性,并且用于描述一个问题的解集,可以用逻辑表达式、代数表达式等数学语言来描述

这里的语言是一个抽象的数学对象,它并不特指自然语言,而是任何形式化的字符串集合

在自动机理论中,语言通常由某种形式化规则定义。这里的“语言”沿用传统定义,表示可以被某种形式化系统识别的字符串集合

而在计算复杂性理论中,一个语言 A 通常对应于一个决策问题。判定一个字符串 w 是否属于语言 A,等同于解决一个具体的问题

验证器 V

V 是一个算法,用于确定某个给定字符串 w 是否属于语言 A

V 的设计是基于 A 的定义,也就是说 V 了解 A 所定义的性质,并被编写成可以检查某个 w 是否具有这些性质的程序

V 可以是一个形式化验证工具、一个SAT求解器、一个模型检测器,或一个测试框架,等等。

模型/待检验对象 w

w 有多种表现形式,可以是一段待验证的算法或程序,一个系统的抽象模型,一个系统或算法的一组具体输入数据,等等

证明/反例 c

c 的作用是为 V 提供附加的信息来辅助判断一个字符串 w 是否属于 A

验证不同的 w 是否属于 A,可能要对应寻找不同的 c

c 不一定是必须的,需不需要c 取决于问题的具体上下文和问题的复杂性。对于 NP 类问题,c 是关键的,而对于 P 类问题,c 可能不需要

c 可以是一个形式化证明过程,确保 w 属于 A,也可以是一个反例,说明 w 不属于 A

例子

我想验证一段排序算法代码的正确性

设计规约

我希望排序后数组中的每个元素都应小于或等于后一个元素

A: \quad i,j (\text{if} \ \ i < j \ \ \text{then} \ \ arr[i]≤arr[j])

构建模型

代码的行为就是模型 w,验证代码的正确性就是验证 w 是否属于规约 A,即是否有 w \in A

构建反例或证明

我构造了一个测试样例集,这些测试样例也许就存在一个反例 c_1 能证明我的算法不正确

或者,我将代码逻辑抽象到数学层次,对其使用形式化语言进行描述,使用数学工具(命题逻辑、数学归纳法等)对算法的正确性给出了证明 c_2

验证

我采用自动化测试框架作为验证器 V_1

V_1 依次抽取测试样例输入给 w,验证 w 的输出。如果存在一个反例 c_1V_1 将告知我 w \notin A(这样的 V_1 能证伪,但不能证明)

我采用交互式的定理证明辅助工具作为验证器 V_2

V_2 检验我的证明过程是否有推理错误、是否完整,如果考察通过说明我的证明无误,则算法的正确性得以被证明

模型检验

基本概念

计算机系统的设计、规约以及验证往往是使用逻辑语言来描述如下关系

\mathcal{M} \models \phi

\mathcal{M} 是系统的某种情况或模型

\phi 是一个规范,用一个逻辑的公式来表示 \mathcal{M} 应该满足某种约束

\mathcal{M} \models \phi 表示 \mathcal{M} 满足 \phi

逻辑语言的选择

如何统一化定义 \mathcal{M}\phi?使用同一种逻辑来描述 \mathcal{M}\phi

经典逻辑(命题逻辑、一阶逻辑、高阶逻辑等)可以来描述 \mathcal{M}\phi

但是命题逻辑的描述能力太弱,只能处理基本的真假关系

一阶逻辑和高阶逻辑的表达能力强大,但同时也带来更高的复杂性,使得验证过程更困难

重新定义 \phi

使用时序逻辑(线性时序逻辑 LTL、计算树逻辑 CTL)来描述系统行为随时间变化的逻辑

重新定义 \mathcal{M}

使用状态转换系统对系统进行建模:\mathcal{M} = (S, \to, L)

  • S 是系统状态的集合
  • \to 是状态转换关系,表示从状态 s \in S 到下一个状态 s′ \in S 的转换关系
  • L 是状态标签函数,是 S\mathcal{P}(\text{Atoms}) 的映射,\text{Atoms} 是系统的基本原子命题,\mathcal{P}(\text{Atoms}) 表示原子命题集合的子集。表示:当处于状态图中的哪个状态时,对应着哪些原子命题为真

例子

为了检验一个系统 P 是否满足某个性质,通常需要按照以下步骤进行

  1. 先选择模型检查器
  2. 再使用模型检查器的规约语言对系统 P 进行建模,得到模型 \mathcal{M}
  3. 使用模型检查器的规约语言对属性进行编码,得到逻辑公式 \phi
  4. 最后将 \mathcal{M}\phi 输入给模型检查器

评论