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

Что такое сокращение, в отношении Haskell QuickCheck?

Я изучаю веревки QuickCheck >= 2.6, но я не понимаю, что такое усадка. Если посмотреть на подпись , то сжатие больше похоже на расширение! Пожалуйста, осветите меня:)

4b9b3361

Ответ 1

Когда QuickCheck находит вход, который нарушает свойство, он сначала попытается найти более мелкие входы, которые также нарушают свойство, чтобы дать разработчику лучшее сообщение о характере сбоя.

Что значит быть "маленьким", конечно, зависит от соответствующего типа данных: QuickCheck - это что-то, что выходит из функции shrink.

Это лучше всего объяснить в сеансе QuickCheck:

Prelude Test.QuickCheck> let prop l = all (/= 5) l
Prelude Test.QuickCheck> quickCheck prop
*** Failed! Falsifiable (after 10 tests and 2 shrinks):    
[5]

Таким образом, QuickCheck смог дать самый маленький встречный пример, но, судя по комментариям, он сначала имел больший список, а затем уменьшил его с помощью shrink. Чтобы более подробно посмотреть, что происходит, мы используем verboseCheck:

Prelude Test.QuickCheck> verboseCheck prop
Passed:  
[]
Passed: 
[0]
Passed:  
[-2,1]
Passed:  
[-2,2,-2]
Passed:  
[-4]
Failed:  
[-1,-2,5,4,2]
*** Failed! Passed:                       
[]
Failed:                                       
[5,4,2]
Passed:                                    
[]
Passed:                                       
[4,2]
Failed:                                       
[5,2]
Passed:                                     
[]
Passed:                                       
[2]
Failed:                                       
[5]
Passed:                                     
[]
Passed:                                       
[0]
Passed:                                       
[3]
Passed:                                       
[4]
Falsifiable (after 6 tests and 3 shrinks):    
[5]

QuickCheck пробует несколько списков, для которых выполняется предложение, а затем находит [-1,-2,5,4,2]. Теперь он уменьшает список, пытаясь подсказать его. Вы можете убедить себя в GHCi, что shrink [-1,-2,5,4,2] == [[],[5,4,2],[-1,-2,2],..., а вторая запись - первая, которая все еще терпит неудачу. Затем QuickCheck продолжает и продолжает сокращаться: shrink [5,4,2] == [[],[4,2],[5,2],... и далее shrink [5,2] [[],[2],[5],.... Наконец, он пытается сжать [5] дальше, но ни один из shrink [5] == [[],[0],[3],[4]] не выполняет предложение, поэтому итоговый пример подсчета [5].

Ответ 2

Один shrink является ступенчатым уменьшением сложности некоторого тестового примера Arbitrary ( "немедленная усадка" ). Это может быть что-то вроде 2 -> 1 или 1:[] -> []. Для более сложных типов может быть несколько способов "постепенного сокращения" типа, чтобы вы указали все из них в списке.

Например, деревья могут быть сжаты, удалив любой лист, поэтому, если есть n, листья сжимаются, выдает список длины n.