78 then there is a convenient, though again ``quick-and-dirty'', method for |
78 then there is a convenient, though again ``quick-and-dirty'', method for |
79 converting values into strings, namely the function @{ML makestring}: |
79 converting values into strings, namely the function @{ML makestring}: |
80 |
80 |
81 @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} |
81 @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} |
82 |
82 |
83 However @{ML makestring} only works if the type of what is converted is monomorphic |
83 However, @{ML makestring} only works if the type of what is converted is monomorphic |
84 and not a function. |
84 and not a function. |
85 |
85 |
86 The function @{ML "warning"} should only be used for testing purposes, because any |
86 The function @{ML "warning"} should only be used for testing purposes, because any |
87 output this function generates will be overwritten as soon as an error is |
87 output this function generates will be overwritten as soon as an error is |
88 raised. For printing anything more serious and elaborate, the |
88 raised. For printing anything more serious and elaborate, the |
90 a separate tracing buffer. For example: |
90 a separate tracing buffer. For example: |
91 |
91 |
92 @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""} |
92 @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""} |
93 |
93 |
94 It is also possible to redirect the ``channel'' where the string @{text "foo"} is |
94 It is also possible to redirect the ``channel'' where the string @{text "foo"} is |
95 printed to a separate file, e.g.~to prevent ProofGeneral from choking on massive |
95 printed to a separate file, e.g., to prevent ProofGeneral from choking on massive |
96 amounts of trace output. This redirection can be achieved with the code: |
96 amounts of trace output. This redirection can be achieved with the code: |
97 *} |
97 *} |
98 |
98 |
99 ML{*val strip_specials = |
99 ML{*val strip_specials = |
100 let |
100 let |
249 |> (fn x => (x, x)) |
249 |> (fn x => (x, x)) |
250 |> fst |
250 |> fst |
251 |> (fn x => x + 4)*} |
251 |> (fn x => x + 4)*} |
252 |
252 |
253 text {* |
253 text {* |
254 which increments its argument @{text x} by 5. It does this by first incrementing |
254 which increments its argument @{text x} by 5. It proceeds by first incrementing |
255 the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking |
255 the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking |
256 the first component of the pair (Line 4) and finally incrementing the first |
256 the first component of the pair (Line 4) and finally incrementing the first |
257 component by 4 (Line 5). This kind of cascading manipulations of values is quite |
257 component by 4 (Line 5). This kind of cascading manipulations of values is quite |
258 common when dealing with theories (for example by adding a definition, followed by |
258 common when dealing with theories (for example by adding a definition, followed by |
259 lemmas and so on). The reverse application allows you to read what happens in |
259 lemmas and so on). The reverse application allows you to read what happens in |
350 intermediate result inside the tracing buffer. The function @{ML tap} can |
350 intermediate result inside the tracing buffer. The function @{ML tap} can |
351 only be used for side-calculations, because any value that is computed |
351 only be used for side-calculations, because any value that is computed |
352 cannot be merged back into the ``main waterfall''. To do this, you can use |
352 cannot be merged back into the ``main waterfall''. To do this, you can use |
353 the next combinator. |
353 the next combinator. |
354 |
354 |
355 The combinator @{ML "`"} is similar to @{ML tap}, but applies a function to the value |
355 The combinator @{ML "`"} (a backtick) is similar to @{ML tap}, but applies a |
356 and returns the result together with the value (as a pair). For example |
356 function to the value and returns the result together with the value (as a |
357 the function |
357 pair). For example the function |
358 *} |
358 *} |
359 |
359 |
360 ML{*fun inc_as_pair x = |
360 ML{*fun inc_as_pair x = |
361 x |> `(fn x => x + 1) |
361 x |> `(fn x => x + 1) |
362 |> (fn (x, y) => (x, y + 1))*} |
362 |> (fn (x, y) => (x, y + 1))*} |
394 ML{*fun double x = |
394 ML{*fun double x = |
395 x |> (fn x => (x, x)) |
395 x |> (fn x => (x, x)) |
396 |-> (fn x => fn y => x + y)*} |
396 |-> (fn x => fn y => x + y)*} |
397 |
397 |
398 text {* |
398 text {* |
399 Recall that @{ML "|>"} is the reverse function applications. Recall also that the related |
399 Recall that @{ML "|>"} is the reverse function application. Recall also that |
|
400 the related |
400 reverse function composition is @{ML "#>"}. In fact all the combinators @{ML "|->"}, |
401 reverse function composition is @{ML "#>"}. In fact all the combinators @{ML "|->"}, |
401 @{ML "|>>"} and @{ML "||>"} described above have related combinators for function |
402 @{ML "|>>"} and @{ML "||>"} described above have related combinators for function |
402 composition, namely @{ML "#->"}, @{ML "#>>"} and @{ML "##>"}. Using @{ML "#->"}, |
403 composition, namely @{ML "#->"}, @{ML "#>>"} and @{ML "##>"}. Using @{ML "#->"}, |
403 for example, the function @{text double} can also be written as: |
404 for example, the function @{text double} can also be written as: |
404 *} |
405 *} |
484 |
486 |
485 @{ML_response_fake [display,gray] |
487 @{ML_response_fake [display,gray] |
486 "get_thm_names_from_ss @{simpset}" |
488 "get_thm_names_from_ss @{simpset}" |
487 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
489 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
488 |
490 |
489 Again, this way or referencing simpsets makes you independent from additions |
491 Again, this way of referencing simpsets makes you independent from additions |
490 of lemmas to the simpset by the user that potentially cause loops. |
492 of lemmas to the simpset by the user that potentially cause loops. |
491 |
493 |
492 On the ML-level of Isabelle, you often have to work with qualified names; |
494 On the ML-level of Isabelle, you often have to work with qualified names; |
493 these are strings with some additional information, such positional information |
495 these are strings with some additional information, such as positional information |
494 and qualifiers. Such bindings can be generated with the antiquotation |
496 and qualifiers. Such bindings can be generated with the antiquotation |
495 @{text "@{bindin \<dots>}"}. |
497 @{text "@{binding \<dots>}"}. |
496 |
498 |
497 @{ML_response [display,gray] |
499 @{ML_response [display,gray] |
498 "@{binding \"name\"}" |
500 "@{binding \"name\"}" |
499 "name"} |
501 "name"} |
500 |
502 |
501 An example where a binding is needed is the function @{ML define in LocalTheory}. |
503 An example where a binding is needed is the function @{ML define in |
502 Below this function defines the constant @{term "TrueConj"} as the conjunction |
504 LocalTheory}. Below, this function is used to define the constant @{term |
|
505 "TrueConj"} as the conjunction |
503 @{term "True \<and> True"}. |
506 @{term "True \<and> True"}. |
504 *} |
507 *} |
505 |
508 |
506 local_setup %gray {* |
509 local_setup %gray {* |
507 snd o LocalTheory.define Thm.internalK |
510 snd o LocalTheory.define Thm.internalK |
508 ((@{binding "TrueConj"}, NoSyn), |
511 ((@{binding "TrueConj"}, NoSyn), |
509 (Attrib.empty_binding, @{term "True \<and> True"})) *} |
512 (Attrib.empty_binding, @{term "True \<and> True"})) *} |
510 |
513 |
511 text {* |
514 text {* |
512 While antiquotations have many applications, they were originally introduced in order |
515 While antiquotations have many applications, they were originally introduced |
513 to avoid explicit bindings for theorems such as: |
516 in order to avoid explicit bindings of theorems such as: |
514 *} |
517 *} |
515 |
518 |
516 ML{*val allI = thm "allI" *} |
519 ML{*val allI = thm "allI" *} |
517 |
520 |
518 text {* |
521 text {* |
519 These bindings are difficult to maintain and also can be accidentally |
522 Such bindings are difficult to maintain and can be overwritten by the |
520 overwritten by the user. This often broke Isabelle |
523 user accidentally. This often broke Isabelle |
521 packages. Antiquotations solve this problem, since they are ``linked'' |
524 packages. Antiquotations solve this problem, since they are ``linked'' |
522 statically at compile-time. However, this static linkage also limits their |
525 statically at compile-time. However, this static linkage also limits their |
523 usefulness in cases where data needs to be build up dynamically. In the |
526 usefulness in cases where data needs to be build up dynamically. In the |
524 course of this chapter you will learn more about these antiquotations: |
527 course of this chapter you will learn more about antiquotations: |
525 they can simplify Isabelle programming since one can directly access all |
528 they can simplify Isabelle programming since one can directly access all |
526 kinds of logical elements from th ML-level. |
529 kinds of logical elements from the ML-level. |
527 *} |
530 *} |
528 |
531 |
529 section {* Terms and Types *} |
532 section {* Terms and Types *} |
530 |
533 |
531 text {* |
534 text {* |