module Main where import qualified Combinatorics.Battleship.Count.ShortenShip.Distribution as Distribution import qualified Combinatorics.Battleship.Count.ShortenShip as ShortenShip import qualified Combinatorics.Battleship.Count.CountMap as CountMap import qualified Combinatorics.Battleship.Count.Counter as Counter import qualified Combinatorics.Battleship.Count.Frontier as Frontier import qualified Combinatorics.Battleship.Enumeration as Enumerate import qualified Combinatorics.Battleship.SetCover as SetCover import qualified Combinatorics.Battleship.Fleet as Fleet import qualified Combinatorics.Battleship.Size as Size import qualified Test.QuickCheck.Monadic as QCM import qualified Test.QuickCheck as QC import Test.QuickCheck (quickCheck) factorial :: (Integral a) => a -> a factorial n = product [1..n] multiplicity :: (Integral a) => Fleet.T -> a multiplicity = product . map (factorial . fromIntegral . snd) . Fleet.toList propCountSetCover :: QC.Property propCountSetCover = QC.forAllShrink (QC.choose (0,4)) QC.shrink $ \width -> QC.forAllShrink (QC.choose (0,10)) QC.shrink $ \height -> QC.forAllShrink ShortenShip.genFleet QC.shrink $ \fleet -> Size.reifyInt width $ \w -> Counter.toInteger (ShortenShip.countBounded (w, height) fleet) * multiplicity fleet == fromIntegral (length $ SetCover.enumerateGen id (width,height) $ Fleet.toList fleet) propDistributionSetCover :: QC.Property propDistributionSetCover = QC.forAll (QC.choose (1,4)) $ \width -> QC.forAll (QC.choose (1,10)) $ \height -> QC.forAllShrink ShortenShip.genFleet QC.shrink $ \fleet -> Size.reifyInt width $ \w -> Size.reifyInt height $ \h -> QCM.monadicIO $ do (_c,cd) <- QCM.run $ Distribution.distributionExternalList w h fleet let boardSize = (width,height) board = SetCover.sumMapsStorable boardSize $ map (fmap (\b -> if b then 1 else 0)) $ SetCover.enumerateGen id boardSize $ Fleet.toList fleet QCM.assert $ map (map (multiplicity fleet *)) cd == SetCover.listsFromBoard id boardSize board propCountEnumerate :: QC.Property propCountEnumerate = QC.forAllShrink (QC.choose (0,4)) QC.shrink $ \width -> QC.forAllShrink (QC.choose (0,10)) QC.shrink $ \height -> QC.forAllShrink ShortenShip.genFleet QC.shrink $ \fleet -> Size.reifyInt width $ \w -> Counter.toInteger (ShortenShip.countBounded (w, height) fleet) == (fromIntegral $ length $ Enumerate.configurations (width, height) $ Enumerate.fleetFromSizes $ Fleet.toSizes fleet) quickCheckNum :: QC.Testable prop => Int -> prop -> IO () quickCheckNum n = QC.quickCheckWith (QC.stdArgs {QC.maxSuccess = n}) main :: IO () main = mapM_ (\(msg,io) -> putStr (msg++": ") >> io) $ ("Counter.add", quickCheck Counter.propAdd) : ("Frontier.dilate", quickCheckNum 1000 Frontier.propDilate) : ("Frontier.reverse4", quickCheck Frontier.propReverse4) : ("Frontier.reverse5", quickCheck Frontier.propReverse5) : ("Frontier.reverse6", quickCheck Frontier.propReverse6) : ("Frontier.reverse7", quickCheck Frontier.propReverse7) : ("Frontier.reverse8", quickCheck Frontier.propReverse8) : ("Frontier.reverse9", quickCheck Frontier.propReverse9) : ("Frontier.reverse10", quickCheck Frontier.propReverse10) : ("Fleet.list", quickCheck Fleet.propList) : ("Fleet.sizes", quickCheck Fleet.propSizes) : ("Fleet.cumulate", quickCheck Fleet.propCumulate) : ("Fleet.subset", quickCheck Fleet.propSubset) : ("Fleet.inc", quickCheck Fleet.propInc) : ("Fleet.dec", quickCheck Fleet.propDec) : ("Fleet.incDec", quickCheck Fleet.propIncDec) : ("CountMap.merge", quickCheck CountMap.propMerge) : ("ShortenShip.countSymmetry", quickCheck ShortenShip.propCountSymmetry) : ("ShortenShip.countTransposed", quickCheck ShortenShip.propCountTransposed) : ("ShortenShip.countTouchingTransposed", quickCheck ShortenShip.propCountTouchingTransposed) : ("ShortenShip.countMoreTouching", quickCheck ShortenShip.propCountMoreTouching) : ("ShortenShip.countBounded", quickCheck ShortenShip.propCountBounded) : ("ShortenShip.countExternal", quickCheck ShortenShip.propCountExternal) : ("ShortenShip.countTouchingExternal", quickCheck ShortenShip.propCountTouchingExternal) : ("countSetCover", quickCheck propCountSetCover) : ("countEnumerate", quickCheck propCountEnumerate) : ("distributionSetCover", quickCheck propDistributionSetCover) : ("Distribution.countExternalTotal", quickCheck Distribution.propCountExternalTotal) : ("Distribution.countExternalSimple", quickCheck Distribution.propCountExternalSimple) : ("Distribution.countExternalSymmetric", quickCheck Distribution.propCountExternalSymmetric) : ("Distribution.countExternalTransposed", quickCheck Distribution.propCountExternalTransposed) : []