146 @{text "@{make_string}"}: |
147 @{text "@{make_string}"}: |
147 |
148 |
148 @{ML_response_fake [display,gray] "writeln (@{make_string} 1)" "\"1\""} |
149 @{ML_response_fake [display,gray] "writeln (@{make_string} 1)" "\"1\""} |
149 |
150 |
150 However, @{text "@{makes_tring}"} only works if the type of what |
151 However, @{text "@{makes_tring}"} only works if the type of what |
151 is converted is monomorphic and not a function. |
152 is converted is monomorphic and not a function. |
152 |
153 |
153 The function @{ML "writeln"} should only be used for testing purposes, |
154 You can print out error messages with the function @{ML_ind error in Library}; |
154 because any output this function generates will be overwritten as soon as an |
155 for example: |
155 error is raised. For printing anything more serious and elaborate, the |
|
156 function @{ML_ind tracing in Output} is more appropriate. This function writes all |
|
157 output into a separate tracing buffer. For example: |
|
158 |
|
159 @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""} |
|
160 |
|
161 You can print out error messages with the function @{ML_ind error in Library}; for |
|
162 example: |
|
163 |
156 |
164 @{ML_response_fake [display,gray] |
157 @{ML_response_fake [display,gray] |
165 "if 0=1 then true else (error \"foo\")" |
158 "if 0=1 then true else (error \"foo\")" |
166 "Exception- ERROR \"foo\" raised |
159 "Exception- ERROR \"foo\" raised |
167 At command \"ML\"."} |
160 At command \"ML\"."} |
168 |
161 |
169 This function raises the exception @{text ERROR}, which will then |
162 This function raises the exception @{text ERROR}, which will then |
170 be displayed by the infrastructure. Note that this exception is meant |
163 be displayed by the infrastructure. Note that this exception is meant |
171 for ``user-level'' error messages seen by the ``end-user''. |
164 for ``user-level'' error messages seen by the ``end-user''. |
172 |
165 |
173 For messages where you want to indicate a genuine program error, then |
166 For messages where you want to indicate a genuine program error, then |
174 use the exception @{text Fail}. Here the infrastructure indicates that this |
167 use the exception @{text Fail}. Here the infrastructure indicates that this |
175 is a low-level exception, and also prints the source position of the ML |
168 is a low-level exception, and also prints the source position of the ML |
176 raise statement. |
169 raise statement. |
177 |
|
178 |
|
179 \footnote{\bf FIXME Mention how to work with @{ML_ind debug in Toplevel} and |
|
180 @{ML_ind profiling in Toplevel}.} |
|
181 |
|
182 *} |
|
183 |
|
184 (* FIXME*) |
|
185 (* |
|
186 ML {* reset Toplevel.debug *} |
|
187 |
|
188 ML {* fun dodgy_fun () = (raise TYPE ("",[],[]); 1) *} |
|
189 |
|
190 ML {* fun innocent () = dodgy_fun () *} |
|
191 ML {* exception_trace (fn () => cterm_of @{theory} (Bound 0)) *} |
|
192 ML {* exception_trace (fn () => innocent ()) *} |
|
193 |
|
194 ML {* Toplevel.program (fn () => cterm_of @{theory} (Bound 0)) *} |
|
195 |
|
196 ML {* Toplevel.program (fn () => innocent ()) *} |
|
197 *) |
|
198 |
|
199 text {* |
|
200 %Kernel exceptions TYPE, TERM, THM also have their place in situations |
|
201 %where kernel-like operations are involved. The printing is similar as for |
|
202 %Fail, although there is some special treatment when Toplevel.debug is |
|
203 %enabled. |
|
204 |
170 |
205 Most often you want to inspect data of Isabelle's basic data structures, |
171 Most often you want to inspect data of Isabelle's basic data structures, |
206 namely @{ML_type term}, @{ML_type typ}, @{ML_type cterm}, @{ML_type ctyp} |
172 namely @{ML_type term}, @{ML_type typ}, @{ML_type cterm}, @{ML_type ctyp} |
207 and @{ML_type thm}. Isabelle contains elaborate pretty-printing functions, |
173 and @{ML_type thm}. Isabelle contains elaborate pretty-printing functions, |
208 which we will explain in more detail in Section \ref{sec:pretty}. For now |
174 which we will explain in more detail in Section \ref{sec:pretty}. For now |
250 In this case we obtain |
216 In this case we obtain |
251 *} |
217 *} |
252 |
218 |
253 text {* |
219 text {* |
254 @{ML_response_fake [display, gray] |
220 @{ML_response_fake [display, gray] |
255 "pwriteln (pretty_term |
221 "let |
256 (Config.put show_all_types true @{context}) @{term \"(1::nat, x)\"})" |
222 val show_all_types_ctxt = Config.put show_all_types true @{context} |
|
223 in |
|
224 pwriteln (pretty_term show_all_types_ctxt @{term \"(1::nat, x)\"}) |
|
225 end" |
257 "(Pair::nat \<Rightarrow> 'a \<Rightarrow> nat \<times> 'a) (1::nat) (x::'a)"} |
226 "(Pair::nat \<Rightarrow> 'a \<Rightarrow> nat \<times> 'a) (1::nat) (x::'a)"} |
258 |
227 |
259 where @{term Pair} is the term-constructor for products. |
228 where now even @{term Pair} is written with its type (@{term Pair} is the |
260 Other configuration values that influence printing of terms are |
229 term-constructor for products). Other configuration values that influence |
261 @{ML_ind show_brackets in Syntax} and @{ML_ind show_sorts in Syntax}. |
230 printing of terms are @{ML_ind show_brackets in Syntax} and @{ML_ind |
|
231 show_sorts in Syntax}. |
262 *} |
232 *} |
263 |
233 |
264 text {* |
234 text {* |
265 A @{ML_type cterm} can be printed with the following function. |
235 A @{ML_type cterm} can be printed with the following function. |
266 *} |
236 *} |
295 @{ML_response_fake [display, gray] |
265 @{ML_response_fake [display, gray] |
296 "pwriteln (pretty_thm @{context} @{thm conjI})" |
266 "pwriteln (pretty_thm @{context} @{thm conjI})" |
297 "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"} |
267 "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"} |
298 |
268 |
299 However, in order to improve the readability when printing theorems, we |
269 However, in order to improve the readability when printing theorems, we |
300 convert these schematic variables into free variables using the function |
270 can switch off the question marks as follows: |
301 @{ML_ind import in Variable}. This is similar to statements like @{text |
271 *} |
302 "conjI[no_vars]"} on Isabelle's user-level. |
272 |
303 *} |
273 ML{*fun pretty_thm_no_vars ctxt thm = |
304 |
274 let |
305 ML{*fun no_vars ctxt thm = |
275 val ctxt' = Config.put show_question_marks false ctxt |
306 let |
|
307 val ((_, [thm']), _) = Variable.import true [thm] ctxt |
|
308 in |
276 in |
309 thm' |
277 pretty_term ctxt' (prop_of thm) |
310 end |
278 end*} |
311 |
|
312 fun pretty_thm_no_vars ctxt thm = |
|
313 pretty_term ctxt (prop_of (no_vars ctxt thm))*} |
|
314 |
|
315 |
279 |
316 text {* |
280 text {* |
317 With this function, theorem @{thm [source] conjI} is now printed as follows: |
281 With this function, theorem @{thm [source] conjI} is now printed as follows: |
318 |
282 |
319 @{ML_response_fake [display, gray] |
283 @{ML_response_fake [display, gray] |
540 @{ML "#>"}.\footnote{give example} |
504 @{ML "#>"}.\footnote{give example} |
541 |
505 |
542 The remaining combinators we describe in this section add convenience for the |
506 The remaining combinators we describe in this section add convenience for the |
543 ``waterfall method'' of writing functions. The combinator @{ML_ind tap in |
507 ``waterfall method'' of writing functions. The combinator @{ML_ind tap in |
544 Basics} allows you to get hold of an intermediate result (to do some |
508 Basics} allows you to get hold of an intermediate result (to do some |
545 side-calculations for instance). The function |
509 side-calculations or print out an intermediate result, for instance). The function |
546 *} |
510 *} |
547 |
511 |
548 ML %linenosgray{*fun inc_by_three x = |
512 ML %linenosgray{*fun inc_by_three x = |
549 x |> (fn x => x + 1) |
513 x |> (fn x => x + 1) |
550 |> tap (fn x => tracing (PolyML.makestring x)) |
514 |> tap (fn x => writeln (@{make_string} x)) |
551 |> (fn x => x + 2)*} |
515 |> (fn x => x + 2)*} |
552 |
516 |
553 text {* |
517 text {* |
554 increments the argument first by @{text "1"} and then by @{text "2"}. In the |
518 increments the argument first by @{text "1"} and then by @{text "2"}. In the |
555 middle (Line 3), however, it uses @{ML tap} for printing the ``plus-one'' |
519 middle (Line 3), however, it uses @{ML tap} for printing the ``plus-one'' |