【问题标题】:Dafny: Using "forall" quantifiers with the "reads" or "modifies" clausesDafny:使用带有“reads”或“modifies”子句的“forall”量词
【发布时间】:2018-07-03 22:13:25
【问题描述】:

因此,作为本科项目的一部分,我正在尝试直接根据 CLRS 算法书中算法的描述,在 Dafny 中实现 Dijkstra 的单源最短路径算法。作为实现的一部分,我定义了一个“顶点”对象,其中包含两个字段,分别表示从源到前一个顶点的最短路径的当前长度:

    class Vertex{
    var wfs : int ;   
    var pred: Vertex;
    }

以及包含“顶点”-es 数组的“图形”对象:

    class Graph{
    var vertices: array<Vertex>;
    ....

我正在尝试使用“图形”对象中的谓词来声明顶点数组的每个“顶点”中字段的一些属性:

    predicate vertexIsValid() 
    reads this;
    reads this.vertices;
     {
       vertices != null &&
       vertices.Length == size &&
       forall m :: 0 <= m < vertices.Length ==> vertices[m].wfs != 900000 && 
       vertices[m].pred != null
     }

据我了解,Dafny 中的“读取”和“修改”子句仅适用于一层,我必须向 Dafny 指定我将读取顶点数组中的每个条目(读取 this.vertices[x ])。我尝试使用“forall”子句来做到这一点:

   forall m :: 0 <= m < vertices.Length ==> reads this.vertices[m]

但这似乎不是 Dafny 的功能。有谁知道是否有办法在“读取”子句中使用量词,或者告诉 Dafny 读取包含对象的数组的每个条目中的字段?

感谢您的帮助。

【问题讨论】:

    标签: arrays algorithm formal-verification dafny


    【解决方案1】:

    您可以使用set 作为reads 子句最轻松地做到这一点。

    对于您的示例,vertexIsValid 上的附加 reads 子句对我有用:

    reads set m | 0 <= m < vertices.Length :: vertices[m]
    

    您可以将这个set 表达式视为“所有元素的集合vertices[m] 其中m 在边界内”。

    【讨论】:

    • 您好,感谢您上次回答我的问题。我对这个问题有一个后续问题:我继续处理代码,我遇到了类似的问题,但使用了 modifies 子句。我尝试使用集合作为量词,就像 reads 子句一样,但 dafny 仍然给我一个修改子句错误。我将代码剥离为一个简单的测试来总结我遇到错误的情况:(rise4fun.com/Dafny/ECHa)。你知道为什么 dafny 会遇到麻烦吗?再次感谢您的帮助。
    • 啊,没关系,刚刚找到原因。似乎 dafny 中的循环也必须使用修改子句进行注释,因为如果循环与整个函数的上下文是分开的,则上下文也是如此。很抱歉打扰您。
    猜你喜欢
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多