- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有哪些代码示例可以证明KeY的优势?
细节
有了这么多的正式方法工具,我想知道KeY在哪些方面比其竞争对手更好,以及如何?一些可读的代码示例对于比较和理解非常有帮助。
更新
搜索the KeY website时,我发现了the book中的代码示例-那里是否有合适的代码示例?
此外,我找到了a paper about the bug that KeY found in Java 8’s mergeCollapse in TimSort。 TimSort的最少代码可以证明KeY的实力吗?但是,我不明白为什么模型检查应该找不到该错误-具有64个元素的位数组不应太大而无法处理。其他演绎验证工具是否同样能够发现错误?
是否存在建立有适当代码示例的验证竞赛?
最佳答案
这是一个非常棘手的问题,这就是为什么在一年多前被问到之后为什么还没有得到答案的原因(尽管我们来自KeY社区的人们都知道这一点……)。
互动的力量
首先,我想指出的是,KeY基本上是那里唯一允许进行Java程序的交互式证明的工具。尽管许多证明会自动运行,并且我们有非常强大的自动策略,但有时需要进行交互才能理解证明失败的原因(太弱甚至错误的规范,错误的代码或“仅仅是”证明者的能力不足)并添加适当的更正或增强。
验证检查的反馈
尤其是在证明方无能力的情况下(规格和程序都可以,但是问题很难使证明方自动成功),交互是一项强大的功能。许多程序证明者(例如OpenJML,Dafny,Frama-C等)都依赖于后端的SMT求解器,并以或多或少的小型验证条件作为输入。然后,将这些条件的验证状态报告给用户,基本上是通过或失败-或超时。当断言失败时,用户可以更改程序或完善规范,但不能检查证明的状态以推断出出了什么原因。这种样式有时称为“自动活跃”,而不是交互式。尽管这在很多情况下非常方便(尤其是在通过验证时,因为SMT求解器可以非常迅速地证明某些东西),但可能很难挖掘SMT求解器的输出以获取信息。甚至SMT求解器本身也不知道出了什么问题的原因(尽管他们可以提供反例),因为他们只是被提供了一组试图寻找矛盾的公式。
TimSort:复杂的算法问题
对于您提到的TimSort证明,我们必须进行大量交互才能使它们通过。以排序算法的mergeHi方法为例,该方法已被我所知的最有经验的KeY高级用户之一证明。在460K证明节点的证明中,需要3K用户交互,包括很多简单的交互,例如隐藏分散注意力的公式,还包括478个量词实例化和大约300个割断(在线引理引入)。该方法的代码具有许多困难的Java功能,例如带有标记中断,整数溢出,位算术等的嵌套循环。特别是,在证明树中分支有很多潜在的例外情况和其他原因(这就是为什么在证明中还使用了五个手动状态合并规则应用程序的原因)。证明此方法的工作流程主要是尝试一些策略,然后检查证明状态,修剪证明并引入有用的引理,以减少总体证明工作并重新开始;有时,如果策略本身无法直接找到正确的实例,则可以手动实例化量词,并合并证明分支以应对状态爆炸。我只是在这里声称,(至少当前)使用自动工具无法证明该代码,在这种情况下,您不能以这种方式指导证明者,也无法获得正确的反馈以了解如何进行指导。
KeY的力量
最后,我要说的是KeY在证明棘手的算法问题(例如排序等)方面很强,在这些问题中,复杂的量化不变量和整数算术存在溢出,并且需要通过检查和交互来快速找到量词实例化和小引理。具有证明状态。半交互式验证的KeY方法在SMT求解程序超时的情况下通常也很出色,这样用户无法分辨出是什么问题还是需要附加的引理。
KeY当然也可以证明“简单”的问题,但是您需要注意程序中不要包含不受支持的Java功能(例如浮点数或多线程)。同样,如果尚未在JML中指定库方法,则可能是一个很大的问题(但此问题也适用于其他方法)。
持续发展
顺便提一句,我还想指出,KeY现在越来越多地转变成一个平台,用于对各种程序属性(不仅是Java程序的功能正确性)进行静态分析。一方面,我们开发了诸如Symbolic Execution Debugger之类的工具,非专家也可以使用这些工具来检查顺序Java程序的行为。另一方面,我们目前正在忙于重构系统的体系结构,以便可以为不同于Java的语言添加前端(在我们的内部项目“ KeY-RED”中);此外,正在不断进行现代化的Java前端工作,以支持诸如Lambdas之类的更新语言功能。我们还在研究诸如编译器正确性之类的关系属性。尽管我们已经支持第三方SMT求解器的集成,但我们的集成逻辑核心仍将在那里支持理解SMT和自动化失败情况下的证明情况和手动交互。
TimSort代码示例
既然您要求一个代码示例...我想不起来想到显示KeY实力的“那个”代码示例,但是也许是为了给您带来TimSort算法中mergeHi复杂性的味道,这里是一段简短的摘录,内含一些注释(完整方法大约有100行代码):
private void mergeHi(int base1, int len1, int base2, int len2) {
// ...
T[] tmp = ensureCapacity(len2); // Method call by contract
System.arraycopy(a, base2, tmp, 0, len2); // Manually specified library method
// ...
a[dest--] = a[cursor1--]; // potential overflow, NullPointerException, ArrayIndexOutOfBoundsException
if (--len1 == 0) {
System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
return; // Proof branching
}
if (len2 == 1) {
// ...
return; // Proof branching
}
// ...
outer: // Loop labels...
while (true) {
// ...
do { // Nested loop
if (c.compare(tmp[cursor2], a[cursor1]) < 0) {
// ...
if (--len1 == 0)
break outer; // Labeled break
} else {
// ...
if (--len2 == 1)
break outer; // Labeled break
}
} while ((count1 | count2) < minGallop); // Bit arithmetic
do { // 2nd nested loop
// That's one complex statement below...
count1 = len1 - gallopRight(tmp[cursor2], a, base1, len1, len1 - 1, c);
if (count1 != 0) {
// ...
if (len1 == 0)
break outer;
}
// ...
if (--len2 == 1)
break outer;
count2 = len2 - gallopLeft(a[cursor1], tmp, 0, len2, len2 - 1, c);
if (count2 != 0) {
// ...
if (len2 <= 1)
break outer;
}
a[dest--] = a[cursor1--];
if (--len1 == 0)
break outer;
// ...
} while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
// ...
} // End of "outer" loop
this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
if (len2 == 1) {
// ...
} else if (len2 == 0) {
throw new IllegalArgumentException(
"Comparison method violates its general contract!");
} else {
System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
}
}
关于verification - KeY验证工具在哪里发光?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46754018/
查看“mysqldump -d”并看到一个键是 KEY,而不是“PRIMARY KEY”或“FOREIGN KEY” 什么是关键? 示例: CREATE TABLE IF NOT EXISTS `TA
在我开始使用 Python 的过程中尝试找出最佳编码实践。我用 Pandas 写了一个 csv 到数据框阅读器。它使用格式: dataframe = read_csv(csv_input, useco
在 Flutter 中,用一个例子可以清楚地解释什么? 我的困惑是关于 key,如下面的代码所示。 MyHomepage({Key key, this.title}) : super(key: key
我在我的 Android 应用程序中使用 GCM。要使用 GCM 服务,我们需要创建 Google API key 。因此,我为 android、服务器和浏览器 key 创建了 API key 。似乎
我想在 azure key 保管库中创建一个 secret ,该 key 将具有多个 key (例如 JSON)。 例如- { "storageAccountKey":"XXXXX", "Co
尝试通过带有 encodeforURL() 的 url 发送 key 时,我不断收到错误消息和 decodefromUrl() .代码示例如下。 这是我的入口页面: key = generateSec
是否有检查雪花变体字段中是否存在键的函数? 最佳答案 您可以使用 IS_NULL_VALUE 来查看 key 是否存在。如果键不存在,则结果将为 NULL。如果键存在,如果值为 JSON null,则
我正在尝试运行此命令: sudo apt-key adv --keyserver keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A 但我收到一个错误: Execu
我有一个 csv 文件,我正在尝试对 row[3] 进行计数,然后将其与 row[0] 连接 row[0] row[3] 'A01' 'a' 'B02'
如何编写具有这种形式的函数: A(key, B(key, C(key, ValFactory(key)))) 其中 A、B 和 C 具有此签名: TResult GetOrAdd(string key
审查 this method我很好奇为什么它使用 Object.keys(this).map(key => (this as any)[key])? 只调用 Object.keys(this).ind
我有一个奇怪的情况。我有一个字典,self.containing_dict。使用调试器,我看到了字典的内容,并且可以看到 self 是其中的一个键。但是看看这个: >>> self in self.c
我需要在我的 Google Apps 脚本中使用 RSA-SHA256 和公钥签署消息。 我正在尝试使用 Utilities.computeRsaSha256Signature(value, key)
我是 React 的初学者开发人员,几天前我看到了一些我不理解的有趣语法。 View组件上有{...{key}},我会写成 key={key} ,它完全一样吗?你有链接或解释吗? render()
代理 key 、合成 key 和人工 key 之间有什么区别吗? 我不清楚确切的区别。 最佳答案 代理键、合成键和人工键是同义词。技术关键是另一个。它们都表示“没有商业意义的主键”。它们不同于具有超出
问题陈述:在 Web/控制台 C# 应用程序中以编程方式检索并使用存储在 Azure Key Vault 中的敏感值(例如数据库连接字符串)。 据我所知,您可以在 AAD 中注册应用,并使用其客户端
问题陈述:在 Web/控制台 C# 应用程序中以编程方式检索并使用存储在 Azure Key Vault 中的敏感值(例如数据库连接字符串)。 据我所知,您可以在 AAD 中注册应用,并使用其客户端
我正在寻找 Perl 警告的解决方案 “引用键是实验性的” 我从这样的代码中得到这个: foreach my $f (keys($normal{$nuc}{$e})) {#x, y, and z 我在
我正在为 HSM 实现 JCE 提供程序 JCE中有没有机制指定 key 生成类型例如: session key 或永久 key KeyGenerator keygen = KeyGener
我在 Facebook 上创建了一个应用程序。我已经正确添加了 keyhash 并且应用程序运行良好但是当我今天来并尝试再次运行它时它给了我这个错误。 这已经是第二次了。 Previsouly 当我收
我是一名优秀的程序员,十分优秀!