26 |
26 |
27 |
27 |
28 |
28 |
29 text {* |
29 text {* |
30 The easiest and quickest way to include code in a theory is |
30 The easiest and quickest way to include code in a theory is |
31 by using the \isacommand{ML} command. For example\smallskip |
31 by using the \isacommand{ML}-command. For example\smallskip |
32 |
32 |
33 \isa{\isacommand{ML} |
33 \isa{\isacommand{ML} |
34 \isacharverbatimopen\isanewline |
34 \isacharverbatimopen\isanewline |
35 \hspace{5mm}@{ML "3 + 4"}\isanewline |
35 \hspace{5mm}@{ML "3 + 4"}\isanewline |
36 \isacharverbatimclose\isanewline |
36 \isacharverbatimclose\isanewline |
37 @{ML_text "> 7"}\smallskip} |
37 @{ML_text "> 7"}\smallskip} |
38 |
38 |
39 Expressions inside \isacommand{ML} commands are immediately evaluated, |
39 Expressions inside \isacommand{ML}-commands are immediately evaluated, |
40 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 |
41 your Isabelle environment. The code inside the \isacommand{ML} command |
41 your Isabelle environment. The code inside the \isacommand{ML}-command |
42 can also contain value and function bindings, and even those can be |
42 can also contain value and function bindings, and even those can be |
43 undone when the proof script is retracted. From now on we will drop the |
43 undone when the proof script is retracted. In what follows we will drop the |
44 \isacommand{ML} \isa{\isacharverbatimopen \ldots \isacharverbatimclose} whenever |
44 \isacommand{ML} \isa{\isacharverbatimopen \ldots \isacharverbatimclose} whenever |
45 we show code and its response. |
45 we show code and its response. |
46 |
46 |
47 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 |
48 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 |
79 |
79 |
80 However this only works if the type of what is converted is monomorphic and is not |
80 However this only works if the type of what is converted is monomorphic and is not |
81 a function. |
81 a function. |
82 |
82 |
83 The funtion @{ML "warning"} should only be used for testing purposes, because any |
83 The funtion @{ML "warning"} should only be used for testing purposes, because any |
84 output this funtion generates will be overwritten, as soon as an error is |
84 output this funtion generates will be overwritten as soon as an error is |
85 raised. Therefore for printing anything more serious and elaborate, the |
85 raised. Therefore for printing anything more serious and elaborate, the |
86 function @{ML tracing} should be used. This function writes all output into |
86 function @{ML tracing} should be used. This function writes all output into |
87 a separate tracing buffer. |
87 a separate tracing buffer. For example |
88 |
88 |
89 @{ML [display] "tracing \"foo\""} |
89 @{ML [display] "tracing \"foo\""} |
90 |
90 |
91 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 |
92 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 |
117 |
117 |
118 |
118 |
119 section {* Antiquotations *} |
119 section {* Antiquotations *} |
120 |
120 |
121 text {* |
121 text {* |
122 The main advantage of embedding all code |
122 The main advantage of embedding all code in a theory is that the code can |
123 in a theory is that the code can contain references to entities defined |
123 contain references to entities defined on the logical level of Isabelle (by |
124 on the logical level of Isabelle. This is done using antiquotations. |
124 this we mean definitions, theorems, terms and so on). This is done using |
125 For example, one can print out the name of |
125 antiquotations. For example, one can print out the name of the current |
126 the current theory by typing |
126 theory by typing |
|
127 |
127 |
128 |
128 @{ML_response [display] "Context.theory_name @{theory}" "FirstSteps"} |
129 @{ML_response [display] "Context.theory_name @{theory}" "FirstSteps"} |
129 |
130 |
130 where @{text "@{theory}"} is an antiquotation that is substituted with the |
131 where @{text "@{theory}"} is an antiquotation that is substituted with the |
131 current theory (remember that we assumed we are inside the theory CookBook). |
132 current theory (remember that we assumed we are inside the theory |
132 The name of this theory can be extracted using the function |
133 @{ML_text FirstSteps}). The name of this theory can be extracted using |
133 @{ML "Context.theory_name"}. |
134 the function @{ML "Context.theory_name"}. |
134 |
135 |
135 Note, however, that antiquotations are statically scoped, that is the value is |
136 Note, however, that antiquotations are statically scoped, that is the value is |
136 determined at ``compile-time'', not ``run-time''. For example the function |
137 determined at ``compile-time'', not ``run-time''. For example the function |
137 *} |
138 *} |
138 |
139 |
153 In a similar way you can use antiquotations to refer to theorems or simpsets: |
154 In a similar way you can use antiquotations to refer to theorems or simpsets: |
154 |
155 |
155 @{ML [display] "@{thm allI}"} |
156 @{ML [display] "@{thm allI}"} |
156 @{ML [display] "@{simpset}"} |
157 @{ML [display] "@{simpset}"} |
157 |
158 |
158 While antiquotations have many applications, they were originally introduced to |
159 While antiquotations nowadays have many applications, they were originally introduced to |
159 avoid explicit bindings for theorems such as |
160 avoid explicit bindings for theorems such as |
160 *} |
161 *} |
161 |
162 |
162 ML {* |
163 ML {* |
163 val allI = thm "allI" |
164 val allI = thm "allI" |
164 *} |
165 *} |
165 |
166 |
166 text {* |
167 text {* |
167 These bindings were difficult to maintain and also could be accidentally overwritten |
168 These bindings were difficult to maintain and also could be accidentally |
168 by the user. This usually broke definitional packages. Antiquotations solve this |
169 overwritten by the user. This usually broke definitional |
169 problem, since they are ``linked'' statically at compile time. In the course of this |
170 packages. Antiquotations solve this problem, since they are ``linked'' |
170 introduction, we will learn more about these antiquotations: they greatly simplify |
171 statically at compile-time. However, that also sometimes limits there |
171 Isabelle programming since one can directly access all kinds of logical elements |
172 applicability. In the course of this introduction, we will learn more about |
172 from ML. |
173 these antiquotations: they greatly simplify Isabelle programming since one |
|
174 can directly access all kinds of logical elements from ML. |
|
175 |
173 *} |
176 *} |
174 |
177 |
175 section {* Terms and Types *} |
178 section {* Terms and Types *} |
176 |
179 |
177 text {* |
180 text {* |
178 One way to construct terms of Isabelle on the ML level is by using the antiquotation |
181 One way to construct terms of Isabelle on the ML-level is by using the antiquotation |
179 \mbox{@{text "@{term \<dots>}"}}: |
182 \mbox{@{text "@{term \<dots>}"}}. For example |
180 |
183 |
181 @{ML_response [display] "@{term \"(a::nat) + b = c\"}" |
184 @{ML_response [display] "@{term \"(a::nat) + b = c\"}" |
182 "Const (\"op =\", \<dots>) $ (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"} |
185 "Const (\"op =\", \<dots>) $ (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"} |
183 |
186 |
184 This will show the term @{term "(a::nat) + b = c"}, but printed out using the internal |
187 This will show the term @{term "(a::nat) + b = c"}, but printed out using the internal |
290 The extra prefixes @{ML_text zero_class} and @{ML_text plus_class} are present because |
293 The extra prefixes @{ML_text zero_class} and @{ML_text plus_class} are present because |
291 these constants are defined within type classes; the prefix @{text "HOL"} indicates in |
294 these constants are defined within type classes; the prefix @{text "HOL"} indicates in |
292 which theory they are defined. Guessing such internal names can sometimes be quite hard. |
295 which theory they are defined. Guessing such internal names can sometimes be quite hard. |
293 Therefore Isabellle provides the antiquotation @{text "@{const_name \<dots>}"} which does the |
296 Therefore Isabellle provides the antiquotation @{text "@{const_name \<dots>}"} which does the |
294 expansion automatically, for example: |
297 expansion automatically, for example: |
295 *} |
298 |
296 |
299 @{ML_response_fake [display] "@{const_name \"Nil\"}" "List.list.Nil"} |
297 text {* |
|
298 |
300 |
299 (FIXME: Is it useful to explain @{text "@{const_syntax}"}?) |
301 (FIXME: Is it useful to explain @{text "@{const_syntax}"}?) |
300 |
302 |
301 (FIXME: how to construct types manually) |
303 Similarly, types can be constructed for example as follows: |
|
304 |
|
305 *} |
|
306 |
|
307 ML {* |
|
308 fun make_fun_type tau1 tau2 = Type ("fun",[tau1,tau2]) |
|
309 *} |
|
310 |
|
311 text {* |
|
312 which can be equally written as |
|
313 *} |
|
314 |
|
315 ML {* |
|
316 fun make_fun_type tau1 tau2 = tau1 --> tau2 |
|
317 *} |
|
318 |
|
319 text {* |
302 |
320 |
303 \begin{readmore} |
321 \begin{readmore} |
304 There are many functions in @{ML_file "Pure/logic.ML"} and |
322 There are many functions in @{ML_file "Pure/logic.ML"} and |
305 @{ML_file "HOL/hologic.ML"} that make such manual constructions of terms |
323 @{ML_file "HOL/hologic.ML"} that make such manual constructions of terms |
306 easier.\end{readmore} |
324 and types easier.\end{readmore} |
307 |
325 |
308 Have a look at these files and try to solve the following two exercises: |
326 Have a look at these files and try to solve the following two exercises: |
309 |
327 |
310 *} |
328 *} |
311 |
329 |
325 number representing their sum. |
343 number representing their sum. |
326 \end{exercise} |
344 \end{exercise} |
327 |
345 |
328 *} |
346 *} |
329 |
347 |
330 section {* Type Checking *} |
348 section {* Type-Checking *} |
331 |
349 |
332 text {* |
350 text {* |
333 |
351 |
334 We can freely construct and manipulate terms, since they are just |
352 We can freely construct and manipulate terms, since they are just |
335 arbitrary unchecked trees. However, we eventually want to see if a |
353 arbitrary unchecked trees. However, we eventually want to see if a |
336 term is well-formed, or type checks, relative to a theory. |
354 term is well-formed, or type checks, relative to a theory. |
337 Type checking is done via the function @{ML cterm_of}, which turns |
355 Type-checking is done via the function @{ML cterm_of}, which turns |
338 a @{ML_type term} into a @{ML_type cterm}, a \emph{certified} term. |
356 a @{ML_type term} into a @{ML_type cterm}, a \emph{certified} term. |
339 Unlike @{ML_type term}s, which are just trees, @{ML_type |
357 Unlike @{ML_type term}s, which are just trees, @{ML_type |
340 "cterm"}s are abstract objects that are guaranteed to be |
358 "cterm"}s are abstract objects that are guaranteed to be |
341 type-correct, and that can only be constructed via the official |
359 type-correct, and that can only be constructed via the official |
342 interfaces. |
360 interfaces. |
384 assumes assm\<^isub>1: "\<And>(x::nat). P x \<Longrightarrow> Q x" |
402 assumes assm\<^isub>1: "\<And>(x::nat). P x \<Longrightarrow> Q x" |
385 and assm\<^isub>2: "P t" |
403 and assm\<^isub>2: "P t" |
386 shows "Q t" (*<*)oops(*>*) |
404 shows "Q t" (*<*)oops(*>*) |
387 |
405 |
388 text {* |
406 text {* |
389 on the ML level:\footnote{Note that @{text "|>"} is reverse |
407 on the ML-level:\footnote{Note that @{text "|>"} is reverse |
390 application. This combinator, and several variants are defined in |
408 application. This combinator, and several variants are defined in |
391 @{ML_file "Pure/General/basics.ML"}.} |
409 @{ML_file "Pure/General/basics.ML"}.} |
392 |
410 |
393 @{ML_response_fake [display] |
411 @{ML_response_fake [display] |
394 "let |
412 "let |
395 val thy = @{theory} |
413 val thy = @{theory} |
396 |
414 |
397 val assm1 = cterm_of thy @{prop \"\<And>(x::nat). P x \<Longrightarrow> Q x\"} |
415 val assm1 = cterm_of thy @{prop \"\<And>(x::nat). P x \<Longrightarrow> Q x\"} |
398 val assm2 = cterm_of thy @{prop \"((P::nat\<Rightarrow>bool) t)\"} |
416 val assm2 = cterm_of thy @{prop \"(P::nat\<Rightarrow>bool) t\"} |
399 |
417 |
400 val Pt_implies_Qt = |
418 val Pt_implies_Qt = |
401 assume assm1 |
419 assume assm1 |
402 |> forall_elim (cterm_of thy @{term \"t::nat\"}); |
420 |> forall_elim (cterm_of thy @{term \"t::nat\"}); |
403 |
421 |
445 A goal (or goal state) is a special @{ML_type thm}, which by |
463 A goal (or goal state) is a special @{ML_type thm}, which by |
446 convention is an implication of the form: |
464 convention is an implication of the form: |
447 |
465 |
448 @{text[display] "A\<^isub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^isub>n \<Longrightarrow> #(C)"} |
466 @{text[display] "A\<^isub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^isub>n \<Longrightarrow> #(C)"} |
449 |
467 |
450 where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are the open subgoals. |
468 where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are the open |
|
469 subgoals. |
451 Since the goal @{term C} can potentially be an implication, there is a |
470 Since the goal @{term C} can potentially be an implication, there is a |
452 @{text "#"} wrapped around it, which prevents that premises are |
471 @{text "#"} wrapped around it, which prevents that premises are |
453 misinterpreted as open subgoals. The protection @{text "# :: prop \<Rightarrow> |
472 misinterpreted as open subgoals. The protection @{text "# :: prop \<Rightarrow> |
454 prop"} is just the identity function and used as a syntactic marker. |
473 prop"} is just the identity function and used as a syntactic marker. |
455 |
474 |
456 (FIXME: maybe show how this is printed on the screen) |
|
457 |
|
458 \begin{readmore} |
475 \begin{readmore} |
459 For more on goals see \isccite{sec:tactical-goals}. |
476 For more on goals see \isccite{sec:tactical-goals}. |
460 \end{readmore} |
477 \end{readmore} |
461 |
478 |
462 Tactics are functions that map a goal state to a (lazy) |
479 Tactics are functions that map a goal state to a (lazy) |
474 While tactics can operate on the subgoals (the @{text "A\<^isub>i"} above), they |
491 While tactics can operate on the subgoals (the @{text "A\<^isub>i"} above), they |
475 are expected to leave the conclusion @{term C} intact, with the |
492 are expected to leave the conclusion @{term C} intact, with the |
476 exception of possibly instantiating schematic variables. |
493 exception of possibly instantiating schematic variables. |
477 |
494 |
478 To see how tactics work, let us transcribe a simple @{text apply}-style |
495 To see how tactics work, let us transcribe a simple @{text apply}-style |
479 proof from the tutorial \cite{isa-tutorial} into ML: |
496 proof from the tutorial~\cite{isa-tutorial} into ML: |
480 *} |
497 *} |
481 |
498 |
482 lemma disj_swap: "P \<or> Q \<Longrightarrow> Q \<or> P" |
499 lemma disj_swap: "P \<or> Q \<Longrightarrow> Q \<or> P" |
483 apply (erule disjE) |
500 apply (erule disjE) |
484 apply (rule disjI2) |
501 apply (rule disjI2) |