3 import ParseType (parseType')
4 import SimpleFT (freeTheorem)
5 import Expr (specialize)
6 import ExFindExtended (getComplete')
7 import Language.Haskell.FreeTheorems.Parser.Haskell98 as FTP
8 import Language.Haskell.FreeTheorems
17 , LanguageSubset(BasicSubset)
21 import Data.ByteString.Lazy.UTF8 (fromString)
25 import Text.PrettyPrint.HughesPJ (render)
27 askDiv v e = maindiv << (
28 p << ( "Please enter a function type, prepended with a list of type variables, " +++
29 "whose relations should be allowed to be nonstrict, and a single dot.") +++ p << ( input ! [name "type", value v] +++ " " +++
30 submit "submit" "Generate Free Theorem and counter example" ) +++
35 askTypeForm = askDiv "a. (a -> b) -> b" noHtml
37 typeError typeStr err = askDiv typeStr (
38 p << ("There was a problem parsing your type: " +++
42 generateResult typeStr typ = askDiv typeStr noHtml +++
44 h3 << "The Free Theorem" +++
46 Left err -> p << "The full Free Theorem deriver failed:" +++
48 Right s -> p << "For your type, the following Free Theorem holds:" +++
51 p << "Specializing relations to functions, canceling irrelvant terms and eta-reduction, this theorem can be written as:" +++
52 pre << show ft_simple +++
53 p << "Further specializing all types to (), all strict functions to id and all non-strict functions to const (), this theorem can be written as:" +++
54 pre << show (specialize ft_simple)
57 h3 << "The counter-example" +++
58 case counter_example of
59 Left err -> p << "No term could be derived: " +++ pre << err
61 p << ("By disregarding the strictness conditions for the chosen "+++
62 "relations, the following term is a counter example:" +++
63 pre << ("f = " ++ res) ) +++
64 p << ("Whereas the abstraced variables are chosen as follows:" +++
67 maindiv ( p << ("In the simplified theorems, the following custom haskell " +++
68 "functions might appear:") +++
71 where ft_full = let properType = "f :: " ++ case span (/='.') typeStr of
74 (ds,es) = runChecks (parse properType >>= check)
75 [s] = filterSignatures ds
77 then case interpret [] BasicSubset s of
78 Nothing -> Left "interpret returned nothing"
79 Just i -> Right $ render (prettyTheorem [] (asTheorem i)) ++
80 case unfoldLifts [] i of
82 ls -> "\n\nWhereas the occuring lifts are defined as:\n\n "++
83 unlines (map (render . prettyUnfoldedLift []) ls)
84 else Left (unlines (map render es))
86 ft_simple = freeTheorem typ
87 counter_example = getComplete' typ
89 main = runCGI (handleErrors cgiMain)
92 setHeader "Content-type" "text/xml; charset=UTF-8"
94 mTypeStr <- getInput "type"
97 let content = case mTypeStr of
98 Nothing -> askTypeForm
99 Just typeStr -> case parseType' typeStr of
100 Left err -> typeError typeStr err
101 Right typ -> generateResult typeStr typ
103 outputFPS $ fromString $ showHtml $
105 thetitle << "PolyFix" +++
106 style ! [ thetype "text/css" ] << cdata cssStyle
108 body ( form ! [method "POST", action "#"] << (
109 thediv ! [theclass "top"] << (
110 thespan ! [theclass "title"] << "PolyFix" +++
111 thespan ! [theclass "subtitle"] << "Counter Examples for Free Theorems"
114 maindiv ( p << ("© 2008 Daniel Seidel und Joachim Breitner <" +++
115 hotlink "mailto:mail@joachim-breitner.de" << "mail@joachim-breitner.de" +++
120 maindiv = thediv ! [theclass "main"]
122 cdata s = primHtml ("<![CDATA[\n"++ s ++ "\n]]>")
125 [ "body { padding:0px; margin: 0px; }"
126 , "div.top { margin:0px; padding:10px; margin-bottom:20px;"
127 , " background-color:#efefef;"
128 , " border-bottom:1px solid black; }"
129 , "span.title { font-size:xx-large; font-weight:bold; }"
130 , "span.subtitle { padding-left:30px; font-size:large; }"
131 , "div.main { border:1px dotted black;"
132 , " padding:10px; margin:10px; }"
133 , "div.submain { padding:10px; margin:11px; }"
134 , "p.subtitle { font-size:large; font-weight:bold; }"
135 , "input.type { font-family:monospace; }"
136 , "input[type=\"submit\"] { font-family:monospace; background-color:#efefef; }"
137 , "span.mono { font-family:monospace; }"
138 , "pre { margin:10px; margin-left:20px; padding:10px;"
139 , " border:1px solid black; }"
140 , "textarea { margin:10px; margin-left:20px; padding:10px; }"
141 , "p { text-align:justify; }"
145 [ "allZipWith :: (a -> b -> Bool) -> [a] -> [b] -> Bool"
146 , "allZipWith p [] [] = True"
147 , "allZipWith p [] _ = False"
148 , "allZipWith p _ [] = False"
149 , "allZipWith p (x:xs) (y:ys) = p x y && allZipWith p xs ys"
151 , "eitherMap :: (a -> b) -> (c -> d) -> Either a c -> Either b d"
152 , "eitherMap f1 f2 (Left v) = Left (f1 v)"
153 , "eitherMap f1 f2 (Right v) = Right (f2 v)"
155 , "andEither :: (a -> b -> Bool) -> (c -> d -> Bool) -> Either a c -> Bool"
156 , "andEither p1 p2 (Left v1) (Left v2) = p1 v1 v2"
157 , "andEither p1 p2 (Right v1) (Right v2) = p2 v1 v2"
158 , "andEither _ _ _ _ = False"