130 section {* Printing and Debugging\label{sec:printing} *} |
130 section {* Printing and Debugging\label{sec:printing} *} |
131 |
131 |
132 text {* |
132 text {* |
133 During development you might find it necessary to inspect some data in your |
133 During development you might find it necessary to inspect some data in your |
134 code. This can be done in a ``quick-and-dirty'' fashion using the function |
134 code. This can be done in a ``quick-and-dirty'' fashion using the function |
135 @{ML_ind "writeln"}. For example |
135 @{ML_ind writeln in Output}. For example |
136 |
136 |
137 @{ML_response_eq [display,gray] "writeln \"any string\"" "\"any string\"" with "(op =)"} |
137 @{ML_response_eq [display,gray] "writeln \"any string\"" "\"any string\"" with "(op =)"} |
138 |
138 |
139 will print out @{text [quotes] "any string"} inside the response buffer of |
139 will print out @{text [quotes] "any string"} inside the response buffer of |
140 Isabelle. This function expects a string as argument. If you develop under |
140 Isabelle. This function expects a string as argument. If you develop under |
141 PolyML, then there is a convenient, though again ``quick-and-dirty'', method |
141 PolyML, then there is a convenient, though again ``quick-and-dirty'', method |
142 for converting values into strings, namely the function |
142 for converting values into strings, namely the function |
143 @{ML_ind makestring in PolyML}: |
143 @{ML_ind makestring in PolyML}: |
144 |
144 |
145 @{ML_response_eq [display,gray] "writeln (PolyML.makestring 1)" "\"1\"" with "(op =)"} |
145 @{ML_response_eq [display,gray] "writeln (PolyML.makestring 1)" "\"1\"" with "(op =)"} |
146 |
146 |
147 However, @{ML makestring in PolyML} only works if the type of what |
147 However, @{ML makestring in PolyML} only works if the type of what |
148 is converted is monomorphic and not a function. |
148 is converted is monomorphic and not a function. |
149 |
149 |
150 The function @{ML "writeln"} should only be used for testing purposes, |
150 The function @{ML "writeln"} should only be used for testing purposes, |
151 because any output this function generates will be overwritten as soon as an |
151 because any output this function generates will be overwritten as soon as an |
152 error is raised. For printing anything more serious and elaborate, the |
152 error is raised. For printing anything more serious and elaborate, the |
153 function @{ML_ind tracing} is more appropriate. This function writes all |
153 function @{ML_ind tracing in Output} is more appropriate. This function writes all |
154 output into a separate tracing buffer. For example: |
154 output into a separate tracing buffer. For example: |
155 |
155 |
156 @{ML_response_eq [display,gray] "tracing \"foo\"" "\"foo\"" with "(op =)"} |
156 @{ML_response_eq [display,gray] "tracing \"foo\"" "\"foo\"" with "(op =)"} |
157 |
157 |
158 It is also possible to redirect the ``channel'' where the string @{text |
158 It is also possible to redirect the ``channel'' where the string @{text |
181 |
181 |
182 @{ML [display,gray] "redirect_tracing (TextIO.openOut \"foo.bar\")"} |
182 @{ML [display,gray] "redirect_tracing (TextIO.openOut \"foo.bar\")"} |
183 |
183 |
184 will cause that all tracing information is printed into the file @{text "foo.bar"}. |
184 will cause that all tracing information is printed into the file @{text "foo.bar"}. |
185 |
185 |
186 You can print out error messages with the function @{ML_ind error}; for |
186 You can print out error messages with the function @{ML_ind error in Library}; for |
187 example: |
187 example: |
188 |
188 |
189 @{ML_response_fake [display,gray] |
189 @{ML_response_fake [display,gray] |
190 "if 0=1 then true else (error \"foo\")" |
190 "if 0=1 then true else (error \"foo\")" |
191 "Exception- ERROR \"foo\" raised |
191 "Exception- ERROR \"foo\" raised |
232 "string_of_term @{context} @{term \"1::nat\"}" |
232 "string_of_term @{context} @{term \"1::nat\"}" |
233 "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""} |
233 "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""} |
234 |
234 |
235 We obtain a string corrsponding to the term @{term [show_types] "1::nat"} with some |
235 We obtain a string corrsponding to the term @{term [show_types] "1::nat"} with some |
236 additional information encoded in it. The string can be properly printed by |
236 additional information encoded in it. The string can be properly printed by |
237 using either the function @{ML_ind writeln} or @{ML_ind tracing}: |
237 using either the function @{ML writeln} or @{ML tracing}: |
238 |
238 |
239 @{ML_response_fake [display,gray] |
239 @{ML_response_fake [display,gray] |
240 "writeln (string_of_term @{context} @{term \"1::nat\"})" |
240 "writeln (string_of_term @{context} @{term \"1::nat\"})" |
241 "\"1\""} |
241 "\"1\""} |
242 |
242 |
245 @{ML_response_fake [display,gray] |
245 @{ML_response_fake [display,gray] |
246 "tracing (string_of_term @{context} @{term \"1::nat\"})" |
246 "tracing (string_of_term @{context} @{term \"1::nat\"})" |
247 "\"1\""} |
247 "\"1\""} |
248 |
248 |
249 If there are more than one term to be printed, you can use the |
249 If there are more than one term to be printed, you can use the |
250 function @{ML_ind commas} to separate them. |
250 function @{ML_ind commas in Library} to separate them. |
251 *} |
251 *} |
252 |
252 |
253 ML{*fun string_of_terms ctxt ts = |
253 ML{*fun string_of_terms ctxt ts = |
254 commas (map (string_of_term ctxt) ts)*} |
254 commas (map (string_of_term ctxt) ts)*} |
255 |
255 |
259 |
259 |
260 ML{*fun string_of_cterm ctxt ct = |
260 ML{*fun string_of_cterm ctxt ct = |
261 string_of_term ctxt (term_of ct)*} |
261 string_of_term ctxt (term_of ct)*} |
262 |
262 |
263 text {* |
263 text {* |
264 In this example the function @{ML_ind term_of} extracts the @{ML_type |
264 In this example the function @{ML_ind term_of in Thm} extracts the @{ML_type |
265 term} from a @{ML_type cterm}. More than one @{ML_type cterm}s can again be |
265 term} from a @{ML_type cterm}. More than one @{ML_type cterm}s can again be |
266 printed with @{ML_ind commas}. |
266 printed with @{ML commas}. |
267 *} |
267 *} |
268 |
268 |
269 ML{*fun string_of_cterms ctxt cts = |
269 ML{*fun string_of_cterms ctxt cts = |
270 commas (map (string_of_cterm ctxt) cts)*} |
270 commas (map (string_of_cterm ctxt) cts)*} |
271 |
271 |
272 text {* |
272 text {* |
273 The easiest way to get the string of a theorem is to transform it |
273 The easiest way to get the string of a theorem is to transform it |
274 into a @{ML_type term} using the function @{ML_ind prop_of}. |
274 into a @{ML_type term} using the function @{ML_ind prop_of in Thm}. |
275 *} |
275 *} |
276 |
276 |
277 ML{*fun string_of_thm ctxt thm = |
277 ML{*fun string_of_thm ctxt thm = |
278 string_of_term ctxt (prop_of thm)*} |
278 string_of_term ctxt (prop_of thm)*} |
279 |
279 |
338 "tracing (\"First half,\" ^ \"\\n\" ^ \"and second half.\")" |
338 "tracing (\"First half,\" ^ \"\\n\" ^ \"and second half.\")" |
339 "First half, |
339 "First half, |
340 and second half."} |
340 and second half."} |
341 |
341 |
342 To ease this kind of string manipulations, there are a number |
342 To ease this kind of string manipulations, there are a number |
343 of library functions. For example, the function @{ML_ind cat_lines} |
343 of library functions. For example, the function @{ML_ind cat_lines in Library} |
344 concatenates a list of strings and inserts newlines. |
344 concatenates a list of strings and inserts newlines. |
345 |
345 |
346 @{ML_response [display, gray] |
346 @{ML_response [display, gray] |
347 "cat_lines [\"foo\", \"bar\"]" |
347 "cat_lines [\"foo\", \"bar\"]" |
348 "\"foo\\nbar\""} |
348 "\"foo\\nbar\""} |
713 defined on the logical level of Isabelle. By this we mean definitions, |
713 defined on the logical level of Isabelle. By this we mean definitions, |
714 theorems, terms and so on. This kind of reference is realised in Isabelle |
714 theorems, terms and so on. This kind of reference is realised in Isabelle |
715 with ML-antiquotations, often just called antiquotations.\footnote{There are |
715 with ML-antiquotations, often just called antiquotations.\footnote{There are |
716 two kinds of antiquotations in Isabelle, which have very different purposes |
716 two kinds of antiquotations in Isabelle, which have very different purposes |
717 and infrastructures. The first kind, described in this section, are |
717 and infrastructures. The first kind, described in this section, are |
718 \emph{\index*{ML-antiquotations}}. They are used to refer to entities (like terms, |
718 \emph{\index*{ML-antiquotation}}. They are used to refer to entities (like terms, |
719 types etc) from Isabelle's logic layer inside ML-code. The other kind of |
719 types etc) from Isabelle's logic layer inside ML-code. The other kind of |
720 antiquotations are \emph{document}\index{document antiquotationa} antiquotations. |
720 antiquotations are \emph{document}\index{document antiquotation} antiquotations. |
721 They are used only in the |
721 They are used only in the |
722 text parts of Isabelle and their purpose is to print logical entities inside |
722 text parts of Isabelle and their purpose is to print logical entities inside |
723 \LaTeX-documents. Document antiquotations are part of the user level and |
723 \LaTeX-documents. Document antiquotations are part of the user level and |
724 therefore we are not interested in them in this Tutorial, except in Appendix |
724 therefore we are not interested in them in this Tutorial, except in Appendix |
725 \ref{rec:docantiquotations} where we show how to implement your own document |
725 \ref{rec:docantiquotations} where we show how to implement your own document |