【问题标题】:dafny - puzzling postcondition violationdafny - 令人费解的后置条件违规
【发布时间】:2018-08-12 16:26:57
【问题描述】:

所以我在尝试完成的 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 发现未分配返回整数的情况?

为什么违反了先决条件?

感谢任何帮助。

【问题讨论】:

    标签: graph-algorithm formal-verification dafny


    【解决方案1】:

    getVertexwfs,我觉得我一定错过了什么。为什么后置条件不能是ensures d[v.id] == i?为什么身体不能是i := d[v.id];。循环似乎没有做任何有趣的事情。它只是不必要地从 0 搜索到 v.id

    另外,在hasVertex 中,您可以只写v in vertices。它相当于你所拥有的。

    最后,在isValid 中,您需要在量词周围加上括号,例如(forall m | m in vertices :: m != null &amp;&amp; 0 &lt;= m.id &lt; d.Length)。否则,这意味着forall 继续到谓词的末尾。此外,在现代 Dafny 中,用作类型的类名自动暗示非空性。如果您从不打算将null 存储在数据结构中,则可以保持类型不变,并删除isValid 中所有谈论不是null 的部分。

    如果我进行这些更改,程序会验证。

    【讨论】:

      猜你喜欢
      • 2016-03-18
      • 2020-04-29
      • 2018-11-23
      • 2017-11-03
      • 2018-10-25
      • 2018-11-01
      • 2021-12-05
      • 1970-01-01
      相关资源
      最近更新 更多