Mercurial > 12ws.info2
diff exercises/src/Exercise_8_Form.hs @ 18:a899535b1674
week 8
author | Markus Kaiser <markus.kaiser@in.tum.de> |
---|---|
date | Fri, 07 Dec 2012 01:26:31 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exercises/src/Exercise_8_Form.hs Fri Dec 07 01:26:31 2012 +0100 @@ -0,0 +1,114 @@ +module Form where + +import Data.List (nub) +import Control.Monad +import Test.QuickCheck + +type Name = String +data Form = F | T | Var Name | Not Form | Form :&: Form | Form :|: Form + deriving Eq + +instance Show Form where + show F = "F" + show T = "T" + show (Var x) = x + show (Not p) = par("~" ++ show p) + show (p :&: q) = par(show p ++ " & " ++ show q) + show (p :|: q) = par(show p ++ " | " ++ show q) + {- TODO -} + +par :: String -> String +par s = "(" ++ s ++ ")" + +-- Wertebelegung +type Valuation = [(Name,Bool)] + +eval :: Valuation -> Form -> Bool +eval e F = False +eval e T = True +eval e (Var x) = the(lookup x e) where the(Just b) = b +eval e (Not p) = not(eval e p) +eval e (p :&: q) = eval e p && eval e q +eval e (p :|: q) = eval e p || eval e q +{- TODO -} + +vars :: Form -> [Name] +vars F = [] +vars T = [] +vars (Var x) = [x] +vars (Not p) = vars p +vars (p :&: q) = nub (vars p ++ vars q) +vars (p :|: q) = nub (vars p ++ vars q) +{- TODO -} + +vals :: [Name] -> [Valuation] +vals [] = [[]] +vals (x:xs) = [ (x,False):e | e <- vals xs ] ++ [ (x,True ):e | e <- vals xs ] + +satisfiable :: Form -> Bool +satisfiable p = or [eval e p | e <- vals(vars p)] + +tautology :: Form -> Bool +tautology = not . satisfiable . Not + +prop_vals1 xs = + length(vals xs) == 2 ^ length xs + +prop_vals2 xs = + distinct (vals xs) + +distinct :: Eq a => [a] -> Bool +distinct [] = True +distinct (x:xs) = not(elem x xs) && distinct xs + +prop_vals1' xs = + length xs <= 10 ==> + length(vals xs) == 2 ^ length xs + +prop_vals2' xs = + length xs <= 10 ==> distinct (vals xs) + +isSimple :: Form -> Bool +isSimple (Not p) = not (isOp p) + where + isOp (Not p) = True + isOp (p :&: q) = True + isOp (p :|: q) = True + isOp p = False +isSimple (p :&: q) = isSimple p && isSimple q +isSimple (p :|: q) = isSimple p && isSimple q +isSimple p = True +{- TODO -} + +simplify :: Form -> Form +simplify (Not p) = pushNot (simplify p) + where + pushNot (Not p) = p + pushNot (p :&: q) = pushNot p :|: pushNot q + pushNot (p :|: q) = pushNot p :&: pushNot q + pushNot p = Not p +simplify (p :&: q) = simplify p :&: simplify q +simplify (p :|: q) = simplify p :|: simplify q +simplify p = p +{- TODO -} + +-- allow QuickCheck to generate arbitrary values of type Form +instance Arbitrary Form where + arbitrary = sized prop + where + name = sized $ \size -> elements (map (:[]) $ take (size + 1) ['a'..'z']) + prop 0 = + oneof [return F, + return T, + liftM Var name] + prop n | n > 0 = + oneof [return F, + return T, + liftM Var name, + liftM Not (prop (n-1)), + liftM2 (:&:) (prop(n `div` 2)) (prop(n `div` 2)), + liftM2 (:|:) (prop(n `div` 2)) (prop(n `div` 2))] +{- TODO -} + +prop_simplify p = isSimple(simplify p) +{- TODO -}