You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dafny无法证明旧状态相关真命题,求无冗余解决方案

Dafny中旧状态引理复用的优化方案

在Dafny中,单状态引理无法直接通过old()修饰调用,导致需要重复编写双状态版本引理,造成代码冗余。以下是几种更优的解决方法:

方法一:状态参数化(推荐)

将谓词和引理抽象为接受显式State参数的通用版本,同时支持单状态和双状态场景,彻底避免冗余。

// 用State参数显式指定谓词所属的状态
predicate A(s: State)
predicate B(s: State)
predicate C()

// 通用引理,适用于任意状态
lemma {:axiom} AimpliesB(s: State)
    requires A(s)
    ensures B(s)

twostate lemma {:axiom} oldBimpliesC()
    requires old(B(State))
    ensures C()

twostate lemma oldAimpliesC()
    requires old(A(State))
    ensures C()
{
    // 直接传入旧状态实例调用通用引理
    AimpliesB(old(State));
    oldBimpliesC();
}

单状态场景下使用时,直接传当前状态State即可,和原单状态引理效果一致:

lemma SingleStateExample()
    requires A(State)
    ensures B(State)
{
    AimpliesB(State);
}

方法二:幽灵变量捕获旧状态

对于非公理引理,可以通过幽灵变量和假设模拟旧状态下的引理调用,避免重复编写双状态版本:

predicate A() reads *
predicate B() reads *
predicate C()

lemma {:axiom} AimpliesB()
    requires A()
    ensures B()

twostate lemma {:axiom} oldBimpliesC()
    requires old(B())
    ensures C()

twostate lemma oldAimpliesC()
    requires old(A())
    ensures C()
{
    ghost var oldA := old(A());
    ghost var derivedOldB;

    // 在幽灵块中模拟旧状态环境
    ghost {
        assume oldA;          // 假设旧状态下A成立
        AimpliesB();          // 调用单状态引理,推导该环境下B成立
        derivedOldB := B();   // 捕获该环境下的B结果
    }

    assume old(derivedOldB);  // 将捕获的结果关联到实际旧状态
    oldBimpliesC();
}

方法三:直接逻辑推导

如果引理是公理性质的,可直接利用逻辑蕴涵让Dafny自动推导,无需显式调用引理:

twostate lemma oldAimpliesC()
    requires old(A())
    ensures C()
{
    // 借助AimpliesB公理,自动推导旧状态下B成立
    assert old(B()) {:by AimpliesB()};
    oldBimpliesC();
}

若Dafny无法自动触发推导,可通过{:by}注解指定依赖的公理引理,引导证明器完成推导。

内容的提问来源于stack exchange,提问作者Frank Seidl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 10:23:11