packages feed

battleship-combinatorics-0.0: test/Test.hs

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) :
   []