190 likes | 325 Views
第四课 程序设计方法学基本理论 —— 程序正确性证明. START. a. I(x,y). Read(x,y). b. P(x,y). F. x<>0. z:=y. g. T. c. O(x,y,z). T. y>x. F. STOP. d. e. y:=y-x. x :=x- y. 程序部分正确但不终止实例. 例:求两个非负整数 x、y 的最大公约数 z 的程序。. 可以利用不变式断言证明该程序的部分正确性,但无法证明它是终止的。 因为当 y=0 时,程序循环将不终止!. Program A
E N D
第四课 程序设计方法学基本理论——程序正确性证明
START a I(x,y) Read(x,y) b P(x,y) F x<>0 z:=y g T c O(x,y,z) T y>x F STOP d e y:=y-x x :=x-y 程序部分正确但不终止实例 • 例:求两个非负整数x、y的最大公约数z的程序。 可以利用不变式断言证明该程序的部分正确性,但无法证明它是终止的。 因为当y=0时,程序循环将不终止! • Program A • var x,y,z,s:integer; • begin • read(x,y); • while x <> 0 do • if y > x then y = y – x; • else x = x – y; • z = y; • write (z); • end.
本课的内容 • 程序终止性证明方法:良序集方法 • 程序终止性证明方法:计数器方法
良序集方法证明程序终止性 • 1.基本概念 • 偏序集 • 良序集 • 2.采用良序集方法证明程序终止性
良序集的概念(1/2) • 1. 偏序集 • 设有一个非空集合W和一个定义在W上的二元关系 < ,且这个关系 < 满足下列性质: • 1)传递性,即对于一切a,b,c∈W,如果a<b,b<c ,则a<c • 2)反对称性,即对于a<b,则有b≮a • 3)反自反性,即对于一切a∈W,a ≮a • 称W为具有关系<的偏序集,记做(W,<) • 例如: • (1)具有小于关系(<)的,位于0~1之间的实数集合A1。 • (2)具有小于关系(<)的全体整数集合B1。 • 但将 < 换成 ≤ 就不是偏序集。 • (1)具有小于关系(≤)的,位于0~1之间的实数集合A1。 • (2)具有小于关系(≤)的全体整数集合B1。
良序集的概念(2/2) • 2.良序集 • 设(W,<)是偏序集,如果不存在由W中的元素构成的无限递减序列: ……a2<a1<a0 ,则称(W,<)是良序集。 • 例如: • (1)若N是自然数集合,那么(N,<)是良序集。 • (2)具有通常序A < B < C… < Z的字母表∑={A,B,…,Z}是良序集。 • 但下述集合A1和B1是偏序集,但不是良序集。 • (1)具有小于关系(<)的,位于0~1之间的实数集合A1。 • (2)具有小于关系(<)的全体整数集合B1。
采用良序集证明程序终止性思路 • 1、结构化程序由顺序、选择和循环三种基本结构组成,而影响程序终止性的是循环结构,因此,是程序终止性证明的重点。 • 2、程序终止性证明思路: • A. 选取良序集合(W,<); • B. 选取割点集,割断循环; • C. 在割点上寻找函数u,使u∈W; • D. 证明每次循环,u依次递减。 • 由于良序集合(W,<)不存在无穷递减序列,因此,循环必然终止。
用良序集方法证明程序终止性步骤 • 1.选取一个点集去截断程序的各个循环部分,并在每个截断点I处建立中间断言Qi (x,y) • 2.选取一个良序集(W,<),并在每个截断点处定义一个终止表达式E i (x,y),表达式在W上取值 • 3.证明对每一个从程序入口到截断点j的通路aj有 • I(x) ^ Raj (x,y) => Qj(x,raj(x,y)) • 证明对每一个从截断点i到截断点j的通路aij,有 • Qi (x,y) ^ R a i j (x,y) => Q j (x,r a i j (x,y)) • 即证明中间断言是“正确的”,是“良断言” • 4.证明 Qi (x,y) = > E i (x,y) ∈W,即终止表达式是良函数 • 5.证明对于每一个从截断点i到截断点j的通路aij,有 • Qi (x,y) ^ Raj (x,y) =>[E j (x,y) < E i (x,y)]
开始 (0,0,1)->(y1,y2,y3) y2+y3->y2 y2 ≥x y1->z (y1+1,y3+2)->(y1,y3) 结束 良序集方法证明程序终止性实例 • 例子:对任一给定的自然数x,计算z=[ ],即计算x的平方根取整 · B’ T F
良序集方法证明程序终止性实例 • 1.选取断点B’ ,建立中间断言 • Q(x,y1,y2,y3): y2 < x ^ y3>0 • 2.取良序集(N,<),其中N为自然数集合,在B’建立终止表达式: • E(x,y1,y2,y3) : x-y2 • 3.证明Q(x,y1,y2,y3)是良断言 • 从程序开始点->B’ :I(x) => Q(x,y1,y2,y3), • 即:x>0=>[0<x ^ 1>0] • 从截断点B’->B’: • Q(x,y1,y2,y3) ^ y2+y3<x => Q(x,y1+1,y2+y3,y3+2) • 即:[y2<x ^ y3>0 ^ y2+y3<x] => [y2+y3<x ^ y3+2>0]
良序集方法证明程序终止性实例 • 4.证明E(x,y)是良函数,即证明q(x,y) => E(x,y)∈N ,即 • [y2<x ^ y3>0] => x-y2>0 ∈ N • 5.证明终止条件成立 • [Q(x,y) ^ y2+y3<x] = > [E(x,y1+1,y2+y3,y3+2) < E(x,y1,y2,y3)] • 即: • [y2<x ^ y3>0 ^ y2+y3<x] => [x - y2-y3 < x-y2]
采用良序集证明程序终止性总结 • 1、采用良序集方法证明程序终止性,关键在于选择合适的良序集Qi (x,y)和终止表达式Ei (x,y) 。 • 2、采用良序集证明程序终止性,与程序部分正确性证明采用了不同途径,相互完全独立,因此,证明程序的完全正确性工作量较大。 • 3、采用计数器方法可以将程序的部分正确性和终止性证明结合进行。
计数器方法证明程序终止性 • 证明思路 • 通过估计循环执行的最大次数的方法。 • 证明步骤 • 1.为程序的每一个循环附加一个新的变量作为该循环的计数器,初始值置为0,每循环一次该计数器加1。 • 2.为每个循环设置一个中间断言,它表示相应的计数器不会超过固定的界限。 • 3.证明(2)中的中间断言是不变式断言。
START a I(x,y) Read(x,y) b P(x,y) F x<>0 z:=y T T y ≥ x F STOP d e y:=y-x x y 计数器方法证明程序终止性实例 • 计算非负整数的 • 最大公约数 • var x,y,z,s: integer; • begin • Read(x,y) • while x<>0 do • begin • If y≥x then y:=y-x; • else s:=x;x:=y;y:=s; • end • z:=y;write(z); • end.
计数器方法证明程序终止性实例 • 1.引进计数器I,并建立如下断言 • x>=0 ^ y>=0 ^ 2x+y+I ≤ 2x0+y0 • var x,y,z,s: integer; • read(x,y); • I:=0; //计数器赋初值 • while x<>0 do • begin If y>x then y:=y-x; else s:=x;x:=y;y:=s; I := I+1; //计数器递增 • end • z:=y; • write(z);
计数器方法证明程序终止性实例 • 2.建立检验条件并证明,从而证明计数器断言为不变式断言 • 检验条件1:a -> b • [x0>=0 ^ y0>=0 ] => [x0>=0 ^ y0>=0 ^ 2x0+y0+0 ≤ 2x0+ y0] • 检验条件2:b -> d -> b • [x>=0 ^ y>=0 ^ (2x+y+I ≤ 2x0+y0) ^ x<>0 ^ y>=x] => • [x>=0 ^ y-x>=0 ^ (2x+(y-x) + I + 1) ≤ 2x0 + y0)] • 证明:(x-1>=0) • 2x+(y-x) + I + 1 =2x+y+I-(x-1) <= 2x+y+I ≤ 2x0+y0 • 检验条件3:b -> e -> b • [x>=0 ^ y>=0 ^ (2x+y+I ≤ 2x0+y0) ^ x<>0 ^ y<x] => • [y>=0 ^ x>=0 ^ 2y+x+I+1 ≤ 2x0 + y0] • 证明: (y<x ^ x<>0 ^ x<>1 => y<x-1) • 2y+x+I+1 < y+2x+I < 2x0+ y0 由于2x+y+I ≤ 2x0+y0是不变式断言,因此,I(循环次数)必定小于常 量2x0+y0,也就是循环只能执行有限次,即程序终止。 采用计数器方法程序证明终止性和利用不变式断言法证明部分正确性步骤完全类似,只要再添加至输出断言部分检验条件并证明,即可完成程序部分正确性证明。 因此,可以把上述两者联合起来,完成程序的完全正确性证明。
另一种计数器方法证明程序终止性 • 证明思路: • 1.对程序中的每一个循环,构造一个和该循环中变量有关的整数函数N(x,y),若N(x,y)满足以下条件: • 1.1 当循环条件成立时,N(x,y) > 0。 • 1.2 每次循环,N(x,y)都减小。 • 由N(x,y)的值构成一个单调递减的整数序列, N(x,y) > 0,因而,循环只能执行有限次。
START (x1,x2)->(y1,y2) F y1<>y2 z:=y1 T y1>y2 STOP F T y1:=y1-y2 y2:=y2-y1 另一种计数器方法证明程序终止性实例 • 例:设x,y为正整数,求x,y的最大公约数z的程序,即z=gcd(x,y)。 • 选取 N(y1,y2) = max(y1,y2) • 容易证明: • N(y1,y2) > 0; • N(y1,y2) 是递减的。
采用计数器方法证明程序终止性难点 • 采用计数器方法证明程序终止性关键在于确定一个合适的中间断言(或选取一个合适的函数N(x,y)),尤其对于一些循环次数事先难以估计的程序,要找出循环次数的上限更为困难。