{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Puzzles.Counts where
import Data.SBV
import Data.List (sortOn)
type Count = SWord8
count :: Count -> [Count] -> [Count]
count :: Count -> [Count] -> [Count]
count Count
n [Count]
cnts = SBool -> [Count] -> [Count] -> [Count]
forall a. Mergeable a => SBool -> a -> a -> a
ite (Count
n Count -> Count -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< Count
10)
(Count -> [Count] -> [Count]
forall c a.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
n [Count]
cnts)
(SBool -> [Count] -> [Count] -> [Count]
forall a. Mergeable a => SBool -> a -> a -> a
ite (Count
n Count -> Count -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< Count
100)
(Count -> [Count] -> [Count]
forall c a.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d1 (Count -> [Count] -> [Count]
forall c a.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d2 [Count]
cnts))
(Count -> [Count] -> [Count]
forall c a.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d1 (Count -> [Count] -> [Count]
forall c a.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d2 (Count -> [Count] -> [Count]
forall c a.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d3 [Count]
cnts))))
where (Count
r1, Count
d1) = Count
n Count -> Count -> (Count, Count)
forall a. SDivisible a => a -> a -> (a, a)
`sQuotRem` Count
10
(Count
d3, Count
d2) = Count
r1 Count -> Count -> (Count, Count)
forall a. SDivisible a => a -> a -> (a, a)
`sQuotRem` Count
10
upd :: a -> [c] -> [c]
upd a
d = (a -> c -> c) -> [a] -> [c] -> [c]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> c -> c
forall a. (Mergeable a, Num a) => a -> a -> a
inc [a
0..]
where inc :: a -> a -> a
inc a
i a
c = SBool -> a -> a -> a
forall a. Mergeable a => SBool -> a -> a -> a
ite (a
i a -> a -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== a
d) (a
ca -> a -> a
forall a. Num a => a -> a -> a
+a
1) a
c
puzzle :: [Count] -> SBool
puzzle :: [Count] -> SBool
puzzle [Count]
cnt = [Count]
cnt [Count] -> [Count] -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== [[Count]] -> [Count]
forall a. [a] -> a
last [[Count]]
css
where ones :: [Count]
ones = Int -> Count -> [Count]
forall a. Int -> a -> [a]
replicate Int
10 Count
1
css :: [[Count]]
css = [Count]
ones [Count] -> [[Count]] -> [[Count]]
forall a. a -> [a] -> [a]
: (Count -> [Count] -> [Count]) -> [Count] -> [[Count]] -> [[Count]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Count -> [Count] -> [Count]
count [Count]
cnt [[Count]]
css
counts :: IO ()
counts :: IO ()
counts = do AllSatResult
res <- SymbolicT IO SBool -> IO AllSatResult
forall a. Provable a => a -> IO AllSatResult
allSat (SymbolicT IO SBool -> IO AllSatResult)
-> SymbolicT IO SBool -> IO AllSatResult
forall a b. (a -> b) -> a -> b
$ [Count] -> SBool
puzzle ([Count] -> SBool) -> SymbolicT IO [Count] -> SymbolicT IO SBool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Int -> SymbolicT IO [Count]
forall a. SymVal a => Int -> Symbolic [SBV a]
mkExistVars Int
10
Int
cnt <- ([(Bool, [Word8])] -> [(Bool, [Word8])])
-> (Int -> (Bool, [Word8]) -> IO ()) -> AllSatResult -> IO Int
forall a.
SatModel a =>
([(Bool, a)] -> [(Bool, a)])
-> (Int -> (Bool, a) -> IO ()) -> AllSatResult -> IO Int
displayModels (((Bool, [Word8]) -> String)
-> [(Bool, [Word8])] -> [(Bool, [Word8])]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (Bool, [Word8]) -> String
forall a. Show a => a -> String
show) Int -> (Bool, [Word8]) -> IO ()
forall a a. Show a => a -> (a, [Word8]) -> IO ()
disp AllSatResult
res
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Found: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
cnt String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" solution(s)."
where disp :: a -> (a, [Word8]) -> IO ()
disp a
n (a
_, [Word8]
s) = do String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Solution #" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
n
[Word8] -> IO ()
dispSolution [Word8]
s
dispSolution :: [Word8] -> IO ()
dispSolution :: [Word8] -> IO ()
dispSolution [Word8]
ns = String -> IO ()
putStrLn String
soln
where soln :: String
soln = String
"In this sentence, the number of occurrences"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" of 0 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
0)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 1 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
1)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 2 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
2)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 3 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
3)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 4 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
4)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 5 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
5)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 6 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
6)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 7 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
7)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 8 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
8)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", of 9 is " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show ([Word8]
ns [Word8] -> Int -> Word8
forall a. [a] -> Int -> a
!! Int
9)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
{-# ANN counts ("HLint: ignore Use head" :: String) #-}