Подтвердить что ты не робот

В чем смысл предположения в scala по сравнению с утверждением?

Scala, кажется, определяет 3 вида утверждений: assert, require и assume.

Насколько я понимаю, разница (по сравнению с общим утверждением) require заключается в том, что она специально предназначена для проверки входов (аргументов, входящих сообщений и т.д.). И каков смысл assume then?

4b9b3361

Ответ 1

Если вы посмотрите на код в 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).

Разница заключается в типе исключения, который они генерируют, и сообщении об ошибке, которое они генерируют.

Однако, статические шашки могли обрабатывать все три по-разному. Цель состоит в том, чтобы assert указать условие, которое статическая проверка должна пытаться доказать, assume должна использоваться для условия, которое может содержать проверочное устройство, а require указывает условие, которое вызывающий должен обеспечить, Если статическая проверка обнаруживает нарушение assert, она считает это ошибкой в ​​коде, а при нарушении require она предполагает, что вызывающий абонент неисправен.

Ответ 2

Разность

Разница между assert() и accept() заключается в том, что

  • assert() - способ документировать и динамически проверять инварианты, а
  • Предполагается, что() предназначено для использования инструментами статического анализа.

Предполагаемый потребитель/контекст assert() тестируется, например, тест Scala JUnit, а метод accept() - как средство спецификации дизайна по контракту до и после условий на функциях с намерением, чтобы эти спецификации могли потребляться инструментом статического анализа "(выдержка из scaladoc).

Статический анализ/проверка модели

В контексте статического анализа, как указал Адам Залчан, assert() - это утверждение всех путей выполнения, чтобы проверить глобальный инвариант, а предполагается() работает локально, чтобы уменьшить количество проверки того, что анализатор должен сделать. Предположим, что() используется в контексте предполагаемого-обоснованного рассуждения, которое является механизмом разделения и завоевания, чтобы помочь моделируемым шашкам принять что-то о методе, чтобы решить проблему государственного взрыва, возникающую при попытке проверить все пути, которые программа может занять. Например, если вы знали, что в дизайне вашей программы функция f1 (n1: Int, n2: Int) НИКОГДА не передается n2 < n1, то утверждение этого предположения явно помогло бы анализатору не проверять LOT комбинаций n1 и n2.

На практике

На практике, поскольку такие целые программные модели-шашки по-прежнему в основном теории, давайте посмотрим, что делает компилятор и интерпретатор Scala:

  • выражения accept() и assert() проверяются во время выполнения
  • -Xdisable-assertions отключает проверку assert() и assert()

Подробнее

Больше от превосходного scaladoc на эту тему:

утверждения

Набор функций assert предоставляется для использования в качестве способа документирования и динамической проверки инвариантов в коде. утверждения assert можно отбросить во время выполнения, предоставив аргумент командной строки -Xdisable-assertions команде scala.

Также предлагаются варианты assert, предназначенные для использования со средствами статического анализа: assume, require и ensuring. require и обеспечение предназначены для использования в качестве средства спецификации дизайна по контракту до и после условий для функций с намерением, чтобы эти спецификации могли потребляться инструментом статического анализа. Например,

def addNaturals(nats: List[Int]): Int = {
  require(nats forall (_ >= 0), "List contains negative numbers")
  nats.foldLeft(0)(_ + _)
} ensuring(_ >= 0)

Объявление addNaturals утверждает, что список прошедших целых чисел должен содержать только натуральные числа (т.е. неотрицательные), и возвращенный результат также будет естественным. require отличается от assert тем, что если условие терпит неудачу, тогда вызывающая функция виновата, а не логическая ошибка, сделанная внутри самих addNaturals. обеспечивает форму утверждения, объявляющую гарантию, предоставляемую функцией в отношении возвращаемого значения. )

Ответ 3

I второй ответ Adams, вот только некоторые небольшие дополнения:

Когда assume нарушается, инструмент проверки молчает путь, т.е. не будет следовать по пути глубже.

Следовательно, assume часто используется для формулировки предварительных условий, assert для формулировки пост-условий.

Эти концепции используются многими инструментами, например. инструмент анализа concolic KLEE, программные средства проверки ограниченной модели, такие как CBMC и LLBMC, а также частично статические инструменты анализа кода, основанные на абстрактной интерпретации. Статья Поиск общей основы: выберите, Assert, Предположите, вводит эти понятия и пытается их стандартизировать.