形式陈述
设源、目标小步语义 公理库 小步操作语义 Small-step operational semantics · Structural operational semantics 用配置间的一步转移及有限或无限路径精确描述执行顺序、终止、卡住与发散。 分别为 s → t S s ′ 与 q → t T q ′ ,t 是可观察事件迹,空迹记作 ϵ 。编译器前向模拟给出模拟关系 公理库 模拟关系 Simulation relation · Forward simulation · Weak simulation 用方向性的状态关系要求一个系统的每步行为能够由另一个系统匹配。 R ( s , q ) ,覆盖对应初态与终态,并要求每个源步可由目标若干步匹配:
R ( s , q ) ∧ s → t S s ′ ⟹ ∃ q ′ . q ⇒ t T q ′ ∧ R ( s ′ , q ′ ) . ⇒ t 表示目标走零步或多步,连接后的可见迹恰为 t 。若允许空迹源步由目标零步匹配,必须再给良基集合 ( W , ≺ ) 与度量 μ ( s ) :每次零步匹配都严格满足 μ ( s ′ ) ≺ μ ( s ) ;否则一个无限源执行可能永远由静止目标“匹配”。另一种更简单的接口要求每个非终止源步由目标至少一步匹配。
完整接口还包含三类端点责任:每个源初态 s 0 有相关目标初态 q 0 ;若相关源状态以值 v 或 trap 终止,目标能以契约对应的结果终止;源进行外部调用时,目标产生相同事件并把兼容的环境应答带回关系。仅证明普通内部 step 条款,会漏掉空程序、立即错误和调用返回这些没有下一条普通指令的执行。
这一方法是证明编译阶段语义保持 公理库 语义保持的编译器阶段 Semantics-preserving compiler pass · Correct compiler transformation · 编译阶段语义保持 在固定观察、错误与未定义行为契约下,要求一次编译变换的目标程序不产生源程序未允许的行为。 的常用构件,但方向要单独推导。上述条件直接说明源的每条行为可在目标中重现,即 Beh S ⊆ Beh T 的存在性方向;它本身不排除目标拥有额外行为。
直觉
前向模拟跟着源程序的录像向前播放。源每走一格,目标可以走一格、展开成数格,或在源格只是被优化掉的静默行政动作时暂时不走。关系 R 不要求两边寄存器和临时量同名,只要求目标状态仍正确表示源状态的可观察部分。
良基度量是一只不能无限下降的沙漏。它允许有限次零步匹配,又阻止证明者把真正的无限工作都藏成“目标无需行动”。度量必须随每次停顿严格下降;只说优化最终会赶上,或使用普通自然数但不证明下降,都没有完成进展责任。
例子与边界
源语言把 “skip; c” 先走一步化为 c ,目标在编译时已删除 skip。令 R ( skip n ; c , q ) 表示 q 是 c 的目标代码,并取 μ = n 。源删除一个前导 skip 时,目标零步,度量从 n 降到 n − 1 ;源开始执行 c 后,目标走相应实步。因为自然数良基,不可能无限次用同一目标状态掩盖源进展。
指令展开则给出正步例。源一步执行 r := ( x + 4 ) × 8 ,目标先执行 t := x + 4 再左移三位;若两层都按 w 位模算术解释,两个目标步的组合与源一步同值。关系在中间状态可以记住“已算出 x + 4 、尚未移位”的阶段索引,最后恢复主状态关系。
反例揭示包含方向:源初态只有一条标为 a 的边到返回 0 ;目标除同一条边外还多一条 b 边到返回 1 。每个源步仍能在目标匹配,所以前向模拟成立,但目标新增了行为 b , 1 ,不满足目标行为包含于源。若目标语义确定且源语义具相应 receptiveness,并满足事件与终态条件,可由标准定理把前向模拟转成后向模拟;缺少这些假设时不得宣称二者等价。
推论与应用
前向模拟易按源语义规则归纳:每种源指令只需展示目标生成代码怎样走到相关状态。多个阶段的前向模拟可在迹拼接与停顿度量兼容时复合;中间层若隐藏事件,复合前必须证明事件投影一致。
CompCert 的许多单个 pass 使用这种源步到目标多步的证明形状,再利用源的 receptiveness 与目标的 determinacy 等元性质取得整编译器需要的行为改进结论。编译器后向模拟 公理库 编译器后向模拟 Compiler backward simulation · Backward simulation proof for compilers · 编译正确性的后向模拟 从目标执行步反向要求源语义给出同迹匹配,以直接排除编译结果新增源程序不允许的行为。 直接从目标步出发,证明义务和处理非确定性的方式不同;两者互为对照,而非无条件同义词。
有限终止执行可对源步数归纳,连接每段目标 ⇒ t ;无限执行则还要证明这些有限匹配能形成一条无限目标路径,且不会在某个有限目标前缀后只靠关系选择“重新开始”。正步条件或良基停顿度量正是这项提升的关键。迹上若允许 silent 事件擦除,还需证明投影与拼接相容。
参考资料
Xavier Leroy, “A Formally Verified Compiler Back-end,” Journal of Automated Reasoning 43(4), 2009, §§3–4.
Sandrine Blazy and Xavier Leroy, “Mechanized Semantics for the Clight Subset of the C Language,” Journal of Automated Reasoning 43(3), 2009, pp. 263–288.
Nancy A. Lynch and Frits W. Vaandrager, “Forward and Backward Simulations: I. Untimed Systems,” Information and Computation 121(2), 1995, pp. 214–233.