zoukankan      html  css  js  c++  java
  • $Abstract^2 Interpretation$

    POPL'19

    本文提出 (A^2I),即 (Abstract^2 Interpretation),也叫做 meta-abstract interpretation,是指使用抽象解释(abstract interpretation)分析静态程序分析器(static program analyser)的特性。

    静态程序分析(static program analysis)是自动提取程序动态行为特性的技术。抽象解释是一种生成静态程序分析方法的理论框架,思想是提取程序特性以逼近程序语义(semantics)。

    要理解 (A^2I),就得先理解 AI(抽象解释,下同)。

    我们以单调数据流分析框架(monotone dataflow analysis framework)为基础开始讲。单调框架包括三部分:

    1. 特性格(property lattice),这里说一下,所谓特性,一般就是指抽象值(abstract value);
    2. 格中元素的含义,即如何解释分析的结果;
    3. 转移函数(transfer function)。

    单调框架只是一种表示静态分析的数学格式,它的问题在于其正确性证明一般依赖于寻找不变量(invariant),每个分析的正确性证明是独立的(ad-hoc)。

    为此,抽象解释提出一种构建程序分析的系统化的方法。需要:

    1. 特性格;
    2. 表示函数(representation function),即如何解释格中的元素。

    然后可以定义出满足一定条件的可计算函数作为转移函数。

    抽象解释对分析的定义是增量的,分析由正确性易证的“分析”开始,即收集语义(collecting semantics),收集程序的准确信息,但是直接对其静态分析是困难甚至不可能的,因为特性空间(property space)太大或不满足升链条件(ACC: Ascending Chain Condition,满足ACC也称为诺特的,Noetherian。(a_1 leq a_2 leq cdots, exist n, forall m > n, a_m = a_n))。接着我们计算得到收集语义的一个近似,即由基础分析(basic analysis)得到精化分析(refined analysis)。最后不断迭代精化(近似)过程直到得到一个可计算函数。

    具体程序执行(concrete program execution)可以表示如下:

    [v_0 ightsquigarrow v_1 ightsquigarrow cdots ightsquigarrow v_i cdots ]

    (V = lbrace v_i brace) 是值或状态的集合,( ightsquigarrow) 是传递关系,当具体执行是确定性的(deterministic)时候,传递关系就是一个函数。

    而程序分析,即程序的抽象执行(abstract execution)可以表示为:

    [l_0 mapsto l_1 mapsto cdots mapsto l_i cdots ]

    其中 (l_{i+1} = f_L(l_i))(f_L : L ightarrow L) 是一个函数,L 是完全格(complete lattice)。在 (A_2I) 的论文中,作者严格区分了完全格与:1)dcpo(有向偏序),每个子集都有上确界;2)cpo(完全偏序),包含最小元素的dcpo。

    (l_i)(v_i) 的抽象,由此为了提供正确性证明的机制,需要定义两者之间一种正确性关系(correctness relation),(R subseteq V imes L)

    1. (forall v, l_1, l_2, (vRl_1) igwedge (l_1 sqsubseteq l_2) ightarrow (vRl_2)),即在特性格 L 中,(l_1) 是比 (l_2) 更精确的对 v 的抽象;
    2. (forall v, forall L^{'} subseteq L, (forall l subseteq L^{'}, (vRl)) ightarrow vR(sqcap L^{'})),即 (sqcap L^{'}) 是 v 的最精确近似(valid approximation)。

    特性空间是格是为了比较抽象值之间的精度,更小更精确,更大更安全(仍然正确)。

    由此已经证明了抽象的正确性,由归纳也易证传递的正确性。即我们已经得到了基础分析。

    给定一个程序点 p,由 (v_0) 出发的所有路径都会达到 p,但计算所有路径的抽象值得到特性格中的一个元素是不可行的。由数据流方程(dataflow equation)可以计算不动点(fixed point),但需要满足两个条件:

    1. 单调;
    2. L满足ACC。

    这是传统的计算程序分析结果的方法。

    但是很多时候分析收敛(converge)很慢,或者不满足 ACC。为此抽象解释使用一个更小(更精确)的格 M 来对 L 进一步抽象,L 和 M 之间满足伽罗瓦连接(Galois connection)(langle L, alpha, gamma, M angle)。其中 (alpha)(gamma) 是单调函数,(alpha) 把 L 中的元素映射到 M 中,称为抽象化函数(abstraction function);(gamma) 把 M 中的元素映射到 L 中,称为具体化函数(concretization function)。且满足两个约束:

    1. (alpha circ gamma sqsubseteq_M lambda m.m),即具体化不损失精度;
    2. (gamma circ alpha sqsupseteq_L lambda l.l),即抽象化可能损失精度。

    由此我们得到精化分析。(可以证明S也满足正确性关系。)

    到这里我们就说明了 slides 第 8 页的:

    1. 语义是抽象解释的实例;
    2. 收集语义是抽象解释的实例;
    3. 对抽象解释实例的抽象是抽象解释的实例。

    所以,由对程序特性的抽象(AI)上升到对程序分析特性的抽象((A^2I))是可行的。

    回到之前的讨论,有了精化分析之后,不动点的计算可以转化为求 AKS(Ascending Kleene Sequence)的极限,AKS 可以表示为 ((f^n( au))_n),其中 (f : L ightarrow L) 是单调的传递函数,( au) 以 L 的底元作为起始值。若 AKS 会趋于稳定(连续格,有限格上连续和单调等价),则其稳定于 f 的最小不动点 lfp(f)。但有时并不会趋于稳定,或者是迭代太慢,为此又引入 widening 技术来计算 AKS 的上近似(upper approximation),AAS(Ascending Approximation Sequence),它有着更快的收敛速度。由此求得 lfp(f) 的上近似。(不考虑抽象解释,数据流分析也可以使用widening,有略微不同。)

    widening 算子 ( abla : L imes L ightarrow L) 定义如下:

    1. ( abla) 是一个上界(upper bound)算子,即 (forall l_1, l_2, l_1 sqsubseteq l_1 abla l2, l_2 sqsubseteq l_1 abla l2)
    2. 对 L 中所有的上升链 ((l_n)_n),上升链 ((l_n^{ abla})_n)(也在 L 中)必趋于稳定。

    由链的构造易知:

    [l_0^{ abla} = l_0, l_1^{ abla} = l_0^{ abla} abla l_1 = l_0 abla l_1, l_2^{ abla} = l_1^{ abla} abla l_2 = l_0 abla l_1 abla l_2, cdots ]

    稳定性易证。将上升链扩展到单调函数也同理。

    narrowing 算子与 widening 类似,而这两个算子的实质就是:分析程序分析的不动点迭代的变化,来计算下一个迭代。其实已经有了 (A^2I) 的雏形。作者把这一类归入 online meta-analysis(during program analysis),此外还有 offline meta-analysis(before/after program analysis)。

    为了支持A2I,需要对抽象解释做一些修改,把收集语义扩展到跟踪语义(trace semantics),即由可达抽象值集合扩展到抽象解释器不动点迭代的序列。以间隔分析(interval analysis)为例,考虑下面的程序:

    [x = 0; while^{l_1} (true) lbrace x = x + 2;^{l_2} brace ]

    收集语义下的 Jacobi 迭代为:

    对于由底元开始的序列

    [egin{bmatrix} x_{11} \ x_{21} end{bmatrix}, egin{bmatrix} x_{12} \ x_{22} end{bmatrix}, cdots, egin{bmatrix} x_{1i} \ x_{2i} end{bmatrix}, cdots ]

    推导规则为:

    [egin{bmatrix} x_{1(i+1)} \ x_{2(i+1)} end{bmatrix} = egin{bmatrix} [0, 0] sqcup x_{2i} \ x_{21} igoplus [2, 2] end{bmatrix} ]

    跟踪语义下的Jacobi迭代则是:

    其包含过程信息。

    将对其抽象定义为:

    根据该定义手推前5项:

    通过对常量传播(constant propagation)分析的抽象,可以将以上迭代加快如下:

    其推导规则为:

    [egin{bmatrix} langle l_{1(i+1)}, h_{1(i+1)} angle \ langle l_{2(i+1)}, h_{2(i+1)} angle end{bmatrix} = egin{bmatrix} langle l_{1i} sqcup 0 sqcup min(0, l_{2i}), h_{1i} sqcup 0 sqcup max(0, h_{2i}) angle \ langle l_{2i} sqcup (l_{1i} igoplus 2), h_{2i} sqcup (h_{1i} igoplus 2) angle end{bmatrix} ]

    这里可能看不明白,同样我们手推前5项(在第5项就收敛了)。

    这里看到利用常量传播格 (D_c) 的积格(product lattice)(D_c^2),大幅提升了收敛速度。

    后面作者举了很多 online/offline (A^2I) 的例子,都是一些比较新的静态分析的工作,(A^2I) 可以看作是对它们通用的理论上的提炼,一作 Cousot 就是 AI 的提出者。作者指出从 1977 年提出 AI 至今,软件的规模、复杂性不断上升,很多软件也并不是安全攸关的(safety-critical),希望这一框架可以使传统抽象解释步入现代,指导高效精确的程序分析算法设计。

  • 相关阅读:
    257. Binary Tree Paths
    324. Wiggle Sort II
    315. Count of Smaller Numbers After Self
    350. Intersection of Two Arrays II
    295. Find Median from Data Stream
    289. Game of Life
    287. Find the Duplicate Number
    279. Perfect Squares
    384. Shuffle an Array
    E
  • 原文地址:https://www.cnblogs.com/humz/p/11492863.html
Copyright © 2011-2022 走看看