前言
抽象,晦涩,难懂
另一个视角下的迭代算法
回忆数据流分析里面的迭代算法
OUT没有变化时,迭代就结束了。
我们从另外一个角度来看,给定一个k个节点的CFG,迭代算法每次迭代对每个节点的OUT进行更新。
例子
假设值域是V,我们可以定义一个k元组:
初始化为空,用bottom(⊥)表示。
i和i+1的元组是一样的,所以结束。
此时Xi就是一个F的不动点(Fixed point)
思考
迭代算法对数据流分析生成一个算法
- 算法保证一定能停止或者达到不动点吗?或者说总有一个解吗?
- 假设可以停止,那只有一个解或者一个不动点吗?如果有超过一个,那我们的解答是最优的吗?
- 什么时候算法可以达到不动点?
为了解答这些问题,我们得开始学数学。
偏序
定义
设R是集合A上的一个二元关系,若R满足:
Ⅰ 自反性:对任意x∈A,有xRx;
Ⅱ 反对称性(即反对称关系):对任意x,y∈A,若xRy,且yRx,则x=y;
Ⅲ 传递性:对任意x, y,z∈A,若xRy,且yRz,则xRz。 [1]
则称R为A上的偏序关系,通常记作≼。注意这里的≼不必是指一般意义上的“小于或等于”。
若然有x≼y,我们也说x排在y前面(x precedes y)
整数集上的小于等于关系就是一个偏序关系。
整数集上的小于关系不是一个偏序关系。
英文单词上的子串关系是一个偏序关系。
这也是一个偏序关系
上下界
定义
考虑一个偏序集 (P, ⊑),集合S ⊆ P,如果对任何一个S中的x,x ⊑ u,u ∈ P是P的上界。
反过来,如果对任何一个S中的x,l ⊑ x,l ∈ P是P的下界。
一个例子。
对每个S的上界,如果⊔S ⊑ u,⊔S是最小上界。
对每个S的上界,如果l ⊑ ⊓S,⊓S是最大下界。
如果子集S仅包含两个元素a,b,那么:
- ⊔S能被写作 a ⊔ b(a join b)
- ⊓S能被写作 a ⊓ b(a meet b)
一些性质
- 不是每个偏序集都有最小上界和最大下界
- 如果有最小上界或最大下界,则是唯一的
假设有两个最小上界,根据反对称性,这两个上界是同一个。
格
定义
如果偏序集(P, ⊑),∀a, b ∈ P,如果 a ⊔ b 和 a ⊓ b 都存在,那么这个偏序集(P, ⊑)被称作一个格。
格可能是描述这种上下都有边界的抽象格子。
半格
定义
给定偏序集(P, ⊑),∀a, b ∈ P,
如果只有 a ⊔ b 存在,则称偏序集为一个join 半格
如果只有 a ⊓ b 存在,则称偏序集为一个meet 半格
全格
定义
给定一个格(P, ⊑),对于P的任意子集S,如果S的最小上界⊔S(lub)和最大下界⊓S(glb)都存在,这个格就是一个全格。
性质
全格一定有一个最大元素T和最小元素⊥
任意有限的格都是全格
所以大部分时候我们在数据流分析中关注全格。
乘积格
定义
给定n个格,L1 = (P1, ⊑1), L2 = (P2, ⊑2), …, Ln = (Pn, ⊑n),如果每个格都有对应的⊔i(最小上界)和⊓i(最大下界),那么我们得到一个乘积格 Ln = (P, ⊑)并有以下四个定义:
- P = P1 × … × Pn
- (x1, …, xn) ⊑ (y1, …, yn) ⟺ (x1 ⊑ y1) ∧ … ∧ (xn ⊑ yn)
- (x1, …, xn) ⊔ (y1, …, yn) = (x1 ⊔1 y1, …, xn ⊔n yn)
- (x1, …, xn) ⊓ (y1, …, yn) = (x1 ⊓1 y1, …, xn ⊓n yn)
- 乘积格也是格
- 如果L是一系列全格的乘积,那么L也是全格。
基于格的数据流分析框架
数据流分析框架(D, L, F)包含:
- D: 数据流方向:前向或者后向
- L: 包含值域V和一个meet或join操作符的格
- F:一系列V到V的传递函数
数据流分析可以被认为是迭代地在格上使用转换函数和meet/join操作。
回忆我们之前的问题
迭代算法对数据流分析生成一个算法
- 算法保证一定能停止或者达到不动点吗?或者说总有一个解吗?(回忆输出永远不缩水,和单调性有关)
- 假设可以停止,那只有一个解或者一个不动点吗?如果有超过一个,那我们的解答是最优的吗?
- 什么时候算法可以达到不动点?
单调性
如果对于∀x, y ∈ L,x ⊑ y ⟹ f(x) ⊑ f(y),函数f:L->L(L是一个格)是单调的。
不动点定理
对于全格 (L, ⊑),如果1)f: L->L是单调的 2)L是有限的,则f的最小不动点可以通过迭代f(⊥), f(f(⊥)), …, fk(⊥) ,最大不动点可以通过迭代f(T), f(f(T)), …, fk(T) 来获得。