9 \begin{flushright} |
9 \begin{flushright} |
10 {\em |
10 {\em |
11 ``We will most likely never realize the full importance of painting the Tower,\\ |
11 ``We will most likely never realize the full importance of painting the Tower,\\ |
12 that it is the essential element in the conservation of metal works and the\\ |
12 that it is the essential element in the conservation of metal works and the\\ |
13 more meticulous the paint job, the longer the Tower shall endure.''} \\[1ex] |
13 more meticulous the paint job, the longer the Tower shall endure.''} \\[1ex] |
14 Gustave Eiffel, In The 300-Meter Tower.\footnote{The Eiffel Tower has been |
14 Gustave Eiffel, In his book {\em The 300-Meter Tower}.\footnote{The Eiffel Tower has been |
15 re-painted 18 times since its initial construction, an average of once every |
15 re-painted 18 times since its initial construction, an average of once every |
16 seven years. It takes more than a year for a team of 25 painters to paint the Tower |
16 seven years. It takes more than a year for a team of 25 painters to paint the Tower |
17 from top to bottom.}\\[1ex] |
17 from top to bottom.} |
18 \end{flushright} |
18 \end{flushright} |
19 |
19 |
|
20 \medskip |
20 Isabelle programming is done in ML. Just like lemmas and proofs, ML-code for |
21 Isabelle programming is done in ML. Just like lemmas and proofs, ML-code for |
21 Isabelle must be part of a theory. If you want to follow the code given in |
22 Isabelle must be part of a theory. If you want to follow the code given in |
22 this chapter, we assume you are working inside the theory starting with |
23 this chapter, we assume you are working inside the theory starting with |
23 |
24 |
24 \begin{quote} |
25 \begin{quote} |
250 |
251 |
251 ML{*fun string_of_cterm ctxt ct = |
252 ML{*fun string_of_cterm ctxt ct = |
252 string_of_term ctxt (term_of ct)*} |
253 string_of_term ctxt (term_of ct)*} |
253 |
254 |
254 text {* |
255 text {* |
255 In this example the function @{ML_ind term_of} extracts the @{ML_type |
256 In this example the function @{ML_ind term_of} extracts the @{ML_type |
256 term} from a @{ML_type cterm}. More than one @{ML_type cterm}s can again be |
257 term} from a @{ML_type cterm}. More than one @{ML_type cterm}s can again be |
257 printed with @{ML_ind commas}. |
258 printed with @{ML_ind commas}. |
258 *} |
259 *} |
259 |
260 |
260 ML{*fun string_of_cterms ctxt cts = |
261 ML{*fun string_of_cterms ctxt cts = |
261 commas (map (string_of_cterm ctxt) cts)*} |
262 commas (map (string_of_cterm ctxt) cts)*} |
262 |
263 |
263 text {* |
264 text {* |
264 The easiest way to get the string of a theorem is to transform it |
265 The easiest way to get the string of a theorem is to transform it |
265 into a @{ML_type cterm} using the function @{ML_ind crep_thm}. |
266 into a @{ML_type term} using the function @{ML_ind prop_of}. |
266 *} |
267 *} |
|
268 |
|
269 ML {* Thm.rep_thm @{thm mp} *} |
267 |
270 |
268 ML{*fun string_of_thm ctxt thm = |
271 ML{*fun string_of_thm ctxt thm = |
269 string_of_cterm ctxt (#prop (crep_thm thm))*} |
272 Syntax.string_of_term ctxt (prop_of thm)*} |
270 |
273 |
271 text {* |
274 text {* |
272 Theorems also include schematic variables, such as @{text "?P"}, |
275 Theorems also include schematic variables, such as @{text "?P"}, |
273 @{text "?Q"} and so on. They are needed in order to able to |
276 @{text "?Q"} and so on. They are needed in order to able to |
274 instantiate theorems when they are applied. For example the theorem |
277 instantiate theorems when they are applied. For example the theorem |
313 |
316 |
314 text {* |
317 text {* |
315 Note, that when printing out several parcels of information that |
318 Note, that when printing out several parcels of information that |
316 semantically belong together, like a warning message consisting for example |
319 semantically belong together, like a warning message consisting for example |
317 of a term and a type, you should try to keep this information together in a |
320 of a term and a type, you should try to keep this information together in a |
318 single string. So do not print out information as |
321 single string. Therefore do not print out information as |
319 |
322 |
320 @{ML_response_fake [display,gray] |
323 @{ML_response_fake [display,gray] |
321 "tracing \"First half,\"; |
324 "tracing \"First half,\"; |
322 tracing \"and second half.\"" |
325 tracing \"and second half.\"" |
323 "First half, |
326 "First half, |
395 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*} |
398 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*} |
396 |
399 |
397 text {* or *} |
400 text {* or *} |
398 |
401 |
399 ML{*fun inc_by_five x = |
402 ML{*fun inc_by_five x = |
400 ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*} |
403 ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*} |
401 |
404 |
402 text {* and typographically more economical than *} |
405 text {* and typographically more economical than *} |
403 |
406 |
404 ML{*fun inc_by_five x = |
407 ML{*fun inc_by_five x = |
405 let val y1 = x + 1 |
408 let val y1 = x + 1 |
442 end" |
445 end" |
443 "P z za zb"} |
446 "P z za zb"} |
444 |
447 |
445 You can read off this behaviour from how @{ML apply_fresh_args} is |
448 You can read off this behaviour from how @{ML apply_fresh_args} is |
446 coded: in Line 2, the function @{ML_ind fastype_of} calculates the type of the |
449 coded: in Line 2, the function @{ML_ind fastype_of} calculates the type of the |
447 term; @{ML_ind binder_types} in the next line produces the list of argument |
450 term; @{ML_ind binder_types} in the next line produces the list of argument |
448 types (in the case above the list @{text "[nat, int, unit]"}); Line 4 |
451 types (in the case above the list @{text "[nat, int, unit]"}); Line 4 |
449 pairs up each type with the string @{text "z"}; the |
452 pairs up each type with the string @{text "z"}; the |
450 function @{ML_ind variant_frees in Variable} generates for each @{text "z"} a |
453 function @{ML_ind variant_frees in Variable} generates for each @{text "z"} a |
451 unique name avoiding the given @{text f}; the list of name-type pairs is turned |
454 unique name avoiding the given @{text f}; the list of name-type pairs is turned |
452 into a list of variable terms in Line 6, which in the last line is applied |
455 into a list of variable terms in Line 6, which in the last line is applied |
641 |
644 |
642 @{ML_response_fake [display, gray] |
645 @{ML_response_fake [display, gray] |
643 "let |
646 "let |
644 val ctxt = @{context} |
647 val ctxt = @{context} |
645 in |
648 in |
646 map (Syntax.parse_term ctxt) [\"m + n\", \"m - (n::nat)\"] |
649 map (Syntax.parse_term ctxt) [\"m + n\", \"m * n\", \"m - (n::nat)\"] |
647 |> Syntax.check_terms ctxt |
650 |> Syntax.check_terms ctxt |
648 |> string_of_terms ctxt |
651 |> string_of_terms ctxt |
649 |> tracing |
652 |> tracing |
650 end" |
653 end" |
651 "m + n, m - n"} |
654 "m + n, m * n, m - n"} |
652 *} |
655 *} |
653 |
656 |
654 text {* |
657 text {* |
655 In this example we obtain two terms with appropriate typing. However, if you |
658 In this example we obtain three terms where @{text m} and @{text n} are of |
656 have only a single term, then @{ML check_terms in Syntax} needs to be |
659 type @{typ "nat"}. However, if you have only a single term, then @{ML |
657 adapted. This can be done with the ``plumbing'' function @{ML |
660 check_terms in Syntax} needs plumbing. This can be done with the function |
658 singleton}.\footnote{There is already a function @{ML check_term in Syntax} |
661 @{ML singleton}.\footnote{There is already a function @{ML check_term in |
659 in the Isabelle sources that is defined in terms of @{ML singleton} and @{ML |
662 Syntax} in the Isabelle sources that is defined in terms of @{ML singleton} |
660 check_terms in Syntax}.} For example |
663 and @{ML check_terms in Syntax}.} For example |
661 |
664 |
662 @{ML_response_fake [display, gray] |
665 @{ML_response_fake [display, gray] |
663 "let |
666 "let |
664 val ctxt = @{context} |
667 val ctxt = @{context} |
665 in |
668 in |
687 |
690 |
688 text {* |
691 text {* |
689 The main advantage of embedding all code in a theory is that the code can |
692 The main advantage of embedding all code in a theory is that the code can |
690 contain references to entities defined on the logical level of Isabelle. By |
693 contain references to entities defined on the logical level of Isabelle. By |
691 this we mean definitions, theorems, terms and so on. This kind of reference |
694 this we mean definitions, theorems, terms and so on. This kind of reference |
692 is realised with ML-antiquotations, often also referred to as just |
695 is realised with ML-antiquotations, often just called |
693 antiquotations.\footnote{There are two kinds of antiquotations in Isabelle, |
696 antiquotations.\footnote{There are two kinds of antiquotations in Isabelle, |
694 which have very different purpose and infrastructures. The first kind, |
697 which have very different purpose and infrastructures. The first kind, |
695 described in this section, are \emph{ML-antiquotations}. They are used to |
698 described in this section, are \emph{ML-antiquotations}. They are used to |
696 refer to entities (like terms, types etc) from Isabelle's logic layer inside |
699 refer to entities (like terms, types etc) from Isabelle's logic layer inside |
697 ML-code. The other kind of antiquotations are \emph{document} antiquotations. They |
700 ML-code. The other kind of antiquotations are \emph{document} |
698 are used only in the text parts of Isabelle and their purpose is to print |
701 antiquotations. They are used only in the text parts of Isabelle and their |
699 logical entities inside \LaTeX-documents. They are part of the user level |
702 purpose is to print logical entities inside \LaTeX-documents. They are part |
700 and therefore we are not interested in them in this Tutorial, except in |
703 of the user level and therefore we are not interested in them in this |
701 Appendix \ref{rec:docantiquotations} where we show how to implement your own |
704 Tutorial, except in Appendix \ref{rec:docantiquotations} where we show how |
702 document antiquotations.} |
705 to implement your own document antiquotations.} For example, one can print |
703 For example, one can print out the name of the current |
706 out the name of the current theory by typing |
704 theory by typing |
|
705 |
|
706 |
707 |
707 @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""} |
708 @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""} |
708 |
709 |
709 where @{text "@{theory}"} is an antiquotation that is substituted with the |
710 where @{text "@{theory}"} is an antiquotation that is substituted with the |
710 current theory (remember that we assumed we are inside the theory |
711 current theory (remember that we assumed we are inside the theory |
819 |> ML_Syntax.print_term |
820 |> ML_Syntax.print_term |
820 |> ML_Syntax.atomic))*} |
821 |> ML_Syntax.atomic))*} |
821 |
822 |
822 text {* |
823 text {* |
823 The parser in Line 2 provides us with a context and a string; this string is |
824 The parser in Line 2 provides us with a context and a string; this string is |
824 transformed into a term using the function @{ML_ind read_term_pattern in |
825 transformed into a term using the function @{ML_ind read_term_pattern in |
825 ProofContext} (Line 4); the next two lines print the term so that the |
826 ProofContext} (Line 4); the next two lines transform the term into a string |
826 ML-system can understand them. The function @{ML atomic in ML_Syntax} |
827 so that the ML-system can understand them. The function @{ML_ind atomic in |
827 just encloses the term in parentheses. An example for the usage of this |
828 ML_Syntax} just encloses the term in parentheses. An example for the usage |
828 antiquotation is: |
829 of this antiquotation is: |
829 |
830 |
830 @{ML_response_fake [display,gray] |
831 @{ML_response_fake [display,gray] |
831 "@{term_pat \"Suc (?x::nat)\"}" |
832 "@{term_pat \"Suc (?x::nat)\"}" |
832 "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"} |
833 "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"} |
833 |
834 |
842 |
843 |
843 section {* Storing Data (TBD) *} |
844 section {* Storing Data (TBD) *} |
844 |
845 |
845 text {* |
846 text {* |
846 Isabelle provides a mechanism to store (and retrieve) arbitrary data. Before we |
847 Isabelle provides a mechanism to store (and retrieve) arbitrary data. Before we |
847 explain this mechanism. |
848 explain this mechanism, let us digress a bit. Convenitional wisdom is that the |
|
849 type-system of ML ensures that for example an @{ML_type "'a list"} can only |
|
850 hold elements of type @{ML_type "'a"}. |
848 *} |
851 *} |
849 |
852 |
850 ML{*signature UNIVERSAL_TYPE = |
853 ML{*signature UNIVERSAL_TYPE = |
851 sig |
854 sig |
852 type t |
855 type t |