Dafny:使用" forall"量词与"读取"或者"修改"条款

时间:2018-01-24 18:55:50

标签: arrays algorithm formal-verification dafny

所以我试图在Dafny中直接根据CLRS算法书中对算法的描述来实现Dijkstra的单源最短路径算法,作为本科项目的一部分。作为实施的一部分,我已经定义了一个" Vertex"具有两个字段的对象,表示从源和前任顶点的最短路径的当前长度:

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

以及" Graph"包含" Vertex" -es:

数组的对象
    class Graph{
    var vertices: array<Vertex>;
    ....

我试图说明每个&#34; Vertex&#34;中字段的一些属性。使用&#34; Graph&#34;中的谓词的顶点数组对象:

    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
     }

根据我的理解,&#34;读取&#34;和&#34;修改&#34; Dafny中的子句只能在一个层上工作,我必须向Dafny指定我将读取顶点数组中的每个条目(读取this.vertices [x])。我尝试使用&#34; forall&#34;条款:

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

但这似乎不是Dafny的一个功能。有没有人知道是否有办法使用量词与&#34;读取&#34;子句或以其他方式告诉Dafny读取包含对象的数组的每个条目中的字段?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

使用set作为reads子句,您可以轻松完成此操作。

对于您的示例,reads上的这个额外vertexIsValid条款对我有用:

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

您可以将此set表达式视为“vertices[m]所在的所有元素m的集合”。