为什么我不能从 Dafny 的鬼域中调用(非静态)引理?

Why can't I call a (non-static) lemma from a ghost field in Dafny?

在 Dafny 上,lemma 被实现为 ghost method,因此,它仅对规范有用。

但是,您不能从 ghost field 调用引理,如下所示:

class A {
    var i: int;
    lemma sum_is_commutative(i: int, j: int)
        ensures i + j == j + i
    {}
}
class B {
    ghost var a: A;
    lemma a_sum_is_commutative(i: int, j: int)
        ensures i + j == j + i
    { a.sum_is_commutative(i, j); }
    method test() {
        // a.sum_is_commutative(3, 2); // <- Cannot use directly this
        a_sum_is_commutative(3, 2);
    }
}

这种行为的理由是什么?如何解决?最好的选择是只重复内部 class 中的引理并利用(通常是调用)另一个 class 的 lemma?

我不熟悉 Dafny,但我认为您还需要将 test 方法声明为 ghost 才能在其中使用 ghost 参数。

通常在程序验证框架中,ghost表示定义会在运行时被擦除,这里仅用于证明目的。因此,您的 test 方法不应包含其定义将被擦除的代码,或者应将其标记为可擦除 (ghost)。

我无法评论此行为的基本原理(如果有学术答案,我会更新所选答案,而不仅仅是错误或缺乏实施)。

为了解决这个问题,定义

在语义上是一样的
class A {
  lemma sum_commutative(i: int, j: int) {}
}

类似于

class A {
  static lemma sum_commutative(a: A, i: int, j: int) {}
}

因此,即使您需要访问 this 实例,您也可以将其作为参数传递,而不是隐式依赖它。

然后,您可以从任何其他 class 调用您的引理作为 A.sum_commutative(a, i, j) 而无需 运行 进入从非调用 ghost 变量的 ghost 方法的问题-鬼法.

感谢您发现并报告这一点。这是一个错误。我刚刚推送了一个修复程序。

鲁斯坦