-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Exercise 1
Nice solution with uncurry.
Exercise 2
parserTest :: Int -> Int -> IO ()
parserTest testsExecuted totalTests = if testsExecuted == totalTests then putStrLn ("\x1b[32m" ++ show totalTests ++ " tests passed\x1b[0m")
else generateActualForm >>= \x -> let resultingForm = parse (show x) in if length resultingForm == 1 && equiv x (head resultingForm) then
do putStrLn ("pass on: " ++ show x)
parserTest (testsExecuted+1) totalTests
else error ("failed test on: " ++ show x)
equiv is not sufficient. Required is: That the forms have the same shape. So
parserTest :: Int -> Int -> IO ()
parserTest testsExecuted totalTests = if testsExecuted == totalTests then putStrLn ("\x1b[32m" ++ show totalTests ++ " tests passed\x1b[0m")
else generateActualForm >>= \x -> let resultingForm = parse (show x) in if length resultingForm == 1 && x == (head resultingForm) then
do putStrLn ("pass on: " ++ show x)
parserTest (testsExecuted+1) totalTests
else error ("failed test on: " ++ show x)
Exercise 3
The following rule is too complicated. I don't recognize the rule -- p ∨ (q ∧ r) == (p ∨ q) ∧ (p ∨ r) in the following fragment
applyDistributiveLaw (Dsj formList) = Dsj (foldr (\x acc -> let y = applyDistributiveLaw x in
if not (null acc) && (isConjunction x || isConjunction (head acc)) then let cnjOne = head acc
cnjTwo = y
conj = Cnj (if isDisjunction cnjOne then map (\ x -> Dsj (x : getAsList cnjOne)) (getAsList cnjTwo)
else if isDisjunction cnjTwo then map (\ x -> Dsj (x : getAsList cnjTwo)) (getAsList cnjOne)
else [Dsj [x,y] | x <- getAsList cnjOne, y <- getAsList cnjTwo]) in conj: tail acc
else if isDisjunction y then getAsList y++acc
else y:acc) [] formList)
Simpler solution:
cnf :: Form -> Form
cnf x = cnf' $ nnf $ arrowfree x
-- preconditions: input is arrowfree and in nnf
cnf' :: Form -> Form
cnf' (Prop x) = Prop x
cnf' (Neg (Prop x)) = Neg (Prop x)
cnf' (Cnj fs) = Cnj (map cnf' fs)
cnf' (Dsj []) = Dsj []
cnf' (Dsj [f]) = cnf' f
cnf' (Dsj (f1:f2:fs)) = dist (cnf' f1) (cnf' (Dsj(f2:fs)))
dist :: Form -> Form -> Form
dist (Cnj []) f = Cnj[] {-- f --}
dist (Cnj [f1]) f2 = dist f1 f2
dist (Cnj (f1:fs)) f2 = Cnj [dist f1 f2, dist (Cnj fs) f2]
dist f (Cnj []) = Cnj[] {-- f --}
dist f1 (Cnj [f2]) = dist f1 f2
dist f1 (Cnj (f2:fs)) = Cnj [dist f1 f2, dist f1 (Cnj fs)]
dist f1 f2 = Dsj [f1,f2]
Exercise 4
-- This method generates an infinite list of random floating-point numbers between 0 and 1. These numbers are generated in advance, so I can unwrap the monad
-- they're in and don't have to further bother any IO monads till the algorithm is over. The `curRand` field of the `TreeState` datatype holds the current
-- index that will be fetched from this list.
randomNumberStream :: IO [Float]
randomNumberStream = do
g <- newStdGen
return $ randomRs (0.00,1.00) g
Why not
randomNumberStream ::Int-> IO [Int]
randomNumberStream n = do
g <- newStdGen
return $ randomRs (0,n) g
? Floats occur nowhere.
Metadata
Metadata
Assignees
Labels
No labels