annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
1 module Form where
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
2
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
3 import Data.List (nub)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
4 import Control.Monad
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
5 import Test.QuickCheck
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
6
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
7 type Name = String
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
8 data Form = F | T | Var Name | Not Form | Form :&: Form | Form :|: Form
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
9 deriving Eq
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
10
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
11 instance Show Form where
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
12 show F = "F"
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
13 show T = "T"
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
14 show (Var x) = x
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
15 show (Not p) = par("~" ++ show p)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
16 show (p :&: q) = par(show p ++ " & " ++ show q)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
17 show (p :|: q) = par(show p ++ " | " ++ show q)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
18 {- TODO -}
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
19
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
20 par :: String -> String
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
21 par s = "(" ++ s ++ ")"
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
22
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
23 -- Wertebelegung
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
24 type Valuation = [(Name,Bool)]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
25
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
26 eval :: Valuation -> Form -> Bool
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
27 eval e F = False
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
28 eval e T = True
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
29 eval e (Var x) = the(lookup x e) where the(Just b) = b
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
30 eval e (Not p) = not(eval e p)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
31 eval e (p :&: q) = eval e p && eval e q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
32 eval e (p :|: q) = eval e p || eval e q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
33 {- TODO -}
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
34
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
35 vars :: Form -> [Name]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
36 vars F = []
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
37 vars T = []
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
38 vars (Var x) = [x]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
39 vars (Not p) = vars p
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
40 vars (p :&: q) = nub (vars p ++ vars q)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
41 vars (p :|: q) = nub (vars p ++ vars q)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
42 {- TODO -}
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
43
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
44 vals :: [Name] -> [Valuation]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
45 vals [] = [[]]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
46 vals (x:xs) = [ (x,False):e | e <- vals xs ] ++ [ (x,True ):e | e <- vals xs ]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
47
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
48 satisfiable :: Form -> Bool
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
49 satisfiable p = or [eval e p | e <- vals(vars p)]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
50
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
51 tautology :: Form -> Bool
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
52 tautology = not . satisfiable . Not
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
53
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
54 prop_vals1 xs =
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
55 length(vals xs) == 2 ^ length xs
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
56
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
57 prop_vals2 xs =
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
58 distinct (vals xs)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
59
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
60 distinct :: Eq a => [a] -> Bool
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
61 distinct [] = True
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
62 distinct (x:xs) = not(elem x xs) && distinct xs
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
63
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
64 prop_vals1' xs =
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
65 length xs <= 10 ==>
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
66 length(vals xs) == 2 ^ length xs
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
67
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
68 prop_vals2' xs =
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
69 length xs <= 10 ==> distinct (vals xs)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
70
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
71 isSimple :: Form -> Bool
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
72 isSimple (Not p) = not (isOp p)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
73 where
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
74 isOp (Not p) = True
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
75 isOp (p :&: q) = True
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
76 isOp (p :|: q) = True
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
77 isOp p = False
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
78 isSimple (p :&: q) = isSimple p && isSimple q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
79 isSimple (p :|: q) = isSimple p && isSimple q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
80 isSimple p = True
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
81 {- TODO -}
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
82
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
83 simplify :: Form -> Form
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
84 simplify (Not p) = pushNot (simplify p)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
85 where
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
86 pushNot (Not p) = p
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
87 pushNot (p :&: q) = pushNot p :|: pushNot q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
88 pushNot (p :|: q) = pushNot p :&: pushNot q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
89 pushNot p = Not p
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
90 simplify (p :&: q) = simplify p :&: simplify q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
91 simplify (p :|: q) = simplify p :|: simplify q
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
92 simplify p = p
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
93 {- TODO -}
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
94
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
95 -- allow QuickCheck to generate arbitrary values of type Form
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
96 instance Arbitrary Form where
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
97 arbitrary = sized prop
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
98 where
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
99 name = sized $ \size -> elements (map (:[]) $ take (size + 1) ['a'..'z'])
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
100 prop 0 =
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
101 oneof [return F,
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
102 return T,
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
103 liftM Var name]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
104 prop n | n > 0 =
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
105 oneof [return F,
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
106 return T,
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
107 liftM Var name,
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
108 liftM Not (prop (n-1)),
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
109 liftM2 (:&:) (prop(n `div` 2)) (prop(n `div` 2)),
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
110 liftM2 (:|:) (prop(n `div` 2)) (prop(n `div` 2))]
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
111 {- TODO -}
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
112
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
113 prop_simplify p = isSimple(simplify p)
Markus Kaiser <markus.kaiser@in.tum.de>
parents:
diff changeset
114 {- TODO -}