35 @{ML_text "> 7"}\smallskip} |
37 @{ML_text "> 7"}\smallskip} |
36 |
38 |
37 Expressions inside \isacommand{ML} commands are immediately evaluated, |
39 Expressions inside \isacommand{ML} commands are immediately evaluated, |
38 like ``normal'' Isabelle proof scripts, by using the advance and undo buttons of |
40 like ``normal'' Isabelle proof scripts, by using the advance and undo buttons of |
39 your Isabelle environment. The code inside the \isacommand{ML} command |
41 your Isabelle environment. The code inside the \isacommand{ML} command |
40 can also contain value and function bindings. However on such \isacommand{ML} |
42 can also contain value and function bindings, and even those can be |
41 commands the undo operation behaves slightly counter-intuitive, because |
43 undone when the proof script is retracted. From now on we will drop the |
42 if you define\smallskip |
|
43 |
|
44 \isa{\isacommand{ML} |
|
45 \isacharverbatimopen\isanewline |
|
46 \hspace{5mm}@{ML_text "val foo = true"}\isanewline |
|
47 \isacharverbatimclose\isanewline |
|
48 @{ML_text "> true"}\smallskip} |
|
49 |
|
50 then Isabelle's undo operation has no effect on the definition of |
|
51 @{ML_text "foo"}. Note that from now on we will drop the |
|
52 \isacommand{ML} \isa{\isacharverbatimopen \ldots \isacharverbatimclose} whenever |
44 \isacommand{ML} \isa{\isacharverbatimopen \ldots \isacharverbatimclose} whenever |
53 we show code and its response. |
45 we show code and its response. |
54 |
46 |
55 Once a portion of code is relatively stable, one usually wants to |
47 Once a portion of code is relatively stable, one usually wants to |
56 export it to a separate ML-file. Such files can then be included in a |
48 export it to a separate ML-file. Such files can then be included in a |
76 in your code. This can be done in a ``quick-and-dirty'' fashion using |
68 in your code. This can be done in a ``quick-and-dirty'' fashion using |
77 the function @{ML "warning"}. For example |
69 the function @{ML "warning"}. For example |
78 |
70 |
79 @{ML [display] "warning \"any string\""} |
71 @{ML [display] "warning \"any string\""} |
80 |
72 |
81 will print out @{ML_text "\"any string\""} inside the response buffer of Isabelle. |
73 will print out @{ML_text [quotes] "any string"} inside the response buffer of Isabelle. |
82 If you develop under PolyML, then there is a convenient, though again |
74 If you develop under PolyML, then there is a convenient, though again |
83 ``quick-and-dirty'', method for converting values into strings, |
75 ``quick-and-dirty'', method for converting values into strings, |
84 for example: |
76 for example: |
85 |
77 |
86 @{ML [display] "warning (makestring 1)"} |
78 @{ML [display] "warning (makestring 1)"} |
99 It is also possible to redirect the channel where the @{ML_text "foo"} is |
91 It is also possible to redirect the channel where the @{ML_text "foo"} is |
100 printed to a separate file, e.g. to prevent Proof General from choking on massive |
92 printed to a separate file, e.g. to prevent Proof General from choking on massive |
101 amounts of trace output. This rediretion can be achieved using the code |
93 amounts of trace output. This rediretion can be achieved using the code |
102 *} |
94 *} |
103 |
95 |
104 ML {* |
96 ML{* |
105 val strip_specials = |
97 val strip_specials = |
106 let |
98 let |
107 fun strip ("\^A" :: _ :: cs) = strip cs |
99 fun strip ("\^A" :: _ :: cs) = strip cs |
108 | strip (c :: cs) = c :: strip cs |
100 | strip (c :: cs) = c :: strip cs |
109 | strip [] = []; |
101 | strip [] = []; |
111 |
103 |
112 fun redirect_tracing stream = |
104 fun redirect_tracing stream = |
113 Output.tracing_fn := (fn s => |
105 Output.tracing_fn := (fn s => |
114 (TextIO.output (stream, (strip_specials s)); |
106 (TextIO.output (stream, (strip_specials s)); |
115 TextIO.output (stream, "\n"); |
107 TextIO.output (stream, "\n"); |
116 TextIO.flushOut stream)); |
108 TextIO.flushOut stream)); |
117 *} |
109 *} |
118 |
110 |
119 text {* |
111 text {* |
120 |
112 |
121 Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} |
113 Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} |
161 In a similar way you can use antiquotations to refer to theorems or simpsets: |
153 In a similar way you can use antiquotations to refer to theorems or simpsets: |
162 |
154 |
163 @{ML [display] "@{thm allI}"} |
155 @{ML [display] "@{thm allI}"} |
164 @{ML [display] "@{simpset}"} |
156 @{ML [display] "@{simpset}"} |
165 |
157 |
166 While antiquotations have many uses, they were introduced to avoid explicit |
158 While antiquotations have many applications, they were originally introduced to |
167 bindings for theorems such as |
159 avoid explicit bindings for theorems such as |
168 *} |
160 *} |
169 |
161 |
170 ML {* |
162 ML {* |
171 val allI = thm "allI" |
163 val allI = thm "allI" |
172 *} |
164 *} |
173 |
165 |
174 text {* |
166 text {* |
175 These bindings were difficult to maintain and also could be overwritten |
167 These bindings were difficult to maintain and also could be accidentally overwritten |
176 by bindings introduced by the user. This had the potential to break |
168 by the user. This usually broke definitional packages. Antiquotations solve this |
177 definitional packages. This additional layer of maintenance complexity |
169 problem, since they are ``linked'' statically at compile time. In the course of this |
178 can be avoided by using antiquotations, since they are ``linked'' statically |
170 introduction, we will learn more about these antiquotations: they greatly simplify |
179 at compile time. In the course of this introduction, we will learn more about |
171 Isabelle programming since one can directly access all kinds of logical elements |
180 these antiquotations: they greatly simplify Isabelle programming since one |
172 from ML. |
181 can directly access all kinds of logical elements from ML. |
|
182 |
|
183 *} |
173 *} |
184 |
174 |
185 section {* Terms and Types *} |
175 section {* Terms and Types *} |
186 |
176 |
187 text {* |
177 text {* |
206 definition and many useful operations can be found in @{ML_file "Pure/term.ML"}. |
196 definition and many useful operations can be found in @{ML_file "Pure/term.ML"}. |
207 \end{readmore} |
197 \end{readmore} |
208 |
198 |
209 Sometimes the internal representation of terms can be surprisingly different |
199 Sometimes the internal representation of terms can be surprisingly different |
210 from what you see at the user level, because the layers of |
200 from what you see at the user level, because the layers of |
211 parsing/type checking/pretty printing can be quite elaborate. |
201 parsing/type-checking/pretty printing can be quite elaborate. |
212 *} |
202 |
213 |
|
214 text {* |
|
215 \begin{exercise} |
203 \begin{exercise} |
216 Look at the internal term representation of the following terms, and |
204 Look at the internal term representation of the following terms, and |
217 find out why they are represented like this. |
205 find out why they are represented like this. |
218 |
206 |
219 \begin{itemize} |
207 \begin{itemize} |
244 @{ML_response [display] "@{prop \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"} |
232 @{ML_response [display] "@{prop \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"} |
245 |
233 |
246 which does not. |
234 which does not. |
247 |
235 |
248 Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example |
236 Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example |
249 |
|
250 *} |
|
251 |
|
252 |
|
253 text {* |
|
254 |
237 |
255 @{ML_response_fake [display] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"} |
238 @{ML_response_fake [display] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"} |
256 |
|
257 (FIXME: Unlike the term antiquotation, @{text "@{typ \<dots>}"} does not print the |
|
258 internal representation. Is there a reason for this, that needs to be explained |
|
259 here?) |
|
260 |
239 |
261 \begin{readmore} |
240 \begin{readmore} |
262 Types are described in detail in \isccite{sec:types}. Their |
241 Types are described in detail in \isccite{sec:types}. Their |
263 definition and many useful operations can be found in @{ML_file "Pure/type.ML"}. |
242 definition and many useful operations can be found in @{ML_file "Pure/type.ML"}. |
264 \end{readmore} |
243 \end{readmore} |
265 |
244 *} |
266 *} |
|
267 |
245 |
268 |
246 |
269 section {* Constructing Terms and Types Manually *} |
247 section {* Constructing Terms and Types Manually *} |
270 |
248 |
271 text {* |
249 text {* |
272 |
250 |
273 While antiquotations are very convenient for constructing terms and types, |
251 While antiquotations are very convenient for constructing terms and types, |
274 they can only construct fixed terms. Unfortunately, one often needs to construct them |
252 they can only construct fixed terms. Unfortunately, one often needs to construct terms |
275 dynamically. For example, a function that returns the implication |
253 dynamically. For example, a function that returns the implication |
276 @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the typ @{term "\<tau>"} |
254 @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the typ @{term "\<tau>"} |
277 as arguments can only be written as |
255 as arguments can only be written as |
278 *} |
256 *} |
279 |
257 |
362 type-correct, and that can only be constructed via the official |
343 type-correct, and that can only be constructed via the official |
363 interfaces. |
344 interfaces. |
364 |
345 |
365 Type checking is always relative to a theory context. For now we can use |
346 Type checking is always relative to a theory context. For now we can use |
366 the @{ML "@{theory}"} antiquotation to get hold of the current theory. |
347 the @{ML "@{theory}"} antiquotation to get hold of the current theory. |
367 For example we can write: |
348 For example we can write |
|
349 |
|
350 @{ML_response_fake [display] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"} |
|
351 |
|
352 or use the antiquotation |
368 |
353 |
369 @{ML_response_fake [display] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"} |
354 @{ML_response_fake [display] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"} |
370 |
355 |
371 and |
356 A slightly more elaborate example is |
372 |
357 |
373 @{ML_response_fake [display] |
358 @{ML_response_fake [display] |
374 "let |
359 "let |
375 val natT = @{typ \"nat\"} |
360 val natT = @{typ \"nat\"} |
376 val zero = @{term \"0::nat\"} |
361 val zero = @{term \"0::nat\"} |