- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Dafny 中实现选择排序。
我的 sorted
和 FindMin
函数确实有效,但 selectionsort
本身包含 Dafny 无法证明的断言,即使它们是正确的。
这是我的程序:
predicate sorted(a:array<int>,i:int)
requires a != null;
requires 0 <= i <= a.Length;
reads a;
{
forall k :: 0 < k < i ==> a[k-1] < a[k]
}
method FindMin(a:array<int>,i:int) returns(m:int)
requires a != null;
requires 0 <= i < a.Length;
ensures i <= m < a.Length;
ensures forall k :: i <= k < a.Length ==> a[k] >= a[m];
{
var j := i;
m := i;
while(j < a.Length)
decreases a.Length - j;
invariant i <= j <= a.Length;
invariant i <= m < a.Length;
invariant forall k :: i <= k < j ==> a[k] >= a[m];
{
if(a[j] < a[m]){m := j;}
j := j + 1;
}
}
method selectionsort(a:array<int>) returns(s:array<int>)
requires a != null;
modifies a;
ensures s != null;
ensures sorted(s,s.Length);
{
var c,m := 0,0;
var t;
s := a;
assert s != null;
assert s.Length == a.Length;
while(c<s.Length)
decreases s.Length-c;
invariant 0 <= c <= s.Length;
invariant c-1 <= m <= s.Length;
invariant sorted(s,c);
{
m := FindMin(s,c);
assert forall k :: c <= k < s.Length ==> s[k] >= s[m];
assert forall k :: 0 <= k < c ==> s[k] <= s[m];
assert s[c] >= s[m];
t := s[c];
s[m] := t;
s[c] := s[m];
assert s[m] >= s[c];
assert forall k :: c <= k < s.Length ==> s[k] >= s[c];
c := c+1;
assert c+1 < s.Length ==> s[c-1] <= s[c];
}
}
为什么这是错误的? “后置条件可能不成立”是什么意思? Dafny 能举个反例吗?
最佳答案
您似乎了解循环不变量背后的基本思想,这是使用 Dafny 验证程序所必需的。
你的程序不正确。发现这一点的一种方法是使用 Visual Studio 中 Dafny IDE 内的验证调试器。单击报告的最后一个错误( c
增量之前的行上的断言),您将看到数组的上半部分包含一个比 s[c]
都小的元素。和s[m]
。然后选择 3 语句交换操作周围的程序点,您会发现您的交换实际上并未交换。
要修复交换,请交换 3 语句交换的第二个和第三个语句。更好的是,利用 Dafny 的多重赋值语句,这使得代码更容易正确:
s[c], s[m] := s[m], s[c];
还有另外两个问题。一是循环内的第二个断言未验证:
assert forall k :: 0 <= k < c ==> s[k] <= s[m];
同时s[m]
是数组上部的最小元素,循环不变式需要证明数组下部的元素不大于上部的元素——这是选择排序算法的基本属性。下面的循环不变量就可以解决这个问题:
invariant forall k, l :: 0 <= k < c <= l < a.Length ==> s[k] <= s[l];
最后是关于属性(property)的投诉sorted(s,c)
不被循环维护是因为您定义了 sorted
严格递增,除非数组的元素最初都是不同的,否则交换永远不会实现。因此,达夫尼指出了您必须对排序例程做出的设计决策。您可以决定您的selectionsort
方法将仅适用于没有重复元素的数组,您可以通过添加来实现
forall k, l :: 0 <= k < l < a.Length ==> a[k] != a[l];
作为 selectionsort
的前提条件(并且循环不变) 。或者,更传统的是,您可以修复 sorted
的定义。替换a[k] > a[m]
与 a[k] >= a[m]
.
要稍微清理一下代码,您现在可以删除所有断言语句和 t
的声明。自 m
仅在循环内部使用,您可以移动 m
的声明到调用 FindMin
的语句,这也表明循环不变式 c-1 <= m <= s.Length
不需要。两个decreases
子句可以省略;对于您的程序,Dafny 将自动提供这些。最后,您的selectionsort
方法就地修改给定的数组,因此没有真正的理由返回引用 a
在输出参数 s
;相反,您可以省略输出参数并替换 s
通过a
无处不在。
关于sorting - Dafny 中的选择排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24591668/
我想在多个程序中重复使用相同的 Dafny 代码。是否可以将一个 Dafny 文件包含在另一个文件中?该手册没有描述任何方法。 最佳答案 是的,在 2013 年 12 月,对“include”语句的支
以下数组反转代码已被 Dafny“证明是正确的”,但显然不正确。我做错了什么? 一个反例是数组: var a = new int[4] {1,3,5,7}; 预期结果 {7,5,3,1} 和实际结果
我正在尝试在 Dafny 中验证一个简单的账户转账,这就是我想出的: function sum(items: seq): int decreases |items| { if items ==
我是 Dafny 的新手,正在尝试编写一个简单的链表实现,将存储在链表中的所有整数相加。这是代码: class Node { var elem: int; var next: Node?; const
有没有一种方法可以对读取堆并返回与堆无关的快照的函数进行编码?这对于我想开发的实验编码非常有用。 例如,我尝试编写一个名为 edges 的 Dafny 函数,我打算仅将其用于规范。它应该采用一组 No
他们来自微软,似乎他们是证明助理?除了句法上的差异之外,还有哪些实际方面使它们彼此不同(比如自动化能力、表达能力等)?我是形式验证的新手。 编辑:我是不是 询问哪个更好,我只是对这些工具提供的不同功能
我一直在尝试证明当两个位向量的所有单独位都相等时它们是等价的。换句话说,下面的语句中a和b是bv64,BitIsSet是提取的函数>来自位向量的第 位,WORD_SIZE 为 64。 (a == b)
我真的很难摆脱 Dafny 程序中的最后一个错误。有人可以指出我正确的方向吗? 这是代码:http://rise4fun.com/Dafny/2FPo 我收到此错误:赋值可能会更新不在封闭上下文的修改
这可能是一个非常愚蠢的问题,但这里是: 为什么 Dafny 可以做到这一点: var arr := new int[2]; arr[0], arr[1] := -1, -2; assert exist
这可能是一个非常愚蠢的问题,但这里是: 为什么 Dafny 可以做到这一点: var arr := new int[2]; arr[0], arr[1] := -1, -2; assert exist
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界. 这篇CFSDN的博客文章dafny : 微软推出的形式化验证语言由作者收集整理,如果你对这篇文章
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界. 这篇CFSDN的博客文章dafny : 微软推出的形式化验证语言由作者收集整理,如果你对这篇文章
我正在尝试使用 Dafny 证明以下程序的正确性/不正确性。 datatype List = Nil | Cons(T, List) function tail(l:List):List {
我有以下用于 tic tac toe 游戏的 Dafny 代码片段,用于检查玩家 1 是否在棋盘上有获胜行: predicate isWinRowForPlayer1(board: array2)
我正在尝试编写一个简单的经过验证的子字符串方法的实现。我的方法接受 2 个字符串并检查 str2 是否在 str1 中。我首先试图弄清楚为什么我的不变量不成立 - 达夫尼标记不变量可能在进入时不成立,
I am used to loops while Grd invariant Inv { ..} assert Inv && !Grd; 没有任何中断,Dafny 知道 Inv && ! Grd 是正
我正在尝试在 Dafny 中实现选择排序。 我的 sorted 和 FindMin 函数确实有效,但 selectionsort 本身包含 Dafny 无法证明的断言,即使它们是正确的。 这是我的程序
I am used to loops while Grd invariant Inv { ..} assert Inv && !Grd; 没有任何中断,Dafny 知道 Inv && ! Grd 是正
我正在对几种在考虑验证的情况下创建的语言(Whiley、Dafny 和 Frama-C 等)进行语言比较。我得到了一个函数示例,该函数将一个数组的区域复制到具有不同位置的另一个数组在目标数组中。我提出
在 Dafny 中迭代有限集对象的元素的最佳方法是什么?一个工作代码的例子将是令人愉快的。 最佳答案 这个答案解释了如何使用 while 循环而不是通过定义迭代器来做到这一点。诀窍是使用“分配这样”运
我是一名优秀的程序员,十分优秀!