证明程序的等价性

Proving equivalence of programs

优化编译器的终极目标是在 space 程序中搜索与原始程序等效但速度更快的程序。这在实践中已经针对非常小的基本块完成:https://en.wikipedia.org/wiki/Superoptimization

听起来困难的部分在于搜索的指数性质 space,但实际上并非如此;困难的部分是,假设你找到了你要找的东西,你如何证明新的、更快的程序真的等同于原来的程序?

上次我研究它时,在证明程序在某些情况下的某些属性方面取得了一些进展,特别是在非常小的范围内,当你谈论标量变量或小的固定位向量时,但不是真的当您谈论复杂的数据结构时,在更大范围内证明程序的等价性。

有没有人找到解决这个问题的方法,甚至是“模解决这个我们还不知道如何解决的 NP 难搜索问题”?

编辑:是的,我们都知道停机问题。它是根据一般情况定义的。人类是一个存在证明,可以为许多感兴趣的实际案例做到这一点。

你问的是一个相当广泛的问题,但让我看看我是否可以让你继续。

John Regehr 在调查一些关于超级优化器的相关论文方面做得非常好:https://blog.regehr.org/archives/923

问题是您真的不需要为这些类型的优化证明整个程序的等价性。相反,您只需要证明给定 CPU 处于特定状态,2 个代码序列以相同的方式修改 CPU 状态。为了在许多优化(即大规模)中证明这一点,通常您可能首先在两个序列上抛出一些随机输入。如果它们不是等效的代码位,那么您可能会很幸运并很快证明这一点(矛盾证明),然后您可以继续前进。如果您没有发现矛盾,您现在可以尝试通过计算量大的 SAT 求解器来证明等价性。 (顺便说一句,如果您对超级优化器感兴趣,Regehr 提到的 STOKE 论文会特别有趣。)

现在看看整个程序的语义等价性,这里的一种方法是 CompCert 编译器使用的方法。本质上,编译器正在证明这个定理:

如果 CompCert 能够将 C 代码 X 翻译成汇编代码 Y,那么 X 和 Y 在语义上是等价的。

此外,CompCert 确实应用了一些编译器优化,实际上这些优化通常是传统编译器出错的地方。也许像 CompCert 这样的东西就是你所追求的,在这种情况下,编译器通过一系列细化过程来处理事情,它证明如果每个过程都成功,结果在语义上等同于前一个过程。