所以我在尝试完成的 Dijkstra 算法的实现中有一个 Vertex 类和 Edge 类。它看起来像这样:
class Vertex{
var id : int ;
var wfs : int ;
var pred: int ;
constructor Init()
modifies this
{
this.wfs :=-1;
this.pred := -1;
}
}
class Edge{
var source : int;
var dest: int;
var weight : int;
}
和一个看起来像这样的 Graph 类:
class Graph{
var vertices : set<Vertex>
var edges : set<Edge>
var d : array<int>
}
有一堆关于在算法运行中假设的图的谓词。我正在尝试编写一个将顶点作为输入的方法,然后从源中输出该顶点的当前最短路径,该路径存储在 d 中,其中 d 的索引是顶点的“id”。该方法如下所示:
method getVertexwfs(v: Vertex) returns (i: int)
requires isValid() && hasVertex(v) && v != null
requires hasVertex(v) ==> 0 <= v.id < d.Length && v in vertices
ensures exists s :: 0 <= s < d.Length && d[s] == i
{
var x: int := 0;
while (x < d.Length)
invariant hasVertex(v)
invariant hasVertex(v) ==> 0 <= v.id < d.Length
invariant v in vertices && 0 <= v.id < d.Length
{
if(v.id == x){ i := d[x]; }
x := x + 1 ;
}
//return i;
}
涉及的谓词是:
predicate isValid()
reads this, this.edges, this.vertices
{
d != null && |vertices| > 0 && |edges| > 0 &&
d.Length == |vertices| &&
forall m | m in vertices :: (m != null && 0 <= m.id < d.Length ) &&
forall m , n | m in vertices && n in vertices && m != n :: (m != null && n
!= null && m.id != n.id) &&
forall e | e in edges :: e != null && 0 <= e.source <= e.dest < d.Length &&
forall e | e in edges :: !exists d | d in edges :: d != e && d.source == e.source && d.dest == e.dest
}
和
predicate method hasVertex(v: Vertex)
requires isValid()
reads this, this.vertices, this.edges
{
vertices * {v} == {v}
}
违反了 getVertexwfs() 方法的后置条件,尽管我坚持函数 v 存在于图中的先决条件,并且这意味着 v 的 ID 是 d 范围内的索引。
我是否错过了 Dafny 发现未分配返回整数的情况?
为什么违反前提条件?
任何帮助表示赞赏。