haskell - QuickCheck 中是否有 "there exists"量词?

标签 haskell quickcheck

forAll量词返回一个检查所有测试用例是否通过的属性。有没有办法定义一个“存在”量词,它返回一个属性来检查它至少一个测试用例是否通过?

最佳答案

通过枚举测试存在会更可靠:SmallCheck , LeanCheck , FEAT .
如果必须使用随机生成,QuickCheck 中有一些间接方法。

expectFailure 似乎是一个很好的否定候选人。然而它并不完全如此,因为它不是内合的,所以你必须以其他方式否定该属性,如 not ,如果您的属性实际上是 bool 值。

exists :: Gen a -> (a -> Bool) -> Property
exists gen prop = once $ expectFailure (forAll gen (not . prop))
不过,这会将崩溃视为失败,从而使测试通过,即使您可能没有预料到。

存在量化是一种析取,QuickCheck 有 disjoin .只要做一个足够大的析取。
exists :: Gen a -> (a -> Property) -> Property
exists gen prop = once $ disjoin $ replicate 10000 $ forAll gen prop
但是当没有找到好的例子时,你会收到反例的垃圾邮件。
或许改写forAll的逻辑比较好自己避免调用counterexample .

更简单地说,您始终可以编写自己的属性作为生成器来获得正确的量化。
exists :: Gen a -> (a -> Bool) -> Property
exists gen prop = property (exists' 1000 gen prop)

exists' :: Int -> Gen a -> (a -> Bool) -> Gen Bool
exists' 0 _ _ = return False
exists' n gen prop = do
  a <- gen
  if prop a
    then return True
    else exists' (n - 1) gen prop
手动执行此操作还具有 if prop 的属性。意外崩溃,它立即报告为失败,与以前的方法相反。

编辑
因此,如果您只有 (a -> Property)而不是 (a -> Bool)获得一个好的结果似乎要复杂得多,因为检查一个属性是否成功并非易事。正确的方法是弄乱 QuickCheck 的内部结构,可能类似于 disjoin .这是一个快速破解
  • 使用mapResult使 disjoin 的输出静音当没有找到(反)示例时。
  • 覆盖大小参数,因为如果您的见证不平凡,那么如果大小太小或太大,将无法找到它们。
  • import Test.QuickCheck
    import Test.QuickCheck.Property as P
    
    -- Retry n times.
    exists :: Testable prop => Int -> Gen a -> (a -> prop) -> Property
    exists n gen prop =
      mapResult (\r -> r {P.reason = "No witness found.", P.callbacks = []}) $
      once $
      disjoin $
      replicate n $ do
        a <- gen
        return (prop a)
    
    main = quickCheck $ exists 100
      (resize 5 arbitrary)
      (\x -> (x :: Integer) == 2)
    

    关于haskell - QuickCheck 中是否有 "there exists"量词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42764847/

    相关文章:

    haskell - 为一个类定义一套测试

    python - pytest-hypothesis 运行之间的测试隔离

    Haskell 非详尽模式缺失

    haskell - Haskell 中组合的参数数量

    haskell - 如何在 Haskell 中获得大数的数字总和?

    unit-testing - 快速检查 Smalltalk?

    haskell - 为什么我不能让 `where` 在 Hspec 中工作

    haskell - 如何测试 Applicatives 上的多态函数?

    haskell - 为什么列表仿函数代表不确定性选择的上下文?

    database - 有没有适用于 Haskell 的 ORM 工具?