与断言相比,scala中的假设是什么意思?
斯卡拉似乎定义了三种断言: assert
, require
和assume
。
据我所知, require
的区别(与通用断言相比)是专门用于检查input(参数,传入消息等)的。 那么assume
的含义是什么?
如果你看Predef.scala
中的代码,你会发现所有三个代码都做了非常类似的工作:
def assert(assertion: Boolean) { if (!assertion) throw new java.lang.AssertionError("assertion failed") } def assume(assumption: Boolean) { if (!assumption) throw new java.lang.AssertionError("assumption failed") } def require(requirement: Boolean) { if (!requirement) throw new IllegalArgumentException("requirement failed") }
还有一些版本需要额外的参数来报告(参见http://harrah.github.com/browse/samples/library/scala/Predef.scala.html )。
区别在于它们抛出的exceptiontypes以及它们生成的错误消息。
但是,静态检查器可以对待所有三个不同的方法。 其目的是为了assert
一个条件,静态检查应该试图certificate, assume
是用于条件,检查可以假设举行,而require
指定的条件,主叫方必须确保。 如果静态检查器发现违反了assert
则认为它是代码中的错误,而当违反规定时,假定调用者出错。
区别
assert()和assume()之间的区别在于
- assert()是一种logging和dynamic检查不variables的方法
- 假设()旨在被静态分析工具所使用
assert()的预期消费者/上下文是testing,比如Scala JUnittesting,而assume()则是“作为契约式devise的函数前后条件规范的一种手段,意图这些规格可以被静态分析工具消耗“(摘自scaladoc )。
静态分析/模型检查
在静态分析的背景下,正如Adam Zalcman指出的那样,assert()是一个全执行path断言,用来检查一个全局不variables,而assume()在本地工作,以减less分析器需要检查的数量做。 假设()用于假设 – 保证推理,这是一种分而治之的机制,可以帮助模型检测人员假设一些关于该方法的信息,从而解决当试图检查程序的所有path时出现的状态爆炸问题可能需要。 例如,如果你知道在你的程序devise中,函数f1(n1:Int,n2:Int)从来没有通过n2 <n1,那么明确说明这个假设将有助于分析器不必检查很多组合的n1和n2。
在实践中
实际上,由于这样的全程序模型检查器仍然主要是理论,让我们来看看scala编译器和解释器的作用:
- 在运行时检查assume()和assert()expression式
- -Xdisable-assertions禁用了assume()和assert()检查
更多
更多来自优秀的scaladoc关于这个话题:
断言
提供了一组assert
函数,用于在代码中logging和dynamic检查不variables。 通过向scala
命令提供命令行参数-Xdisable-assertions
,可以在运行时消除断言语句。
还提供了旨在用于静态分析工具的assert
变体: assume
, require
和ensuring
。 require
和确保的目的是为了作为一种手段,按照契约式的方式规定function上的前后条件,意图是这些规范可以被静态分析工具所使用。 例如,
def addNaturals(nats: List[Int]): Int = { require(nats forall (_ >= 0), "List contains negative numbers") nats.foldLeft(0)(_ + _) } ensuring(_ >= 0)
addNaturals的声明指出,传递的整数列表应该只包含自然数(即非负),返回的结果也是自然的。 require与assert不同的地方在于,如果条件失败,那么函数的调用者应该责怪addNaturals本身而不是逻辑错误。 确保是一种声明的forms,声明函数提供的关于它的返回值的保证。 )
我第二个亚当斯的回答,这里只是一些小的补充:
当assume
被违反时,validation工具默默地修剪path,即不遵循path更深。
因此, assume
通常用于制定前提条件, assert
制定后置条件。
这些概念被许多工具所使用,例如concolictesting工具KLEE , CBMC和LLBMC等软件有限的模型检查工具,部分也是基于抽象解释的静态代码分析工具。 文章find共同点:select,断言,承担介绍这些概念,并试图规范他们。