Adjust CGI output text
[darcs-mirror-polyfix.git] / nameme-cgi.hs
1 module Main where
2
3 import ParseType (parseType')
4 import SimpleFT  (freeTheorem)
5 import ExFindExtended (getComplete')
6 import Language.Haskell.FreeTheorems.Parser.Haskell98 as FTP
7 import Language.Haskell.FreeTheorems
8         ( runChecks
9         , check
10         , filterSignatures
11         , prettyTheorem
12         , asTheorem
13         , interpret
14         , unfoldLifts
15         , prettyUnfoldedLift
16         , LanguageSubset(BasicSubset)
17         )
18
19 import Network.CGI
20 import Data.ByteString.Lazy.UTF8 (fromString)
21 import Text.XHtml
22 import Control.Monad
23 import System.Random (randomRIO)
24 import Data.Maybe
25 import Text.PrettyPrint.HughesPJ (render)
26
27 main = runCGI (handleErrors cgiMain)
28
29 cgiMain = do
30         setHeader "Content-type" "text/xml; charset=UTF-8"
31         
32         mTypeStr <- getInput "type"
33
34         
35         let content = case mTypeStr of 
36                 Nothing      -> askTypeForm
37                 Just typeStr -> case parseType' typeStr of
38                         Left err  -> typeError typeStr err
39                         Right typ -> generateResult typeStr typ
40         
41         outputFPS $ fromString $ showHtml $
42                header (
43                 thetitle << "Name Me" +++
44                 style ! [ thetype "text/css" ] << cdata cssStyle
45                ) +++
46                body ( form ! [method "POST", action "#"] << (
47                 thediv ! [theclass "top"] << (
48                         thespan ! [theclass "title"] << "Name Me" +++
49                         thespan ! [theclass "subtitle"] << "Counter Examples for Free Theorems"
50                 ) +++
51                 content +++
52                 maindiv ( p << ("© 2008 Daniel Seidel und Joachim Breitner <" +++
53                               hotlink "mailto:mail@joachim-breitner.de" << "mail@joachim-breitner.de" +++
54                               ">")
55                         )       
56                 ))
57
58 maindiv = thediv ! [theclass "main"]
59
60 cdata s = primHtml ("<![CDATA[\n"++ s ++ "\n]]>")
61
62 cssStyle = unlines 
63         [ "body { padding:0px; margin: 0px; }"
64         , "div.top { margin:0px; padding:10px; margin-bottom:20px;"
65         , "              background-color:#efefef;"
66         , "              border-bottom:1px solid black; }"
67         , "span.title { font-size:xx-large; font-weight:bold; }"
68         , "span.subtitle { padding-left:30px; font-size:large; }"
69         , "div.main { border:1px dotted black;"
70         , "                   padding:10px; margin:10px; }"
71         , "div.submain { padding:10px; margin:11px; }"
72         , "p.subtitle { font-size:large; font-weight:bold; }"
73         , "input.type { font-family:monospace; }"
74         , "input[type=\"submit\"] { font-family:monospace; background-color:#efefef; }"
75         , "span.mono { font-family:monospace; }"
76         , "pre { margin:10px; margin-left:20px; padding:10px;"
77         , "          border:1px solid black; }"
78         , "textarea { margin:10px; margin-left:20px; padding:10px;  }"
79         , "p { text-align:justify; }"
80         ]
81
82 askDiv v e =  maindiv << (
83         p << ( "Please enter a function type, prepended with a list of type variables, " +++
84                "whose relations should be allowed to be nonstrict, and a single dot.") +++            p << ( input ! [name "type", value v] +++ " " +++
85                submit "submit" "Generate Free Theorem and counter example" ) +++
86         e
87         )
88
89
90 askTypeForm = askDiv "a. (a -> b) -> b" noHtml
91
92 typeError typeStr err = askDiv typeStr (
93         p << ("There was a problem parsing your type: " +++
94               pre << err )
95         )
96
97 generateResult typeStr typ = askDiv typeStr noHtml +++
98         maindiv << (
99         h3 << "The Free Theorem" +++
100         (case ft_full of
101                 Left err -> p << "The full Free Theorem deriver failed:" +++
102                             pre << err
103                 Right s  -> p << "For your type, the following Free Theorem holds:" +++
104                             pre << s
105         ) +++
106         p << "Specializing relations to functions, canceling irrelvant terms and eta-reduction, this theorem can be written as:" +++
107         pre << show ft_simple
108         ) +++
109         maindiv << (
110         h3 << "The counter-example" +++
111         case counter_example of 
112                 Left err -> p << "No term could be derived: " +++ pre << err
113                 Right (res,used) ->
114                         p << ("By disregarding the strictness conditions for the pointed "+++
115                               "variables(?), the following term is a counter example:" +++
116                               pre << ("f = " ++ res) ) +++
117                         p << ("Wheres the abstraced variables are chosen as follows:" +++
118                               pre << used)
119         )
120   where ft_full = let properType = "f :: " ++ case span (/='.') typeStr of
121                                        (s,"")  -> s
122                                        (_,_:s) -> s
123                       (ds,es) = runChecks (parse properType >>= check)
124                       [s]     = filterSignatures ds
125                   in if null es
126                      then case interpret [] BasicSubset s of
127                         Nothing -> Left "interpret returned nothing"
128                         Just i  -> Right $ render (prettyTheorem [] (asTheorem i)) ++
129                               case unfoldLifts [] i of
130                                 [] -> ""
131                                 ls -> "\n\nWhereas the occuring lifts are defined as:\n\n "++
132                                       unlines (map (render . prettyUnfoldedLift []) ls)
133                      else Left (unlines (map render es))
134                     
135         ft_simple = freeTheorem typ
136         counter_example = getComplete' typ
137