renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
eliminated slightly odd alias structure T;
1 (* Title: Tools/WWW_Find/find_theorems.ML
2 Author: Timothy Bourke, NICTA
4 Simple find_theorems server.
8 val default_limit = 20;
9 val thy_names = sort string_ord (ThyInfo.get_names ());
11 val find_theorems_url = "find_theorems";
15 |> Proofterm.approximate_proof_body
16 |> Proofterm.all_oracles_of
17 |> exists (fn (x, _) => x = "Pure.skip_proof");
20 fun find_theorems_form thy_name (query, limit, withdups) =
25 itype = TextInput { value = query, maxlength = NONE }});
27 val max_results = divele noid
29 label (noid, { for = "limit" }, "Max. results:"),
32 itype = TextInput { value = SOME (Int.toString limit),
36 val theories = divele noid
38 label (noid, { for = "theory" }, "Search in:"),
39 select (id "theory", { name = "theory", value = SOME thy_name })
43 val with_dups = divele noid
45 label (noid, { for = "withdups" }, "Allow duplicates:"),
48 itype = Checkbox { checked = withdups, value = SOME "true" }})
51 val help = divele (class "help")
52 [ a { href="/pasting_help.html", text="(pasting from proof general)" } ];
54 form (id "findtheorems", { method = "post", action = "/isabelle/find_theorems" })
56 [tag "legend" [] [text "find_theorems"],
57 (add_script (OnKeyPress, "encodequery(this)")
58 o add_script (OnChange, "encodequery(this)")
59 o add_script (OnMouseUp, "encodequery(this)")) query_input,
60 divele (class "settings") [ max_results, theories, with_dups, help ],
61 divele (class "mainbuttons")
62 [ reset_button (id "reset"), submit_button (id "submit") ]
67 fun html_header thy_name args =
68 html { lang = "en" } [
69 head { title = "Find Theorems: results", stylesheet_href = "/basic.css" }
70 [script (noid, { script_type="text/javascript",
71 src="/find_theorems.js" })],
72 add_script (OnLoad, "encodequery(document.getElementById('query'))")
74 h (noid, 1, "Theory " ^ thy_name),
75 find_theorems_form thy_name args,
80 fun html_error msg = p ((class "error"), msg);
82 val find_theorems_table =
83 table (class "findtheorems")
85 thead noid [tr [th (noid, "name"), th (noid, "theorem")]],
89 fun show_criterion (b, c) =
92 val (c, v) = if b then ("criterion", s) else ("ncriterion", "-" ^ s);
93 in span (class c, v) end;
98 then ("criterion", "with " ^ s)
99 else ("ncriterion", "without " ^ s);
100 in span (class c, v) end;
103 Find_Theorems.Name name => prfx ("name: " ^ quote name)
104 | Find_Theorems.Intro => prfx "intro"
105 | Find_Theorems.IntroIff => prfx "introiff"
106 | Find_Theorems.Elim => prfx "elim"
107 | Find_Theorems.Dest => prfx "dest"
108 | Find_Theorems.Solves => prfx "solves"
109 | Find_Theorems.Simp pat => prfx ("simp: \"" ^ pat ^ "\"")
110 | Find_Theorems.Pattern pat => prfx ("\"" ^ pat ^ "\""))
113 fun find_theorems_summary (othmslen, thmslen, query, args) =
118 | SOME l => Symtab.update ("limit", Int.toString l) args)
119 val qargs = HttpUtil.make_query_string args;
123 NONE => text (Int.toString thmslen)
125 a { href = find_theorems_url ^
126 (if qargs = "" then "" else "?" ^ qargs),
127 text = Int.toString l })
128 val found = [text "found ", num_found_text, text " theorems"] : tag list;
131 then " (" ^ Int.toString thmslen ^ " displayed)"
133 fun show_search c = tr [ td' noid [show_criterion c] ];
135 table (class "findtheoremsquery")
136 (* [ tr [ th (noid, "searched for:") ] ]
137 @ map show_search query @ *)
138 [ tr [ th' noid (found @ [text (displayed ^ ":")]) ] ]
141 fun sorry_class thm = if is_sorry thm then class "sorried" else noid;
143 fun html_thm ctxt (n, (thmref, thm)) =
146 Output.output o Pretty.string_of_margin 100 o
147 setmp_CRITICAL show_question_marks false (Display.pretty_thm ctxt);
149 tag' "tr" (class ("row" ^ Int.toString (n mod 2)))
151 tag' "td" (class "name")
152 [span' (sorry_class thm)
153 [raw_text (Facts.string_of_ref thmref)]
155 tag' "td" (class "thm") [pre noid (string_of_thm thm)]
161 structure P = OuterParse
163 and FT = Find_Theorems;
166 P.reserved "name" |-- P.!!! (P.$$$ ":" |-- P.xname) >> Find_Theorems.Name ||
167 P.reserved "intro" >> K Find_Theorems.Intro ||
168 P.reserved "elim" >> K Find_Theorems.Elim ||
169 P.reserved "dest" >> K Find_Theorems.Dest ||
170 P.reserved "solves" >> K Find_Theorems.Solves ||
171 P.reserved "simp" |-- P.!!! (P.$$$ ":" |-- P.term) >> Find_Theorems.Simp ||
172 P.term >> Find_Theorems.Pattern;
175 Scan.repeat (((Scan.option P.minus >> is_none) -- criterion));
177 fun app_index f xs = fold_index (fn x => K (f x)) xs ();
179 fun find_theorems (req as ScgiReq.Req {request_method, query_string, ...},
183 (case request_method of
184 ScgiReq.Get => query_string
187 |> Byte.bytesToString
188 |> HttpUtil.parse_query_string
189 | ScgiReq.Head => raise Fail "Cannot handle Head requests.");
191 val args = Symtab.lookup arg_data;
193 val query = the_default "" (args "query");
197 |> OuterSyntax.scan Position.start
198 |> filter Token.is_proper
199 |> Scan.error parse_query
204 |> Option.mapPartial Int.fromString
205 |> the_default default_limit;
208 |> the_default "Main";
209 val with_dups = is_some (args "with_dups");
213 val ctxt = ProofContext.init_global (theory thy_name);
214 val query = get_query ();
215 val (othmslen, thms) = apsnd rev
216 (Find_Theorems.find_theorems ctxt NONE (SOME limit) with_dups query);
217 val thmslen = length thms;
218 fun thm_row args = Xhtml.write send (html_thm ctxt args);
221 (find_theorems_summary (othmslen, thmslen, query, arg_data));
223 else (Xhtml.write_open send find_theorems_table;
224 HTML_Unicode.print_mode (app_index thm_row) thms;
225 Xhtml.write_close send find_theorems_table)
228 val header = (html_header thy_name (args "query", limit, with_dups));
230 send Xhtml.doctype_xhtml1_0_strict;
231 Xhtml.write_open send header;
232 if query = "" then ()
236 ERROR msg => Xhtml.write send (html_error msg)
237 | e => Xhtml.write send (html_error ("Server error: " ^ exnMessage e));
238 Xhtml.write_close send header
241 val () = show_question_marks := false;
242 val () = ScgiServer.register (find_theorems_url, SOME Mime.html, find_theorems);