Theorem.
求值器与一步规约一致
Theorem. 求值器与一步规约一致
取
Rust 求值器
step
step
, 规约关系采用
一步规约
, 实现论证采用
算术语言形式化的未展开前提
的资源与基础操作假设. 对任意项 与 :
step(t) = Some(u)
step(t) = Some(u)
当且仅当 .
两个方向各有分工. “仅当”方向(
step
step
蕴涵规则)说明函数返回的每个后继都能由规则推出, 函数不会凭空造出规则不允许的一步. “若”方向(规则蕴涵
step
step
)说明规则允许的每个后继函数都能返回, 函数没有漏掉任何合法路线.
“若”方向要用
值不可规约
排除“别的分支抢先匹配”的情形, 这与
确定性
证明里的排除论证同源. 反过来看也成立:
step
step
是函数,所以只要这条定理成立, 若 且 ,则
step(t)
step(t)
同时等于
Some(u)
Some(u)
与
Some(u')
Some(u')
,于是 . 因此对这十条规则,这条定理蕴涵确定性,给出了确定性的另一条证明路线. 若把 E-PredSucc 放宽成任意项,“若”方向会在这一情形失败, 见
E-PredSucc 的数值限制
.
(仅当:
step(t) = Some(u)
step(t) = Some(u)
蕴涵 ) 对 结构归纳,按
step
step
实际走到的分支分情形. 常量 、、 上
step
step
返回
None
None
,前提不成立. 当 时,若 是 则返回 (对应 E-IfTrue),若是 则返回 (对应 E-IfFalse);否则
step(t1) = Some(t1')
step(t1) = Some(t1')
且 ,由
归纳假设
得 ,再用 E-If 即得. 当 时,
step(t1) = Some(t1')
step(t1) = Some(t1')
且 ,由
归纳假设
与 E-Succ 即得. 当 时,若 是 则返回 (E-PredZero),若 t_(1) = succ nv(
is_nv
is_nv
为真)则返回 nv(E-PredSucc),其余情形
step(t1) = Some(t1')
step(t1) = Some(t1')
,由
归纳假设
与 E-Pred 即得. 与 的三个分支一一对应,分别用 E-IsZeroZero、E-IsZeroSucc、E-IsZero.
(若: 蕴涵
step(t) = Some(u)
step(t) = Some(u)
) 对 作规则归纳(
规则归纳法
), 按最后一步的规则分情形. 对 E-IfTrue、E-IfFalse,条件分别是 、,
step
step
的前两个分支直接返回 、. 对 E-If,前提为 ;由
值不可规约
知 不属于值,不可能匹配 或 ,所以
step
step
走第三个分支,再由
归纳假设
得
step(t1) = Some(t1')
step(t1) = Some(t1')
,返回 . 对 E-Succ,由
归纳假设
直接得到. 对 E-PredZero、E-PredSucc,
step
step
的前两个分支返回规则的结论,其中 E-PredSucc 的条件
is_nv
is_nv
正是规则对 nv 的限制. 对 E-Pred,前提为 ;由
值不可规约
知 不属于值,不可能匹配 或数值 succ nv,
step
step
走第三个分支,由
归纳假设
得
step(t1) = Some(t1')
step(t1) = Some(t1')
. E-IsZeroZero、E-IsZeroSucc、E-IsZero 与 的三条一一对应,论证相同.
这条定理接上的是“规则”与“Rust 函数”之间那道缝, 与
算法可靠性
和
算法完备性
对类型检查器做的事相呼应. 它是对这段 Rust 代码的纸面论证,未经机器检查; 对代码里没有写出的细节(例如
clone
clone
的行为)仍然依赖对 Rust 语义的默认理解. 配套工程
code/plt-arith
code/plt-arith
里的
determinism
determinism
测试把
step
step
与逐条照抄规则的枚举器在有限样本上对照, 作为对定理的经验检验.