1339 |
1339 |
1340 local_setup %gray {* |
1340 local_setup %gray {* |
1341 Local_Theory.note ((@{binding "my_thm"}, []), [my_thm]) #> snd *} |
1341 Local_Theory.note ((@{binding "my_thm"}, []), [my_thm]) #> snd *} |
1342 |
1342 |
1343 text {* |
1343 text {* |
1344 The fourth argument of @{ML note in Local_Theory} is the list of theorems we |
1344 The third argument of @{ML note in Local_Theory} is the list of theorems we |
1345 want to store under a name. We can store more than one under a single name. |
1345 want to store under a name. We can store more than one under a single name. |
1346 The first argument @{ML_ind theoremK in Thm} is |
1346 The first argument of @{ML note in Local_Theory} is the name under |
1347 a kind indicator, which classifies the theorem. There are several such kind |
1347 which we store the theorem or theorems. The second argument can contain a |
1348 indicators: for a theorem arising from a definition you should use @{ML_ind |
|
1349 definitionK in Thm}, and for |
|
1350 ``normal'' theorems the kinds @{ML_ind theoremK in Thm} or @{ML_ind lemmaK |
|
1351 in Thm}. The second argument of @{ML note in Local_Theory} is the name under |
|
1352 which we store the theorem or theorems. The third argument can contain a |
|
1353 list of theorem attributes, which we will explain in detail in |
1348 list of theorem attributes, which we will explain in detail in |
1354 Section~\ref{sec:attributes}. Below we just use one such attribute for |
1349 Section~\ref{sec:attributes}. Below we just use one such attribute for |
1355 adding the theorem to the simpset: |
1350 adding the theorem to the simpset: |
1356 *} |
1351 *} |
1357 |
1352 |
1898 as argument and resolve the theorem with this list (one theorem |
1893 as argument and resolve the theorem with this list (one theorem |
1899 after another). The code for this attribute is |
1894 after another). The code for this attribute is |
1900 *} |
1895 *} |
1901 |
1896 |
1902 ML{*fun MY_THEN thms = |
1897 ML{*fun MY_THEN thms = |
1903 Thm.rule_attribute |
1898 let |
1904 (fn _ => fn thm => fold (curry ((op RS) o swap)) thms thm)*} |
1899 fun RS_rev thm1 thm2 = thm2 RS thm1 |
|
1900 in |
|
1901 Thm.rule_attribute (fn _ => fn thm => fold RS_rev thms thm) |
|
1902 end*} |
1905 |
1903 |
1906 text {* |
1904 text {* |
1907 where @{ML swap} swaps the components of a pair. The setup of this theorem |
1905 where for convenience we define the reverse and curried version of @{ML RS}. |
1908 attribute uses the parser @{ML thms in Attrib}, which parses a list of |
1906 The setup of this theorem attribute uses the parser @{ML thms in Attrib}, |
1909 theorems. |
1907 which parses a list of theorems. |
1910 *} |
1908 *} |
1911 |
1909 |
1912 attribute_setup %gray MY_THEN = {* Attrib.thms >> MY_THEN *} |
1910 attribute_setup %gray MY_THEN = {* Attrib.thms >> MY_THEN *} |
1913 "resolving the list of theorems with the theorem" |
1911 "resolving the list of theorems with the theorem" |
1914 |
1912 |
2218 "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 |
2217 "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 |
2219 and 22 |
2218 and 22 |
2220 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 and |
2219 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 and |
2221 28"} |
2220 28"} |
2222 |
2221 |
2223 Next we like to pretty-print a term and its type. For this we use the |
2222 Like @{ML blk in Pretty}, the function @{ML_ind chunks in Pretty} prints out |
2224 function @{text "tell_type"}. |
2223 a list of items, but automatically inserts forced breaks between each item. |
2225 *} |
2224 Compare |
2226 |
2225 |
2227 ML %linenosgray{*fun tell_type ctxt t = |
2226 @{ML_response_fake [display,gray] |
2228 let |
2227 "let |
2229 fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s)) |
2228 val a_and_b = [Pretty.str \"a\", Pretty.str \"b\"] |
2230 val ptrm = Pretty.quote (Syntax.pretty_term ctxt t) |
2229 in |
2231 val pty = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of t)) |
2230 pprint (Pretty.blk (0, a_and_b)); |
2232 in |
2231 pprint (Pretty.chunks a_and_b) |
2233 pprint (Pretty.blk (0, |
2232 end" |
2234 (pstr "The term " @ [ptrm] @ pstr " has type " |
2233 "ab |
2235 @ [pty, Pretty.str "."]))) |
2234 a |
2236 end*} |
2235 b"} |
2237 |
|
2238 text {* |
|
2239 In Line 3 we define a function that inserts possible linebreaks in places |
|
2240 where a space is. In Lines 4 and 5 we pretty-print the term and its type |
|
2241 using the functions @{ML_ind pretty_term in Syntax} and @{ML_ind |
|
2242 pretty_typ in Syntax}. We also use the function @{ML_ind quote in |
|
2243 Pretty} in order to enclose the term and type inside quotation marks. In |
|
2244 Line 9 we add a period right after the type without the possibility of a |
|
2245 line break, because we do not want that a line break occurs there. |
|
2246 Now you can write |
|
2247 |
|
2248 @{ML_response_fake [display,gray] |
|
2249 "tell_type @{context} @{term \"min (Suc 0)\"}" |
|
2250 "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."} |
|
2251 |
|
2252 To see the proper line breaking, you can try out the function on a bigger term |
|
2253 and type. For example: |
|
2254 |
|
2255 @{ML_response_fake [display,gray] |
|
2256 "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}" |
|
2257 "The term \"op = (op = (op = (op = (op = op =))))\" has type |
|
2258 \"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."} |
|
2259 |
2236 |
2260 The function @{ML_ind big_list in Pretty} helps with printing long lists. |
2237 The function @{ML_ind big_list in Pretty} helps with printing long lists. |
2261 It is used for example in the command \isacommand{print\_theorems}. An |
2238 It is used for example in the command \isacommand{print\_theorems}. An |
2262 example is as follows. |
2239 example is as follows. |
2263 |
2240 |
2274 7 |
2251 7 |
2275 8 |
2252 8 |
2276 9 |
2253 9 |
2277 10"} |
2254 10"} |
2278 |
2255 |
2279 Like @{ML blk in Pretty}, the function @{ML_ind chunks in Pretty} prints out |
2256 The point of the pretty-printing functions is to conveninetly obtain |
2280 a list of items, but automatically inserts forced breaks between each item. |
2257 a lay-out of terms and types that is pleasing to the eye. If we print |
2281 Compare |
2258 out the the terms produced by the the function @{ML de_bruijn} from |
2282 |
2259 exercise~\ref{ex:debruijn} we obtain the following: |
2283 @{ML_response_fake [display,gray] |
2260 |
2284 "let |
2261 @{ML_response_fake [display,gray] |
2285 val a_and_b = [Pretty.str \"a\", Pretty.str \"b\"] |
2262 "pprint (Syntax.pretty_term @{context} (de_bruijn 4))" |
2286 in |
2263 "(P 3 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and> |
2287 pprint (Pretty.blk (0, a_and_b)); |
2264 (P 2 = P 3 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and> |
2288 pprint (Pretty.chunks a_and_b) |
2265 (P 1 = P 2 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and> |
2289 end" |
2266 (P 1 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<longrightarrow> |
2290 "ab |
2267 P 4 \<and> P 3 \<and> P 2 \<and> P 1"} |
2291 a |
2268 |
2292 b"} |
2269 We use the function @{ML_ind pretty_term in Syntax} for pretty-printing |
|
2270 terms. Next we like to pretty-print a term and its type. For this we use the |
|
2271 function @{text "tell_type"}. |
|
2272 *} |
|
2273 |
|
2274 ML %linenosgray{*fun tell_type ctxt trm = |
|
2275 let |
|
2276 fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s)) |
|
2277 val ptrm = Pretty.quote (Syntax.pretty_term ctxt trm) |
|
2278 val pty = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of trm)) |
|
2279 in |
|
2280 pprint (Pretty.blk (0, |
|
2281 (pstr "The term " @ [ptrm] @ pstr " has type " |
|
2282 @ [pty, Pretty.str "."]))) |
|
2283 end*} |
|
2284 |
|
2285 text {* |
|
2286 In Line 3 we define a function that inserts possible linebreaks in places |
|
2287 where a space is. In Lines 4 and 5 we pretty-print the term and its type |
|
2288 using the functions @{ML pretty_term in Syntax} and @{ML_ind |
|
2289 pretty_typ in Syntax}. We also use the function @{ML_ind quote in |
|
2290 Pretty} in order to enclose the term and type inside quotation marks. In |
|
2291 Line 9 we add a period right after the type without the possibility of a |
|
2292 line break, because we do not want that a line break occurs there. |
|
2293 Now you can write |
|
2294 |
|
2295 @{ML_response_fake [display,gray] |
|
2296 "tell_type @{context} @{term \"min (Suc 0)\"}" |
|
2297 "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."} |
2293 |
2298 |
2294 \footnote{\bf FIXME: What happens with printing big formulae?} |
2299 To see the proper line breaking, you can try out the function on a bigger term |
2295 |
2300 and type. For example: |
2296 |
2301 |
|
2302 @{ML_response_fake [display,gray] |
|
2303 "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}" |
|
2304 "The term \"op = (op = (op = (op = (op = op =))))\" has type |
|
2305 \"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."} |
2297 |
2306 |
2298 \begin{readmore} |
2307 \begin{readmore} |
2299 The general infrastructure for pretty-printing is implemented in the file |
2308 The general infrastructure for pretty-printing is implemented in the file |
2300 @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"} |
2309 @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"} |
2301 contains pretty-printing functions for terms, types, theorems and so on. |
2310 contains pretty-printing functions for terms, types, theorems and so on. |
2302 |
2311 |
2303 @{ML_file "Pure/General/markup.ML"} |
2312 @{ML_file "Pure/General/markup.ML"} |
2304 \end{readmore} |
2313 \end{readmore} |
2305 *} |
2314 *} |
2306 |
2315 |
2307 (* |
|
2308 text {* |
|
2309 printing into the goal buffer as part of the proof state |
|
2310 *} |
|
2311 |
|
2312 text {* writing into the goal buffer *} |
|
2313 |
|
2314 ML {* fun my_hook interactive state = |
|
2315 (interactive ? Proof.goal_message (fn () => Pretty.str |
|
2316 "foo")) state |
|
2317 *} |
|
2318 |
|
2319 setup %gray {* Context.theory_map (Specification.add_theorem_hook my_hook) *} |
|
2320 |
|
2321 lemma "False" |
|
2322 oops |
|
2323 *) |
|
2324 |
|
2325 (* |
|
2326 ML {* |
|
2327 fun setmp_show_all_types f = |
|
2328 setmp show_all_types |
|
2329 (! show_types orelse ! show_sorts orelse ! show_all_types) f; |
|
2330 |
|
2331 val ctxt = @{context}; |
|
2332 val t1 = @{term "undefined::nat"}; |
|
2333 val t2 = @{term "Suc y"}; |
|
2334 val pty = Pretty.block (Pretty.breaks |
|
2335 [(setmp show_question_marks false o setmp_show_all_types) |
|
2336 (Syntax.pretty_term ctxt) t1, |
|
2337 Pretty.str "=", Syntax.pretty_term ctxt t2]); |
|
2338 pty |> Pretty.string_of |
|
2339 *} |
|
2340 |
|
2341 text {* the infrastructure of Syntax-pretty-term makes sure it is printed nicely *} |
|
2342 |
|
2343 |
|
2344 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of |> tracing *} |
|
2345 ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *} |
|
2346 *) |
|
2347 |
|
2348 section {* Summary *} |
2316 section {* Summary *} |
2349 |
2317 |
2350 text {* |
2318 text {* |
2351 \begin{conventions} |
2319 \begin{conventions} |
2352 \begin{itemize} |
2320 \begin{itemize} |