程序验证(九):程序正确性规范

2024-03-02 14:32

本文主要是介绍程序验证(九):程序正确性规范,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

程序验证(九):程序正确性规范

什么是程序的正确性?应当在指定的前提下,进行预定的行为,达到指定的结果。

部分正确性(Partial Correctness)

部分正确性指的是一个程序的停止行为
我们将部分正确性用霍尔三元组(Hoare triples)表达:
{ P } c { Q } \{P\}c\{Q\} {P}c{Q}
这里:

  • c c c是一个程序
  • P P P Q Q Q是一阶逻辑的断言(assertion)
  • P P P, Q Q Q的自由变量可以在程序的变量中随意选择
  • P P P是先验条件(precondition), Q Q Q是后验条件(postcondition)
    { P } c { Q } \{P\}c\{Q\} {P}c{Q}的含义:
  • 在一个满足 P P P的环境中开始执行 c c c
  • 如果 c c c终止
  • 那么它的最终环境将满足 Q Q Q
    注意,部分正确性没有排除以下两点:
  • 程序执行不终止
  • 程序没有从 P P P开始执行

完全正确性(Total Correctness)

部分正确性没有要求终止
完全正确性是一个更强的声明,写作:
[ P ] c [ Q ] [P]c[Q] [P]c[Q]
[ P ] c [ Q ] [P]c[Q] [P]c[Q]的含义:

  • 如果我们从一个满足 P P P的环境开始执行 c c c
  • 那么 c c c一定终止
  • 而且它最终的环境满足 Q Q Q

断言

给定三元组
{ P } c { Q } \{P\}c\{Q\} {P}c{Q}
公式 P P P Q Q Q是一阶断言
对于Imp,有用的理论是 T Z ∪ T A T_Z\cup T_A TZTA
P P P Q Q Q中的变量包括程序变量、量词变量、其他逻辑变量,即
v a r s ( Q ) = p v a r s ( Q ) ∪ q v a r s ( Q ) ∪ l v a r s ( Q ) vars(Q)=pvars(Q)\cup qvars(Q)\cup lvars(Q) vars(Q)=pvars(Q)qvars(Q)lvars(Q)

断言的语义

由于 l v a r s ( Q ) lvars(Q) lvars(Q)的存在,我们不能仅依据环境 σ \sigma σ来判断 Q Q Q的值
所以,令 α \alpha α l v a r s ( Q ) lvars(Q) lvars(Q)的变量的一个赋值,那么
( α ∪ σ ) ( x ) ≡ { α ( x ) i f x ∈ α σ ( x ) i f x ∈ σ (\alpha \cup\sigma)(x)\equiv \begin{cases} \alpha(x) &if~x\in\alpha\\ \sigma(x) &if~x\in\sigma\end{cases} (ασ)(x){α(x)σ(x)if xαif xσ
断言的可满足性与永真性:
σ ⊨ α Q ( σ ∪ α ) ⊨ T Q σ s a t i s f i e s Q u n d e r α \sigma \models_{\alpha}Q\qquad(\sigma\cup\alpha)\models_TQ\qquad \sigma~satisfies~Q~under~\alpha σαQ(σα)TQσ satisfies Q under α
σ ⊨ Q ∀ α . ( σ ∪ α ) ⊨ T Q Q i s v a l i d i n σ \sigma\models Q\qquad \forall \alpha. (\sigma\cup\alpha)\models_TQ\qquad Q~is~valid~in~\sigma σQα.(σα)TQQ is valid in σ
如果对于所有 σ \sigma σ σ ⊨ Q \sigma\models Q σQ,那么我们写作 ⊨ Q \models Q Q

部分正确性的语义

我们说 { P } c { Q } \{P\}c\{Q\} {P}c{Q} σ \sigma σ中在 α \alpha α下永真,写作 σ ⊨ α { P } c { Q } \sigma\models_{\alpha} \{P\}c\{Q\} σα{P}c{Q},如果:
∀ σ ′ . ( σ ⊨ α P ∧ ⟨ c , σ ⟩ ⇓ σ ′ ) → σ ′ ⊨ α Q \forall \sigma'.(\sigma\models_{\alpha}P\wedge \langle c,\sigma\rangle\Downarrow\sigma')\to\sigma'\models_{\alpha}Q σ.(σαPc,σσ)σαQ
也就是说:

  1. 只要 σ \sigma σ α \alpha α下满足 P P P
  2. 而且 c c c σ \sigma σ中执行得到 σ ′ \sigma' σ
  3. 那么 σ ′ \sigma' σ α \alpha α下满足 Q Q Q

我们说 { P } c { Q } \{P\}c\{Q\} {P}c{Q}是永真的,写作 ⊨ { P } c { Q } \models \{P\}c\{Q\} {P}c{Q},如果:
∀ σ , α . σ ⊨ α { P } c { Q } \forall \sigma,\alpha.\sigma\models_{\alpha} \{P\}c\{Q\} σ,α.σα{P}c{Q}
也就是
∀ σ , σ ′ , α . ( σ ⊨ α P ∧ ⟨ c , σ ⟩ ⇓ σ ′ ) → σ ′ ⊨ α Q \forall \sigma,\sigma',\alpha. (\sigma\models_{\alpha}P\wedge\langle c,\sigma\rangle\Downarrow\sigma') \to \sigma'\models_{\alpha} Q σ,σ,α.(σαPc,σσ)σαQ

三元组的证明(verify)

我们将引入一种逻辑,该逻辑能从已知的三元组推出新的三元组,这种逻辑叫做霍尔逻辑(Hoare logic)
引入规则的形式为
⊢ { P } c { Q } \vdash \{P\}c\{Q\} {P}c{Q}

跳过与赋值(skip&assignment)

S k i p { P } s k i p { P } Skip~\frac{}{\{P\}\mathbf{skip}\{P\}} Skip {P}skip{P}
A s g n { Q [ a / x ] } x : = a { Q } Asgn~ \frac{}{\{Q[a/x]\}x:=a\{Q\}} Asgn {Q[a/x]}x:=a{Q}
Q [ a / x ] Q[a/x] Q[a/x]:在 Q Q Q中把所有 x x x换成 a a a,举个例子:
( 5 + x ) [ ( x + 1 ) / x ] = 5 + ( x + 1 ) (5+x)[(x+1)/x]=5+(x+1) (5+x)[(x+1)/x]=5+(x+1)

逻辑的加强与削弱

注意,我们不能证明一个很显而易见的东西:
⊢ { y = 0 } x : = 1 { x = 1 } \vdash\{y=0\}x:=1\{x=1\} {y=0}x:=1{x=1}
但我们可以证明:
⊢ { 1 = 1 } x : = 1 { x = 1 } \vdash\{1=1\}x:=1\{x=1\} {1=1}x:=1{x=1}
于是引入前提加强(precondition strengthening):
P r e ⊢ { P ′ } c { Q } P ⇒ P ′ { P } c { Q } Pre~\frac{\vdash\{P'\}c\{Q\}\qquad P\Rightarrow P'}{\{P\}c\{Q\}} Pre {P}c{Q}{P}c{Q}PP
例如:
P r e A s g n ⊢ { 1 = 1 } x : = 1 { x = 1 } y = 0 ⇒ 1 = 1 { y = 0 } x : = 1 { x = 1 } Pre~\frac{Asgn~\frac{}{\vdash\{1=1\}x:=1\{x=1\}}\qquad y=0\Rightarrow 1=1}{\{y=0\}x:=1\{x=1\}} Pre {y=0}x:=1{x=1}Asgn {1=1}x:=1{x=1}y=01=1
与之相似,引入一削弱后验条件的规则:
P o s t ⊢ { P } c { Q ′ } Q ′ ⇒ Q { P } c { Q } Post~\frac{\vdash\{P\}c\{Q'\}\qquad Q'\Rightarrow Q}{\{P\}c\{Q\}} Post {P}c{Q}{P}c{Q}QQ
在二者的基础上,引入序列规则(consequence rule):
C o n s e q P ⇒ P ′ ⊢ { P ′ } c { Q ′ } Q ′ ⇒ Q { P } c { Q } Conseq~\frac{P\Rightarrow P'\qquad\vdash \{P'\}c\{Q'\}\qquad Q'\Rightarrow Q}{\{P\}c\{Q\}} Conseq {P}c{Q}PP{P}c{Q}QQ

组合(composition)

S e q { P } c 1 { P ′ } { P ′ } c 2 { Q } { P } c 1 ; c 2 { Q } Seq~\frac{\{P\}c_1\{P'\}\qquad \{P'\}c_2\{Q\}}{\{P\}c_1;c_2\{Q\}} Seq {P}c1;c2{Q}{P}c1{P}{P}c2{Q}
举例:使用霍尔逻辑证明swap函数:
{ x = x ′ ∧ y = y ′ } t : = x ; x : = y ; y : = t { y = x ′ ∧ x = y ′ } \{x=x'\wedge y=y'\}t:=x;x:=y;y:=t\{y=x'\wedge x=y'\} {x=xy=y}t:=x;x:=y;y:=t{y=xx=y}

  1. 由Asgn, { x = x ′ ∧ y = y ′ } t : = x { t = x ′ ∧ y = y ′ } \{x=x'\wedge y=y'\}t:=x\{t=x'\wedge y=y'\} {x=xy=y}t:=x{t=xy=y}
  2. 由Asgn, { t = x ′ ∧ y = y ′ } x : = y { t = x ′ ∧ x = y ′ } \{t=x'\wedge y=y'\}x:=y\{t=x'\wedge x=y'\} {t=xy=y}x:=y{t=xx=y}
  3. 由Asgn, { t = x ′ ∧ x = y ′ } y : = t { y = x ′ ∧ x = y ′ } \{t=x'\wedge x=y'\}y:=t\{y=x'\wedge x=y'\} {t=xx=y}y:=t{y=xx=y}
  4. 由1,2,Seq, { x = x ′ ∧ y = y ′ } t : = x ; x : = y { t = x ′ ∧ x = y ′ } \{x=x'\wedge y=y'\}t:=x;x:=y\{t=x'\wedge x=y'\} {x=xy=y}t:=x;x:=y{t=xx=y}
  5. 最后,由3,4,Seq, Q . E . D Q.E.D Q.E.D

条件(conditional)

I f { P ∧ b } c 1 { Q } { P ∧ ¬ b } c 2 { Q } { P } i f b t h e n c 1 e l s e c 2 { Q } If~\frac{\{P\wedge b\}c_1\{Q\}\qquad \{P\wedge \neg b\}c_2\{Q\}}{\{P\}\mathbf{if}~b~\mathbf{then}~c_1~\mathbf{else}~c_2\{Q\}} If {P}if b then c1 else c2{Q}{Pb}c1{Q}{P¬b}c2{Q}

  • 在true分支:如果 b b b成立,我们需要证明 { P ∧ b } c 1 { Q } \{P\wedge b\}c_1\{Q\} {Pb}c1{Q}
  • 在false分支:如果 ¬ b \neg b ¬b成立,我们需要证明 { P ∧ ¬ b } c 2 { Q } \{P\wedge\neg b\}c_2\{Q\} {P¬b}c2{Q}

while循环(loop)

W h i l e { P ∧ b } c { P } { P } w h i l e b d o c { P ∧ ¬ b } While~\frac{\{P\wedge b\}c\{P\}}{\{P\}\mathbf{while}~b~\mathbf{do}~c\{P\wedge\neg b\}} While {P}while b do c{P¬b}{Pb}c{P}

  • P P P是循环不变量(loop invariant)
    • 在进入循环前成立,并且在每次迭代后保持不变
    • 这由前提 { P ∧ b } c { P } \{P\wedge b\}c\{P\} {Pb}c{P}所确定
  • 为了使用While,需要先证明 P P P是不变量

可靠性与完备性

之前的规则对于部分正确性都是可靠的
对于Imp,是不完备的,因为可以归约为 T P A T_{PA} TPA

这篇关于程序验证(九):程序正确性规范的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/766432

相关文章

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

JavaEE7 Servlet 3.1(JSR 340)规范中文版

http://www.iteye.com/news/27727-jinnianshilongnian     Jave EE 7中的部分规范已正式获得批准通过,其中包括JSR340 Java Servlet 3.1规范,去年翻译了该规范,在此分享出来,希望对某些朋友有所帮助,不足之处请指正。   点击直接下载    在线版目录   Servlet3.1规范翻译

三维布尔运算对不规范几何数据的兼容处理

1.前言 上一篇文章谈过八叉树布尔运算,对于规范几何数据的情况是没有问题的。 在实际情况中,由于几何数据来源不一,处理和生成方式不一,我们无法保证进行布尔运算的几何数据都是规范的,对于不规范情况有时候也有需求,这就需要兼容不规范数据情况,当然这种兼容不是一味的让步,而是对于存在有限的不规范数据的兼容处理。 2.原始数据示例 下图是一个大坝模型和之上要对其进行布尔运算的立方体。 大坝模型由

【C/C++】变量命名规范

在 C++ 中,为 bool 类型的变量命名时,通常遵循以下命名规范,以确保代码的可读性和一致性: 表示状态或条件: 使用 is 前缀表示某个状态或条件,例如 isReady、isValid。使用 has 前缀表示是否拥有某个属性,例如 hasData、hasError。使用 can 前缀表示是否具备某种能力,例如 canExecute、canRead。使用 should 前缀表示是否应该执行

二、Java之关键字与命名规范

Java之关键字与命名规范 零基础学Java什么是关键字命名规范的重要性 零基础学Java Java学习交流 : V:study_51ctofx 什么是关键字 关键字:含有特殊意义,编译器解析成特定的含义; 比如 private、int、void、class、enum 等等, 这些关键字都不能用作变量、方法名、类名等. //错误,static 是关键字 不能用作变量名

[mysql]SQL语言的规则和规范

规则 是什么呢,规则就是我们最基本,每时每刻都要遵守的比如人行道靠右,不能逆行, 规范 呢就是锦上添花,如果你不这么做,是不那么道德,不那么好的,就像小学生见到老师要问好,不问好可以吗,当然也是可以的,但是这样就不那么礼貌了。但是也不会开除你, 规范是建议。规则: USE dbtest2 SELECT * FROM emp 我们之前使用cmd操作的时候,是不是必须要先选择一个数据

android的工程和代码的命名规范(第一篇文章,勿喷)

1。首先我们从编译代码的工具说起吧:工程中的注释一般都是中文写的(毕竟大家都是中国人,还是习惯于中文)这样就设计到乱码的问题了;对于这类问题,我们一般最好的处理方法就是将工程设置成 UTF-8 的格式;下面就说说怎么将工作空间或者是工程设置成UTF-8 的格式吧(当然我这里面说的是eclips

命名规范~

1. 命名原则 1.1 准确性  可读性 "类"名应该是"是什么"。应该是一个名词,作为主语。 "方法"名应该是"干什么"。一个方法应该是动词,作为谓语。 避免不必要的缩写 把类/ 方法的名字写全。但是,首字母缩略词的术语是可行并且推荐的,如 Http , Id , Url 。 以下是可用的、得到普遍认可的缩写:configuration -> configidentifier

设计之道:ORM、DAO、Service与三层架构的规范探索

引言: 实际开发中,遵守一定的开发规范,不仅可以提高开发效率,还可以提高项目的后续维护性以及项目的扩展性;了解一下本博客的项目设计规范,对项目开发很有意义 一、ORM思想 ORM(Object-Relational-Mapping)在对象模型和关系型模型之间做一个映射(转换)。 目的是为了解决面向对象编程语言的发展和关系型数据库的发展不匹配的问题 可以理解为: 将Java中的数据结