2
+ − 1
theory FirstSteps
25
+ − 2
imports Base
2
+ − 3
begin
+ − 4
+ − 5
chapter {* First Steps *}
+ − 6
42
+ − 7
text {*
242
+ − 8
Isabelle programming is done in ML. Just like lemmas and proofs, ML-code
89
+ − 9
in Isabelle is part of a theory. If you want to follow the code given in
54
+ − 10
this chapter, we assume you are working inside the theory starting with
2
+ − 11
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 12
\begin{quote}
5
+ − 13
\begin{tabular}{@ {}l}
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 14
\isacommand{theory} FirstSteps\\
5
+ − 15
\isacommand{imports} Main\\
+ − 16
\isacommand{begin}\\
6
+ − 17
\ldots
5
+ − 18
\end{tabular}
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 19
\end{quote}
157
+ − 20
+ − 21
We also generally assume you are working with HOL. The given examples might
193
+ − 22
need to be adapted if you work in a different logic.
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 23
*}
5
+ − 24
20
+ − 25
section {* Including ML-Code *}
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 26
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 27
text {*
5
+ − 28
The easiest and quickest way to include code in a theory is
89
+ − 29
by using the \isacommand{ML}-command. For example:
2
+ − 30
75
+ − 31
\begin{isabelle}
+ − 32
\begin{graybox}
85
+ − 33
\isacommand{ML}~@{text "\<verbopen>"}\isanewline
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 34
\hspace{5mm}@{ML "3 + 4"}\isanewline
85
+ − 35
@{text "\<verbclose>"}\isanewline
+ − 36
@{text "> 7"}\smallskip
75
+ − 37
\end{graybox}
+ − 38
\end{isabelle}
2
+ − 39
234
+ − 40
Like normal Isabelle scripts, \isacommand{ML}-commands can be
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 41
evaluated by using the advance and undo buttons of your Isabelle
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 42
environment. The code inside the \isacommand{ML}-command can also contain
193
+ − 43
value and function bindings, for example
+ − 44
*}
+ − 45
+ − 46
ML %gray {*
+ − 47
val r = ref 0
+ − 48
fun f n = n + 1
+ − 49
*}
+ − 50
+ − 51
text {*
+ − 52
and even those can be undone when the proof
+ − 53
script is retracted. As mentioned in the Introduction, we will drop the
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 54
\isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"} scaffolding whenever we
107
+ − 55
show code. The lines prefixed with @{text [quotes] ">"} are not part of the
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 56
code, rather they indicate what the response is when the code is evaluated.
254
+ − 57
There are also the commands \isacommand{ML\_val} and \isacommand{ML\_prf} for
+ − 58
including ML-code. The first evaluates the given code, but any effect on the
264
+ − 59
theory, in which the code is embedded, is suppressed. The second needs to
+ − 60
be used if ML-code is defined
253
+ − 61
inside a proof. For example
+ − 62
254
+ − 63
\begin{quote}
+ − 64
\begin{isabelle}
+ − 65
\isacommand{lemma}~@{text "test:"}\isanewline
+ − 66
\isacommand{shows}~@{text [quotes] "True"}\isanewline
+ − 67
\isacommand{ML\_prf}~@{text "\<verbopen>"}~@{ML "writeln \"Trivial!\""}~@{text "\<verbclose>"}\isanewline
+ − 68
\isacommand{oops}
+ − 69
\end{isabelle}
+ − 70
\end{quote}
253
+ − 71
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 72
However, both commands will only play minor roles in this tutorial (we will always
264
+ − 73
arrange that the ML-code is defined outside of proofs, for example).
10
+ − 74
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 75
Once a portion of code is relatively stable, you usually want to export it
235
+ − 76
to a separate ML-file. Such files can then be included somewhere inside a
+ − 77
theory by using the command \isacommand{use}. For example
+ − 78
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 79
\begin{quote}
235
+ − 80
\begin{tabular}{@ {}l}
+ − 81
\isacommand{theory} FirstSteps\\
+ − 82
\isacommand{imports} Main\\
+ − 83
\isacommand{uses}~@{text "(\"file_to_be_included.ML\")"} @{text "\<dots>"}\\
+ − 84
\isacommand{begin}\\
+ − 85
\ldots\\
+ − 86
\isacommand{use}~@{text "\"file_to_be_included.ML\""}\\
+ − 87
\ldots
+ − 88
\end{tabular}
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 89
\end{quote}
235
+ − 90
+ − 91
The \isacommand{uses}-command in the header of the theory is needed in order
+ − 92
to indicate the dependency of the theory on the ML-file. Alternatively, the
+ − 93
file can be included by just writing in the header
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 94
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 95
\begin{quote}
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 96
\begin{tabular}{@ {}l}
54
+ − 97
\isacommand{theory} FirstSteps\\
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 98
\isacommand{imports} Main\\
58
+ − 99
\isacommand{uses} @{text "\"file_to_be_included.ML\""} @{text "\<dots>"}\\
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 100
\isacommand{begin}\\
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 101
\ldots
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 102
\end{tabular}
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 103
\end{quote}
235
+ − 104
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 105
Note that no parentheses are given this time. Note also that the
264
+ − 106
included ML-file should not contain any
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 107
\isacommand{use} itself. Otherwise Isabelle is unable to record all
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 108
file dependencies, which is a nuisance if you have to track down
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 109
errors.
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 110
*}
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 111
126
+ − 112
section {* Debugging and Printing\label{sec:printing} *}
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 113
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 114
text {*
13
+ − 115
50
+ − 116
During development you might find it necessary to inspect some data
10
+ − 117
in your code. This can be done in a ``quick-and-dirty'' fashion using
256
+ − 118
the function @{ML [index] "writeln"}. For example
10
+ − 119
239
+ − 120
@{ML_response_fake [display,gray] "writeln \"any string\"" "\"any string\""}
10
+ − 121
58
+ − 122
will print out @{text [quotes] "any string"} inside the response buffer
+ − 123
of Isabelle. This function expects a string as argument. If you develop under PolyML,
50
+ − 124
then there is a convenient, though again ``quick-and-dirty'', method for
240
+ − 125
converting values into strings, namely the function @{ML PolyML.makestring}:
10
+ − 126
240
+ − 127
@{ML_response_fake [display,gray] "writeln (PolyML.makestring 1)" "\"1\""}
12
+ − 128
260
+ − 129
However, @{ML [index] makestring in PolyML} only works if the type of what is converted is monomorphic
78
+ − 130
and not a function.
12
+ − 131
239
+ − 132
The function @{ML "writeln"} should only be used for testing purposes, because any
52
+ − 133
output this function generates will be overwritten as soon as an error is
50
+ − 134
raised. For printing anything more serious and elaborate, the
256
+ − 135
function @{ML [index] tracing} is more appropriate. This function writes all output into
89
+ − 136
a separate tracing buffer. For example:
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 137
161
+ − 138
@{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""}
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 139
58
+ − 140
It is also possible to redirect the ``channel'' where the string @{text "foo"} is
196
+ − 141
printed to a separate file, e.g., to prevent ProofGeneral from choking on massive
107
+ − 142
amounts of trace output. This redirection can be achieved with the code:
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 143
*}
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 144
69
+ − 145
ML{*val strip_specials =
42
+ − 146
let
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 147
fun strip ("\^A" :: _ :: cs) = strip cs
42
+ − 148
| strip (c :: cs) = c :: strip cs
+ − 149
| strip [] = [];
+ − 150
in implode o strip o explode end;
+ − 151
+ − 152
fun redirect_tracing stream =
+ − 153
Output.tracing_fn := (fn s =>
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 154
(TextIO.output (stream, (strip_specials s));
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 155
TextIO.output (stream, "\n");
69
+ − 156
TextIO.flushOut stream)) *}
14
1c17e99f6f66
added a paragraph about "uses" and started a paragraph about tracing
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 157
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 158
text {*
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 159
Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"}
58
+ − 160
will cause that all tracing information is printed into the file @{text "foo.bar"}.
75
+ − 161
256
+ − 162
You can print out error messages with the function @{ML [index] error}; for example:
75
+ − 163
122
+ − 164
@{ML_response_fake [display,gray] "if 0=1 then true else (error \"foo\")"
+ − 165
"Exception- ERROR \"foo\" raised
+ − 166
At command \"ML\"."}
75
+ − 167
256
+ − 168
(FIXME Mention how to work with @{ML [index] debug in Toplevel} and
+ − 169
@{ML [index] profiling in Toplevel}.)
192
+ − 170
*}
+ − 171
+ − 172
(*
207
+ − 173
ML {* reset Toplevel.debug *}
+ − 174
+ − 175
ML {* fun dodgy_fun () = (raise TYPE ("",[],[]); 1) *}
193
+ − 176
207
+ − 177
ML {* fun innocent () = dodgy_fun () *}
+ − 178
ML {* exception_trace (fn () => cterm_of @{theory} (Bound 0)) *}
+ − 179
ML {* exception_trace (fn () => innocent ()) *}
192
+ − 180
207
+ − 181
ML {* Toplevel.program (fn () => cterm_of @{theory} (Bound 0)) *}
192
+ − 182
207
+ − 183
ML {* Toplevel.program (fn () => innocent ()) *}
192
+ − 184
*)
+ − 185
+ − 186
text {*
126
+ − 187
Most often you want to inspect data of type @{ML_type term}, @{ML_type cterm}
251
+ − 188
or @{ML_type thm}. Isabelle contains elaborate pretty-printing functions for printing
+ − 189
them (see Section \ref{sec:pretty}),
126
+ − 190
but for quick-and-dirty solutions they are far too unwieldy. A simple way to transform
256
+ − 191
a term into a string is to use the function @{ML [index] string_of_term in Syntax}.
126
+ − 192
+ − 193
@{ML_response_fake [display,gray]
+ − 194
"Syntax.string_of_term @{context} @{term \"1::nat\"}"
+ − 195
"\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""}
+ − 196
+ − 197
This produces a string with some additional information encoded in it. The string
256
+ − 198
can be properly printed by using the function @{ML [index] writeln}.
126
+ − 199
+ − 200
@{ML_response_fake [display,gray]
239
+ − 201
"writeln (Syntax.string_of_term @{context} @{term \"1::nat\"})"
126
+ − 202
"\"1\""}
+ − 203
+ − 204
A @{ML_type cterm} can be transformed into a string by the following function.
+ − 205
*}
+ − 206
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 207
ML{*fun string_of_cterm ctxt t =
126
+ − 208
Syntax.string_of_term ctxt (term_of t)*}
+ − 209
+ − 210
text {*
256
+ − 211
In this example the function @{ML [index] term_of} extracts the @{ML_type term} from
149
+ − 212
a @{ML_type cterm}. If there are more than one @{ML_type cterm}s to be
256
+ − 213
printed, you can use the function @{ML [index] commas} to separate them.
126
+ − 214
*}
+ − 215
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 216
ML{*fun string_of_cterms ctxt ts =
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 217
commas (map (string_of_cterm ctxt) ts)*}
126
+ − 218
+ − 219
text {*
+ − 220
The easiest way to get the string of a theorem is to transform it
256
+ − 221
into a @{ML_type cterm} using the function @{ML [index] crep_thm}.
190
+ − 222
*}
+ − 223
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 224
ML{*fun string_of_thm ctxt thm =
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 225
string_of_cterm ctxt (#prop (crep_thm thm))*}
190
+ − 226
+ − 227
text {*
+ − 228
Theorems also include schematic variables, such as @{text "?P"},
+ − 229
@{text "?Q"} and so on.
+ − 230
+ − 231
@{ML_response_fake [display, gray]
301
+ − 232
"tracing (string_of_thm @{context} @{thm conjI})"
190
+ − 233
"\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"}
+ − 234
+ − 235
In order to improve the readability of theorems we convert
158
d7944bdf7b3f
removed infix_conv and moved function no_vars into the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 236
these schematic variables into free variables using the
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 237
function @{ML [index] import in Variable}.
126
+ − 238
*}
+ − 239
158
d7944bdf7b3f
removed infix_conv and moved function no_vars into the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 240
ML{*fun no_vars ctxt thm =
d7944bdf7b3f
removed infix_conv and moved function no_vars into the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 241
let
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 242
val ((_, [thm']), _) = Variable.import true [thm] ctxt
158
d7944bdf7b3f
removed infix_conv and moved function no_vars into the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 243
in
d7944bdf7b3f
removed infix_conv and moved function no_vars into the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 244
thm'
d7944bdf7b3f
removed infix_conv and moved function no_vars into the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 245
end
d7944bdf7b3f
removed infix_conv and moved function no_vars into the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 246
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 247
fun string_of_thm_no_vars ctxt thm =
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 248
string_of_cterm ctxt (#prop (crep_thm (no_vars ctxt thm)))*}
126
+ − 249
+ − 250
text {*
207
+ − 251
Theorem @{thm [source] conjI} is now printed as follows:
190
+ − 252
+ − 253
@{ML_response_fake [display, gray]
301
+ − 254
"tracing (string_of_thm_no_vars @{context} @{thm conjI})"
196
+ − 255
"\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
190
+ − 256
126
+ − 257
Again the function @{ML commas} helps with printing more than one theorem.
+ − 258
*}
+ − 259
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 260
ML{*fun string_of_thms ctxt thms =
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 261
commas (map (string_of_thm ctxt) thms)
190
+ − 262
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 263
fun string_of_thms_no_vars ctxt thms =
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 264
commas (map (string_of_thm_no_vars ctxt) thms) *}
126
+ − 265
+ − 266
section {* Combinators\label{sec:combinators} *}
+ − 267
+ − 268
text {*
131
+ − 269
For beginners perhaps the most puzzling parts in the existing code of Isabelle are
126
+ − 270
the combinators. At first they seem to greatly obstruct the
+ − 271
comprehension of the code, but after getting familiar with them, they
+ − 272
actually ease the understanding and also the programming.
+ − 273
256
+ − 274
The simplest combinator is @{ML [index] I}, which is just the identity function defined as
126
+ − 275
*}
+ − 276
+ − 277
ML{*fun I x = x*}
+ − 278
256
+ − 279
text {* Another simple combinator is @{ML [index] K}, defined as *}
126
+ − 280
+ − 281
ML{*fun K x = fn _ => x*}
+ − 282
+ − 283
text {*
256
+ − 284
@{ML [index] K} ``wraps'' a function around the argument @{text "x"}. However, this
126
+ − 285
function ignores its argument. As a result, @{ML K} defines a constant function
+ − 286
always returning @{text x}.
+ − 287
256
+ − 288
The next combinator is reverse application, @{ML [index] "|>"}, defined as:
126
+ − 289
*}
+ − 290
+ − 291
ML{*fun x |> f = f x*}
+ − 292
+ − 293
text {* While just syntactic sugar for the usual function application,
+ − 294
the purpose of this combinator is to implement functions in a
+ − 295
``waterfall fashion''. Consider for example the function *}
+ − 296
+ − 297
ML %linenosgray{*fun inc_by_five x =
+ − 298
x |> (fn x => x + 1)
+ − 299
|> (fn x => (x, x))
+ − 300
|> fst
+ − 301
|> (fn x => x + 4)*}
+ − 302
+ − 303
text {*
196
+ − 304
which increments its argument @{text x} by 5. It proceeds by first incrementing
126
+ − 305
the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking
+ − 306
the first component of the pair (Line 4) and finally incrementing the first
+ − 307
component by 4 (Line 5). This kind of cascading manipulations of values is quite
+ − 308
common when dealing with theories (for example by adding a definition, followed by
+ − 309
lemmas and so on). The reverse application allows you to read what happens in
+ − 310
a top-down manner. This kind of coding should also be familiar,
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 311
if you have been exposed to Haskell's {\it do}-notation. Writing the function
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 312
@{ML inc_by_five} using the reverse application is much clearer than writing
126
+ − 313
*}
+ − 314
+ − 315
ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
+ − 316
+ − 317
text {* or *}
+ − 318
+ − 319
ML{*fun inc_by_five x =
+ − 320
((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*}
+ − 321
+ − 322
text {* and typographically more economical than *}
+ − 323
+ − 324
ML{*fun inc_by_five x =
257
+ − 325
let val y1 = x + 1
+ − 326
val y2 = (y1, y1)
+ − 327
val y3 = fst y2
+ − 328
val y4 = y3 + 4
+ − 329
in y4 end*}
126
+ − 330
+ − 331
text {*
+ − 332
Another reason why the let-bindings in the code above are better to be
+ − 333
avoided: it is more than easy to get the intermediate values wrong, not to
+ − 334
mention the nightmares the maintenance of this code causes!
+ − 335
215
+ − 336
In Isabelle, a ``real world'' example for a function written in
178
fb8f22dd8ad0
adapted to latest Attrib.setup changes and more work on the simple induct chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 337
the waterfall fashion might be the following code:
177
+ − 338
*}
126
+ − 339
193
+ − 340
ML %linenosgray{*fun apply_fresh_args f ctxt =
+ − 341
f |> fastype_of
+ − 342
|> binder_types
+ − 343
|> map (pair "z")
+ − 344
|> Variable.variant_frees ctxt [f]
+ − 345
|> map Free
257
+ − 346
|> curry list_comb f *}
126
+ − 347
177
+ − 348
text {*
266
+ − 349
This function takes a term and a context as argument. If the term is of function
+ − 350
type, then @{ML "apply_fresh_args"} returns the term with distinct variables
298
+ − 351
applied to it. For example below variables are applied to the term
+ − 352
@{term [show_types] "P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool"}:
183
+ − 353
+ − 354
@{ML_response_fake [display,gray]
266
+ − 355
"let
+ − 356
val t = @{term \"P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool\"}
+ − 357
val ctxt = @{context}
+ − 358
in
+ − 359
apply_fresh_args t ctxt
+ − 360
|> Syntax.string_of_term ctxt
301
+ − 361
|> tracing
266
+ − 362
end"
183
+ − 363
"P z za zb"}
177
+ − 364
184
+ − 365
You can read off this behaviour from how @{ML apply_fresh_args} is
256
+ − 366
coded: in Line 2, the function @{ML [index] fastype_of} calculates the type of the
298
+ − 367
term; @{ML [index] binder_types} in the next line produces the list of argument
184
+ − 368
types (in the case above the list @{text "[nat, int, unit]"}); Line 4
+ − 369
pairs up each type with the string @{text "z"}; the
256
+ − 370
function @{ML [index] variant_frees in Variable} generates for each @{text "z"} a
193
+ − 371
unique name avoiding the given @{text f}; the list of name-type pairs is turned
184
+ − 372
into a list of variable terms in Line 6, which in the last line is applied
298
+ − 373
by the function @{ML [index] list_comb} to the term. In this last step we have to
256
+ − 374
use the function @{ML [index] curry}, because @{ML [index] list_comb} expects the
+ − 375
function and the variables list as a pair. This kind of functions is often needed when
298
+ − 376
constructing terms with fresh variables. The infrastructure helps tremendously
+ − 377
to avoid any name clashes. Consider for example:
252
+ − 378
+ − 379
@{ML_response_fake [display,gray]
266
+ − 380
"let
+ − 381
val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"}
+ − 382
val ctxt = @{context}
+ − 383
in
+ − 384
apply_fresh_args t ctxt
+ − 385
|> Syntax.string_of_term ctxt
301
+ − 386
|> tracing
266
+ − 387
end"
252
+ − 388
"za z zb"}
177
+ − 389
266
+ − 390
where the @{text "za"} is correctly avoided.
+ − 391
256
+ − 392
The combinator @{ML [index] "#>"} is the reverse function composition. It can be
177
+ − 393
used to define the following function
126
+ − 394
*}
+ − 395
+ − 396
ML{*val inc_by_six =
+ − 397
(fn x => x + 1)
+ − 398
#> (fn x => x + 2)
+ − 399
#> (fn x => x + 3)*}
+ − 400
+ − 401
text {*
+ − 402
which is the function composed of first the increment-by-one function and then
+ − 403
increment-by-two, followed by increment-by-three. Again, the reverse function
+ − 404
composition allows you to read the code top-down.
+ − 405
+ − 406
The remaining combinators described in this section add convenience for the
256
+ − 407
``waterfall method'' of writing functions. The combinator @{ML [index] tap} allows
126
+ − 408
you to get hold of an intermediate result (to do some side-calculations for
+ − 409
instance). The function
+ − 410
+ − 411
*}
+ − 412
+ − 413
ML %linenosgray{*fun inc_by_three x =
+ − 414
x |> (fn x => x + 1)
240
+ − 415
|> tap (fn x => tracing (PolyML.makestring x))
126
+ − 416
|> (fn x => x + 2)*}
+ − 417
+ − 418
text {*
+ − 419
increments the argument first by @{text "1"} and then by @{text "2"}. In the
256
+ − 420
middle (Line 3), however, it uses @{ML [index] tap} for printing the ``plus-one''
+ − 421
intermediate result inside the tracing buffer. The function @{ML [index] tap} can
126
+ − 422
only be used for side-calculations, because any value that is computed
+ − 423
cannot be merged back into the ``main waterfall''. To do this, you can use
+ − 424
the next combinator.
+ − 425
256
+ − 426
The combinator @{ML [index] "`"} (a backtick) is similar to @{ML tap}, but applies a
196
+ − 427
function to the value and returns the result together with the value (as a
+ − 428
pair). For example the function
126
+ − 429
*}
+ − 430
+ − 431
ML{*fun inc_as_pair x =
+ − 432
x |> `(fn x => x + 1)
+ − 433
|> (fn (x, y) => (x, y + 1))*}
+ − 434
+ − 435
text {*
+ − 436
takes @{text x} as argument, and then increments @{text x}, but also keeps
+ − 437
@{text x}. The intermediate result is therefore the pair @{ML "(x + 1, x)"
+ − 438
for x}. After that, the function increments the right-hand component of the
+ − 439
pair. So finally the result will be @{ML "(x + 1, x + 1)" for x}.
+ − 440
256
+ − 441
The combinators @{ML [index] "|>>"} and @{ML [index] "||>"} are defined for
126
+ − 442
functions manipulating pairs. The first applies the function to
+ − 443
the first component of the pair, defined as
+ − 444
*}
+ − 445
+ − 446
ML{*fun (x, y) |>> f = (f x, y)*}
+ − 447
+ − 448
text {*
+ − 449
and the second combinator to the second component, defined as
+ − 450
*}
+ − 451
+ − 452
ML{*fun (x, y) ||> f = (x, f y)*}
+ − 453
+ − 454
text {*
256
+ − 455
With the combinator @{ML [index] "|->"} you can re-combine the elements from a pair.
126
+ − 456
This combinator is defined as
+ − 457
*}
+ − 458
+ − 459
ML{*fun (x, y) |-> f = f x y*}
+ − 460
215
+ − 461
text {*
+ − 462
and can be used to write the following roundabout version
126
+ − 463
of the @{text double} function:
+ − 464
*}
+ − 465
+ − 466
ML{*fun double x =
+ − 467
x |> (fn x => (x, x))
+ − 468
|-> (fn x => fn y => x + y)*}
+ − 469
215
+ − 470
text {*
256
+ − 471
The combinator @{ML [index] ||>>} plays a central rôle whenever your task is to update a
215
+ − 472
theory and the update also produces a side-result (for example a theorem). Functions
+ − 473
for such tasks return a pair whose second component is the theory and the fist
256
+ − 474
component is the side-result. Using @{ML [index] ||>>}, you can do conveniently the update
280
+ − 475
and also accumulate the side-results. Consider the following simple function.
215
+ − 476
*}
+ − 477
+ − 478
ML %linenosgray{*fun acc_incs x =
+ − 479
x |> (fn x => ("", x))
+ − 480
||>> (fn x => (x, x + 1))
+ − 481
||>> (fn x => (x, x + 1))
+ − 482
||>> (fn x => (x, x + 1))*}
+ − 483
+ − 484
text {*
+ − 485
The purpose of Line 2 is to just pair up the argument with a dummy value (since
256
+ − 486
@{ML [index] "||>>"} operates on pairs). Each of the next three lines just increment
280
+ − 487
the value by one, but also nest the intermediate results to the left. For example
215
+ − 488
+ − 489
@{ML_response [display,gray]
+ − 490
"acc_incs 1"
+ − 491
"((((\"\", 1), 2), 3), 4)"}
+ − 492
+ − 493
You can continue this chain with:
+ − 494
+ − 495
@{ML_response [display,gray]
+ − 496
"acc_incs 1 ||>> (fn x => (x, x + 2))"
+ − 497
"(((((\"\", 1), 2), 3), 4), 6)"}
+ − 498
298
+ − 499
(FIXME: maybe give a ``real world'' example for this combinator)
215
+ − 500
*}
+ − 501
126
+ − 502
text {*
256
+ − 503
Recall that @{ML [index] "|>"} is the reverse function application. Recall also that
196
+ − 504
the related
256
+ − 505
reverse function composition is @{ML [index] "#>"}. In fact all the combinators
+ − 506
@{ML [index] "|->"}, @{ML [index] "|>>"} , @{ML [index] "||>"} and @{ML [index]
+ − 507
"||>>"} described above have related combinators for
+ − 508
function composition, namely @{ML [index] "#->"}, @{ML [index] "#>>"},
+ − 509
@{ML [index] "##>"} and @{ML [index] "##>>"}.
+ − 510
Using @{ML [index] "#->"}, for example, the function @{text double} can also be written as:
126
+ − 511
*}
+ − 512
+ − 513
ML{*val double =
+ − 514
(fn x => (x, x))
+ − 515
#-> (fn x => fn y => x + y)*}
+ − 516
+ − 517
text {*
+ − 518
+ − 519
(FIXME: find a good exercise for combinators)
127
+ − 520
+ − 521
\begin{readmore}
196
+ − 522
The most frequently used combinators are defined in the files @{ML_file
+ − 523
"Pure/library.ML"}
127
+ − 524
and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans}
+ − 525
contains further information about combinators.
+ − 526
\end{readmore}
126
+ − 527
251
+ − 528
(FIXME: say something about calling conventions)
15
+ − 529
*}
+ − 530
10
+ − 531
2
+ − 532
section {* Antiquotations *}
+ − 533
+ − 534
text {*
49
+ − 535
The main advantage of embedding all code in a theory is that the code can
58
+ − 536
contain references to entities defined on the logical level of Isabelle. By
+ − 537
this we mean definitions, theorems, terms and so on. This kind of reference is
298
+ − 538
realised with antiquotations, sometimes also referred to as ML-antiquotations.
+ − 539
For example, one can print out the name of the current
49
+ − 540
theory by typing
+ − 541
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 542
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 543
@{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 544
5
+ − 545
where @{text "@{theory}"} is an antiquotation that is substituted with the
49
+ − 546
current theory (remember that we assumed we are inside the theory
89
+ − 547
@{text FirstSteps}). The name of this theory can be extracted using
256
+ − 548
the function @{ML [index] theory_name in Context}.
5
+ − 549
89
+ − 550
Note, however, that antiquotations are statically linked, that is their value is
12
+ − 551
determined at ``compile-time'', not ``run-time''. For example the function
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 552
*}
5
+ − 553
69
+ − 554
ML{*fun not_current_thyname () = Context.theory_name @{theory} *}
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 555
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 556
text {*
2
+ − 557
89
+ − 558
does \emph{not} return the name of the current theory, if it is run in a
5
+ − 559
different theory. Instead, the code above defines the constant function
58
+ − 560
that always returns the string @{text [quotes] "FirstSteps"}, no matter where the
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 561
function is called. Operationally speaking, the antiquotation @{text "@{theory}"} is
5
+ − 562
\emph{not} replaced with code that will look up the current theory in
+ − 563
some data structure and return it. Instead, it is literally
+ − 564
replaced with the value representing the theory name.
2
+ − 565
132
+ − 566
In a similar way you can use antiquotations to refer to proved theorems:
133
+ − 567
@{text "@{thm \<dots>}"} for a single theorem
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 568
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 569
@{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"}
75
+ − 570
133
+ − 571
and @{text "@{thms \<dots>}"} for more than one
132
+ − 572
+ − 573
@{ML_response_fake [display,gray] "@{thms conj_ac}"
+ − 574
"(?P \<and> ?Q) = (?Q \<and> ?P)
+ − 575
(?P \<and> ?Q \<and> ?R) = (?Q \<and> ?P \<and> ?R)
+ − 576
((?P \<and> ?Q) \<and> ?R) = (?P \<and> ?Q \<and> ?R)"}
+ − 577
292
+ − 578
The point of these antiquotations is that referring to theorems in this way
+ − 579
makes your code independent from what theorems the user might have stored
+ − 580
under this name (this becomes especially important when you deal with
+ − 581
theorem lists; see Section \ref{sec:attributes}).
+ − 582
+ − 583
You can also refer to the current simpset via an antiquotation. To illustrate
+ − 584
this we implement the function that extracts the theorem names stored in a
+ − 585
simpset.
131
+ − 586
*}
75
+ − 587
149
+ − 588
ML{*fun get_thm_names_from_ss simpset =
131
+ − 589
let
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 590
val {simps,...} = MetaSimplifier.dest_ss simpset
70
+ − 591
in
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 592
map #1 simps
131
+ − 593
end*}
54
+ − 594
131
+ − 595
text {*
256
+ − 596
The function @{ML [index] dest_ss in MetaSimplifier} returns a record containing all
193
+ − 597
information stored in the simpset, but we are only interested in the names of the
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 598
simp-rules. Now you can feed in the current simpset into this function.
193
+ − 599
The current simpset can be referred to using the antiquotation @{text "@{simpset}"}.
81
+ − 600
131
+ − 601
@{ML_response_fake [display,gray]
149
+ − 602
"get_thm_names_from_ss @{simpset}"
+ − 603
"[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
10
+ − 604
196
+ − 605
Again, this way of referencing simpsets makes you independent from additions
292
+ − 606
of lemmas to the simpset by the user that can potentially cause loops in your
+ − 607
code.
156
+ − 608
251
+ − 609
On the ML-level of Isabelle, you often have to work with qualified names.
+ − 610
These are strings with some additional information, such as positional information
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 611
and qualifiers. Such qualified names can be generated with the antiquotation
292
+ − 612
@{text "@{binding \<dots>}"}. For example
192
+ − 613
+ − 614
@{ML_response [display,gray]
+ − 615
"@{binding \"name\"}"
+ − 616
"name"}
+ − 617
292
+ − 618
An example where a qualified name is needed is the function
+ − 619
@{ML [index] define in LocalTheory}. This function is used below to define
+ − 620
the constant @{term "TrueConj"} as the conjunction @{term "True \<and> True"}.
192
+ − 621
*}
+ − 622
+ − 623
local_setup %gray {*
+ − 624
snd o LocalTheory.define Thm.internalK
+ − 625
((@{binding "TrueConj"}, NoSyn),
+ − 626
(Attrib.empty_binding, @{term "True \<and> True"})) *}
+ − 627
193
+ − 628
text {*
+ − 629
Now querying the definition you obtain:
+ − 630
+ − 631
\begin{isabelle}
+ − 632
\isacommand{thm}~@{text "TrueConj_def"}\\
225
+ − 633
@{text "> "}~@{thm TrueConj_def}
193
+ − 634
\end{isabelle}
+ − 635
194
+ − 636
(FIXME give a better example why bindings are important; maybe
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 637
give a pointer to \isacommand{local\_setup}; if not, then explain
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 638
why @{ML snd} is needed)
193
+ − 639
292
+ − 640
It is also possible to define your own antiquotations. But you should
298
+ − 641
exercise care when introducing new ones, as they can also make your
+ − 642
code also difficult to read. In the next section we will see how the (build in)
292
+ − 643
antiquotation @{text "@{term \<dots>}"} can be used to construct terms.
+ − 644
A restriction of this antiquotation is that it does not allow you to
298
+ − 645
use schematic variables. If you want an antiquotation that does not
292
+ − 646
have this restriction, you can implement your own using the
298
+ − 647
function @{ML [index] ML_Antiquote.inline}. The code is as follows.
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 648
*}
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 649
292
+ − 650
ML %linenosgray{*ML_Antiquote.inline "term_pat"
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 651
(Args.context -- Scan.lift Args.name_source >>
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 652
(fn (ctxt, s) =>
264
+ − 653
s |> ProofContext.read_term_pattern ctxt
+ − 654
|> ML_Syntax.print_term
+ − 655
|> ML_Syntax.atomic))*}
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 656
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 657
text {*
298
+ − 658
We call the new antiquotation @{text "term_pat"} (Line 1); the parser in Line
292
+ − 659
2 provides us with a context and a string; this string is transformed into a
298
+ − 660
term using the function @{ML [index] read_term_pattern in ProofContext} (Line 4);
292
+ − 661
the next two lines print the term so that the ML-system can understand
+ − 662
them. An example of this antiquotation is as follows.
+ − 663
+ − 664
@{ML_response_fake [display,gray]
+ − 665
"@{term_pat \"Suc (?x::nat)\"}"
+ − 666
"Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
+ − 667
298
+ − 668
which is the internal representation of the term @{text "Suc ?x"}.
+ − 669
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 670
\begin{readmore}
292
+ − 671
The file @{ML_file "Pure/ML/ml_antiquote.ML"} contains the the definitions
+ − 672
for most antiquotations.
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 673
\end{readmore}
292
+ − 674
298
+ − 675
Note one source of possible confusion about antiquotations. There are two kinds
+ − 676
of them in Isabelle, which have very different purpose and infrastructures. The
+ − 677
first kind, described in this section, are \emph{ML-antiquotations}. They are
+ − 678
used to refer to entities (like terms, types etc) from Isabelle's logic layer
+ − 679
inside ML-code. They are ``linked'' statically at compile-time, which limits
+ − 680
sometimes their usefulness in cases where, for example, terms needs to be
+ − 681
built up dynamically.
+ − 682
+ − 683
The other kind of antiquotations are \emph{document} antiquotations.
+ − 684
They are used only in the text parts of Isabelle and their purpose is to print
+ − 685
logical entities inside \LaTeX-documents. They are part of the user level and
+ − 686
therefore we are not interested in them in this Tutorial, except in
+ − 687
Appendix \ref{rec:docantiquotations} where we show how to implement your
+ − 688
own document antiquotations.
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 689
*}
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 690
15
+ − 691
section {* Terms and Types *}
2
+ − 692
+ − 693
text {*
197
+ − 694
One way to construct Isabelle terms, is by using the antiquotation
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 695
\mbox{@{text "@{term \<dots>}"}}. For example
2
+ − 696
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 697
@{ML_response [display,gray]
75
+ − 698
"@{term \"(a::nat) + b = c\"}"
+ − 699
"Const (\"op =\", \<dots>) $
149
+ − 700
(Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
2
+ − 701
207
+ − 702
will show the term @{term "(a::nat) + b = c"}, but printed using the internal
256
+ − 703
representation corresponding to the datatype @{ML_type [index] "term"} defined as follows:
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 704
*}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 705
254
+ − 706
ML_val %linenosgray{*datatype term =
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 707
Const of string * typ
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 708
| Free of string * typ
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 709
| Var of indexname * typ
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 710
| Bound of int
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 711
| Abs of string * typ * term
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 712
| $ of term * term *}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 713
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 714
text {*
298
+ − 715
This datatype implements lambda-terms typed in Church-style.
254
+ − 716
As can be seen in Line 5, terms use the usual de Bruijn index mechanism
+ − 717
for representing bound variables. For
251
+ − 718
example in
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 719
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 720
@{ML_response_fake [display, gray]
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 721
"@{term \"\<lambda>x y. x y\"}"
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 722
"Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 723
298
+ − 724
the indices refer to the number of Abstractions (@{ML Abs}) that we need to
+ − 725
skip until we hit the @{ML Abs} that binds the corresponding variable. Constructing
+ − 726
a term with dangling de Bruijn indices is possible, but will be flagged as
+ − 727
ill-formed when you try to typecheck or certify it (see
+ − 728
Section~\ref{sec:typechecking}). Note that the names of bound variables are kept at
+ − 729
abstractions for printing purposes, and so should be treated only as
+ − 730
``comments''. Application in Isabelle is realised with the term-constructor
+ − 731
@{ML $}.
+ − 732
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 733
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 734
Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free})
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 735
and variables (term-constructor @{ML Var}). The latter correspond to the schematic
251
+ − 736
variables that when printed show up with a question mark in front of them. Consider
+ − 737
the following two examples
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 738
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 739
@{ML_response_fake [display, gray]
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 740
"let
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 741
val v1 = Var ((\"x\", 3), @{typ bool})
251
+ − 742
val v2 = Var ((\"x1\", 3), @{typ bool})
298
+ − 743
val v3 = Free (\"x\", @{typ bool})
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 744
in
301
+ − 745
tracing (Syntax.string_of_term @{context} v1);
+ − 746
tracing (Syntax.string_of_term @{context} v2);
+ − 747
tracing (Syntax.string_of_term @{context} v3)
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 748
end"
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 749
"?x3
298
+ − 750
?x1.3
+ − 751
x"}
+ − 752
+ − 753
When constructing terms, you are usually concerned with free variables (as mentioned earlier,
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 754
you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}).
254
+ − 755
If you deal with theorems, you have to, however, observe the distinction. A similar
251
+ − 756
distinction holds for types (see below).
10
+ − 757
2
+ − 758
\begin{readmore}
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 759
Terms and types are described in detail in \isccite{sec:terms}. Their
78
+ − 760
definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}.
254
+ − 761
For constructing terms involving HOL constants, many helper functions are defined
+ − 762
in @{ML_file "HOL/Tools/hologic.ML"}.
2
+ − 763
\end{readmore}
193
+ − 764
+ − 765
Constructing terms via antiquotations has the advantage that only typable
+ − 766
terms can be constructed. For example
2
+ − 767
193
+ − 768
@{ML_response_fake_both [display,gray]
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 769
"@{term \"x x\"}"
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 770
"Type unification failed: Occurs check!"}
193
+ − 771
194
+ − 772
raises a typing error, while it perfectly ok to construct the term
251
+ − 773
+ − 774
@{ML_response_fake [display,gray]
+ − 775
"let
+ − 776
val omega = Free (\"x\", @{typ nat}) $ Free (\"x\", @{typ nat})
+ − 777
in
301
+ − 778
tracing (Syntax.string_of_term @{context} omega)
251
+ − 779
end"
+ − 780
"x x"}
193
+ − 781
+ − 782
with the raw ML-constructors.
255
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 783
13
+ − 784
Sometimes the internal representation of terms can be surprisingly different
157
+ − 785
from what you see at the user-level, because the layers of
47
4daf913fdbe1
hakked latex so that it does not display ML {* *}; general tuning
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 786
parsing/type-checking/pretty printing can be quite elaborate.
2
+ − 787
10
+ − 788
\begin{exercise}
2
+ − 789
Look at the internal term representation of the following terms, and
89
+ − 790
find out why they are represented like this:
2
+ − 791
+ − 792
\begin{itemize}
+ − 793
\item @{term "case x of 0 \<Rightarrow> 0 | Suc y \<Rightarrow> y"}
+ − 794
\item @{term "\<lambda>(x,y). P y x"}
+ − 795
\item @{term "{ [x::int] | x. x \<le> -2 }"}
+ − 796
\end{itemize}
+ − 797
+ − 798
Hint: The third term is already quite big, and the pretty printer
+ − 799
may omit parts of it by default. If you want to see all of it, you
122
+ − 800
can use the following ML-function to set the printing depth to a higher
+ − 801
value:
12
+ − 802
75
+ − 803
@{ML [display,gray] "print_depth 50"}
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 804
\end{exercise}
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 805
13
+ − 806
The antiquotation @{text "@{prop \<dots>}"} constructs terms of propositional type,
50
+ − 807
inserting the invisible @{text "Trueprop"}-coercions whenever necessary.
68
+ − 808
Consider for example the pairs
12
+ − 809
126
+ − 810
@{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})"
+ − 811
"(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
149
+ − 812
Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
65
+ − 813
108
8bea3f74889d
added to the tactical chapter; polished; added the tabularstar environment (which is just tabular*)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 814
where a coercion is inserted in the second component and
12
+ − 815
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 816
@{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})"
65
+ − 817
"(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"}
12
+ − 818
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 819
where it is not (since it is already constructed by a meta-implication).
19
+ − 820
193
+ − 821
As already seen above, types can be constructed using the antiquotation
+ − 822
@{text "@{typ \<dots>}"}. For example:
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 823
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 824
@{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
39
631d12c25bde
substantial changes to the antiquotations (preliminary version)
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 825
298
+ − 826
The corresponding datatype is
251
+ − 827
*}
+ − 828
+ − 829
ML_val{*datatype typ =
+ − 830
Type of string * typ list
+ − 831
| TFree of string * sort
+ − 832
| TVar of indexname * sort *}
+ − 833
+ − 834
text {*
+ − 835
Like with terms, there is the distinction between free type
+ − 836
variables (term-constructor @{ML "TFree"} and schematic
+ − 837
type variables (term-constructor @{ML "TVar"}). A type constant,
+ − 838
like @{typ "int"} or @{typ bool}, are types with an empty list
298
+ − 839
of argument types. However, it is a bit difficult to show an
+ − 840
example, because Isabelle always pretty-prints types (unlike terms).
+ − 841
Here is a contrived example:
+ − 842
+ − 843
@{ML_response [display, gray]
+ − 844
"if Type (\"bool\", []) = @{typ \"bool\"} then true else false"
+ − 845
"true"}
251
+ − 846
19
+ − 847
\begin{readmore}
+ − 848
Types are described in detail in \isccite{sec:types}. Their
78
+ − 849
definition and many useful operations are implemented
+ − 850
in @{ML_file "Pure/type.ML"}.
19
+ − 851
\end{readmore}
47
4daf913fdbe1
hakked latex so that it does not display ML {* *}; general tuning
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 852
*}
19
+ − 853
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 854
section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *}
12
+ − 855
+ − 856
text {*
81
+ − 857
While antiquotations are very convenient for constructing terms, they can
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 858
only construct fixed terms (remember they are ``linked'' at compile-time).
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 859
However, you often need to construct terms dynamically. For example, a
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 860
function that returns the implication @{text "\<And>(x::nat). P x \<Longrightarrow> Q x"} taking
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 861
@{term P} and @{term Q} as arguments can only be written as:
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 862
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 863
*}
12
+ − 864
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 865
ML{*fun make_imp P Q =
131
+ − 866
let
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 867
val x = Free ("x", @{typ nat})
131
+ − 868
in
+ − 869
Logic.all x (Logic.mk_implies (P $ x, Q $ x))
+ − 870
end *}
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 871
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 872
text {*
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 873
The reason is that you cannot pass the arguments @{term P} and @{term Q}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 874
into an antiquotation.\footnote{At least not at the moment.} For example
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 875
the following does \emph{not} work.
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 876
*}
13
+ − 877
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 878
ML{*fun make_wrong_imp P Q = @{prop "\<And>(x::nat). P x \<Longrightarrow> Q x"} *}
12
+ − 879
43
02f76f1b6e7b
added positions to anti-quotations; removed old antiquotation_setup; tuned the text a bit
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 880
text {*
194
+ − 881
To see this, apply @{text "@{term S}"} and @{text "@{term T}"}
193
+ − 882
to both functions. With @{ML make_imp} you obtain the intended term involving
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 883
the given arguments
65
+ − 884
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 885
@{ML_response [display,gray] "make_imp @{term S} @{term T}"
162
+ − 886
"Const \<dots> $
+ − 887
Abs (\"x\", Type (\"nat\",[]),
+ − 888
Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ (Free (\"T\",\<dots>) $ \<dots>))"}
68
+ − 889
193
+ − 890
whereas with @{ML make_wrong_imp} you obtain a term involving the @{term "P"}
68
+ − 891
and @{text "Q"} from the antiquotation.
+ − 892
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 893
@{ML_response [display,gray] "make_wrong_imp @{term S} @{term T}"
162
+ − 894
"Const \<dots> $
+ − 895
Abs (\"x\", \<dots>,
+ − 896
Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $
192
+ − 897
(Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"}
65
+ − 898
192
+ − 899
There are a number of handy functions that are frequently used for
256
+ − 900
constructing terms. One is the function @{ML [index] list_comb}, which takes a term
199
+ − 901
and a list of terms as arguments, and produces as output the term
192
+ − 902
list applied to the term. For example
+ − 903
+ − 904
@{ML_response_fake [display,gray]
298
+ − 905
"let
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 906
val trm = @{term \"P::nat\"}
298
+ − 907
val args = [@{term \"True\"}, @{term \"False\"}]
+ − 908
in
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 909
list_comb (trm, args)
298
+ − 910
end"
192
+ − 911
"Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"}
+ − 912
256
+ − 913
Another handy function is @{ML [index] lambda}, which abstracts a variable
193
+ − 914
in a term. For example
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 915
193
+ − 916
@{ML_response_fake [display,gray]
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 917
"let
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 918
val x_nat = @{term \"x::nat\"}
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 919
val trm = @{term \"(P::nat \<Rightarrow> bool) x\"}
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 920
in
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 921
lambda x_nat trm
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 922
end"
193
+ − 923
"Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
+ − 924
298
+ − 925
In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound 0"}),
193
+ − 926
and an abstraction. It also records the type of the abstracted
+ − 927
variable and for printing purposes also its name. Note that because of the
+ − 928
typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"}
+ − 929
is of the same type as the abstracted variable. If it is of different type,
+ − 930
as in
+ − 931
+ − 932
@{ML_response_fake [display,gray]
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 933
"let
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 934
val x_int = @{term \"x::int\"}
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 935
val trm = @{term \"(P::nat \<Rightarrow> bool) x\"}
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 936
in
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 937
lambda x_int trm
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 938
end"
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 939
"Abs (\"x\", \"int\", Free (\"P\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"}
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 940
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 941
then the variable @{text "Free (\"x\", \"int\")"} is \emph{not} abstracted.
193
+ − 942
This is a fundamental principle
+ − 943
of Church-style typing, where variables with the same name still differ, if they
+ − 944
have different type.
192
+ − 945
256
+ − 946
There is also the function @{ML [index] subst_free} with which terms can
194
+ − 947
be replaced by other terms. For example below, we will replace in
292
+ − 948
@{term "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0 x"}
+ − 949
the subterm @{term "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0"} by @{term y}, and @{term x} by @{term True}.
49
+ − 950
193
+ − 951
@{ML_response_fake [display,gray]
292
+ − 952
"let
+ − 953
val s1 = (@{term \"(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0\"}, @{term \"y::nat \<Rightarrow> nat\"})
+ − 954
val s2 = (@{term \"x::nat\"}, @{term \"True\"})
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 955
val trm = @{term \"((f::nat \<Rightarrow> nat \<Rightarrow> nat) 0) x\"}
292
+ − 956
in
+ − 957
subst_free [s1, s2] trm
+ − 958
end"
193
+ − 959
"Free (\"y\", \"nat \<Rightarrow> nat\") $ Const (\"True\", \"bool\")"}
+ − 960
+ − 961
As can be seen, @{ML subst_free} does not take typability into account.
+ − 962
However it takes alpha-equivalence into account:
+ − 963
+ − 964
@{ML_response_fake [display, gray]
292
+ − 965
"let
+ − 966
val s = (@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})
+ − 967
val trm = @{term \"(\<lambda>x::nat. x)\"}
+ − 968
in
+ − 969
subst_free [s] trm
+ − 970
end"
193
+ − 971
"Free (\"x\", \"nat\")"}
192
+ − 972
255
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 973
There are many convenient functions that construct specific HOL-terms. For
256
+ − 974
example @{ML [index] mk_eq in HOLogic} constructs an equality out of two terms.
255
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 975
The types needed in this equality are calculated from the type of the
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 976
arguments. For example
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 977
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 978
@{ML_response_fake [gray,display]
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 979
"let
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 980
val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 981
in
301
+ − 982
tracing (Syntax.string_of_term @{context} eq)
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 983
end"
255
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 984
"True = False"}
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 985
*}
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 986
292
+ − 987
text {*
+ − 988
\begin{readmore}
+ − 989
Most of the HOL-specific operations on terms and types are defined
+ − 990
in @{ML_file "HOL/Tools/hologic.ML"}.
+ − 991
\end{readmore}
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 992
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 993
When constructing terms manually, there are a few subtle issues with
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 994
constants. They usually crop up when pattern matching terms or types, or
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 995
when constructing them. While it is perfectly ok to write the function
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 996
@{text is_true} as follows
122
+ − 997
*}
+ − 998
+ − 999
ML{*fun is_true @{term True} = true
+ − 1000
| is_true _ = false*}
+ − 1001
+ − 1002
text {*
+ − 1003
this does not work for picking out @{text "\<forall>"}-quantified terms. Because
+ − 1004
the function
+ − 1005
*}
+ − 1006
+ − 1007
ML{*fun is_all (@{term All} $ _) = true
+ − 1008
| is_all _ = false*}
+ − 1009
+ − 1010
text {*
275
+ − 1011
will not correctly match the formula @{prop[source] "\<forall>x::nat. P x"}:
122
+ − 1012
+ − 1013
@{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "false"}
+ − 1014
+ − 1015
The problem is that the @{text "@term"}-antiquotation in the pattern
123
+ − 1016
fixes the type of the constant @{term "All"} to be @{typ "('a \<Rightarrow> bool) \<Rightarrow> bool"} for
122
+ − 1017
an arbitrary, but fixed type @{typ "'a"}. A properly working alternative
+ − 1018
for this function is
+ − 1019
*}
+ − 1020
+ − 1021
ML{*fun is_all (Const ("All", _) $ _) = true
+ − 1022
| is_all _ = false*}
+ − 1023
+ − 1024
text {*
+ − 1025
because now
+ − 1026
+ − 1027
@{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "true"}
+ − 1028
149
+ − 1029
matches correctly (the first wildcard in the pattern matches any type and the
+ − 1030
second any term).
122
+ − 1031
123
+ − 1032
However there is still a problem: consider the similar function that
131
+ − 1033
attempts to pick out @{text "Nil"}-terms:
122
+ − 1034
*}
+ − 1035
+ − 1036
ML{*fun is_nil (Const ("Nil", _)) = true
+ − 1037
| is_nil _ = false *}
+ − 1038
+ − 1039
text {*
123
+ − 1040
Unfortunately, also this function does \emph{not} work as expected, since
122
+ − 1041
+ − 1042
@{ML_response [display,gray] "is_nil @{term \"Nil\"}" "false"}
+ − 1043
123
+ − 1044
The problem is that on the ML-level the name of a constant is more
149
+ − 1045
subtle than you might expect. The function @{ML is_all} worked correctly,
123
+ − 1046
because @{term "All"} is such a fundamental constant, which can be referenced
+ − 1047
by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at
122
+ − 1048
+ − 1049
@{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"}
+ − 1050
131
+ − 1051
the name of the constant @{text "Nil"} depends on the theory in which the
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1052
term constructor is defined (@{text "List"}) and also in which datatype
128
+ − 1053
(@{text "list"}). Even worse, some constants have a name involving
+ − 1054
type-classes. Consider for example the constants for @{term "zero"} and
131
+ − 1055
\mbox{@{text "(op *)"}}:
122
+ − 1056
290
+ − 1057
@{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"(op *)\"})"
126
+ − 1058
"(Const (\"HOL.zero_class.zero\", \<dots>),
122
+ − 1059
Const (\"HOL.times_class.times\", \<dots>))"}
+ − 1060
123
+ − 1061
While you could use the complete name, for example
+ − 1062
@{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or
122
+ − 1063
matching against @{text "Nil"}, this would make the code rather brittle.
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1064
The reason is that the theory and the name of the datatype can easily change.
123
+ − 1065
To make the code more robust, it is better to use the antiquotation
122
+ − 1066
@{text "@{const_name \<dots>}"}. With this antiquotation you can harness the
200
+ − 1067
variable parts of the constant's name. Therefore a function for
123
+ − 1068
matching against constants that have a polymorphic type should
+ − 1069
be written as follows.
122
+ − 1070
*}
+ − 1071
+ − 1072
ML{*fun is_nil_or_all (Const (@{const_name "Nil"}, _)) = true
+ − 1073
| is_nil_or_all (Const (@{const_name "All"}, _) $ _) = true
+ − 1074
| is_nil_or_all _ = false *}
+ − 1075
+ − 1076
text {*
274
+ − 1077
\begin{readmore}
+ − 1078
There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file "Pure/logic.ML"} and
+ − 1079
@{ML_file "HOL/Tools/hologic.ML"} that make such manual constructions of terms
+ − 1080
and types easier.\end{readmore}
+ − 1081
+ − 1082
Have a look at these files and try to solve the following two exercises:
+ − 1083
+ − 1084
\begin{exercise}\label{fun:revsum}
+ − 1085
Write a function @{text "rev_sum : term -> term"} that takes a
+ − 1086
term of the form @{text "t\<^isub>1 + t\<^isub>2 + \<dots> + t\<^isub>n"} (whereby @{text "n"} might be one)
+ − 1087
and returns the reversed sum @{text "t\<^isub>n + \<dots> + t\<^isub>2 + t\<^isub>1"}. Assume
+ − 1088
the @{text "t\<^isub>i"} can be arbitrary expressions and also note that @{text "+"}
+ − 1089
associates to the left. Try your function on some examples.
+ − 1090
\end{exercise}
+ − 1091
+ − 1092
\begin{exercise}\label{fun:makesum}
+ − 1093
Write a function which takes two terms representing natural numbers
+ − 1094
in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
+ − 1095
number representing their sum.
+ − 1096
\end{exercise}
+ − 1097
+ − 1098
The antiquotation for properly referencing type constants is @{text "@{type_name \<dots>}"}.
242
+ − 1099
For example
+ − 1100
+ − 1101
@{ML_response [display,gray]
+ − 1102
"@{type_name \"list\"}" "\"List.list\""}
+ − 1103
251
+ − 1104
(FIXME: Explain the following better.)
+ − 1105
200
+ − 1106
Occasionally you have to calculate what the ``base'' name of a given
258
+ − 1107
constant is. For this you can use the function @{ML [index] "Sign.extern_const"} or
+ − 1108
@{ML [index] Long_Name.base_name}. For example:
124
+ − 1109
+ − 1110
@{ML_response [display,gray] "Sign.extern_const @{theory} \"List.list.Nil\"" "\"Nil\""}
122
+ − 1111
124
+ − 1112
The difference between both functions is that @{ML extern_const in Sign} returns
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1113
the smallest name that is still unique, whereas @{ML base_name in Long_Name} always
124
+ − 1114
strips off all qualifiers.
122
+ − 1115
+ − 1116
\begin{readmore}
162
+ − 1117
Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};
+ − 1118
functions about signatures in @{ML_file "Pure/sign.ML"}.
122
+ − 1119
\end{readmore}
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1120
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1121
Although types of terms can often be inferred, there are many
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1122
situations where you need to construct types manually, especially
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1123
when defining constants. For example the function returning a function
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1124
type is as follows:
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1125
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1126
*}
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1127
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1128
ML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1129
256
+ − 1130
text {* This can be equally written with the combinator @{ML [index] "-->"} as: *}
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1131
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1132
ML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1133
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1134
text {*
255
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1135
If you want to construct a function type with more than one argument
256
+ − 1136
type, then you can use @{ML [index] "--->"}.
255
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1137
*}
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1138
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1139
ML{*fun make_fun_types tys ty = tys ---> ty *}
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1140
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1141
text {*
256
+ − 1142
A handy function for manipulating terms is @{ML [index] map_types}: it takes a
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1143
function and applies it to every type in a term. You can, for example,
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1144
change every @{typ nat} in a term into an @{typ int} using the function:
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1145
*}
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1146
252
+ − 1147
ML{*fun nat_to_int ty =
+ − 1148
(case ty of
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1149
@{typ nat} => @{typ int}
252
+ − 1150
| Type (s, tys) => Type (s, map nat_to_int tys)
+ − 1151
| _ => ty)*}
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1152
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1153
text {*
200
+ − 1154
Here is an example:
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1155
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1156
@{ML_response_fake [display,gray]
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1157
"map_types nat_to_int @{term \"a = (1::nat)\"}"
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1158
"Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1159
$ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"}
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1160
251
+ − 1161
If you want to obtain the list of free type-variables of a term, you
256
+ − 1162
can use the function @{ML [index] add_tfrees in Term}
+ − 1163
(similarly @{ML [index] add_tvars in Term} for the schematic type-variables).
+ − 1164
One would expect that such functions
251
+ − 1165
take a term as input and return a list of types. But their type is actually
+ − 1166
+ − 1167
@{text[display] "Term.term -> (string * Term.sort) list -> (string * Term.sort) list"}
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1168
251
+ − 1169
that is they take, besides a term, also a list of type-variables as input.
+ − 1170
So in order to obtain the list of type-variables of a term you have to
+ − 1171
call them as follows
+ − 1172
+ − 1173
@{ML_response [gray,display]
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1174
"Term.add_tfrees @{term \"(a, b)\"} []"
251
+ − 1175
"[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"}
+ − 1176
256
+ − 1177
The reason for this definition is that @{ML add_tfrees in Term} can
251
+ − 1178
be easily folded over a list of terms. Similarly for all functions
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1179
named @{text "add_*"} in @{ML_file "Pure/term.ML"}.
251
+ − 1180
122
+ − 1181
*}
162
+ − 1182
122
+ − 1183
298
+ − 1184
section {* Type-Checking\label{sec:typechecking} *}
124
+ − 1185
+ − 1186
text {*
+ − 1187
131
+ − 1188
You can freely construct and manipulate @{ML_type "term"}s and @{ML_type
+ − 1189
typ}es, since they are just arbitrary unchecked trees. However, you
+ − 1190
eventually want to see if a term is well-formed, or type-checks, relative to
256
+ − 1191
a theory. Type-checking is done via the function @{ML [index] cterm_of}, which
+ − 1192
converts a @{ML_type [index] term} into a @{ML_type [index] cterm}, a \emph{certified}
131
+ − 1193
term. Unlike @{ML_type term}s, which are just trees, @{ML_type "cterm"}s are
+ − 1194
abstract objects that are guaranteed to be type-correct, and they can only
+ − 1195
be constructed via ``official interfaces''.
+ − 1196
124
+ − 1197
+ − 1198
Type-checking is always relative to a theory context. For now we use
+ − 1199
the @{ML "@{theory}"} antiquotation to get hold of the current theory.
+ − 1200
For example you can write:
+ − 1201
149
+ − 1202
@{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"(a::nat) + b = c\"}" "a + b = c"}
124
+ − 1203
+ − 1204
This can also be written with an antiquotation:
+ − 1205
+ − 1206
@{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
+ − 1207
+ − 1208
Attempting to obtain the certified term for
+ − 1209
+ − 1210
@{ML_response_fake_both [display,gray] "@{cterm \"1 + True\"}" "Type unification failed \<dots>"}
+ − 1211
+ − 1212
yields an error (since the term is not typable). A slightly more elaborate
+ − 1213
example that type-checks is:
+ − 1214
+ − 1215
@{ML_response_fake [display,gray]
+ − 1216
"let
+ − 1217
val natT = @{typ \"nat\"}
+ − 1218
val zero = @{term \"0::nat\"}
+ − 1219
in
+ − 1220
cterm_of @{theory}
+ − 1221
(Const (@{const_name plus}, natT --> natT --> natT) $ zero $ zero)
+ − 1222
end" "0 + 0"}
+ − 1223
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1224
In Isabelle not just terms need to be certified, but also types. For example,
198
+ − 1225
you obtain the certified type for the Isabelle type @{typ "nat \<Rightarrow> bool"} on
178
fb8f22dd8ad0
adapted to latest Attrib.setup changes and more work on the simple induct chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1226
the ML-level as follows:
160
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1227
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1228
@{ML_response_fake [display,gray]
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1229
"ctyp_of @{theory} (@{typ nat} --> @{typ bool})"
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1230
"nat \<Rightarrow> bool"}
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1231
207
+ − 1232
or with the antiquotation:
+ − 1233
+ − 1234
@{ML_response_fake [display,gray]
+ − 1235
"@{ctyp \"nat \<Rightarrow> bool\"}"
+ − 1236
"nat \<Rightarrow> bool"}
+ − 1237
160
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1238
\begin{readmore}
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1239
For functions related to @{ML_type cterm}s and @{ML_type ctyp}s see
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1240
the file @{ML_file "Pure/thm.ML"}.
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1241
\end{readmore}
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1242
293
+ − 1243
\begin{exercise}
124
+ − 1244
Check that the function defined in Exercise~\ref{fun:revsum} returns a
293
+ − 1245
result that type-checks. See what happens to the solutions of this
+ − 1246
exercise given in \ref{ch:solutions} when they receive an ill-typed term
+ − 1247
as input.
124
+ − 1248
\end{exercise}
+ − 1249
200
+ − 1250
Remember Isabelle follows the Church-style typing for terms, i.e., a term contains
178
fb8f22dd8ad0
adapted to latest Attrib.setup changes and more work on the simple induct chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1251
enough typing information (constants, free variables and abstractions all have typing
124
+ − 1252
information) so that it is always clear what the type of a term is.
256
+ − 1253
Given a well-typed term, the function @{ML [index] type_of} returns the
124
+ − 1254
type of a term. Consider for example:
+ − 1255
+ − 1256
@{ML_response [display,gray]
+ − 1257
"type_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::nat\"})" "bool"}
+ − 1258
+ − 1259
To calculate the type, this function traverses the whole term and will
197
+ − 1260
detect any typing inconsistency. For example changing the type of the variable
149
+ − 1261
@{term "x"} from @{typ "nat"} to @{typ "int"} will result in the error message:
124
+ − 1262
+ − 1263
@{ML_response_fake [display,gray]
+ − 1264
"type_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::int\"})"
+ − 1265
"*** Exception- TYPE (\"type_of: type mismatch in application\" \<dots>"}
+ − 1266
+ − 1267
Since the complete traversal might sometimes be too costly and
256
+ − 1268
not necessary, there is the function @{ML [index] fastype_of}, which
149
+ − 1269
also returns the type of a term.
124
+ − 1270
+ − 1271
@{ML_response [display,gray]
+ − 1272
"fastype_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::nat\"})" "bool"}
+ − 1273
177
+ − 1274
However, efficiency is gained on the expense of skipping some tests. You
124
+ − 1275
can see this in the following example
+ − 1276
+ − 1277
@{ML_response [display,gray]
+ − 1278
"fastype_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::int\"})" "bool"}
+ − 1279
149
+ − 1280
where no error is detected.
124
+ − 1281
+ − 1282
Sometimes it is a bit inconvenient to construct a term with
+ − 1283
complete typing annotations, especially in cases where the typing
+ − 1284
information is redundant. A short-cut is to use the ``place-holder''
256
+ − 1285
type @{ML [index] dummyT} and then let type-inference figure out the
124
+ − 1286
complete type. An example is as follows:
+ − 1287
+ − 1288
@{ML_response_fake [display,gray]
+ − 1289
"let
126
+ − 1290
val c = Const (@{const_name \"plus\"}, dummyT)
+ − 1291
val o = @{term \"1::nat\"}
+ − 1292
val v = Free (\"x\", dummyT)
124
+ − 1293
in
126
+ − 1294
Syntax.check_term @{context} (c $ o $ v)
124
+ − 1295
end"
126
+ − 1296
"Const (\"HOL.plus_class.plus\", \"nat \<Rightarrow> nat \<Rightarrow> nat\") $
+ − 1297
Const (\"HOL.one_class.one\", \"nat\") $ Free (\"x\", \"nat\")"}
124
+ − 1298
+ − 1299
Instead of giving explicitly the type for the constant @{text "plus"} and the free
200
+ − 1300
variable @{text "x"}, type-inference fills in the missing information.
124
+ − 1301
+ − 1302
\begin{readmore}
+ − 1303
See @{ML_file "Pure/Syntax/syntax.ML"} where more functions about reading,
200
+ − 1304
checking and pretty-printing of terms are defined. Functions related to
+ − 1305
type-inference are implemented in @{ML_file "Pure/type.ML"} and
160
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1306
@{ML_file "Pure/type_infer.ML"}.
124
+ − 1307
\end{readmore}
162
+ − 1308
+ − 1309
(FIXME: say something about sorts)
124
+ − 1310
*}
+ − 1311
+ − 1312
2
+ − 1313
section {* Theorems *}
+ − 1314
+ − 1315
text {*
50
+ − 1316
Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm}
201
+ − 1317
that can only be built by going through interfaces. As a consequence, every proof
124
+ − 1318
in Isabelle is correct by construction. This follows the tradition of the LCF approach
+ − 1319
\cite{GordonMilnerWadsworth79}.
107
+ − 1320
2
+ − 1321
78
+ − 1322
To see theorems in ``action'', let us give a proof on the ML-level for the following
+ − 1323
statement:
10
+ − 1324
*}
+ − 1325
+ − 1326
lemma
+ − 1327
assumes assm\<^isub>1: "\<And>(x::nat). P x \<Longrightarrow> Q x"
+ − 1328
and assm\<^isub>2: "P t"
13
+ − 1329
shows "Q t" (*<*)oops(*>*)
10
+ − 1330
+ − 1331
text {*
185
+ − 1332
The corresponding ML-code is as follows:
10
+ − 1333
72
7b8c4fe235aa
added an antiquotation option [gray] for gray boxes around displays
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1334
@{ML_response_fake [display,gray]
42
+ − 1335
"let
138
+ − 1336
val assm1 = @{cprop \"\<And>(x::nat). P x \<Longrightarrow> Q x\"}
+ − 1337
val assm2 = @{cprop \"(P::nat\<Rightarrow>bool) t\"}
10
+ − 1338
+ − 1339
val Pt_implies_Qt =
+ − 1340
assume assm1
138
+ − 1341
|> forall_elim @{cterm \"t::nat\"};
10
+ − 1342
+ − 1343
val Qt = implies_elim Pt_implies_Qt (assume assm2);
+ − 1344
in
+ − 1345
Qt
+ − 1346
|> implies_intr assm2
+ − 1347
|> implies_intr assm1
48
+ − 1348
end" "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"}
12
+ − 1349
21
+ − 1350
This code-snippet constructs the following proof:
+ − 1351
+ − 1352
\[
+ − 1353
\infer[(@{text "\<Longrightarrow>"}$-$intro)]{\vdash @{prop "(\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> P t \<Longrightarrow> Q t"}}
+ − 1354
{\infer[(@{text "\<Longrightarrow>"}$-$intro)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
+ − 1355
{\infer[(@{text "\<Longrightarrow>"}$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"}, @{prop "P t"} \vdash @{prop "Q t"}}
+ − 1356
{\infer[(@{text "\<And>"}$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
+ − 1357
{\infer[(assume)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "\<And>x. P x \<Longrightarrow> Q x"}}{}}
+ − 1358
&
+ − 1359
\infer[(assume)]{@{prop "P t"} \vdash @{prop "P t"}}{}
+ − 1360
}
+ − 1361
}
+ − 1362
}
+ − 1363
\]
+ − 1364
102
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1365
However, while we obtained a theorem as result, this theorem is not
5e309df58557
general cleaning up; deleted antiquotation ML_text; adjusted pathnames of various files in the distribution
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1366
yet stored in Isabelle's theorem database. So it cannot be referenced later
128
+ − 1367
on. How to store theorems will be explained in Section~\ref{sec:storing}.
21
+ − 1368
13
+ − 1369
\begin{readmore}
50
+ − 1370
For the functions @{text "assume"}, @{text "forall_elim"} etc
13
+ − 1371
see \isccite{sec:thms}. The basic functions for theorems are defined in
+ − 1372
@{ML_file "Pure/thm.ML"}.
+ − 1373
\end{readmore}
12
+ − 1374
256
+ − 1375
(FIXME: handy functions working on theorems, like @{ML [index] rulify in ObjectLogic} and so on)
207
+ − 1376
230
8def50824320
added material about OuterKeyword.keyword and OuterParse.reserved
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1377
(FIXME: how to add case-names to goal states - maybe in the
207
+ − 1378
next section)
265
+ − 1379
+ − 1380
(FIXME: example for how to add theorem styles)
10
+ − 1381
*}
+ − 1382
265
+ − 1383
ML {*
+ − 1384
fun strip_assums_all (params, Const("all",_) $ Abs(a, T, t)) =
+ − 1385
strip_assums_all ((a, T)::params, t)
+ − 1386
| strip_assums_all (params, B) = (params, B)
+ − 1387
+ − 1388
fun style_parm_premise i ctxt t =
+ − 1389
let val prems = Logic.strip_imp_prems t in
+ − 1390
if i <= length prems
+ − 1391
then let val (params,t) = strip_assums_all([], nth prems (i - 1))
+ − 1392
in subst_bounds(map Free params, t) end
+ − 1393
else error ("Not enough premises for prem" ^ string_of_int i ^
+ − 1394
" in propositon: " ^ Syntax.string_of_term ctxt t)
+ − 1395
end;
+ − 1396
*}
+ − 1397
+ − 1398
ML {*
+ − 1399
strip_assums_all ([], @{term "\<And>x y. A x y"})
+ − 1400
*}
+ − 1401
+ − 1402
setup {*
+ − 1403
TermStyle.add_style "no_all_prem1" (style_parm_premise 1) #>
+ − 1404
TermStyle.add_style "no_all_prem2" (style_parm_premise 2)
+ − 1405
*}
+ − 1406
+ − 1407
243
+ − 1408
section {* Setups (TBD) *}
+ − 1409
+ − 1410
text {*
+ − 1411
In the previous section we used \isacommand{setup} in order to make
+ − 1412
a theorem attribute known to Isabelle. What happens behind the scenes
+ − 1413
is that \isacommand{setup} expects a function of type
+ − 1414
@{ML_type "theory -> theory"}: the input theory is the current theory and the
+ − 1415
output the theory where the theory attribute has been stored.
+ − 1416
+ − 1417
This is a fundamental principle in Isabelle. A similar situation occurs
+ − 1418
for example with declaring constants. The function that declares a
256
+ − 1419
constant on the ML-level is @{ML [index] add_consts_i in Sign}.
243
+ − 1420
If you write\footnote{Recall that ML-code needs to be
+ − 1421
enclosed in \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"}.}
+ − 1422
*}
+ − 1423
+ − 1424
ML{*Sign.add_consts_i [(@{binding "BAR"}, @{typ "nat"}, NoSyn)] @{theory} *}
+ − 1425
+ − 1426
text {*
+ − 1427
for declaring the constant @{text "BAR"} with type @{typ nat} and
+ − 1428
run the code, then you indeed obtain a theory as result. But if you
+ − 1429
query the constant on the Isabelle level using the command \isacommand{term}
+ − 1430
+ − 1431
\begin{isabelle}
+ − 1432
\isacommand{term}~@{text [quotes] "BAR"}\\
+ − 1433
@{text "> \"BAR\" :: \"'a\""}
+ − 1434
\end{isabelle}
+ − 1435
+ − 1436
you do not obtain a constant of type @{typ nat}, but a free variable (printed in
+ − 1437
blue) of polymorphic type. The problem is that the ML-expression above did
+ − 1438
not register the declaration with the current theory. This is what the command
+ − 1439
\isacommand{setup} is for. The constant is properly declared with
+ − 1440
*}
+ − 1441
+ − 1442
setup %gray {* Sign.add_consts_i [(@{binding "BAR"}, @{typ "nat"}, NoSyn)] *}
+ − 1443
+ − 1444
text {*
+ − 1445
Now
+ − 1446
+ − 1447
\begin{isabelle}
+ − 1448
\isacommand{term}~@{text [quotes] "BAR"}\\
+ − 1449
@{text "> \"BAR\" :: \"nat\""}
+ − 1450
\end{isabelle}
+ − 1451
+ − 1452
returns a (black) constant with the type @{typ nat}.
+ − 1453
+ − 1454
A similar command is \isacommand{local\_setup}, which expects a function
+ − 1455
of type @{ML_type "local_theory -> local_theory"}. Later on we will also
+ − 1456
use the commands \isacommand{method\_setup} for installing methods in the
+ − 1457
current theory and \isacommand{simproc\_setup} for adding new simprocs to
+ − 1458
the current simpset.
+ − 1459
*}
+ − 1460
292
+ − 1461
section {* Theorem Attributes\label{sec:attributes} *}
123
+ − 1462
127
+ − 1463
text {*
193
+ − 1464
Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text
+ − 1465
"[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags
136
+ − 1466
annotated to theorems, but functions that do further processing once a
193
+ − 1467
theorem is proved. In particular, it is not possible to find out
136
+ − 1468
what are all theorems that have a given attribute in common, unless of course
197
+ − 1469
the function behind the attribute stores the theorems in a retrievable
+ − 1470
data structure.
127
+ − 1471
193
+ − 1472
If you want to print out all currently known attributes a theorem can have,
+ − 1473
you can use the Isabelle command
127
+ − 1474
193
+ − 1475
\begin{isabelle}
+ − 1476
\isacommand{print\_attributes}\\
+ − 1477
@{text "> COMP: direct composition with rules (no lifting)"}\\
+ − 1478
@{text "> HOL.dest: declaration of Classical destruction rule"}\\
+ − 1479
@{text "> HOL.elim: declaration of Classical elimination rule"}\\
+ − 1480
@{text "> \<dots>"}
+ − 1481
\end{isabelle}
+ − 1482
+ − 1483
The theorem attributes fall roughly into two categories: the first category manipulates
207
+ − 1484
the proved theorem (for example @{text "[symmetric]"} and @{text "[THEN \<dots>]"}), and the second
+ − 1485
stores the proved theorem somewhere as data (for example @{text "[simp]"}, which adds
193
+ − 1486
the theorem to the current simpset).
127
+ − 1487
136
+ − 1488
To explain how to write your own attribute, let us start with an extremely simple
+ − 1489
version of the attribute @{text "[symmetric]"}. The purpose of this attribute is
+ − 1490
to produce the ``symmetric'' version of an equation. The main function behind
+ − 1491
this attribute is
127
+ − 1492
*}
+ − 1493
133
+ − 1494
ML{*val my_symmetric = Thm.rule_attribute (fn _ => fn thm => thm RS @{thm sym})*}
+ − 1495
+ − 1496
text {*
256
+ − 1497
where the function @{ML [index] rule_attribute in Thm} expects a function taking a
149
+ − 1498
context (which we ignore in the code above) and a theorem (@{text thm}), and
207
+ − 1499
returns another theorem (namely @{text thm} resolved with the theorem
256
+ − 1500
@{thm [source] sym}: @{thm sym[no_vars]}).\footnote{The function @{ML [index] RS}
+ − 1501
is explained in Section~\ref{sec:simpletacs}.} The function
+ − 1502
@{ML rule_attribute in Thm} then returns an attribute.
136
+ − 1503
+ − 1504
Before we can use the attribute, we need to set it up. This can be done
193
+ − 1505
using the Isabelle command \isacommand{attribute\_setup} as follows:
133
+ − 1506
*}
+ − 1507
193
+ − 1508
attribute_setup %gray my_sym = {* Scan.succeed my_symmetric *}
+ − 1509
"applying the sym rule"
133
+ − 1510
136
+ − 1511
text {*
207
+ − 1512
Inside the @{text "\<verbopen> \<dots> \<verbclose>"}, we have to specify a parser
+ − 1513
for the theorem attribute. Since the attribute does not expect any further
+ − 1514
arguments (unlike @{text "[THEN \<dots>]"}, for example), we use the parser @{ML
+ − 1515
Scan.succeed}. Later on we will also consider attributes taking further
+ − 1516
arguments. An example for the attribute @{text "[my_sym]"} is the proof
136
+ − 1517
*}
+ − 1518
+ − 1519
lemma test[my_sym]: "2 = Suc (Suc 0)" by simp
133
+ − 1520
+ − 1521
text {*
193
+ − 1522
which stores the theorem @{thm test} under the name @{thm [source] test}. You
+ − 1523
can see this, if you query the lemma:
+ − 1524
+ − 1525
\begin{isabelle}
+ − 1526
\isacommand{thm}~@{text "test"}\\
+ − 1527
@{text "> "}~@{thm test}
+ − 1528
\end{isabelle}
+ − 1529
+ − 1530
We can also use the attribute when referring to this theorem:
136
+ − 1531
+ − 1532
\begin{isabelle}
+ − 1533
\isacommand{thm}~@{text "test[my_sym]"}\\
+ − 1534
@{text "> "}~@{thm test[my_sym]}
+ − 1535
\end{isabelle}
+ − 1536
256
+ − 1537
An alternative for setting up an attribute is the function @{ML [index] setup in Attrib}.
243
+ − 1538
So instead of using \isacommand{attribute\_setup}, you can also set up the
+ − 1539
attribute as follows:
+ − 1540
*}
+ − 1541
+ − 1542
ML{*Attrib.setup @{binding "my_sym"} (Scan.succeed my_symmetric)
+ − 1543
"applying the sym rule" *}
+ − 1544
+ − 1545
text {*
+ − 1546
This gives a function from @{ML_type "Context.theory -> Context.theory"}, which
+ − 1547
can be used for example with \isacommand{setup}.
+ − 1548
193
+ − 1549
As an example of a slightly more complicated theorem attribute, we implement
207
+ − 1550
our own version of @{text "[THEN \<dots>]"}. This attribute will take a list of theorems
194
+ − 1551
as argument and resolve the proved theorem with this list (one theorem
+ − 1552
after another). The code for this attribute is
193
+ − 1553
*}
+ − 1554
+ − 1555
ML{*fun MY_THEN thms =
+ − 1556
Thm.rule_attribute (fn _ => fn thm => foldl ((op RS) o swap) thm thms)*}
+ − 1557
+ − 1558
text {*
207
+ − 1559
where @{ML swap} swaps the components of a pair. The setup of this theorem
256
+ − 1560
attribute uses the parser @{ML thms in Attrib}, which parses a list of
193
+ − 1561
theorems.
+ − 1562
*}
+ − 1563
+ − 1564
attribute_setup %gray MY_THEN = {* Attrib.thms >> MY_THEN *}
+ − 1565
"resolving the list of theorems with the proved theorem"
+ − 1566
+ − 1567
text {*
+ − 1568
You can, for example, use this theorem attribute to turn an equation into a
+ − 1569
meta-equation:
+ − 1570
+ − 1571
\begin{isabelle}
+ − 1572
\isacommand{thm}~@{text "test[MY_THEN eq_reflection]"}\\
+ − 1573
@{text "> "}~@{thm test[MY_THEN eq_reflection]}
+ − 1574
\end{isabelle}
+ − 1575
+ − 1576
If you need the symmetric version as a meta-equation, you can write
+ − 1577
+ − 1578
\begin{isabelle}
+ − 1579
\isacommand{thm}~@{text "test[MY_THEN sym eq_reflection]"}\\
+ − 1580
@{text "> "}~@{thm test[MY_THEN sym eq_reflection]}
+ − 1581
\end{isabelle}
+ − 1582
194
+ − 1583
It is also possible to combine different theorem attributes, as in:
193
+ − 1584
+ − 1585
\begin{isabelle}
+ − 1586
\isacommand{thm}~@{text "test[my_sym, MY_THEN eq_reflection]"}\\
+ − 1587
@{text "> "}~@{thm test[my_sym, MY_THEN eq_reflection]}
+ − 1588
\end{isabelle}
+ − 1589
+ − 1590
However, here also a weakness of the concept
194
+ − 1591
of theorem attributes shows through: since theorem attributes can be
193
+ − 1592
arbitrary functions, they do not in general commute. If you try
+ − 1593
+ − 1594
\begin{isabelle}
+ − 1595
\isacommand{thm}~@{text "test[MY_THEN eq_reflection, my_sym]"}\\
+ − 1596
@{text "> "}~@{text "exception THM 1 raised: RSN: no unifiers"}
+ − 1597
\end{isabelle}
+ − 1598
+ − 1599
you get an exception indicating that the theorem @{thm [source] sym}
+ − 1600
does not resolve with meta-equations.
+ − 1601
256
+ − 1602
The purpose of @{ML [index] rule_attribute in Thm} is to directly manipulate theorems.
194
+ − 1603
Another usage of theorem attributes is to add and delete theorems from stored data.
+ − 1604
For example the theorem attribute @{text "[simp]"} adds or deletes a theorem from the
256
+ − 1605
current simpset. For these applications, you can use @{ML [index] declaration_attribute in Thm}.
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1606
To illustrate this function, let us introduce a reference containing a list
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1607
of theorems.
133
+ − 1608
*}
+ − 1609
193
+ − 1610
ML{*val my_thms = ref ([] : thm list)*}
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1611
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1612
text {*
279
+ − 1613
The purpose of this reference is to store a list of theorems.
+ − 1614
We are going to modify it by adding and deleting theorems.
+ − 1615
However, a word of warning: such references must not
207
+ − 1616
be used in any code that is meant to be more than just for testing purposes!
+ − 1617
Here it is only used to illustrate matters. We will show later how to store
+ − 1618
data properly without using references.
193
+ − 1619
207
+ − 1620
We need to provide two functions that add and delete theorems from this list.
153
+ − 1621
For this we use the two functions:
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1622
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1623
207
+ − 1624
ML{*fun my_thm_add thm ctxt =
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1625
(my_thms := Thm.add_thm thm (!my_thms); ctxt)
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1626
207
+ − 1627
fun my_thm_del thm ctxt =
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1628
(my_thms := Thm.del_thm thm (!my_thms); ctxt)*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1629
133
+ − 1630
text {*
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1631
These functions take a theorem and a context and, for what we are explaining
156
+ − 1632
here it is sufficient that they just return the context unchanged. They change
256
+ − 1633
however the reference @{ML my_thms}, whereby the function
+ − 1634
@{ML [index] add_thm in Thm} adds a theorem if it is not already included in
+ − 1635
the list, and @{ML [index] del_thm in Thm} deletes one (both functions use the
+ − 1636
predicate @{ML [index] eq_thm_prop in Thm}, which compares theorems according to
+ − 1637
their proved propositions modulo alpha-equivalence).
133
+ − 1638
207
+ − 1639
You can turn functions @{ML my_thm_add} and @{ML my_thm_del} into
194
+ − 1640
attributes with the code
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1641
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1642
207
+ − 1643
ML{*val my_add = Thm.declaration_attribute my_thm_add
+ − 1644
val my_del = Thm.declaration_attribute my_thm_del *}
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1645
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1646
text {*
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1647
and set up the attributes as follows
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1648
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1649
193
+ − 1650
attribute_setup %gray my_thms = {* Attrib.add_del my_add my_del *}
207
+ − 1651
"maintaining a list of my_thms - rough test only!"
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1652
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1653
text {*
280
+ − 1654
The parser @{ML [index] add_del in Attrib} is a predefined parser for
194
+ − 1655
adding and deleting lemmas. Now if you prove the next lemma
207
+ − 1656
and attach to it the attribute @{text "[my_thms]"}
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1657
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1658
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1659
lemma trueI_2[my_thms]: "True" by simp
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1660
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1661
text {*
194
+ − 1662
then you can see it is added to the initially empty list.
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1663
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1664
@{ML_response_fake [display,gray]
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1665
"!my_thms" "[\"True\"]"}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1666
160
cc9359bfacf4
redefined the functions warning and tracing in order to properly match more antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1667
You can also add theorems using the command \isacommand{declare}.
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1668
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1669
207
+ − 1670
declare test[my_thms] trueI_2[my_thms add]
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1671
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1672
text {*
207
+ − 1673
With this attribute, the @{text "add"} operation is the default and does
+ − 1674
not need to be explicitly given. These three declarations will cause the
194
+ − 1675
theorem list to be updated as:
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1676
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1677
@{ML_response_fake [display,gray]
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1678
"!my_thms"
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1679
"[\"True\", \"Suc (Suc 0) = 2\"]"}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1680
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1681
The theorem @{thm [source] trueI_2} only appears once, since the
256
+ − 1682
function @{ML [index] add_thm in Thm} tests for duplicates, before extending
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1683
the list. Deletion from the list works as follows:
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1684
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1685
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1686
declare test[my_thms del]
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1687
156
+ − 1688
text {* After this, the theorem list is again:
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1689
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1690
@{ML_response_fake [display,gray]
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1691
"!my_thms"
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1692
"[\"True\"]"}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1693
256
+ − 1694
We used in this example two functions declared as @{ML [index] declaration_attribute in Thm},
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1695
but there can be any number of them. We just have to change the parser for reading
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1696
the arguments accordingly.
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1697
156
+ − 1698
However, as said at the beginning of this example, using references for storing theorems is
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1699
\emph{not} the received way of doing such things. The received way is to
207
+ − 1700
start a ``data slot'', below called @{text MyThmsData}, generated by the functor
194
+ − 1701
@{text GenericDataFun}:
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1702
*}
133
+ − 1703
255
ef1da1abee46
added infrastructure for index; antiquotations have now the options [index] and [indexc]
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1704
ML{*structure MyThmsData = GenericDataFun
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1705
(type T = thm list
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1706
val empty = []
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1707
val extend = I
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1708
fun merge _ = Thm.merge_thms) *}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1709
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1710
text {*
207
+ − 1711
The type @{text "T"} of this data slot is @{ML_type "thm list"}.\footnote{FIXME: give a pointer
+ − 1712
to where data slots are explained properly.}
+ − 1713
To use this data slot, you only have to change @{ML my_thm_add} and
+ − 1714
@{ML my_thm_del} to:
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1715
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1716
207
+ − 1717
ML{*val my_thm_add = MyThmsData.map o Thm.add_thm
+ − 1718
val my_thm_del = MyThmsData.map o Thm.del_thm*}
193
+ − 1719
+ − 1720
text {*
194
+ − 1721
where @{ML MyThmsData.map} updates the data appropriately. The
280
+ − 1722
corresponding theorem attributes are
193
+ − 1723
*}
+ − 1724
207
+ − 1725
ML{*val my_add = Thm.declaration_attribute my_thm_add
+ − 1726
val my_del = Thm.declaration_attribute my_thm_del *}
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1727
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1728
text {*
194
+ − 1729
and the setup is as follows
193
+ − 1730
*}
+ − 1731
207
+ − 1732
attribute_setup %gray my_thms2 = {* Attrib.add_del my_add my_del *}
193
+ − 1733
"properly maintaining a list of my_thms"
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1734
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1735
text {*
207
+ − 1736
Initially, the data slot is empty
193
+ − 1737
194
+ − 1738
@{ML_response_fake [display,gray]
+ − 1739
"MyThmsData.get (Context.Proof @{context})"
+ − 1740
"[]"}
193
+ − 1741
194
+ − 1742
but if you prove
+ − 1743
*}
+ − 1744
+ − 1745
lemma three[my_thms2]: "3 = Suc (Suc (Suc 0))" by simp
193
+ − 1746
+ − 1747
text {*
207
+ − 1748
then the lemma is recorded.
194
+ − 1749
+ − 1750
@{ML_response_fake [display,gray]
+ − 1751
"MyThmsData.get (Context.Proof @{context})"
+ − 1752
"[\"3 = Suc (Suc (Suc 0))\"]"}
+ − 1753
207
+ − 1754
With theorem attribute @{text my_thms2} you can also nicely see why it
+ − 1755
is important to
194
+ − 1756
store data in a ``data slot'' and \emph{not} in a reference. Backtrack
207
+ − 1757
to the point just before the lemma @{thm [source] three} was proved and
256
+ − 1758
check the the content of @{ML_struct MyThmsData}: it should be empty.
207
+ − 1759
The addition has been properly retracted. Now consider the proof:
194
+ − 1760
*}
+ − 1761
+ − 1762
lemma four[my_thms]: "4 = Suc (Suc (Suc (Suc 0)))" by simp
193
+ − 1763
194
+ − 1764
text {*
+ − 1765
Checking the content of @{ML my_thms} gives
+ − 1766
+ − 1767
@{ML_response_fake [display,gray]
+ − 1768
"!my_thms"
+ − 1769
"[\"4 = Suc (Suc (Suc (Suc 0)))\", \"True\"]"}
+ − 1770
207
+ − 1771
as expected, but if you backtrack before the lemma @{thm [source] four}, the
194
+ − 1772
content of @{ML my_thms} is unchanged. The backtracking mechanism
207
+ − 1773
of Isabelle is completely oblivious about what to do with references, but
+ − 1774
properly treats ``data slots''!
194
+ − 1775
207
+ − 1776
Since storing theorems in a list is such a common task, there is the special
265
+ − 1777
functor @{ML_functor Named_Thms}, which does most of the work for you. To obtain
281
+ − 1778
a named theorem list, you just declare
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1779
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1780
265
+ − 1781
ML{*structure FooRules = Named_Thms
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1782
(val name = "foo"
194
+ − 1783
val description = "Rules for foo") *}
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1784
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1785
text {*
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1786
and set up the @{ML_struct FooRules} with the command
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1787
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1788
177
+ − 1789
setup %gray {* FooRules.setup *}
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1790
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1791
text {*
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1792
This code declares a data slot where the theorems are stored,
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1793
an attribute @{text foo} (with the @{text add} and @{text del} options
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1794
for adding and deleting theorems) and an internal ML interface to retrieve and
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1795
modify the theorems.
133
+ − 1796
157
+ − 1797
Furthermore, the facts are made available on the user-level under the dynamic
156
+ − 1798
fact name @{text foo}. For example you can declare three lemmas to be of the kind
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1799
@{text foo} by:
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1800
*}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1801
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1802
lemma rule1[foo]: "A" sorry
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1803
lemma rule2[foo]: "B" sorry
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1804
lemma rule3[foo]: "C" sorry
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1805
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1806
text {* and undeclare the first one by: *}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1807
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1808
declare rule1[foo del]
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1809
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1810
text {* and query the remaining ones with:
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1811
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1812
\begin{isabelle}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1813
\isacommand{thm}~@{text "foo"}\\
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1814
@{text "> ?C"}\\
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1815
@{text "> ?B"}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1816
\end{isabelle}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1817
156
+ − 1818
On the ML-level the rules marked with @{text "foo"} can be retrieved
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1819
using the function @{ML FooRules.get}:
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1820
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1821
@{ML_response_fake [display,gray] "FooRules.get @{context}" "[\"?C\",\"?B\"]"}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1822
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1823
\begin{readmore}
263
195c4444dff7
added section about code maintenance and added an example for antiquotations
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1824
For more information see @{ML_file "Pure/Tools/named_thms.ML"}.
151
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1825
\end{readmore}
7e0bf13bf743
added more material to the attribute section; merged the recipe about named theorems into the main body; added a solution to an exercise in the conversion section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1826
156
+ − 1827
(FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?)
133
+ − 1828
+ − 1829
+ − 1830
\begin{readmore}
207
+ − 1831
FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in
+ − 1832
@{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
+ − 1833
parsing.
133
+ − 1834
\end{readmore}
+ − 1835
*}
+ − 1836
127
+ − 1837
178
fb8f22dd8ad0
adapted to latest Attrib.setup changes and more work on the simple induct chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1838
153
+ − 1839
section {* Theories, Contexts and Local Theories (TBD) *}
123
+ − 1840
126
+ − 1841
text {*
+ − 1842
There are theories, proof contexts and local theories (in this order, if you
+ − 1843
want to order them).
+ − 1844
+ − 1845
In contrast to an ordinary theory, which simply consists of a type
+ − 1846
signature, as well as tables for constants, axioms and theorems, a local
202
+ − 1847
theory contains additional context information, such as locally fixed
126
+ − 1848
variables and local assumptions that may be used by the package. The type
+ − 1849
@{ML_type local_theory} is identical to the type of \emph{proof contexts}
+ − 1850
@{ML_type "Proof.context"}, although not every proof context constitutes a
+ − 1851
valid local theory.
178
fb8f22dd8ad0
adapted to latest Attrib.setup changes and more work on the simple induct chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1852
*}
126
+ − 1853
235
+ − 1854
(*
229
+ − 1855
ML{*signature UNIVERSAL_TYPE =
+ − 1856
sig
+ − 1857
type t
+ − 1858
+ − 1859
val embed: unit -> ('a -> t) * (t -> 'a option)
+ − 1860
end*}
+ − 1861
+ − 1862
ML{*structure U:> UNIVERSAL_TYPE =
+ − 1863
struct
+ − 1864
type t = exn
+ − 1865
+ − 1866
fun 'a embed () =
+ − 1867
let
+ − 1868
exception E of 'a
+ − 1869
fun project (e: t): 'a option =
+ − 1870
case e of
+ − 1871
E a => SOME a
+ − 1872
| _ => NONE
+ − 1873
in
+ − 1874
(E, project)
+ − 1875
end
+ − 1876
end*}
+ − 1877
+ − 1878
text {*
+ − 1879
The idea is that type t is the universal type and that each call to embed
+ − 1880
returns a new pair of functions (inject, project), where inject embeds a
+ − 1881
value into the universal type and project extracts the value from the
+ − 1882
universal type. A pair (inject, project) returned by embed works together in
+ − 1883
that project u will return SOME v if and only if u was created by inject
+ − 1884
v. If u was created by a different function inject', then project returns
+ − 1885
NONE.
+ − 1886
+ − 1887
in library.ML
+ − 1888
*}
+ − 1889
+ − 1890
ML_val{*structure Object = struct type T = exn end; *}
+ − 1891
+ − 1892
ML{*functor Test (U: UNIVERSAL_TYPE): sig end =
+ − 1893
struct
+ − 1894
val (intIn: int -> U.t, intOut) = U.embed ()
+ − 1895
val r: U.t ref = ref (intIn 13)
+ − 1896
val s1 =
+ − 1897
case intOut (!r) of
+ − 1898
NONE => "NONE"
+ − 1899
| SOME i => Int.toString i
+ − 1900
val (realIn: real -> U.t, realOut) = U.embed ()
+ − 1901
val () = r := realIn 13.0
+ − 1902
val s2 =
+ − 1903
case intOut (!r) of
+ − 1904
NONE => "NONE"
+ − 1905
| SOME i => Int.toString i
+ − 1906
val s3 =
+ − 1907
case realOut (!r) of
+ − 1908
NONE => "NONE"
+ − 1909
| SOME x => Real.toString x
301
+ − 1910
val () = tracing (concat [s1, " ", s2, " ", s3, "\n"])
229
+ − 1911
end*}
+ − 1912
+ − 1913
ML_val{*structure t = Test(U) *}
+ − 1914
+ − 1915
ML_val{*structure Datatab = TableFun(type key = int val ord = int_ord);*}
+ − 1916
235
+ − 1917
ML {* LocalTheory.restore *}
+ − 1918
ML {* LocalTheory.set_group *}
+ − 1919
*)
+ − 1920
153
+ − 1921
section {* Storing Theorems\label{sec:storing} (TBD) *}
123
+ − 1922
256
+ − 1923
text {* @{ML [index] add_thms_dynamic in PureThy} *}
123
+ − 1924
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1925
local_setup {*
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1926
LocalTheory.note Thm.theoremK
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1927
((@{binding "allI_alt"}, []), [@{thm allI}]) #> snd *}
100
+ − 1928
75
+ − 1929
126
+ − 1930
(* FIXME: some code below *)
89
+ − 1931
+ − 1932
(*<*)
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1933
(*
89
+ − 1934
setup {*
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1935
Sign.add_consts_i [(Binding"bar", @{typ "nat"},NoSyn)]
89
+ − 1936
*}
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1937
*)
89
+ − 1938
lemma "bar = (1::nat)"
+ − 1939
oops
+ − 1940
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1941
(*
89
+ − 1942
setup {*
+ − 1943
Sign.add_consts_i [("foo", @{typ "nat"},NoSyn)]
186
371e4375c994
made the Ackermann function example safer and included suggestions from MW
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1944
#> PureThy.add_defs false [((@{binding "foo_def"},
89
+ − 1945
Logic.mk_equals (Const ("FirstSteps.foo", @{typ "nat"}), @{term "1::nat"})), [])]
+ − 1946
#> snd
+ − 1947
*}
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1948
*)
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1949
(*
89
+ − 1950
lemma "foo = (1::nat)"
+ − 1951
apply(simp add: foo_def)
+ − 1952
done
+ − 1953
+ − 1954
thm foo_def
163
2319cff107f0
removed rep_ss, and used dest_ss instead; some very slight changes to simple_inductive
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1955
*)
89
+ − 1956
(*>*)
+ − 1957
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1958
section {* Pretty-Printing\label{sec:pretty} *}
247
+ − 1959
+ − 1960
text {*
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1961
So far we printed out only plain strings without any formatting except for
280
+ − 1962
occasional explicit line breaks using @{text [quotes] "\\n"}. This is
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1963
sufficient for ``quick-and-dirty'' printouts. For something more
249
+ − 1964
sophisticated, Isabelle includes an infrastructure for properly formatting text.
+ − 1965
This infrastructure is loosely based on a paper by Oppen~\cite{Oppen80}. Most of
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1966
its functions do not operate on @{ML_type string}s, but on instances of the
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1967
type:
247
+ − 1968
256
+ − 1969
@{ML_type [display, gray, index] "Pretty.T"}
+ − 1970
+ − 1971
The function @{ML str in Pretty} transforms a (plain) string into such a pretty
247
+ − 1972
type. For example
+ − 1973
+ − 1974
@{ML_response_fake [display,gray]
+ − 1975
"Pretty.str \"test\"" "String (\"test\", 4)"}
+ − 1976
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1977
where the result indicates that we transformed a string with length 4. Once
249
+ − 1978
you have a pretty type, you can, for example, control where linebreaks may
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1979
occur in case the text wraps over a line, or with how much indentation a
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1980
text should be printed. However, if you want to actually output the
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1981
formatted text, you have to transform the pretty type back into a @{ML_type
256
+ − 1982
string}. This can be done with the function @{ML [index] string_of in Pretty}. In what
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1983
follows we will use the following wrapper function for printing a pretty
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1984
type:
247
+ − 1985
*}
+ − 1986
301
+ − 1987
ML{*fun pprint prt = tracing (Pretty.string_of prt)*}
153
+ − 1988
+ − 1989
text {*
249
+ − 1990
The point of the pretty-printing infrastructure is to give hints about how to
+ − 1991
layout text and let Isabelle do the actual layout. Let us first explain
280
+ − 1992
how you can insert places where a line break can occur. For this assume the
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 1993
following function that replicates a string n times:
247
+ − 1994
*}
+ − 1995
+ − 1996
ML{*fun rep n str = implode (replicate n str) *}
+ − 1997
+ − 1998
text {*
+ − 1999
and suppose we want to print out the string:
+ − 2000
*}
+ − 2001
+ − 2002
ML{*val test_str = rep 8 "fooooooooooooooobaaaaaaaaaaaar "*}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2003
247
+ − 2004
text {*
282
+ − 2005
We deliberately chose a large string so that it spans over more than one line.
249
+ − 2006
If we print out the string using the usual ``quick-and-dirty'' method, then
+ − 2007
we obtain the ugly output:
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2008
247
+ − 2009
@{ML_response_fake [display,gray]
301
+ − 2010
"tracing test_str"
247
+ − 2011
"fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar foooooooooo
+ − 2012
ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa
+ − 2013
aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo
+ − 2014
oooooooooooooobaaaaaaaaaaaar"}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2015
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2016
We obtain the same if we just use
247
+ − 2017
+ − 2018
@{ML_response_fake [display,gray]
+ − 2019
"pprint (Pretty.str test_str)"
+ − 2020
"fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar foooooooooo
+ − 2021
ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa
+ − 2022
aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo
+ − 2023
oooooooooooooobaaaaaaaaaaaar"}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2024
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2025
However by using pretty types you have the ability to indicate a possible
280
+ − 2026
line break for example at each space. You can achieve this with the function
256
+ − 2027
@{ML [index] breaks in Pretty}, which expects a list of pretty types and inserts a
280
+ − 2028
possible line break in between every two elements in this list. To print
249
+ − 2029
this list of pretty types as a single string, we concatenate them
256
+ − 2030
with the function @{ML [index] blk in Pretty} as follows:
210
+ − 2031
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2032
247
+ − 2033
@{ML_response_fake [display,gray]
+ − 2034
"let
+ − 2035
val ptrs = map Pretty.str (space_explode \" \" test_str)
+ − 2036
in
+ − 2037
pprint (Pretty.blk (0, Pretty.breaks ptrs))
+ − 2038
end"
+ − 2039
"fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2040
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2041
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2042
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar"}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2043
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2044
Here the layout of @{ML test_str} is much more pleasing to the
256
+ − 2045
eye. The @{ML "0"} in @{ML [index] blk in Pretty} stands for no indentation
249
+ − 2046
of the printed string. You can increase the indentation and obtain
247
+ − 2047
+ − 2048
@{ML_response_fake [display,gray]
+ − 2049
"let
+ − 2050
val ptrs = map Pretty.str (space_explode \" \" test_str)
+ − 2051
in
+ − 2052
pprint (Pretty.blk (3, Pretty.breaks ptrs))
+ − 2053
end"
+ − 2054
"fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2055
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2056
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2057
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar"}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2058
247
+ − 2059
where starting from the second line the indent is 3. If you want
+ − 2060
that every line starts with the same indent, you can use the
256
+ − 2061
function @{ML [index] indent in Pretty} as follows:
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2062
247
+ − 2063
@{ML_response_fake [display,gray]
+ − 2064
"let
+ − 2065
val ptrs = map Pretty.str (space_explode \" \" test_str)
+ − 2066
in
+ − 2067
pprint (Pretty.indent 10 (Pretty.blk (0, Pretty.breaks ptrs)))
+ − 2068
end"
+ − 2069
" fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2070
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2071
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar
+ − 2072
fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar"}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2073
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2074
If you want to print out a list of items separated by commas and
249
+ − 2075
have the linebreaks handled properly, you can use the function
256
+ − 2076
@{ML [index] commas in Pretty}. For example
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2077
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2078
@{ML_response_fake [display,gray]
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2079
"let
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2080
val ptrs = map (Pretty.str o string_of_int) (99998 upto 100020)
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2081
in
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2082
pprint (Pretty.blk (0, Pretty.commas ptrs))
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2083
end"
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2084
"99998, 99999, 100000, 100001, 100002, 100003, 100004, 100005, 100006,
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2085
100007, 100008, 100009, 100010, 100011, 100012, 100013, 100014, 100015,
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2086
100016, 100017, 100018, 100019, 100020"}
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2087
257
+ − 2088
where @{ML upto} generates a list of integers. You can print out this
283
+ − 2089
list as a ``set'', that means enclosed inside @{text [quotes] "{"} and
249
+ − 2090
@{text [quotes] "}"}, and separated by commas using the function
256
+ − 2091
@{ML [index] enum in Pretty}. For example
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2092
*}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2093
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2094
text {*
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2095
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2096
@{ML_response_fake [display,gray]
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2097
"let
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2098
val ptrs = map (Pretty.str o string_of_int) (99998 upto 100020)
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2099
in
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2100
pprint (Pretty.enum \",\" \"{\" \"}\" ptrs)
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2101
end"
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2102
"{99998, 99999, 100000, 100001, 100002, 100003, 100004, 100005, 100006,
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2103
100007, 100008, 100009, 100010, 100011, 100012, 100013, 100014, 100015,
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2104
100016, 100017, 100018, 100019, 100020}"}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2105
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2106
As can be seen, this function prints out the ``set'' so that starting
257
+ − 2107
from the second, each new line as an indentation of 2.
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2108
257
+ − 2109
If you print out something that goes beyond the capabilities of the
280
+ − 2110
standard functions, you can do relatively easily the formatting
249
+ − 2111
yourself. Assume you want to print out a list of items where like in ``English''
+ − 2112
the last two items are separated by @{text [quotes] "and"}. For this you can
+ − 2113
write the function
+ − 2114
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2115
*}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2116
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2117
ML %linenosgray{*fun and_list [] = []
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2118
| and_list [x] = [x]
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2119
| and_list xs =
247
+ − 2120
let
+ − 2121
val (front, last) = split_last xs
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2122
in
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2123
(Pretty.commas front) @
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2124
[Pretty.brk 1, Pretty.str "and", Pretty.brk 1, last]
247
+ − 2125
end *}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2126
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2127
text {*
257
+ − 2128
where Line 7 prints the beginning of the list and Line
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2129
8 the last item. We have to use @{ML "Pretty.brk 1"} in order
249
+ − 2130
to insert a space (of length 1) before the
280
+ − 2131
@{text [quotes] "and"}. This space is also a place where a line break
+ − 2132
can occur. We do the same after the @{text [quotes] "and"}. This gives you
249
+ − 2133
for example
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2134
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2135
@{ML_response_fake [display,gray]
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2136
"let
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2137
val ptrs = map (Pretty.str o string_of_int) (1 upto 22)
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2138
in
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2139
pprint (Pretty.blk (0, and_list ptrs))
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2140
end"
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2141
"1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2142
and 22"}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2143
249
+ − 2144
Next we like to pretty-print a term and its type. For this we use the
+ − 2145
function @{text "tell_type"}.
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2146
*}
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2147
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2148
ML %linenosgray{*fun tell_type ctxt t =
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2149
let
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2150
fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s))
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2151
val ptrm = Pretty.quote (Syntax.pretty_term ctxt t)
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2152
val pty = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of t))
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2153
in
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2154
pprint (Pretty.blk (0,
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2155
(pstr "The term " @ [ptrm] @ pstr " has type "
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2156
@ [pty, Pretty.str "."])))
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2157
end*}
245
53112deda119
Jasmin and Christian added examples for the pretty-printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2158
210
+ − 2159
text {*
257
+ − 2160
In Line 3 we define a function that inserts possible linebreaks in places
+ − 2161
where a space is. In Lines 4 and 5 we pretty-print the term and its type
+ − 2162
using the functions @{ML [index] pretty_term in Syntax} and @{ML [index]
+ − 2163
pretty_typ in Syntax}. We also use the function @{ML [index] quote in
+ − 2164
Pretty} in order to enclose the term and type inside quotation marks. In
+ − 2165
Line 9 we add a period right after the type without the possibility of a
280
+ − 2166
line break, because we do not want that a line break occurs there.
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2167
257
+ − 2168
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2169
Now you can write
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2170
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2171
@{ML_response_fake [display,gray]
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2172
"tell_type @{context} @{term \"min (Suc 0)\"}"
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2173
"The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."}
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2174
280
+ − 2175
To see the proper line breaking, you can try out the function on a bigger term
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2176
and type. For example:
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2177
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2178
@{ML_response_fake [display,gray]
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2179
"tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2180
"The term \"op = (op = (op = (op = (op = op =))))\" has type
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2181
\"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."}
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2182
257
+ − 2183
+ − 2184
FIXME: TBD below
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2185
*}
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2186
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2187
ML {* pprint (Pretty.big_list "header" (map (Pretty.str o string_of_int) (4 upto 10))) *}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2188
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2189
text {*
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2190
chunks inserts forced breaks (unlike blk where you have to do this yourself)
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2191
*}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2192
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2193
ML {* (Pretty.chunks [Pretty.str "a", Pretty.str "b"],
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2194
Pretty.blk (0, [Pretty.str "a", Pretty.str "b"])) *}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2195
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2196
ML {*
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2197
fun setmp_show_all_types f =
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2198
setmp show_all_types
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2199
(! show_types orelse ! show_sorts orelse ! show_all_types) f;
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2200
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2201
val ctxt = @{context};
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2202
val t1 = @{term "undefined::nat"};
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2203
val t2 = @{term "Suc y"};
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2204
val pty = Pretty.block (Pretty.breaks
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2205
[(setmp show_question_marks false o setmp_show_all_types)
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2206
(Syntax.pretty_term ctxt) t1,
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2207
Pretty.str "=", Syntax.pretty_term ctxt t2]);
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2208
pty |> Pretty.string_of |> priority
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2209
*}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2210
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2211
text {* the infrastructure of Syntax-pretty-term makes sure it is printed nicely *}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2212
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2213
301
+ − 2214
ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of |> tracing *}
+ − 2215
ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *}
+ − 2216
+ − 2217
+ − 2218
ML {* Pretty.mark Markup.subgoal (Pretty.str "foo") |> Pretty.string_of |> tracing *}
+ − 2219
ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *}
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2220
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2221
text {*
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2222
Still to be done:
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2223
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2224
What happens with big formulae?
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2225
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2226
\begin{readmore}
249
+ − 2227
The general infrastructure for pretty-printing is implemented in the file
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2228
@{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
249
+ − 2229
contains pretty-printing functions for terms, types, theorems and so on.
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2230
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2231
@{ML_file "Pure/General/markup.ML"}
248
11851b20fb78
added more to the pretty section and updated the acknowledgements
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2232
\end{readmore}
153
+ − 2233
*}
+ − 2234
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2235
text {*
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2236
printing into the goal buffer as part of the proof state
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2237
*}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2238
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2239
301
+ − 2240
ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of |> tracing *}
+ − 2241
ML {* (Pretty.str "bar") |> Pretty.string_of |> tracing *}
250
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2242
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2243
text {* writing into the goal buffer *}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2244
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2245
ML {* fun my_hook interactive state =
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2246
(interactive ? Proof.goal_message (fn () => Pretty.str
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2247
"foo")) state
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2248
*}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2249
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2250
setup {* Context.theory_map (Specification.add_theorem_hook my_hook) *}
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2251
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2252
lemma "False"
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2253
oops
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2254
ab9e09076462
some polishing; added together with Jasmin more examples to the pretty printing section
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2255
153
+ − 2256
section {* Misc (TBD) *}
92
+ − 2257
262
+ − 2258
ML {*Datatype.get_info @{theory} "List.list"*}
92
+ − 2259
299
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2260
section {* Name Space(TBD) *}
d0b81d6e1b28
updated to Isabelle changes and merged sections in the FirstSteps chapter
Christian Urban <urbanc@in.tum.de>
diff
changeset
+ − 2261
301
+ − 2262
196
+ − 2263
end