什么“必须折叠环以确保终止”是什么意思?

时间:2011-08-25 14:47:29

标签: loops formal-methods abstract-interpretation

我在一篇关于正式方法的论文(精确的抽象解释)中遇到了“循环必须折叠到终止”。我很清楚终止意味着什么,但我不知道折叠循环是什么,也不知道如何在循环上进行折叠。

有人可以向我解释一下折叠环是什么意思吗?如果它不是隐含的,或者没有立即跟随折叠循环的定义,这如何确保终止?

由于

2 个答案:

答案 0 :(得分:4)

折叠循环是与众所周知的循环展开相反的行为,其本身更好地称为 loop unrolling 。给定一个循环,展开它意味着重复几次主体,这样循环测试的执行频率降低。当预先执行循环的次数时,循环可以完全展开,留下简单的指令序列。例如,这个循环

for i := 1 to 4 do
  writeln(i);

可以展开到

writeln(1);
writeln(2);
writeln(3);
writeln(4);

有关部分展开的另一个示例,请参阅C++ loop unfolding, bounds

比喻是节目多次折叠;展开意味着去除部分或全部这些折叠。

在一些静态分析技术中,难以处理循环,因为找到循环入口点的前提条件(即找到循环不变量)需要通常无法解决的固定点计算。因此,一些分析展开循环;这需要对迭代次数有一个合理的限制,这限制了可以分析的程序的范围。

在其他静态分析技术中,找到一个好的不变量是分析的关键部分。它没有帮助展开循环,事实上,部分展开循环会使循环体变大,因此会更难以确定良好的不变量;如果迭代次数很大或无限制,那么完全展开循环将是不切实际或不可能的。在没有看到论文的情况下,我发现这个陈述有点令人惊讶,因为代码可能是用展开的形式编写的,但是可以有一些程序只能以更折叠的形式进行分析。

答案 1 :(得分:0)

我不知道抽象解释,所以我将把函数式编程方法用于折叠。 : - )

在函数式编程中,折叠是应用于列表的操作,用于对每个元素执行某些操作,每次迭代更新一个值。例如,您可以通过这种方式实现map(在Scheme中):

(define (map1 func lst)
  (fold-right (lambda (elem result)
                (cons (func elem) result))
              '() lst))

它的作用是从一个空列表开始(让我们调用结果),然后对于列表中的每个元素,从右侧向左移动,你在上面调用func元素和cons结果列在结果列表中。

就终止而言,这里的关键是,使用折叠,只要列表是有限的,就保证循环终止,因为每次都迭代到列表的下一个元素,如果列表是有限的,然后最终将没有下一个元素。

将此与更多C风格的for循环进行对比,该循环不在列表上运行,而是具有for (init; test; update)形式。 <{1}}不能保证永远返回false,因此不能保证循环完成。