2.2.4 Floyd良序集法 ---- 证明程序终止性
1. 前置的基本概念
-
偏序:设≺为非空集合A上的关系,如果≺满足自反性、反对称性以及传递性,那么≺是集合A上的偏序关系,集合A与关系≺一起称为偏序集,记作<A, ≺>
- 回顾一下:
- 自反性: ∀a∈A都有a≺a ,称≺满足自反性。
- 反对称性: ∀a, b∈A,如果a≺b且b≺a,则a=b。称≺满足反对称性。
- 传递性: ∀a, b, c∈ A ,如果a≺b,b≺c,则a≺c,称≺ 满足传递性。
- 回顾一下:
-
良序集:设<A, ≺>为偏序集,若A中每个非空子集关于 ≺ 均存在最先元素(即元素用≺穿起来能找到最头上的元素),则称<A, ≺>为良序集。
例:实数集上的小于等于“≤”关系是偏序关系,实数集与“≤”关系组成偏序集,但是因为实数集关于小于等于关系不存在最先元素(换个角度将就是没有下界),所以不是良序集;而自然数集最小数(下界)是0,所以是良序集。
2. 基本思想
- 为程序中的每个循环建立一个断点i,同时为每个断点定义一个函数Fi ;然后证明随着循环的执行,每个f的值都会不断下降,并且Fi有确定的下界。从而证明循环过程必然会结束。
3.步骤
-
建断言
- 为程序开始处 (φ(X)) 及每个循环 ( FI( X,Y ) ) 中设置断点,并为每个断点处建立断言,且循环处断言应为循环不变式.
-
选取良序集
- <W, ≺>,在每个循环断点处定义一个函数 fi(X,Y)。 (最常用的良序集是<N,≺>)
-
证断言是良断言
- QIJ(X,Y)表示通路I-J的执行条件,qIJ(X,Y)表示经通路修改的中间变量。则通路I-J可达条件如下:(只需要证明初始和循环的路径)
FI(X,Y)⋀QIJ(X,Y)→FJ(X,q IJ(X,Y))
- QIJ(X,Y)表示通路I-J的执行条件,qIJ(X,Y)表示经通路修改的中间变量。则通路I-J可达条件如下:(只需要证明初始和循环的路径)
-
证所定义函数为良函数
- 即对于每个循环处断点都有:(为了保证函数值域是W的子集)
FI(X,Y)→fI(X,Y)∈W
- 即对于每个循环处断点都有:(为了保证函数值域是W的子集)
-
证每条通路上终止条件成立
FI(X,Y)⋀QIJ(X,Y)→fI(X,q IJ(X,Y)) ≺ fI(X,Y)
注意:要是通路,不是通路不用证明,例如下面题5.7中的BEC、BDC路径。
4.例题
(仅供参考!!答案都不保证完全正确!!解题方法可能有多种)
-
例题 5.3.6
-
题目 5.7
Tips:
- 关于如何确定FI( X,Y ):
- FI为了保证下面的fI(X,Y)能够递减。
- 所以确定FI之前先确定fI,再来反推FI
- 关于如何确定fI( X,Y ):(以例题5.3.6 为例)
- 先找断点的循环中的变量,重点看哪些变量对循环的跳出产生影响 (循环的判断条件为y2>x,则 重点先试y2和x)
- 试试看能不能用上面的变量做递减函数 (单用x,y2发现下面都有路径证明不了,再试)
- 如果2.的不行,尝试进行简单的加减,或者乘以(循环条件中出现的)系数 (先试x-y2,发现不行;看下面y2=y2+y3,试试x-y2+y3,发现可以)
- 都不行就靠想象 (灵感爆发说不定就想出来了,这个东西就很玄学)
- 总之就是慢慢尝试,载带入到通路中尝试,要能保证得出的fI随着变量的改变逐渐逼近良序集的下界