ここに簡単な関数があります。これは入力を取り、ペアInt
の (場合によっては空の) リストを返します(Int, Int)
。ここで、入力Int
は任意のペアの 3 乗要素の合計です。
cubeDecomposition :: Int -> [(Int, Int)]
cubeDecomposition n = [(x, y) | x <- [1..m], y <- [x..m], x^3 + y^3 == n]
where m = truncate $ fromIntegral n ** (1/3)
-- cubeDecomposition 1729
-- [(1,12),(9,10)]
上記が真であるというプロパティをテストしたい。各要素を 3 乗し、返されたタプルのいずれかを合計すると、入力が返されます。
import Control.Arrow
cubedElementsSumToN :: Int -> Bool
cubedElementsSumToN n = all (== n) d
where d = map (uncurry (+) . ((^3) *** (^3))) (cubeDecomposition n)
Int
実行時の考慮事項として、 QuickCheck でこれをテストするときに入力 s を特定のサイズに制限したいと思います。適切なタイプとArbitrary
インスタンスを定義できます。
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Test.QuickCheck
newtype SmallInt = SmallInt Int
deriving (Show, Eq, Enum, Ord, Num, Real, Integral)
instance Arbitrary SmallInt where
arbitrary = fmap SmallInt (choose (-10000000, 10000000))
SmallInt
そして、次の代わりに使用する関数とプロパティのバージョンを定義する必要があると思いますInt
。
cubeDecompositionQC :: SmallInt -> [(SmallInt, SmallInt)]
cubeDecompositionQC n = [(x, y) | x <- [1..m], y <- [x..m], x^3 + y^3 == n]
where m = truncate $ fromIntegral n ** (1/3)
cubedElementsSumToN' :: SmallInt -> Bool
cubedElementsSumToN' n = all (== n) d
where d = map (uncurry (+) . ((^3) *** (^3))) (cubeDecompositionQC n)
-- cubeDecompositionQC 1729
-- [(SmallInt 1,SmallInt 12),(SmallInt 9,SmallInt 10)]
これは正常に機能し、標準の 100 テストは期待どおりにパスします。しかし、本当に必要なのはカスタム ジェネレーターだけである場合、新しい型、インスタンス、および関数を定義する必要はないように思われます。だから私はこれを試しました:
smallInts :: Gen Int
smallInts = choose (-10000000, 10000000)
cubedElementsSumToN'' :: Int -> Property
cubedElementsSumToN'' n = forAll smallInts $ \m -> all (== n) (d m)
where d = map (uncurry (+) . ((^3) *** (^3)))
. cubeDecomposition
さて、これを最初に数回実行したところ、すべてが正常に機能し、すべてのテストに合格しました。しかし、その後の実行では、失敗が観察されました。テストサイズを大きくすると、次のものが確実に見つかります。
*** Failed! Falsifiable (after 674 tests and 1 shrink):
0
8205379
QuickCheck から返された 0 と 8205379の2 つの縮小された入力が存在するため、ここでは少し混乱しています。また、これらの入力は予測どおりに機能します (少なくとも私の show-able プロパティでは):
*Main> cubedElementsSumToN 0
True
*Main> cubedElementsSumToN 8205379
True
Gen
明らかに、私が定義したカスタムを使用するプロパティに問題があるようです。
私は何を間違えましたか?