程序切片(定义+用途)
介绍
让我们假设我们测试了一个程序 p 并失败了(错误的
输出)。然后我们想找出导致失败(故障)的原因。
现在假设我们要更改程序的一部分。我们可能会问:程序的哪些其他部分受到影响
我们想找到导致失败的原因(什么是错误)?
我们想确定程序的哪些部分可以是受变化影响?
这两个问题都与依赖有关。它是一类程序简化技术。
我们将看到几个品种。在每个我们有:
我们必须保留程序行为(语义)的某些元素。
一些我们可以简化程序的方法。
调试:一种策略Tactic
我们可能会插入断点或存储/记录/输出某些变量在特定点的值。
这可能会告诉我们某些变量的值是在执行的某些时候是错误的。然后我们可以尝试确定错误值的原因。
更改代码:一种策略
这可以看作是确定哪些变量(在被更改的点 n 处)受到更改的影响。然后找出程序的哪些其他部分受到影响通过这些变量在 n 处的值。
一个共同的主题
程序切片Program Slicing 正是关于依赖性的,只是我们提取了一个代表这种依赖性的程序。
初始定义(Mark Weiser 于 1979 年提出)
程序 p 的一个(静态的,向后的)程序切片 s 是根据切片标准 (V , n) 构建,其中 V 是一组变量名,n 是程序点。
当要执行的下一个语句在 n 时,p 中的语句不能影响变量在V 的值可能是从 p 中移除以形成 s。
所以简化是通过删除代码。
定义的后果Consequences
我们可以删除任何不能影响值的语句V 中 n 处的任何变量。
唯一允许的简化是通过语句删除。
通常我们会查看程序的结尾(n 是最终节点)。
大多数用于生成程序的静态切片的算法都通过以下方式查看依赖性:
数据:赋给节点n0中变量x的值可以是在另一个节点 n 访问。
控制:n0可以判断节点n是否被执行。
不只是任何切片
程序始终是其自身的有效片段。
通常我们想要最小的切片。
但这个问题是不可计算的:没有总能返回最小切片的通用算法。
然而:有一些高效的算法通常可以产生商品切片。
关于 b 的结束切片例子:
切片的用途
(1)我们将谈谈切片的使用:调试与理解
(2)它也被用于:重复使用; 并行化; 测试
(3)切片的原始动机:
在测试中,我们可能会观察到我们在特定点得到了特定变量的错误值。
我们可以对这个变量/点使用切片来消除不可能是失败根源的语句
(4) 切片可以让我们提取更简单的子行为并简化问题,例如:
这个程序中的变量 x 会发生什么变化?
(5) 在程序维护中特别有用——尤其是当我们的遗留系统文档不足时。
(6)在反向切片backward slicing中,我们删除不影响的语句通过切片准则。在前向切片forward slicing中,我们删除不受影响的语句通过切片准则。
(7) 它允许我们提出以下问题:
代码的哪些部分受节点 n 处的变量 x?
(8) 特别适用于评估变更的影响(以及维护)