| author | Christian Urban <urbanc@in.tum.de> | 
| Sun, 06 Dec 2009 14:26:14 +0100 | |
| changeset 412 | 73f716b9201a | 
| parent 410 | 2656354c7544 | 
| child 414 | 5fc2fb34c323 | 
| permissions | -rw-r--r-- | 
| 395 
2c392f61f400
spilt the Essential's chapter
 Christian Urban <urbanc@in.tum.de> parents: 
394diff
changeset | 1 | theory Essential | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2 | imports Base FirstSteps | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 3 | begin | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 4 | |
| 346 
0fea8b7a14a1
tuned the ML-output mechanism; tuned slightly the text
 Christian Urban <urbanc@in.tum.de> parents: 
345diff
changeset | 5 | (*<*) | 
| 
0fea8b7a14a1
tuned the ML-output mechanism; tuned slightly the text
 Christian Urban <urbanc@in.tum.de> parents: 
345diff
changeset | 6 | setup{*
 | 
| 
0fea8b7a14a1
tuned the ML-output mechanism; tuned slightly the text
 Christian Urban <urbanc@in.tum.de> parents: 
345diff
changeset | 7 | open_file_with_prelude | 
| 398 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 8 | "Essential_Code.thy" | 
| 401 
36d61044f9bf
updated to new Isabelle and clarified Skip_Proof
 Christian Urban <urbanc@in.tum.de> parents: 
400diff
changeset | 9 | ["theory Essential", "imports Base FirstSteps", "begin"] | 
| 346 
0fea8b7a14a1
tuned the ML-output mechanism; tuned slightly the text
 Christian Urban <urbanc@in.tum.de> parents: 
345diff
changeset | 10 | *} | 
| 
0fea8b7a14a1
tuned the ML-output mechanism; tuned slightly the text
 Christian Urban <urbanc@in.tum.de> parents: 
345diff
changeset | 11 | (*>*) | 
| 
0fea8b7a14a1
tuned the ML-output mechanism; tuned slightly the text
 Christian Urban <urbanc@in.tum.de> parents: 
345diff
changeset | 12 | |
| 
0fea8b7a14a1
tuned the ML-output mechanism; tuned slightly the text
 Christian Urban <urbanc@in.tum.de> parents: 
345diff
changeset | 13 | |
| 358 | 14 | chapter {* Isabelle Essentials *}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 15 | |
| 319 
6bce4acf7f2a
added file for producing a keyword file
 Christian Urban <urbanc@in.tum.de> parents: 
318diff
changeset | 16 | text {*
 | 
| 410 | 17 |    \begin{flushright}
 | 
| 18 |   {\em One man's obfuscation is another man's abstraction.} \\[1ex]
 | |
| 19 | Frank Ch.~Eigler on the Linux Kernel Mailing List,\\ | |
| 20 | 24~Nov.~2009 | |
| 21 |   \end{flushright}
 | |
| 22 | ||
| 23 | \medskip | |
| 345 | 24 | Isabelle is build around a few central ideas. One central idea is the | 
| 25 | LCF-approach to theorem proving where there is a small trusted core and | |
| 410 | 26 | everything else is built on top of this trusted core | 
| 351 | 27 |   \cite{GordonMilnerWadsworth79}. The fundamental data
 | 
| 350 | 28 | structures involved in this core are certified terms and certified types, | 
| 29 | as well as theorems. | |
| 319 
6bce4acf7f2a
added file for producing a keyword file
 Christian Urban <urbanc@in.tum.de> parents: 
318diff
changeset | 30 | *} | 
| 
6bce4acf7f2a
added file for producing a keyword file
 Christian Urban <urbanc@in.tum.de> parents: 
318diff
changeset | 31 | |
| 
6bce4acf7f2a
added file for producing a keyword file
 Christian Urban <urbanc@in.tum.de> parents: 
318diff
changeset | 32 | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 33 | section {* Terms and Types *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 34 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 35 | text {*
 | 
| 350 | 36 | In Isabelle, there are certified terms and uncertified terms (respectively types). | 
| 37 | Uncertified terms are often just called terms. One way to construct them is by | |
| 329 | 38 |   using the antiquotation \mbox{@{text "@{term \<dots>}"}}. For example
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 39 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 40 |   @{ML_response [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 41 | "@{term \"(a::nat) + b = c\"}" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 42 | "Const (\"op =\", \<dots>) $ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 43 | (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 44 | |
| 350 | 45 |   constructs the term @{term "(a::nat) + b = c"}. The resulting term is printed using 
 | 
| 46 |   the internal representation corresponding to the datatype @{ML_type_ind "term"}, 
 | |
| 47 | which is defined as follows: | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 48 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 49 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 50 | ML_val %linenosgray{*datatype term =
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 51 | Const of string * typ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 52 | | Free of string * typ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 53 | | Var of indexname * typ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 54 | | Bound of int | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 55 | | Abs of string * typ * term | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 56 | | $ of term * term *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 57 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 58 | text {*
 | 
| 345 | 59 | This datatype implements Church-style lambda-terms, where types are | 
| 350 | 60 | explicitly recorded in variables, constants and abstractions. As can be | 
| 345 | 61 | seen in Line 5, terms use the usual de Bruijn index mechanism for | 
| 62 | representing bound variables. For example in | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 63 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 64 |   @{ML_response_fake [display, gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 65 |   "@{term \"\<lambda>x y. x y\"}"
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 66 | "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 67 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 68 |   the indices refer to the number of Abstractions (@{ML Abs}) that we need to
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 69 |   skip until we hit the @{ML Abs} that binds the corresponding
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 70 | variable. Constructing a term with dangling de Bruijn indices is possible, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 71 | but will be flagged as ill-formed when you try to typecheck or certify it | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 72 |   (see Section~\ref{sec:typechecking}). Note that the names of bound variables
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 73 | are kept at abstractions for printing purposes, and so should be treated | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 74 | only as ``comments''. Application in Isabelle is realised with the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 75 |   term-constructor @{ML $}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 76 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 77 |   Isabelle makes a distinction between \emph{free} variables (term-constructor
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 78 |   @{ML Free} and written on the user level in blue colour) and
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 79 |   \emph{schematic} variables (term-constructor @{ML Var} and written with a
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 80 | leading question mark). Consider the following two examples | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 81 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 82 |   @{ML_response_fake [display, gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 83 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 84 |   val v1 = Var ((\"x\", 3), @{typ bool})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 85 |   val v2 = Var ((\"x1\", 3), @{typ bool})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 86 |   val v3 = Free (\"x\", @{typ bool})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 87 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 88 |   string_of_terms @{context} [v1, v2, v3]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 89 | |> tracing | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 90 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 91 | "?x3, ?x1.3, x"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 92 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 93 | When constructing terms, you are usually concerned with free variables (as | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 94 | mentioned earlier, you cannot construct schematic variables using the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 95 |   antiquotation @{text "@{term \<dots>}"}). If you deal with theorems, you have to,
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 96 | however, observe the distinction. The reason is that only schematic | 
| 345 | 97 | variables can be instantiated with terms when a theorem is applied. A | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 98 | similar distinction between free and schematic variables holds for types | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 99 | (see below). | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 100 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 101 |   \begin{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 102 |   Terms and types are described in detail in \isccite{sec:terms}. Their
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 103 |   definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 104 | For constructing terms involving HOL constants, many helper functions are defined | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 105 |   in @{ML_file "HOL/Tools/hologic.ML"}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 106 |   \end{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 107 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 108 | Constructing terms via antiquotations has the advantage that only typable | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 109 | terms can be constructed. For example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 110 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 111 |   @{ML_response_fake_both [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 112 |   "@{term \"x x\"}"
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 113 | "Type unification failed: Occurs check!"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 114 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 115 | raises a typing error, while it perfectly ok to construct the term | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 116 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 117 |   @{ML_response_fake [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 118 | "let | 
| 345 | 119 |   val omega = Free (\"x\", @{typ \"nat \<Rightarrow> nat\"}) $ Free (\"x\", @{typ nat})
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 120 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 121 |   tracing (string_of_term @{context} omega)
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 122 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 123 | "x x"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 124 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 125 | with the raw ML-constructors. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 126 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 127 | Sometimes the internal representation of terms can be surprisingly different | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 128 | from what you see at the user-level, because the layers of | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 129 | parsing/type-checking/pretty printing can be quite elaborate. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 130 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 131 |   \begin{exercise}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 132 | Look at the internal term representation of the following terms, and | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 133 | find out why they are represented like this: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 134 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 135 |   \begin{itemize}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 136 |   \item @{term "case x of 0 \<Rightarrow> 0 | Suc y \<Rightarrow> y"}  
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 137 |   \item @{term "\<lambda>(x,y). P y x"}  
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 138 |   \item @{term "{ [x::int] | x. x \<le> -2 }"}  
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 139 |   \end{itemize}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 140 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 141 | Hint: The third term is already quite big, and the pretty printer | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 142 | may omit parts of it by default. If you want to see all of it, you | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 143 | can use the following ML-function to set the printing depth to a higher | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 144 | value: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 145 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 146 |   @{ML [display,gray] "print_depth 50"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 147 |   \end{exercise}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 148 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 149 |   The antiquotation @{text "@{prop \<dots>}"} constructs terms by inserting the 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 150 |   usually invisible @{text "Trueprop"}-coercions whenever necessary. 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 151 | Consider for example the pairs | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 152 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 153 | @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 154 | "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>), | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 155 | Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 156 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 157 | where a coercion is inserted in the second component and | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 158 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 159 |   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 160 | "(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 161 | Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 162 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 163 | where it is not (since it is already constructed by a meta-implication). | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 164 |   The purpose of the @{text "Trueprop"}-coercion is to embed formulae of
 | 
| 350 | 165 | an object logic, for example HOL, into the meta-logic of Isabelle. The coercion | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 166 | is needed whenever a term is constructed that will be proved as a theorem. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 167 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 168 | As already seen above, types can be constructed using the antiquotation | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 169 |   @{text "@{typ \<dots>}"}. For example:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 170 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 171 |   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 172 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 173 | The corresponding datatype is | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 174 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 175 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 176 | ML_val{*datatype typ =
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 177 | Type of string * typ list | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 178 | | TFree of string * sort | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 179 | | TVar of indexname * sort *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 180 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 181 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 182 | Like with terms, there is the distinction between free type | 
| 350 | 183 |   variables (term-constructor @{ML "TFree"}) and schematic
 | 
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 184 |   type variables (term-constructor @{ML "TVar"} and printed with
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 185 | a leading question mark). A type constant, | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 186 |   like @{typ "int"} or @{typ bool}, are types with an empty list
 | 
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 187 | of argument types. However, it needs a bit of effort to show an | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 188 | example, because Isabelle always pretty prints types (unlike terms). | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 189 |   Using just the antiquotation @{text "@{typ \"bool\"}"} we only see
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 190 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 191 |   @{ML_response [display, gray]
 | 
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 192 |   "@{typ \"bool\"}"
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 193 | "bool"} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 194 | |
| 393 | 195 |   that is the pretty printed version of @{text "bool"}. However, in PolyML
 | 
| 196 | (version 5.3) it is easy to install your own pretty printer. With the | |
| 197 | function below we mimic the behaviour of the usual pretty printer for | |
| 198 | datatypes (it uses pretty-printing functions which will be explained in more | |
| 199 |   detail in Section~\ref{sec:pretty}).
 | |
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 200 | *} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 201 | |
| 393 | 202 | ML{*local
 | 
| 203 |   fun pp_pair (x, y) = Pretty.list "(" ")" [x, y]
 | |
| 392 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 204 | fun pp_list xs = Pretty.list "[" "]" xs | 
| 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 205 | fun pp_str s = Pretty.str s | 
| 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 206 | fun pp_qstr s = Pretty.quote (pp_str s) | 
| 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 207 | fun pp_int i = pp_str (string_of_int i) | 
| 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 208 | fun pp_sort S = pp_list (map pp_qstr S) | 
| 393 | 209 | fun pp_constr a args = Pretty.block [pp_str a, Pretty.brk 1, args] | 
| 392 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 210 | in | 
| 393 | 211 | fun raw_pp_typ (TVar ((a, i), S)) = | 
| 392 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 212 | pp_constr "TVar" (pp_pair (pp_pair (pp_qstr a, pp_int i), pp_sort S)) | 
| 393 | 213 | | raw_pp_typ (TFree (a, S)) = | 
| 392 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 214 | pp_constr "TFree" (pp_pair (pp_qstr a, pp_sort S)) | 
| 393 | 215 | | raw_pp_typ (Type (a, tys)) = | 
| 392 
47e5b71c7f6c
modified the typ-pretty-printer and added parser exercise
 Christian Urban <urbanc@in.tum.de> parents: 
389diff
changeset | 216 | pp_constr "Type" (pp_pair (pp_qstr a, pp_list (map raw_pp_typ tys))) | 
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 217 | end*} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 218 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 219 | text {*
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 220 | We can install this pretty printer with the function | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 221 |   @{ML_ind addPrettyPrinter in PolyML} as follows.
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 222 | *} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 223 | |
| 393 | 224 | ML{*PolyML.addPrettyPrinter 
 | 
| 225 | (fn _ => fn _ => ml_pretty o Pretty.to_ML o raw_pp_typ)*} | |
| 388 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 226 | |
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 227 | text {*
 | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 228 | Now the type bool is printed out in full detail. | 
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 229 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 230 |   @{ML_response [display,gray]
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 231 |   "@{typ \"bool\"}"
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 232 | "Type (\"bool\", [])"} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 233 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 234 | When printing out a list-type | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 235 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 236 |   @{ML_response [display,gray]
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 237 |   "@{typ \"'a list\"}"
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 238 | "Type (\"List.list\", [TFree (\"'a\", [\"HOL.type\"])])"} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 239 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 240 |   we can see the full name of the type is actually @{text "List.list"}, indicating
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 241 |   that it is defined in the theory @{text "List"}. However, one has to be 
 | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 242 | careful with names of types, because even if | 
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 243 |   @{text "fun"}, @{text "bool"} and @{text "nat"} are defined in the 
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 244 |   theories @{text "HOL"} and @{text "Nat"}, respectively, they are 
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 245 | still represented by their simple name. | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 246 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 247 |    @{ML_response [display,gray]
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 248 |   "@{typ \"bool \<Rightarrow> nat\"}"
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 249 | "Type (\"fun\", [Type (\"bool\", []), Type (\"nat\", [])])"} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 250 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 251 | We can restore the usual behaviour of Isabelle's pretty printer | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 252 | with the code | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 253 | *} | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 254 | |
| 393 | 255 | ML{*PolyML.addPrettyPrinter 
 | 
| 256 | (fn _ => fn _ => ml_pretty o Pretty.to_ML o Proof_Display.pp_typ Pure.thy)*} | |
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 257 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 258 | text {*
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 259 | After that the types for booleans, lists and so on are printed out again | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 260 | the standard Isabelle way. | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 261 | |
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 262 |   @{ML_response_fake [display, gray]
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 263 |   "@{typ \"bool\"};
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 264 | @{typ \"'a list\"}"
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 265 | "\"bool\" | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 266 | \"'a List.list\""} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 267 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 268 |   \begin{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 269 |   Types are described in detail in \isccite{sec:types}. Their
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 270 | definition and many useful operations are implemented | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 271 |   in @{ML_file "Pure/type.ML"}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 272 |   \end{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 273 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 274 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 275 | section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 276 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 277 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 278 | While antiquotations are very convenient for constructing terms, they can | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 279 | only construct fixed terms (remember they are ``linked'' at compile-time). | 
| 335 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 280 | However, you often need to construct terms manually. For example, a | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 281 |   function that returns the implication @{text "\<And>(x::nat). P x \<Longrightarrow> Q x"} taking
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 282 |   @{term P} and @{term Q} as arguments can only be written as:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 283 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 284 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 285 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 286 | ML{*fun make_imp P Q =
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 287 | let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 288 |   val x = Free ("x", @{typ nat})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 289 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 290 | Logic.all x (Logic.mk_implies (P $ x, Q $ x)) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 291 | end *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 292 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 293 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 294 |   The reason is that you cannot pass the arguments @{term P} and @{term Q} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 295 |   into an antiquotation.\footnote{At least not at the moment.} For example 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 296 |   the following does \emph{not} work.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 297 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 298 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 299 | ML{*fun make_wrong_imp P Q = @{prop "\<And>(x::nat). P x \<Longrightarrow> Q x"} *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 300 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 301 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 302 |   To see this, apply @{text "@{term S}"} and @{text "@{term T}"} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 303 |   to both functions. With @{ML make_imp} you obtain the intended term involving 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 304 | the given arguments | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 305 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 306 |   @{ML_response [display,gray] "make_imp @{term S} @{term T}" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 307 | "Const \<dots> $ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 308 | Abs (\"x\", Type (\"nat\",[]), | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 309 | Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ (Free (\"T\",\<dots>) $ \<dots>))"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 310 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 311 |   whereas with @{ML make_wrong_imp} you obtain a term involving the @{term "P"} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 312 |   and @{text "Q"} from the antiquotation.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 313 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 314 |   @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T}" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 315 | "Const \<dots> $ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 316 | Abs (\"x\", \<dots>, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 317 | Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 318 | (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 319 | |
| 345 | 320 | There are a number of handy functions that are frequently used for | 
| 321 |   constructing terms. One is the function @{ML_ind list_comb in Term}, which
 | |
| 350 | 322 | takes as argument a term and a list of terms, and produces as output the | 
| 345 | 323 | term list applied to the term. For example | 
| 324 | ||
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 325 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 326 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 327 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 328 |   val trm = @{term \"P::nat\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 329 |   val args = [@{term \"True\"}, @{term \"False\"}]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 330 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 331 | list_comb (trm, args) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 332 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 333 | "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 334 | |
| 345 | 335 |   Another handy function is @{ML_ind lambda in Term}, which abstracts a variable 
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 336 | in a term. For example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 337 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 338 |   @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 339 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 340 |   val x_nat = @{term \"x::nat\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 341 |   val trm = @{term \"(P::nat \<Rightarrow> bool) x\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 342 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 343 | lambda x_nat trm | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 344 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 345 | "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 346 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 347 |   In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound 0"}), 
 | 
| 350 | 348 | and an abstraction, where it also records the type of the abstracted | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 349 | variable and for printing purposes also its name. Note that because of the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 350 |   typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 351 | is of the same type as the abstracted variable. If it is of different type, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 352 | as in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 353 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 354 |   @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 355 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 356 |   val x_int = @{term \"x::int\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 357 |   val trm = @{term \"(P::nat \<Rightarrow> bool) x\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 358 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 359 | lambda x_int trm | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 360 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 361 | "Abs (\"x\", \"int\", Free (\"P\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 362 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 363 |   then the variable @{text "Free (\"x\", \"int\")"} is \emph{not} abstracted. 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 364 | This is a fundamental principle | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 365 | of Church-style typing, where variables with the same name still differ, if they | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 366 | have different type. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 367 | |
| 345 | 368 |   There is also the function @{ML_ind subst_free in Term} with which terms can be
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 369 |   replaced by other terms. For example below, we will replace in @{term
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 370 |   "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0 x"} the subterm @{term "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0"} by
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 371 |   @{term y}, and @{term x} by @{term True}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 372 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 373 |   @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 374 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 375 |   val sub1 = (@{term \"(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0\"}, @{term \"y::nat \<Rightarrow> nat\"})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 376 |   val sub2 = (@{term \"x::nat\"}, @{term \"True\"})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 377 |   val trm = @{term \"((f::nat \<Rightarrow> nat \<Rightarrow> nat) 0) x\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 378 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 379 | subst_free [sub1, sub2] trm | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 380 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 381 | "Free (\"y\", \"nat \<Rightarrow> nat\") $ Const (\"True\", \"bool\")"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 382 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 383 |   As can be seen, @{ML subst_free} does not take typability into account.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 384 | However it takes alpha-equivalence into account: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 385 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 386 |   @{ML_response_fake [display, gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 387 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 388 |   val sub = (@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 389 |   val trm = @{term \"(\<lambda>x::nat. x)\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 390 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 391 | subst_free [sub] trm | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 392 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 393 | "Free (\"x\", \"nat\")"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 394 | |
| 345 | 395 |   Similarly the function @{ML_ind subst_bounds in Term}, replaces lose bound 
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 396 | variables with terms. To see how this function works, let us implement a | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 397 | function that strips off the outermost quantifiers in a term. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 398 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 399 | |
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 400 | ML{*fun strip_alls t =
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 401 | let | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 402 | fun aux (x, T, t) = strip_alls t |>> cons (Free (x, T)) | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 403 | in | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 404 | case t of | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 405 |     Const ("All", _) $ Abs body => aux body
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 406 | | _ => ([], t) | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 407 | end*} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 408 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 409 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 410 | The function returns a pair consisting of the stripped off variables and | 
| 350 | 411 | the body of the universal quantification. For example | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 412 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 413 |   @{ML_response_fake [display, gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 414 |   "strip_alls @{term \"\<forall>x y. x = (y::bool)\"}"
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 415 | "([Free (\"x\", \"bool\"), Free (\"y\", \"bool\")], | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 416 | Const (\"op =\", \<dots>) $ Bound 1 $ Bound 0)"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 417 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 418 |   After calling @{ML strip_alls}, you obtain a term with lose bound variables. With
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 419 |   the function @{ML subst_bounds}, you can replace these lose @{ML_ind 
 | 
| 345 | 420 | Bound in Term}s with the stripped off variables. | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 421 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 422 |   @{ML_response_fake [display, gray, linenos]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 423 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 424 |   val (vrs, trm) = strip_alls @{term \"\<forall>x y. x = (y::bool)\"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 425 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 426 | subst_bounds (rev vrs, trm) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 427 |   |> string_of_term @{context}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 428 | |> tracing | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 429 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 430 | "x = y"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 431 | |
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 432 |   Note that in Line 4 we had to reverse the list of variables that @{ML
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 433 | strip_alls} returned. The reason is that the head of the list the function | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 434 |   @{ML subst_bounds} takes is the replacement for @{ML "Bound 0"}, the next
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 435 |   element for @{ML "Bound 1"} and so on. 
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 436 | |
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 437 | Notice also that this function might introduce name clashes, since we | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 438 | substitute just a variable with the name recorded in an abstraction. This | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 439 | name is by no means unique. If clashes need to be avoided, then we should | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 440 |   use the function @{ML_ind dest_abs in Term}, which returns the body where
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 441 | the lose de Bruijn index is replaced by a unique free variable. For example | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 442 | |
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 443 | |
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 444 |   @{ML_response_fake [display,gray]
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 445 | "let | 
| 374 | 446 |   val body = Bound 0 $ Free (\"x\", @{typ nat})
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 447 | in | 
| 374 | 448 |   Term.dest_abs (\"x\", @{typ \"nat \<Rightarrow> bool\"}, body)
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 449 | end" | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 450 | "(\"xa\", Free (\"xa\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 451 | |
| 350 | 452 | There are also many convenient functions that construct specific HOL-terms | 
| 453 |   in the structure @{ML_struct HOLogic}. For
 | |
| 345 | 454 |   example @{ML_ind mk_eq in HOLogic} constructs an equality out of two terms.
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 455 | The types needed in this equality are calculated from the type of the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 456 | arguments. For example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 457 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 458 | @{ML_response_fake [gray,display]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 459 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 460 |   val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 461 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 462 |   string_of_term @{context} eq
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 463 | |> tracing | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 464 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 465 | "True = False"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 466 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 467 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 468 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 469 |   \begin{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 470 |   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file
 | 
| 374 | 471 |   "Pure/logic.ML"} and @{ML_file "HOL/Tools/hologic.ML"} that make manual
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 472 | constructions of terms and types easier. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 473 |   \end{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 474 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 475 | When constructing terms manually, there are a few subtle issues with | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 476 | constants. They usually crop up when pattern matching terms or types, or | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 477 | when constructing them. While it is perfectly ok to write the function | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 478 |   @{text is_true} as follows
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 479 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 480 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 481 | ML{*fun is_true @{term True} = true
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 482 | | is_true _ = false*} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 483 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 484 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 485 |   this does not work for picking out @{text "\<forall>"}-quantified terms. Because
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 486 | the function | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 487 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 488 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 489 | ML{*fun is_all (@{term All} $ _) = true
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 490 | | is_all _ = false*} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 491 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 492 | text {* 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 493 |   will not correctly match the formula @{prop[source] "\<forall>x::nat. P x"}: 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 494 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 495 |   @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "false"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 496 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 497 |   The problem is that the @{text "@term"}-antiquotation in the pattern 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 498 |   fixes the type of the constant @{term "All"} to be @{typ "('a \<Rightarrow> bool) \<Rightarrow> bool"} for 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 499 |   an arbitrary, but fixed type @{typ "'a"}. A properly working alternative 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 500 | for this function is | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 501 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 502 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 503 | ML{*fun is_all (Const ("All", _) $ _) = true
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 504 | | is_all _ = false*} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 505 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 506 | text {* 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 507 | because now | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 508 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 509 | @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "true"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 510 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 511 | matches correctly (the first wildcard in the pattern matches any type and the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 512 | second any term). | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 513 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 514 | However there is still a problem: consider the similar function that | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 515 |   attempts to pick out @{text "Nil"}-terms:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 516 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 517 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 518 | ML{*fun is_nil (Const ("Nil", _)) = true
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 519 | | is_nil _ = false *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 520 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 521 | text {* 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 522 |   Unfortunately, also this function does \emph{not} work as expected, since
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 523 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 524 |   @{ML_response [display,gray] "is_nil @{term \"Nil\"}" "false"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 525 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 526 | The problem is that on the ML-level the name of a constant is more | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 527 |   subtle than you might expect. The function @{ML is_all} worked correctly,
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 528 |   because @{term "All"} is such a fundamental constant, which can be referenced
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 529 |   by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 530 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 531 |   @{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 532 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 533 |   the name of the constant @{text "Nil"} depends on the theory in which the
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 534 |   term constructor is defined (@{text "List"}) and also in which datatype
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 535 |   (@{text "list"}). Even worse, some constants have a name involving
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 536 |   type-classes. Consider for example the constants for @{term "zero"} and
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 537 |   \mbox{@{text "(op *)"}}:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 538 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 539 |   @{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"(op *)\"})" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 540 | "(Const (\"HOL.zero_class.zero\", \<dots>), | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 541 | Const (\"HOL.times_class.times\", \<dots>))"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 542 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 543 | While you could use the complete name, for example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 544 |   @{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 545 |   matching against @{text "Nil"}, this would make the code rather brittle. 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 546 | The reason is that the theory and the name of the datatype can easily change. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 547 | To make the code more robust, it is better to use the antiquotation | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 548 |   @{text "@{const_name \<dots>}"}. With this antiquotation you can harness the 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 549 | variable parts of the constant's name. Therefore a function for | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 550 | matching against constants that have a polymorphic type should | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 551 | be written as follows. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 552 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 553 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 554 | ML{*fun is_nil_or_all (Const (@{const_name "Nil"}, _)) = true
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 555 |   | is_nil_or_all (Const (@{const_name "All"}, _) $ _) = true
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 556 | | is_nil_or_all _ = false *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 557 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 558 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 559 |   The antiquotation for properly referencing type constants is @{text "@{type_name \<dots>}"}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 560 | For example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 561 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 562 |   @{ML_response [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 563 |   "@{type_name \"list\"}" "\"List.list\""}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 564 | |
| 329 | 565 |   \footnote{\bf FIXME: Explain the following better; maybe put in a separate
 | 
| 566 | section and link with the comment in the antiquotation section.} | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 567 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 568 | Occasionally you have to calculate what the ``base'' name of a given | 
| 345 | 569 |   constant is. For this you can use the function @{ML_ind "Sign.extern_const"} or
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 570 |   @{ML_ind  Long_Name.base_name}. For example:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 571 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 572 |   @{ML_response [display,gray] "Sign.extern_const @{theory} \"List.list.Nil\"" "\"Nil\""}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 573 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 574 |   The difference between both functions is that @{ML extern_const in Sign} returns
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 575 |   the smallest name that is still unique, whereas @{ML base_name in Long_Name} always
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 576 | strips off all qualifiers. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 577 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 578 |   \begin{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 579 |   Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 580 |   functions about signatures in @{ML_file "Pure/sign.ML"}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 581 |   \end{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 582 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 583 | Although types of terms can often be inferred, there are many | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 584 | situations where you need to construct types manually, especially | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 585 | when defining constants. For example the function returning a function | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 586 | type is as follows: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 587 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 588 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 589 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 590 | ML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 591 | |
| 345 | 592 | text {* This can be equally written with the combinator @{ML_ind "-->" in Term} as: *}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 593 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 594 | ML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 595 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 596 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 597 | If you want to construct a function type with more than one argument | 
| 345 | 598 |   type, then you can use @{ML_ind "--->" in Term}.
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 599 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 600 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 601 | ML{*fun make_fun_types tys ty = tys ---> ty *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 602 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 603 | text {*
 | 
| 369 | 604 |   A handy function for manipulating terms is @{ML_ind map_types in Term}: it takes a 
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 605 | function and applies it to every type in a term. You can, for example, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 606 |   change every @{typ nat} in a term into an @{typ int} using the function:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 607 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 608 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 609 | ML{*fun nat_to_int ty =
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 610 | (case ty of | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 611 |      @{typ nat} => @{typ int}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 612 | | Type (s, tys) => Type (s, map nat_to_int tys) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 613 | | _ => ty)*} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 614 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 615 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 616 | Here is an example: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 617 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 618 | @{ML_response_fake [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 619 | "map_types nat_to_int @{term \"a = (1::nat)\"}" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 620 | "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\") | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 621 | $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 622 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 623 | If you want to obtain the list of free type-variables of a term, you | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 624 |   can use the function @{ML_ind  add_tfrees in Term} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 625 |   (similarly @{ML_ind  add_tvars in Term} for the schematic type-variables). 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 626 | One would expect that such functions | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 627 | take a term as input and return a list of types. But their type is actually | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 628 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 629 |   @{text[display] "Term.term -> (string * Term.sort) list -> (string * Term.sort) list"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 630 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 631 | that is they take, besides a term, also a list of type-variables as input. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 632 | So in order to obtain the list of type-variables of a term you have to | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 633 | call them as follows | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 634 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 635 |   @{ML_response [gray,display]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 636 |   "Term.add_tfrees @{term \"(a, b)\"} []"
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 637 | "[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 638 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 639 |   The reason for this definition is that @{ML add_tfrees in Term} can
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 640 | be easily folded over a list of terms. Similarly for all functions | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 641 |   named @{text "add_*"} in @{ML_file "Pure/term.ML"}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 642 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 643 |   \begin{exercise}\label{fun:revsum}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 644 |   Write a function @{text "rev_sum : term -> term"} that takes a
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 645 |   term of the form @{text "t\<^isub>1 + t\<^isub>2 + \<dots> + t\<^isub>n"} (whereby @{text "n"} might be one)
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 646 |   and returns the reversed sum @{text "t\<^isub>n + \<dots> + t\<^isub>2 + t\<^isub>1"}. Assume
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 647 |   the @{text "t\<^isub>i"} can be arbitrary expressions and also note that @{text "+"} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 648 | associates to the left. Try your function on some examples. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 649 |   \end{exercise}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 650 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 651 |   \begin{exercise}\label{fun:makesum}
 | 
| 350 | 652 | Write a function that takes two terms representing natural numbers | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 653 |   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 654 | number representing their sum. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 655 |   \end{exercise}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 656 | |
| 329 | 657 |   \begin{exercise}\label{ex:debruijn}
 | 
| 350 | 658 | Implement the function, which we below name deBruijn, that depends on a natural | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 659 | number n$>$0 and constructs terms of the form: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 660 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 661 |   \begin{center}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 662 |   \begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 663 |   {\it rhs n} & $\dn$ & {\large$\bigwedge$}{\it i=1\ldots n.  P\,i}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 664 |   {\it lhs n} & $\dn$ & {\large$\bigwedge$}{\it i=1\ldots n. P\,i = P (i + 1 mod n)}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 665 |                         $\longrightarrow$ {\it rhs n}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 666 |   {\it deBruijn n} & $\dn$ & {\it lhs n} $\longrightarrow$ {\it rhs n}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 667 |   \end{tabular}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 668 |   \end{center}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 669 | |
| 329 | 670 | This function returns for n=3 the term | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 671 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 672 |   \begin{center}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 673 |   \begin{tabular}{l}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 674 | (P 1 = P 2 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 675 | (P 2 = P 3 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 676 | (P 3 = P 1 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 677 |   \end{tabular}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 678 |   \end{center}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 679 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 680 |   Make sure you use the functions defined in @{ML_file "HOL/Tools/hologic.ML"}
 | 
| 350 | 681 |   for constructing the terms for the logical connectives.\footnote{Thanks to Roy
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 682 | Dyckhoff for suggesting this exercise and working out the details.} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 683 |   \end{exercise}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 684 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 685 | |
| 412 | 686 | section {* Unification and Matching\label{sec:univ} *}
 | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 687 | |
| 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 688 | text {* 
 | 
| 386 | 689 | As seen earlier, Isabelle's terms and types may contain schematic term variables | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 690 |   (term-constructor @{ML Var}) and schematic type variables (term-constructor
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 691 |   @{ML TVar}). These variables stand for unknown entities, which can be made
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 692 | more concrete by instantiations. Such instantiations might be a result of | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 693 | unification or matching. While in case of types, unification and matching is | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 694 | relatively straightforward, in case of terms the algorithms are | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 695 | substantially more complicated, because terms need higher-order versions of | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 696 | the unification and matching algorithms. Below we shall use the | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 697 |   antiquotations @{text "@{typ_pat \<dots>}"} and @{text "@{term_pat \<dots>}"} from
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 698 |   Section~\ref{sec:antiquote} in order to construct examples involving
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 699 | schematic variables. | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 700 | |
| 403 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 701 | Let us begin with describing the unification and matching functions for | 
| 383 | 702 |   types.  Both return type environments (ML-type @{ML_type "Type.tyenv"})
 | 
| 703 | which map schematic type variables to types and sorts. Below we use the | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 704 |   function @{ML_ind typ_unify in Sign} from the structure @{ML_struct Sign}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 705 |   for unifying the types @{text "?'a * ?'b"} and @{text "?'b list *
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 706 |   nat"}. This will produce the mapping, or type environment, @{text "[?'a :=
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 707 | ?'b list, ?'b := nat]"}. | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 708 | *} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 709 | |
| 382 | 710 | ML %linenosgray{*val (tyenv_unif, _) = let
 | 
| 379 | 711 |   val ty1 = @{typ_pat "?'a * ?'b"}
 | 
| 712 |   val ty2 = @{typ_pat "?'b list * nat"}
 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 713 | in | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 714 |   Sign.typ_unify @{theory} (ty1, ty2) (Vartab.empty, 0) 
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 715 | end*} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 716 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 717 | text {* 
 | 
| 383 | 718 |   The environment @{ML_ind "Vartab.empty"} in line 5 stands for the empty type
 | 
| 719 | environment, which is needed for starting the unification without any | |
| 386 | 720 |   (pre)instantiations. The @{text 0} is an integer index that will be explained
 | 
| 383 | 721 |   below. In case of failure @{ML typ_unify in Sign} will throw the exception
 | 
| 386 | 722 |   @{text TUNIFY}.  We can print out the resulting type environment bound to 
 | 
| 723 |   @{ML tyenv_unif} with the built-in function @{ML_ind dest in Vartab} from the
 | |
| 383 | 724 |   structure @{ML_struct Vartab}.
 | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 725 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 726 |   @{ML_response_fake [display,gray]
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 727 | "Vartab.dest tyenv_unif" | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 728 | "[((\"'a\", 0), ([\"HOL.type\"], \"?'b List.list\")), | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 729 | ((\"'b\", 0), ([\"HOL.type\"], \"nat\"))]"} | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 730 | *} | 
| 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 731 | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 732 | text_raw {*
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 733 |   \begin{figure}[t]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 734 |   \begin{minipage}{\textwidth}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 735 |   \begin{isabelle}*}
 | 
| 389 | 736 | ML{*fun pretty_helper aux env =
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 737 | env |> Vartab.dest | 
| 389 | 738 | |> map ((fn (s1, s2) => s1 ^ " := " ^ s2) o aux) | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 739 | |> commas | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 740 | |> enclose "[" "]" | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 741 | |> tracing | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 742 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 743 | fun pretty_tyenv ctxt tyenv = | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 744 | let | 
| 389 | 745 | fun get_typs (v, (s, T)) = (TVar (v, s), T) | 
| 746 | val print = pairself (Syntax.string_of_typ ctxt) | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 747 | in | 
| 389 | 748 | pretty_helper (print o get_typs) tyenv | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 749 | end*} | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 750 | text_raw {*
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 751 |   \end{isabelle}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 752 |   \end{minipage}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 753 |   \caption{A pretty printing function for type environments, which are 
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 754 |   produced by unification and matching.\label{fig:prettyenv}}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 755 |   \end{figure}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 756 | *} | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 757 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 758 | text {*
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 759 | The first components in this list stand for the schematic type variables and | 
| 383 | 760 | the second are the associated sorts and types. In this example the sort is | 
| 386 | 761 |   the default sort @{text "HOL.type"}. Instead of @{ML "Vartab.dest"}, we will
 | 
| 762 | use in what follows our own pretty-printing function from | |
| 763 |   Figure~\ref{fig:prettyenv} for @{ML_type "Type.tyenv"}s. For the type
 | |
| 764 | environment in the example this function prints out the more legible: | |
| 765 | ||
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 766 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 767 |   @{ML_response_fake [display, gray]
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 768 |   "pretty_tyenv @{context} tyenv_unif"
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 769 | "[?'a := ?'b list, ?'b := nat]"} | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 770 | |
| 383 | 771 |   The way the unification function @{ML typ_unify in Sign} is implemented 
 | 
| 772 | using an initial type environment and initial index makes it easy to | |
| 773 | unify more than two terms. For example | |
| 774 | *} | |
| 775 | ||
| 776 | ML %linenosgray{*val (tyenvs, _) = let
 | |
| 777 |   val tys1 = (@{typ_pat "?'a"}, @{typ_pat "?'b list"})
 | |
| 778 |   val tys2 = (@{typ_pat "?'b"}, @{typ_pat "nat"})
 | |
| 779 | in | |
| 780 |   fold (Sign.typ_unify @{theory}) [tys1, tys2] (Vartab.empty, 0) 
 | |
| 781 | end*} | |
| 782 | ||
| 783 | text {*
 | |
| 784 |   The index @{text 0} in Line 5 is the maximal index of the schematic type
 | |
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 785 |   variables occurring in @{text tys1} and @{text tys2}. This index will be
 | 
| 383 | 786 | increased whenever a new schematic type variable is introduced during | 
| 787 | unification. This is for example the case when two schematic type variables | |
| 788 | have different, incomparable sorts. Then a new schematic type variable is | |
| 789 | introduced with the combined sorts. To show this let us assume two sorts, | |
| 790 |   say @{text "s1"} and @{text "s2"}, which we attach to the schematic type
 | |
| 791 |   variables @{text "?'a"} and @{text "?'b"}. Since we do not make any
 | |
| 792 | assumption about the sorts, they are incomparable. | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 793 | *} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 794 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 795 | ML{*val (tyenv, index) = let
 | 
| 383 | 796 |   val ty1 = @{typ_pat "?'a::s1"}
 | 
| 797 |   val ty2 = @{typ_pat "?'b::s2"}
 | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 798 | in | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 799 |   Sign.typ_unify @{theory} (ty1, ty2) (Vartab.empty, 0) 
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 800 | end*} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 801 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 802 | text {*
 | 
| 383 | 803 | To print out the result type environment we switch on the printing | 
| 804 |   of sort information by setting @{ML_ind show_sorts in Syntax} to 
 | |
| 805 | true. This allows us to inspect the typing environment. | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 806 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 807 |   @{ML_response_fake [display,gray]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 808 |   "pretty_tyenv @{context} tyenv"
 | 
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 809 |   "[?'a::s1 := ?'a1::{s1, s2}, ?'b::s2 := ?'a1::{s1, s2}]"}
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 810 | |
| 383 | 811 |   As can be seen, the type variables @{text "?'a"} and @{text "?'b"} are instantiated
 | 
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 812 |   with a new type variable @{text "?'a1"} with sort @{text "{s1, s2}"}. Since a new
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 813 |   type variable has been introduced the @{ML index}, originally being @{text 0}, 
 | 
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 814 |   has been increased to @{text 1}.
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 815 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 816 |   @{ML_response [display,gray]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 817 | "index" | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 818 | "1"} | 
| 383 | 819 | |
| 386 | 820 |   Let us now return to the unification problem @{text "?'a * ?'b"} and 
 | 
| 821 |   @{text "?'b list * nat"} from the beginning of this section, and the 
 | |
| 383 | 822 |   calculated type environment @{ML tyenv_unif}:
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 823 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 824 |   @{ML_response_fake [display, gray]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 825 |   "pretty_tyenv @{context} tyenv_unif"
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 826 | "[?'a := ?'b list, ?'b := nat]"} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 827 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 828 |   Observe that the type environment which the function @{ML typ_unify in
 | 
| 399 | 829 |   Sign} returns is \emph{not} an instantiation in fully solved form: while @{text
 | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 830 |   "?'b"} is instantiated to @{typ nat}, this is not propagated to the
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 831 |   instantiation for @{text "?'a"}.  In unification theory, this is often
 | 
| 386 | 832 |   called an instantiation in \emph{triangular form}. These triangular 
 | 
| 833 | instantiations, or triangular type environments, are used because of | |
| 834 |   performance reasons. To apply such a type environment to a type, say @{text "?'a *
 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 835 |   ?'b"}, you should use the function @{ML_ind norm_type in Envir}:
 | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 836 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 837 |   @{ML_response_fake [display, gray]
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 838 |   "Envir.norm_type tyenv_unif @{typ_pat \"?'a * ?'b\"}"
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 839 | "nat list * nat"} | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 840 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 841 |   Matching of types can be done with the function @{ML_ind typ_match in Sign}
 | 
| 383 | 842 |   also from the structure @{ML_struct Sign}. This function returns a @{ML_type
 | 
| 843 |   Type.tyenv} as well, but might raise the exception @{text TYPE_MATCH} in case
 | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 844 | of failure. For example | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 845 | *} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 846 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 847 | ML{*val tyenv_match = let
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 848 |   val pat = @{typ_pat "?'a * ?'b"}
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 849 |   and ty  = @{typ_pat "bool list * nat"}
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 850 | in | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 851 |   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 852 | end*} | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 853 | |
| 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 854 | text {*
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 855 | Printing out the calculated matcher gives | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 856 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 857 |   @{ML_response_fake [display,gray]
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 858 |   "pretty_tyenv @{context} tyenv_match"
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 859 | "[?'a := bool list, ?'b := nat]"} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 860 | |
| 383 | 861 |   Unlike unification, which uses the function @{ML norm_type in Envir}, 
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 862 | applying the matcher to a type needs to be done with the function | 
| 386 | 863 |   @{ML_ind subst_type in Envir}. For example
 | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 864 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 865 |   @{ML_response_fake [display, gray]
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 866 |   "Envir.subst_type tyenv_match @{typ_pat \"?'a * ?'b\"}"
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 867 | "bool list * nat"} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 868 | |
| 399 | 869 | Be careful to observe the difference: always use | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 870 |   @{ML subst_type in Envir} for matchers and @{ML norm_type in Envir} 
 | 
| 386 | 871 | for unifiers. To show the difference, let us calculate the | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 872 | following matcher: | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 873 | *} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 874 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 875 | ML{*val tyenv_match' = let
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 876 |   val pat = @{typ_pat "?'a * ?'b"}
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 877 |   and ty  = @{typ_pat "?'b list * nat"}
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 878 | in | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 879 |   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 880 | end*} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 881 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 882 | text {*
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 883 |   Now @{ML tyenv_unif} is equal to @{ML tyenv_match'}. If we apply 
 | 
| 383 | 884 |   @{ML norm_type in Envir} to the type @{text "?'a * ?'b"} we obtain
 | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 885 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 886 |   @{ML_response_fake [display, gray]
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 887 |   "Envir.norm_type tyenv_match' @{typ_pat \"?'a * ?'b\"}"
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 888 | "nat list * nat"} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 889 | |
| 383 | 890 | which does not solve the matching problem, and if | 
| 891 |   we apply @{ML subst_type in Envir} to the same type we obtain
 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 892 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 893 |   @{ML_response_fake [display, gray]
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 894 |   "Envir.subst_type tyenv_unif @{typ_pat \"?'a * ?'b\"}"
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 895 | "?'b list * nat"} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 896 | |
| 383 | 897 | which does not solve the unification problem. | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 898 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 899 |   \begin{readmore}
 | 
| 383 | 900 | Unification and matching for types is implemented | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 901 |   in @{ML_file "Pure/type.ML"}. The ``interface'' functions for them
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 902 |   are in @{ML_file "Pure/sign.ML"}. Matching and unification produce type environments
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 903 |   as results. These are implemented in @{ML_file "Pure/envir.ML"}.
 | 
| 379 | 904 | This file also includes the substitution and normalisation functions, | 
| 386 | 905 | which apply a type environment to a type. Type environments are lookup | 
| 379 | 906 |   tables which are implemented in @{ML_file "Pure/term_ord.ML"}.
 | 
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 907 |   \end{readmore}
 | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 908 | *} | 
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 909 | |
| 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 910 | text {*
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 911 | Unification and matching of terms is substantially more complicated than the | 
| 383 | 912 | type-case. The reason is that terms have abstractions and, in this context, | 
| 913 | unification or matching modulo plain equality is often not meaningful. | |
| 914 |   Nevertheless, Isabelle implements the function @{ML_ind
 | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 915 | first_order_match in Pattern} for terms. This matching function returns a | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 916 | type environment and a term environment. To pretty print the latter we use | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 917 |   the function @{text "pretty_env"}:
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 918 | *} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 919 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 920 | ML{*fun pretty_env ctxt env =
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 921 | let | 
| 389 | 922 | fun get_trms (v, (T, t)) = (Var (v, T), t) | 
| 923 | val print = pairself (string_of_term ctxt) | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 924 | in | 
| 389 | 925 | pretty_helper (print o get_trms) env | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 926 | end*} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 927 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 928 | text {*
 | 
| 389 | 929 |   As can be seen from the @{text "get_trms"}-function, a term environment associates 
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 930 | a schematic term variable with a type and a term. An example of a first-order | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 931 |   matching problem is the term @{term "P (\<lambda>a b. Q b a)"} and the pattern 
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 932 |   @{text "?X ?Y"}.
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 933 | *} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 934 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 935 | ML{*val (_, fo_env) = let
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 936 |   val fo_pat = @{term_pat "(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y"}
 | 
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 937 |   val trm_a = @{term "P::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool"} 
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 938 |   val trm_b = @{term "\<lambda>a b. (Q::nat\<Rightarrow>nat\<Rightarrow>nat) b a"}
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 939 | val init = (Vartab.empty, Vartab.empty) | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 940 | in | 
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 941 |   Pattern.first_order_match @{theory} (fo_pat, trm_a $ trm_b) init
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 942 | end *} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 943 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 944 | text {*
 | 
| 399 | 945 | In this example we annotated types explicitly because then | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 946 | the type environment is empty and can be ignored. The | 
| 383 | 947 | resulting term environment is | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 948 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 949 |   @{ML_response_fake [display, gray]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 950 |   "pretty_env @{context} fo_env"
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 951 | "[?X := P, ?Y := \<lambda>a b. Q b a]"} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 952 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 953 |   The matcher can be applied to a term using the function @{ML_ind subst_term
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 954 |   in Envir} (remember the same convention for types applies to terms: @{ML
 | 
| 383 | 955 |   subst_term in Envir} is for matchers and @{ML norm_term in Envir} for
 | 
| 956 |   unifiers). The function @{ML subst_term in Envir} expects a type environment,
 | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 957 | which is set to empty in the example below, and a term environment. | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 958 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 959 |   @{ML_response_fake [display, gray]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 960 | "let | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 961 |   val trm = @{term_pat \"(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y\"}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 962 | in | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 963 | Envir.subst_term (Vartab.empty, fo_env) trm | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 964 |   |> string_of_term @{context}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 965 | |> tracing | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 966 | end" | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 967 | "P (\<lambda>a b. Q b a)"} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 968 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 969 | First-order matching is useful for matching against applications and | 
| 399 | 970 | variables. It can also deal with abstractions and a limited form of | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 971 | alpha-equivalence, but this kind of matching should be used with care, since | 
| 383 | 972 | it is not clear whether the result is meaningful. A meaningful example is | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 973 |   matching @{text "\<lambda>x. P x"} against the pattern @{text "\<lambda>y. ?X y"}. In this
 | 
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 974 |   case, first-order matching produces @{text "[?X := P]"}.
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 975 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 976 |   @{ML_response_fake [display, gray]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 977 | "let | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 978 |   val fo_pat = @{term_pat \"\<lambda>y. (?X::nat\<Rightarrow>bool) y\"}
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 979 |   val trm = @{term \"\<lambda>x. (P::nat\<Rightarrow>bool) x\"} 
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 980 | val init = (Vartab.empty, Vartab.empty) | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 981 | in | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 982 |   Pattern.first_order_match @{theory} (fo_pat, trm) init
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 983 | |> snd | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 984 |   |> pretty_env @{context} 
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 985 | end" | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 986 | "[?X := P]"} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 987 | *} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 988 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 989 | text {*
 | 
| 383 | 990 | Unification of abstractions is more thoroughly studied in the context | 
| 991 | of higher-order pattern unification and higher-order pattern matching. A | |
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 992 |   \emph{\index*{pattern}} is an abstraction term whose ``head symbol'' (that is the
 | 
| 386 | 993 | first symbol under an abstraction) is either a constant, a schematic or a free | 
| 399 | 994 | variable. If it is a schematic variable then it can only have distinct bound | 
| 995 | variables as arguments. This excludes terms where a schematic variable is an | |
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 996 | argument of another one and where a schematic variable is applied | 
| 383 | 997 |   twice with the same bound variable. The function @{ML_ind pattern in Pattern}
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 998 |   in the structure @{ML_struct Pattern} tests whether a term satisfies these
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 999 | restrictions. | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1000 | |
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1001 |   @{ML_response [display, gray]
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1002 | "let | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1003 | val trm_list = | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1004 |         [@{term_pat \"?X\"},              @{term_pat \"a\"},
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1005 |          @{term_pat \"\<lambda>a b. ?X a b\"},    @{term_pat \"\<lambda>a b. (op +) a b\"},
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1006 |          @{term_pat \"\<lambda>a. (op +) a ?Y\"}, @{term_pat \"?X ?Y\"},
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1007 |          @{term_pat \"\<lambda>a b. ?X a b ?Y\"}, @{term_pat \"\<lambda>a. ?X a a\"}] 
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1008 | in | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1009 | map Pattern.pattern trm_list | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1010 | end" | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1011 | "[true, true, true, true, true, false, false, false]"} | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1012 | |
| 383 | 1013 | The point of the restriction to patterns is that unification and matching | 
| 1014 | are decidable and produce most general unifiers, respectively matchers. | |
| 1015 | In this way, matching and unification can be implemented as functions that | |
| 1016 | produce a type and term environment (unification actually returns a | |
| 1017 |   record of type @{ML_type Envir.env} containing a maxind, a type environment 
 | |
| 386 | 1018 |   and a term environment). The corresponding functions are @{ML_ind match in Pattern},
 | 
| 1019 |   and @{ML_ind unify in Pattern} both implemented in the structure
 | |
| 383 | 1020 |   @{ML_struct Pattern}. An example for higher-order pattern unification is
 | 
| 1021 | ||
| 384 | 1022 |   @{ML_response_fake [display, gray]
 | 
| 1023 | "let | |
| 1024 |   val trm1 = @{term_pat \"\<lambda>x y. g (?X y x) (f (?Y x))\"}
 | |
| 1025 |   val trm2 = @{term_pat \"\<lambda>u v. g u (f u)\"}
 | |
| 1026 | val init = Envir.empty 0 | |
| 1027 |   val env = Pattern.unify @{theory} (trm1, trm2) init
 | |
| 383 | 1028 | in | 
| 384 | 1029 |   pretty_env @{context} (Envir.term_env env)
 | 
| 1030 | end" | |
| 1031 | "[?X := \<lambda>y x. x, ?Y := \<lambda>x. x]"} | |
| 1032 | ||
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1033 |   The function @{ML_ind "Envir.empty"} generates a record with a specified
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1034 |   max-index for the schematic variables (in the example the index is @{text
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1035 |   0}) and empty type and term environments. The function @{ML_ind
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1036 | "Envir.term_env"} pulls out the term environment from the result record. The | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1037 |   function for type environment is @{ML_ind "Envir.type_env"}. An assumption of
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1038 | this function is that the terms to be unified have already the same type. In | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1039 |   case of failure, the exceptions that are raised are either @{text Pattern},
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1040 |   @{text MATCH} or @{text Unif}.
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1041 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1042 | As mentioned before, unrestricted higher-order unification, respectively | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1043 | higher-order matching, is in general undecidable and might also not posses a | 
| 386 | 1044 | single most general solution. Therefore Isabelle implements the unification | 
| 1045 |   function @{ML_ind unifiers in Unify} so that it returns a lazy list of
 | |
| 1046 | potentially infinite unifiers. An example is as follows | |
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1047 | *} | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1048 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1049 | ML{*val uni_seq =
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1050 | let | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1051 |   val trm1 = @{term_pat "?X ?Y"}
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1052 |   val trm2 = @{term "f a"}
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1053 | val init = Envir.empty 0 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1054 | in | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1055 |   Unify.unifiers (@{theory}, init, [(trm1, trm2)])
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1056 | end *} | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1057 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1058 | text {*
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1059 | The unifiers can be extracted from the lazy sequence using the | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1060 |   function @{ML_ind "Seq.pull"}. In the example we obtain three 
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1061 |   unifiers @{text "un1\<dots>un3"}.
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1062 | *} | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1063 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1064 | ML{*val SOME ((un1, _), next1) = Seq.pull uni_seq;
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1065 | val SOME ((un2, _), next2) = Seq.pull next1; | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1066 | val SOME ((un3, _), next3) = Seq.pull next2; | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1067 | val NONE = Seq.pull next3 *} | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1068 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1069 | text {*
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1070 |   \footnote{\bf FIXME: what is the list of term pairs in the unifier: flex-flex pairs?}
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1071 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1072 | We can print them out as follows. | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1073 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1074 |   @{ML_response_fake [display, gray]
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1075 |   "pretty_env @{context} (Envir.term_env un1);
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1076 | pretty_env @{context} (Envir.term_env un2);
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1077 | pretty_env @{context} (Envir.term_env un3)"
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1078 | "[?X := \<lambda>a. a, ?Y := f a] | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1079 | [?X := f, ?Y := a] | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1080 | [?X := \<lambda>b. f a]"} | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1081 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1082 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1083 |   In case of failure the function @{ML_ind unifiers in Unify} does not raise
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1084 | an exception, rather returns the empty sequence. For example | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1085 | |
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1086 |   @{ML_response [display, gray]
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1087 | "let | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1088 |   val trm1 = @{term \"a\"}
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1089 |   val trm2 = @{term \"b\"}
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1090 | val init = Envir.empty 0 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1091 | in | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1092 |   Unify.unifiers (@{theory}, init, [(trm1, trm2)])
 | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1093 | |> Seq.pull | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1094 | end" | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1095 | "NONE"} | 
| 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1096 | |
| 408 | 1097 | In order to find a reasonable solution for a unification problem, Isabelle | 
| 1098 | also tries first to solve the problem by higher-order pattern | |
| 1099 | unification. Only in case of failure full higher-order unification is | |
| 1100 | called. This function has a built-in bound, which can be accessed and | |
| 1101 | manipulated as a configuration value: | |
| 1102 | ||
| 1103 |   @{ML_response_fake [display,gray]
 | |
| 1104 |   "Config.get_thy @{theory} (Unify.search_bound_value)"
 | |
| 1105 | "Int 60"} | |
| 1106 | ||
| 1107 | If this bound is reached during unification, Isabelle prints out the | |
| 1108 |   warning message @{text [quotes] "Unification bound exceeded"} and
 | |
| 409 | 1109 | plenty of diagnostic information (sometimes annoyingly plenty of | 
| 1110 | information). | |
| 408 | 1111 | |
| 387 
5dcee4d751ad
completed the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
386diff
changeset | 1112 | |
| 403 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1113 |   For higher-order matching the function is called @{ML_ind matchers in Unify}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1114 |   implemented in the structure @{ML_struct Unify}. Also this function returns
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1115 |   sequences with possibly more than one matcher.  Like @{ML unifiers in
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1116 | Unify}, this function does not raise an exception in case of failure, but | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1117 | returns an empty sequence. It also first tries out whether the matching | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1118 | problem can be solved by first-order matching. | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1119 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1120 | Higher-order matching might be necessary for instantiating a theorem | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1121 | appropriately (theorems and their instantiation will be described in more | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1122 |   detail in Sections~\ref{sec:theorems}). This is for example the 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1123 |   case when applying the rule @{thm [source] spec}:
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1124 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1125 |   \begin{isabelle}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1126 |   \isacommand{thm}~@{thm [source] spec}\\
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1127 |   @{text "> "}~@{thm spec}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1128 |   \end{isabelle}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1129 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1130 | as an introduction rule. One way is to instantiate this rule. The | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1131 |   instantiation function for theorems is @{ML_ind instantiate in Drule} from
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1132 |   the structure @{ML_struct Drule}. One problem, however, is that this 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1133 |   function expects the instantiations as lists of @{ML_type ctyp} and 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1134 |   @{ML_type cterm} pairs:
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1135 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1136 |   \begin{isabelle}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1137 |   @{ML instantiate in Drule}@{text ":"}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1138 |   @{ML_type "(ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm"}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1139 |   \end{isabelle}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1140 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1141 | This means we have to transform the environment the higher-order matching | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1142 | function returns into such an instantiation. For this we use the functions | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1143 |   @{ML_ind term_env in Envir} and @{ML_ind type_env in Envir}, which extract
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1144 | from an environment the corresponding variable mappings for schematic type | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1145 | and term variables. These mappings can be turned into proper | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1146 |   @{ML_type ctyp}-pairs with the function
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1147 | *} | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1148 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1149 | ML{*fun prep_trm thy (x, (T, t)) = 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1150 | (cterm_of thy (Var (x, T)), cterm_of thy t)*} | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1151 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1152 | text {*
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1153 |   and into proper @{ML_type cterm}-pairs with
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1154 | *} | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1155 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1156 | ML{*fun prep_ty thy (x, (S, ty)) = 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1157 | (ctyp_of thy (TVar (x, S)), ctyp_of thy ty)*} | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1158 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1159 | text {*
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1160 | We can now calculate the instantiations from the matching function. | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1161 | *} | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1162 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1163 | ML %linenosgray{*fun matcher_inst thy pat trm i = 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1164 | let | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1165 | val univ = Unify.matchers thy [(pat, trm)] | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1166 | val env = nth (Seq.list_of univ) i | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1167 | val tenv = Vartab.dest (Envir.term_env env) | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1168 | val tyenv = Vartab.dest (Envir.type_env env) | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1169 | in | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1170 | (map (prep_ty thy) tyenv, map (prep_trm thy) tenv) | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1171 | end*} | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1172 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1173 | text {*
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1174 | In Line 3 we obtain the higher-order matcher. We assume there is a finite | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1175 | number of them and select the one we are interested in via the parameter | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1176 |   @{text i} in the next line. In Lines 5 and 6 we destruct the resulting 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1177 |   environments using the function @{ML_ind dest in Vartab}. Finally, we need 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1178 |   to map the functions @{ML prep_trm} and @{ML prep_ty} over the respective 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1179 | environments (Line 8). As a simple example we instantiate the | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1180 |   @{thm [source] conjI}-rule as follows
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1181 | |
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1182 |   @{ML_response_fake [gray,display] 
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1183 | "let | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1184 |   val pat = Logic.strip_imp_concl (prop_of @{thm spec})
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1185 |   val trm = @{term \"Trueprop (P True)\"}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1186 |   val inst = matcher_inst @{theory} pat trm 1
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1187 | in | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1188 |   Drule.instantiate inst @{thm conjI}
 | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1189 | end" | 
| 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1190 | "\<forall>x. P x \<Longrightarrow> P True"} | 
| 383 | 1191 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 1192 |   \begin{readmore}
 | 
| 383 | 1193 | Unification and matching of higher-order patterns is implemented in | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1194 |   @{ML_file "Pure/pattern.ML"}. This file also contains a first-order matcher
 | 
| 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1195 | for terms. Full higher-order unification is implemented | 
| 383 | 1196 |   in @{ML_file "Pure/unify.ML"}. It uses lazy sequences which are implemented
 | 
| 1197 |   in @{ML_file "Pure/General/seq.ML"}.
 | |
| 378 
8d160d79b48c
section about matching and unification of types
 Christian Urban <urbanc@in.tum.de> parents: 
377diff
changeset | 1198 |   \end{readmore}
 | 
| 377 
272ba2cceeb2
added a section about unification and matching
 Christian Urban <urbanc@in.tum.de> parents: 
375diff
changeset | 1199 | *} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1200 | |
| 395 
2c392f61f400
spilt the Essential's chapter
 Christian Urban <urbanc@in.tum.de> parents: 
394diff
changeset | 1201 | section {* Sorts (TBD) *}
 | 
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1202 | |
| 398 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1203 | text {*
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1204 | Free and schematic variables may be annotated with sorts. Sorts are lists | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1205 | of strings, whereby each string stands for a class. Sorts classify types. | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1206 | |
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1207 | *} | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1208 | |
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1209 | |
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1210 | ML {* Sign.classes_of @{theory} *}
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1211 | |
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1212 | text {*
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1213 |   \begin{readmore}
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1214 |   Classes, sorts and arities are defined in @{ML_file "Pure/term.ML"}.
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1215 | |
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1216 |   @{ML_file "Pure/sign.ML"}
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1217 |   @{ML_file "Pure/sorts.ML"}
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1218 |   @{ML_file "Pure/axclass.ML"}
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1219 |   \end{readmore}
 | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1220 | *} | 
| 
7f7080ce7c2b
started something about sorts
 Christian Urban <urbanc@in.tum.de> parents: 
396diff
changeset | 1221 | |
| 381 
97518188ef0e
added more to the unification section
 Christian Urban <urbanc@in.tum.de> parents: 
380diff
changeset | 1222 | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1223 | section {* Type-Checking\label{sec:typechecking} *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1224 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1225 | text {* 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1226 | Remember Isabelle follows the Church-style typing for terms, i.e., a term contains | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1227 | enough typing information (constants, free variables and abstractions all have typing | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1228 | information) so that it is always clear what the type of a term is. | 
| 369 | 1229 |   Given a well-typed term, the function @{ML_ind type_of in Term} returns the 
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1230 | type of a term. Consider for example: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1231 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1232 |   @{ML_response [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1233 |   "type_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::nat\"})" "bool"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1234 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1235 | To calculate the type, this function traverses the whole term and will | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1236 | detect any typing inconsistency. For example changing the type of the variable | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1237 |   @{term "x"} from @{typ "nat"} to @{typ "int"} will result in the error message: 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1238 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1239 |   @{ML_response_fake [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1240 |   "type_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::int\"})" 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1241 | "*** Exception- TYPE (\"type_of: type mismatch in application\" \<dots>"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1242 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1243 | Since the complete traversal might sometimes be too costly and | 
| 369 | 1244 |   not necessary, there is the function @{ML_ind fastype_of in Term}, which 
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1245 | also returns the type of a term. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1246 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1247 |   @{ML_response [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1248 |   "fastype_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::nat\"})" "bool"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1249 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1250 | However, efficiency is gained on the expense of skipping some tests. You | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1251 | can see this in the following example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1252 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1253 |    @{ML_response [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1254 |   "fastype_of (@{term \"f::nat \<Rightarrow> bool\"} $ @{term \"x::int\"})" "bool"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1255 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1256 | where no error is detected. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1257 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1258 | Sometimes it is a bit inconvenient to construct a term with | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1259 | complete typing annotations, especially in cases where the typing | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1260 | information is redundant. A short-cut is to use the ``place-holder'' | 
| 345 | 1261 |   type @{ML_ind dummyT in Term} and then let type-inference figure out the 
 | 
| 400 | 1262 | complete type. The type inference can be invoked with the function | 
| 1263 |   @{ML_ind check_term in Syntax}. An example is as follows:
 | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1264 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1265 |   @{ML_response_fake [display,gray] 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1266 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1267 |   val c = Const (@{const_name \"plus\"}, dummyT) 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1268 |   val o = @{term \"1::nat\"} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1269 | val v = Free (\"x\", dummyT) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1270 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1271 |   Syntax.check_term @{context} (c $ o $ v)
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1272 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1273 | "Const (\"HOL.plus_class.plus\", \"nat \<Rightarrow> nat \<Rightarrow> nat\") $ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1274 | Const (\"HOL.one_class.one\", \"nat\") $ Free (\"x\", \"nat\")"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1275 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1276 |   Instead of giving explicitly the type for the constant @{text "plus"} and the free 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1277 |   variable @{text "x"}, type-inference fills in the missing information.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1278 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1279 |   \begin{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1280 |   See @{ML_file "Pure/Syntax/syntax.ML"} where more functions about reading,
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1281 | checking and pretty-printing of terms are defined. Functions related to | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1282 |   type-inference are implemented in @{ML_file "Pure/type.ML"} and 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1283 |   @{ML_file "Pure/type_infer.ML"}. 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1284 |   \end{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1285 | |
| 329 | 1286 |   \footnote{\bf FIXME: say something about sorts.}
 | 
| 335 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1287 |   \footnote{\bf FIXME: give a ``readmore''.}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1288 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1289 |   \begin{exercise}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1290 |   Check that the function defined in Exercise~\ref{fun:revsum} returns a
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1291 | result that type-checks. See what happens to the solutions of this | 
| 329 | 1292 |   exercise given in Appendix \ref{ch:solutions} when they receive an 
 | 
| 1293 | ill-typed term as input. | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1294 |   \end{exercise}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1295 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1296 | |
| 335 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1297 | section {* Certified Terms and Certified Types *}
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1298 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1299 | text {*
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1300 |   You can freely construct and manipulate @{ML_type "term"}s and @{ML_type
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1301 | typ}es, since they are just arbitrary unchecked trees. However, you | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1302 | eventually want to see if a term is well-formed, or type-checks, relative to | 
| 369 | 1303 |   a theory.  Type-checking is done via the function @{ML_ind cterm_of in Thm}, which
 | 
| 335 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1304 |   converts a @{ML_type term} into a @{ML_type cterm}, a \emph{certified}
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1305 |   term. Unlike @{ML_type term}s, which are just trees, @{ML_type "cterm"}s are
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1306 | abstract objects that are guaranteed to be type-correct, and they can only | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1307 | be constructed via ``official interfaces''. | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1308 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1309 | Certification is always relative to a theory context. For example you can | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1310 | write: | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1311 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1312 |   @{ML_response_fake [display,gray] 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1313 |   "cterm_of @{theory} @{term \"(a::nat) + b = c\"}" 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1314 | "a + b = c"} | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1315 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1316 | This can also be written with an antiquotation: | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1317 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1318 |   @{ML_response_fake [display,gray] 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1319 |   "@{cterm \"(a::nat) + b = c\"}" 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1320 | "a + b = c"} | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1321 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1322 | Attempting to obtain the certified term for | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1323 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1324 |   @{ML_response_fake_both [display,gray] 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1325 |   "@{cterm \"1 + True\"}" 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1326 | "Type unification failed \<dots>"} | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1327 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1328 | yields an error (since the term is not typable). A slightly more elaborate | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1329 | example that type-checks is: | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1330 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1331 | @{ML_response_fake [display,gray] 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1332 | "let | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1333 |   val natT = @{typ \"nat\"}
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1334 |   val zero = @{term \"0::nat\"}
 | 
| 356 | 1335 |   val plus = Const (@{const_name plus}, [natT, natT] ---> natT)
 | 
| 335 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1336 | in | 
| 356 | 1337 |   cterm_of @{theory} (plus $ zero $ zero)
 | 
| 1338 | end" | |
| 1339 | "0 + 0"} | |
| 335 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1340 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1341 | In Isabelle not just terms need to be certified, but also types. For example, | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1342 |   you obtain the certified type for the Isabelle type @{typ "nat \<Rightarrow> bool"} on 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1343 | the ML-level as follows: | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1344 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1345 |   @{ML_response_fake [display,gray]
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1346 |   "ctyp_of @{theory} (@{typ nat} --> @{typ bool})"
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1347 | "nat \<Rightarrow> bool"} | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1348 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1349 | or with the antiquotation: | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1350 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1351 |   @{ML_response_fake [display,gray]
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1352 |   "@{ctyp \"nat \<Rightarrow> bool\"}"
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1353 | "nat \<Rightarrow> bool"} | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1354 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1355 | Since certified terms are, unlike terms, abstract objects, we cannot | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1356 | pattern-match against them. However, we can construct them. For example | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1357 |   the function @{ML_ind capply in Thm} produces a certified application.
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1358 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1359 |   @{ML_response_fake [display,gray]
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1360 |   "Thm.capply @{cterm \"P::nat \<Rightarrow> bool\"} @{cterm \"3::nat\"}"
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1361 | "P 3"} | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1362 | |
| 351 | 1363 |   Similarly the function @{ML_ind list_comb in Drule} from the structure @{ML_struct Drule}
 | 
| 1364 |   applies a list of @{ML_type cterm}s.
 | |
| 335 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1365 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1366 |   @{ML_response_fake [display,gray]
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1367 | "let | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1368 |   val chead = @{cterm \"P::unit \<Rightarrow> nat \<Rightarrow> bool\"}
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1369 |   val cargs = [@{cterm \"()\"}, @{cterm \"3::nat\"}]
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1370 | in | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1371 | Drule.list_comb (chead, cargs) | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1372 | end" | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1373 | "P () 3"} | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1374 | |
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1375 |   \begin{readmore}
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1376 |   For functions related to @{ML_type cterm}s and @{ML_type ctyp}s see 
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1377 |   the files @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1378 |   @{ML_file "Pure/drule.ML"}.
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1379 |   \end{readmore}
 | 
| 
163ac0662211
reorganised the certified terms section; tuned
 Christian Urban <urbanc@in.tum.de> parents: 
329diff
changeset | 1380 | *} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1381 | |
| 403 
444bc9f17cfc
added something about unifiacation and instantiations
 Christian Urban <urbanc@in.tum.de> parents: 
401diff
changeset | 1382 | section {* Theorems\label{sec:theorems} *}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1383 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1384 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1385 |   Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1386 | that can only be built by going through interfaces. As a consequence, every proof | 
| 388 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1387 | in Isabelle is correct by construction. This follows the tradition of the LCF-approach. | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1388 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1389 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1390 | To see theorems in ``action'', let us give a proof on the ML-level for the following | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1391 | statement: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1392 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1393 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1394 | lemma | 
| 351 | 1395 | assumes assm\<^isub>1: "\<And>(x::nat). P x \<Longrightarrow> Q x" | 
| 1396 | and assm\<^isub>2: "P t" | |
| 1397 | shows "Q t"(*<*)oops(*>*) | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1398 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1399 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1400 | The corresponding ML-code is as follows: | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1401 | *} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1402 | |
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1403 | ML{*val my_thm = 
 | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1404 | let | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1405 |   val assm1 = @{cprop "\<And>(x::nat). P x \<Longrightarrow> Q x"}
 | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1406 |   val assm2 = @{cprop "(P::nat \<Rightarrow> bool) t"}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1407 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1408 | val Pt_implies_Qt = | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1409 | assume assm1 | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1410 |         |> forall_elim @{cterm "t::nat"}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1411 | |
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1412 | val Qt = implies_elim Pt_implies_Qt (assume assm2) | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1413 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1414 | Qt | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1415 | |> implies_intr assm2 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1416 | |> implies_intr assm1 | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1417 | end*} | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1418 | |
| 400 | 1419 | text {*
 | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1420 |   If we print out the value of @{ML my_thm} then we see only the 
 | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1421 | final statement of the theorem. | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1422 | |
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1423 |   @{ML_response_fake [display, gray]
 | 
| 348 | 1424 |   "tracing (string_of_thm @{context} my_thm)"
 | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1425 | "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"} | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1426 | |
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1427 | However, internally the code-snippet constructs the following | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1428 | proof. | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1429 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1430 | \[ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1431 |   \infer[(@{text "\<Longrightarrow>"}$-$intro)]{\vdash @{prop "(\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> P t \<Longrightarrow> Q t"}}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1432 |     {\infer[(@{text "\<Longrightarrow>"}$-$intro)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1433 |        {\infer[(@{text "\<Longrightarrow>"}$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"}, @{prop "P t"} \vdash @{prop "Q t"}}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1434 |           {\infer[(@{text "\<And>"}$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1435 |                  {\infer[(assume)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "\<And>x. P x \<Longrightarrow> Q x"}}{}}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1436 | & | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1437 |            \infer[(assume)]{@{prop "P t"} \vdash @{prop "P t"}}{}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1438 | } | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1439 | } | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1440 | } | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1441 | \] | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1442 | |
| 339 
c588e8422737
used a better implementation of \index in Latex; added more to the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
338diff
changeset | 1443 | While we obtained a theorem as result, this theorem is not | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1444 | yet stored in Isabelle's theorem database. Consequently, it cannot be | 
| 348 | 1445 | referenced on the user level. One way to store it in the theorem database is | 
| 394 | 1446 |   by using the function @{ML_ind note in Local_Theory}.\footnote{\bf FIXME: make sure a pointer
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1447 | to the section about local-setup is given earlier.} | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1448 | *} | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1449 | |
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1450 | local_setup %gray {*
 | 
| 394 | 1451 |   Local_Theory.note ((@{binding "my_thm"}, []), [my_thm]) #> snd *}
 | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1452 | |
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1453 | text {*
 | 
| 396 | 1454 |   The third argument of @{ML note in Local_Theory} is the list of theorems we
 | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1455 | want to store under a name. We can store more than one under a single name. | 
| 396 | 1456 |   The first argument of @{ML note in Local_Theory} is the name under
 | 
| 1457 | which we store the theorem or theorems. The second argument can contain a | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1458 | list of theorem attributes, which we will explain in detail in | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1459 |   Section~\ref{sec:attributes}. Below we just use one such attribute for
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1460 | adding the theorem to the simpset: | 
| 339 
c588e8422737
used a better implementation of \index in Latex; added more to the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
338diff
changeset | 1461 | *} | 
| 
c588e8422737
used a better implementation of \index in Latex; added more to the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
338diff
changeset | 1462 | |
| 
c588e8422737
used a better implementation of \index in Latex; added more to the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
338diff
changeset | 1463 | local_setup %gray {*
 | 
| 394 | 1464 |   Local_Theory.note ((@{binding "my_thm_simp"}, 
 | 
| 347 | 1465 | [Attrib.internal (K Simplifier.simp_add)]), [my_thm]) #> snd *} | 
| 339 
c588e8422737
used a better implementation of \index in Latex; added more to the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
338diff
changeset | 1466 | |
| 
c588e8422737
used a better implementation of \index in Latex; added more to the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
338diff
changeset | 1467 | text {*
 | 
| 348 | 1468 | Note that we have to use another name under which the theorem is stored, | 
| 394 | 1469 |   since Isabelle does not allow us to call  @{ML_ind note in Local_Theory} twice
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1470 |   with the same name. The attribute needs to be wrapped inside the function @{ML_ind
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1471 |   internal in Attrib} from the structure @{ML_struct Attrib}. If we use the function 
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1472 |   @{ML get_thm_names_from_ss} from
 | 
| 348 | 1473 | the previous chapter, we can check whether the theorem has actually been | 
| 1474 | added. | |
| 1475 | ||
| 340 | 1476 | |
| 1477 |   @{ML_response [display,gray]
 | |
| 1478 | "let | |
| 1479 | fun pred s = match_string \"my_thm_simp\" s | |
| 1480 | in | |
| 1481 |   exists pred (get_thm_names_from_ss @{simpset})
 | |
| 1482 | end" | |
| 1483 | "true"} | |
| 1484 | ||
| 347 | 1485 |   The main point of storing the theorems @{thm [source] my_thm} and @{thm
 | 
| 1486 | [source] my_thm_simp} is that they can now also be referenced with the | |
| 1487 |   \isacommand{thm}-command on the user-level of Isabelle
 | |
| 1488 | ||
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1489 | |
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1490 |   \begin{isabelle}
 | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1491 |   \isacommand{thm}~@{text "my_thm"}\isanewline
 | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1492 |    @{text ">"}~@{prop "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"}
 | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1493 |   \end{isabelle}
 | 
| 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1494 | |
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1495 |   or with the @{text "@{thm \<dots>}"}-antiquotation on the ML-level. Otherwise the 
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1496 | user has no access to these theorems. | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1497 | |
| 394 | 1498 |   Recall that Isabelle does not let you call @{ML note in Local_Theory} twice
 | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1499 | with the same theorem name. In effect, once a theorem is stored under a name, | 
| 358 | 1500 | this association is fixed. While this is a ``safety-net'' to make sure a | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1501 | theorem name refers to a particular theorem or collection of theorems, it is | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1502 | also a bit too restrictive in cases where a theorem name should refer to a | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1503 | dynamically expanding list of theorems (like a simpset). Therefore Isabelle | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1504 | also implements a mechanism where a theorem name can refer to a custom theorem | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1505 |   list. For this you can use the function @{ML_ind add_thms_dynamic in PureThy}. 
 | 
| 358 | 1506 |   To see how it works let us assume we defined our own theorem list @{text MyThmList}.
 | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1507 | *} | 
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1508 | |
| 385 | 1509 | ML{*structure MyThmList = Generic_Data
 | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1510 | (type T = thm list | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1511 | val empty = [] | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1512 | val extend = I | 
| 394 | 1513 | val merge = merge Thm.eq_thm_prop) | 
| 1514 | ||
| 1515 | fun update thm = Context.theory_map (MyThmList.map (Thm.add_thm thm))*} | |
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1516 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1517 | text {*
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1518 |   The function @{ML update} allows us to update the theorem list, for example
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1519 |   by adding the theorem @{thm [source] TrueI}.
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1520 | *} | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1521 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1522 | setup %gray {* update @{thm TrueI} *}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1523 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1524 | text {*
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1525 | We can now install the theorem list so that it is visible to the user and | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1526 | can be refered to by a theorem name. For this need to call | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1527 |   @{ML_ind add_thms_dynamic in PureThy}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1528 | *} | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1529 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1530 | setup %gray {* 
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1531 |   PureThy.add_thms_dynamic (@{binding "mythmlist"}, MyThmList.get) 
 | 
| 347 | 1532 | *} | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1533 | |
| 347 | 1534 | text {*
 | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1535 | with a name and a function that accesses the theorem list. Now if the | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1536 | user issues the command | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1537 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1538 |   \begin{isabelle}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1539 |   \isacommand{thm}~@{text "mythmlist"}\\
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1540 |   @{text "> True"}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1541 |   \end{isabelle}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1542 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1543 | the current content of the theorem list is displayed. If more theorems are stored in | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1544 | the list, say | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1545 | *} | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1546 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1547 | setup %gray {* update @{thm FalseE} *}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1548 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1549 | text {*
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1550 | then the same command produces | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1551 | |
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1552 |   \begin{isabelle}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1553 |   \isacommand{thm}~@{text "mythmlist"}\\
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1554 |   @{text "> False \<Longrightarrow> ?P"}\\
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1555 |   @{text "> True"}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1556 |   \end{isabelle}
 | 
| 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1557 | |
| 400 | 1558 |   Note that if we add the theorem @{thm [source] FalseE} again to the list
 | 
| 1559 | *} | |
| 1560 | ||
| 1561 | setup %gray {* update @{thm FalseE} *}
 | |
| 1562 | ||
| 1563 | text {*
 | |
| 1564 |   we still obtain the same list. The reason is that we used the function @{ML_ind
 | |
| 1565 | add_thm in Thm} in our update function. This is a dedicated function which | |
| 1566 | tests whether the theorem is already in the list. This test is done | |
| 1567 | according to alpha-equivalence of the proposition behind the theorem. The | |
| 1568 |   corresponding testing function is @{ML_ind eq_thm_prop in Thm}.
 | |
| 1569 | Suppose you proved the following three theorems. | |
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1570 | *} | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1571 | |
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1572 | lemma | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1573 | shows thm1: "\<forall>x. P x" | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1574 | and thm2: "\<forall>y. P y" | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1575 | and thm3: "\<forall>y. Q y" sorry | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1576 | |
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1577 | text {*
 | 
| 400 | 1578 | Testing them for alpha equality produces: | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1579 | |
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1580 |   @{ML_response [display,gray]
 | 
| 400 | 1581 | "(Thm.eq_thm_prop (@{thm thm1}, @{thm thm2}),
 | 
| 1582 |  Thm.eq_thm_prop (@{thm thm2}, @{thm thm3}))"
 | |
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1583 | "(true, false)"} | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1584 | |
| 340 | 1585 |   Many functions destruct theorems into @{ML_type cterm}s. For example
 | 
| 1586 |   the functions @{ML_ind lhs_of in Thm} and @{ML_ind rhs_of in Thm} return 
 | |
| 1587 | the left and right-hand side, respectively, of a meta-equality. | |
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1588 | |
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1589 |   @{ML_response_fake [display,gray]
 | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1590 | "let | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1591 |   val eq = @{thm True_def}
 | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1592 | in | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1593 | (Thm.lhs_of eq, Thm.rhs_of eq) | 
| 348 | 1594 |   |> pairself (string_of_cterm @{context})
 | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1595 | end" | 
| 348 | 1596 | "(True, (\<lambda>x. x) = (\<lambda>x. x))"} | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1597 | |
| 340 | 1598 | Other function produce terms that can be pattern-matched. | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1599 | Suppose the following two theorems. | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1600 | *} | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1601 | |
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1602 | lemma | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1603 | shows foo_test1: "A \<Longrightarrow> B \<Longrightarrow> C" | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1604 | and foo_test2: "A \<longrightarrow> B \<longrightarrow> C" sorry | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1605 | |
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1606 | text {*
 | 
| 348 | 1607 | We can destruct them into premises and conclusions as follows. | 
| 340 | 1608 | |
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1609 |  @{ML_response_fake [display,gray]
 | 
| 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1610 | "let | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1611 |   val ctxt = @{context}
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1612 | fun prems_and_concl thm = | 
| 348 | 1613 | [\"Premises: \" ^ (string_of_terms ctxt (Thm.prems_of thm))] @ | 
| 1614 | [\"Conclusion: \" ^ (string_of_term ctxt (Thm.concl_of thm))] | |
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1615 | |> cat_lines | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1616 | |> tracing | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1617 | in | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1618 |   prems_and_concl @{thm foo_test1};
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1619 |   prems_and_concl @{thm foo_test2}
 | 
| 338 
3bc732c9f7ff
more on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
337diff
changeset | 1620 | end" | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1621 | "Premises: ?A, ?B | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1622 | Conclusion: ?C | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1623 | Premises: | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1624 | Conclusion: ?A \<longrightarrow> ?B \<longrightarrow> ?C"} | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1625 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1626 | Note that in the second case, there is no premise. | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1627 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1628 |   \begin{readmore}
 | 
| 358 | 1629 | The basic functions for theorems are defined in | 
| 337 
a456a21f608a
a bit more work on the theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
336diff
changeset | 1630 |   @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and @{ML_file "Pure/drule.ML"}. 
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1631 |   \end{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1632 | |
| 388 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1633 | Although we will explain the simplifier in more detail as tactic in | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1634 |   Section~\ref{sec:simplifier}, the simplifier 
 | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1635 | can be used to work directly over theorems, for example to unfold definitions. To show | 
| 382 | 1636 |   this, we build the theorem @{term "True \<equiv> True"} (Line 1) and then 
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1637 |   unfold the constant @{term "True"} according to its definition (Line 2).
 | 
| 347 | 1638 | |
| 1639 |   @{ML_response_fake [display,gray,linenos]
 | |
| 1640 |   "Thm.reflexive @{cterm \"True\"}
 | |
| 1641 |   |> Simplifier.rewrite_rule [@{thm True_def}]
 | |
| 1642 |   |> string_of_thm @{context}
 | |
| 1643 | |> tracing" | |
| 1644 | "(\<lambda>x. x) = (\<lambda>x. x) \<equiv> (\<lambda>x. x) = (\<lambda>x. x)"} | |
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1645 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1646 | Often it is necessary to transform theorems to and from the object | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1647 |   logic, that is replacing all @{text "\<longrightarrow>"} and @{text "\<forall>"} by @{text "\<Longrightarrow>"} 
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1648 |   and @{text "\<And>"}, or the other way around.  A reason for such a transformation 
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1649 | might be stating a definition. The reason is that definitions can only be | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1650 | stated using object logic connectives, while theorems using the connectives | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1651 | from the meta logic are more convenient for reasoning. Therefore there are | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1652 | some build in functions which help with these transformations. The function | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1653 |   @{ML_ind rulify in ObjectLogic} 
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1654 | replaces all object connectives by equivalents in the meta logic. For example | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1655 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1656 |   @{ML_response_fake [display, gray]
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1657 |   "ObjectLogic.rulify @{thm foo_test2}"
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1658 | "\<lbrakk>?A; ?B\<rbrakk> \<Longrightarrow> ?C"} | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1659 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1660 | The transformation in the other direction can be achieved with function | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1661 |   @{ML_ind atomize in ObjectLogic} and the following code.
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1662 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1663 |   @{ML_response_fake [display,gray]
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1664 | "let | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1665 |   val thm = @{thm foo_test1}
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1666 | val meta_eq = ObjectLogic.atomize (cprop_of thm) | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1667 | in | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1668 | MetaSimplifier.rewrite_rule [meta_eq] thm | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1669 | end" | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1670 | "?A \<longrightarrow> ?B \<longrightarrow> ?C"} | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1671 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1672 |   In this code the function @{ML atomize in ObjectLogic} produces 
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1673 | a meta-equation between the given theorem and the theorem transformed | 
| 347 | 1674 | into the object logic. The result is the theorem with object logic | 
| 1675 | connectives. However, in order to completely transform a theorem | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1676 |   involving meta variables, such as @{thm [source] list.induct}, which 
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1677 | is of the form | 
| 347 | 1678 | |
| 1679 |   @{thm [display] list.induct}
 | |
| 1680 | ||
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1681 |   we have to first abstract over the meta variables @{text "?P"} and 
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1682 |   @{text "?list"}. For this we can use the function 
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1683 |   @{ML_ind forall_intr_vars in Drule}. This allows us to implement the
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1684 | following function for atomizing a theorem. | 
| 347 | 1685 | *} | 
| 1686 | ||
| 1687 | ML{*fun atomize_thm thm =
 | |
| 1688 | let | |
| 1689 | val thm' = forall_intr_vars thm | |
| 1690 | val thm'' = ObjectLogic.atomize (cprop_of thm') | |
| 1691 | in | |
| 1692 | MetaSimplifier.rewrite_rule [thm''] thm' | |
| 1693 | end*} | |
| 1694 | ||
| 1695 | text {*
 | |
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1696 |   This function produces for the theorem @{thm [source] list.induct}
 | 
| 347 | 1697 | |
| 1698 |   @{ML_response_fake [display, gray]
 | |
| 1699 |   "atomize_thm @{thm list.induct}"
 | |
| 1700 | "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"} | |
| 1701 | ||
| 388 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1702 |   \footnote{\bf FIXME: say someting about @{ML_ind standard in Drule}.}
 | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1703 | |
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1704 | Theorems can also be produced from terms by giving an explicit proof. | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1705 |   One way to achieve this is by using the function @{ML_ind prove in Goal}
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1706 |   in the structure @{ML_struct Goal}. For example below we use this function
 | 
| 405 
f8d020bbc2c0
improved section on conversions
 Christian Urban <urbanc@in.tum.de> parents: 
404diff
changeset | 1707 |   to prove the term @{term "P \<Longrightarrow> P"}.\footnote{\bf FIXME: What about @{ML_ind prove_internal in Goal}?}
 | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1708 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1709 |   @{ML_response_fake [display,gray]
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1710 | "let | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1711 |   val trm = @{term \"P \<Longrightarrow> P::bool\"}
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1712 | val tac = K (atac 1) | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1713 | in | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1714 |   Goal.prove @{context} [\"P\"] [] trm tac
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1715 | end" | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1716 | "?P \<Longrightarrow> ?P"} | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1717 | |
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1718 | This function takes first a context and second a list of strings. This list | 
| 359 | 1719 | specifies which variables should be turned into schematic variables once the term | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1720 | is proved. The fourth argument is the term to be proved. The fifth is a | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1721 | corresponding proof given in form of a tactic (we explain tactics in | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1722 |   Chapter~\ref{chp:tactical}). In the code above, the tactic proves the theorem
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1723 | by assumption. As before this code will produce a theorem, but the theorem | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1724 | is not yet stored in the theorem database. | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1725 | |
| 388 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1726 | While the LCF-approach of going through interfaces ensures soundness in Isabelle, there | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1727 |   is the function @{ML_ind make_thm in Skip_Proof} in the structure 
 | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1728 |   @{ML_struct Skip_Proof} that allows us to turn any proposition into a theorem.
 | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1729 | Potentially making the system unsound. This is sometimes useful for developing | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1730 | purposes, or when explicit proof construction should be omitted due to performace | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1731 | reasons. An example of this function is as follows: | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1732 | |
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1733 |   @{ML_response_fake [display, gray]
 | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1734 |   "Skip_Proof.make_thm @{theory} @{prop \"True = False\"}"
 | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1735 | "True = False"} | 
| 
0b337dedc306
added Skip_Proof.mk_thm and some pointers about concurrency
 Christian Urban <urbanc@in.tum.de> parents: 
387diff
changeset | 1736 | |
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1737 | Theorems also contain auxiliary data, such as the name of the theorem, its | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1738 | kind, the names for cases and so on. This data is stored in a string-string | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1739 |   list and can be retrieved with the function @{ML_ind get_tags in
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1740 | Thm}. Assume you prove the following lemma. | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1741 | *} | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1742 | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1743 | lemma foo_data: | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1744 | shows "P \<Longrightarrow> P \<Longrightarrow> P" by assumption | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1745 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1746 | text {*
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1747 | The auxiliary data of this lemma can be retrieved using the function | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1748 |   @{ML_ind get_tags in Thm}. So far the the auxiliary data of this lemma is 
 | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1749 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1750 |   @{ML_response_fake [display,gray]
 | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1751 |   "Thm.get_tags @{thm foo_data}"
 | 
| 342 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1752 | "[(\"name\", \"General.foo_data\"), (\"kind\", \"lemma\")]"} | 
| 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1753 | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1754 | consisting of a name and a kind. When we store lemmas in the theorem database, | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1755 | we might want to explicitly extend this data by attaching case names to the | 
| 375 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 1756 |   two premises of the lemma.  This can be done with the function @{ML_ind name in Rule_Cases}
 | 
| 
92f7328dc5cc
added type work and updated to Isabelle and poly 5.3
 Christian Urban <urbanc@in.tum.de> parents: 
374diff
changeset | 1757 |   from the structure @{ML_struct Rule_Cases}.
 | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1758 | *} | 
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1759 | |
| 342 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1760 | local_setup %gray {*
 | 
| 394 | 1761 |   Local_Theory.note ((@{binding "foo_data'"}, []), 
 | 
| 1762 | [(Rule_Cases.name ["foo_case_one", "foo_case_two"] | |
| 1763 |        @{thm foo_data})]) #> snd *}
 | |
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1764 | |
| 342 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1765 | text {*
 | 
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1766 |   The data of the theorem @{thm [source] foo_data'} is then as follows:
 | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1767 | |
| 342 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1768 |   @{ML_response_fake [display,gray]
 | 
| 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1769 |   "Thm.get_tags @{thm foo_data'}"
 | 
| 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1770 | "[(\"name\", \"General.foo_data'\"), (\"kind\", \"lemma\"), | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1771 | (\"case_names\", \"foo_case_one;foo_case_two\")]"} | 
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1772 | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1773 | You can observe the case names of this lemma on the user level when using | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1774 |   the proof methods @{text cases} and @{text induct}. In the proof below
 | 
| 342 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1775 | *} | 
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1776 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1777 | lemma | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1778 | shows "Q \<Longrightarrow> Q \<Longrightarrow> Q" | 
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1779 | proof (cases rule: foo_data') | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1780 | |
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1781 | (*<*)oops(*>*) | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1782 | text_raw{*
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1783 | \begin{tabular}{@ {}l}
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1784 | \isacommand{print\_cases}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1785 | @{text "> cases:"}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1786 | @{text ">   foo_case_one:"}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1787 | @{text ">     let \"?case\" = \"?P\""}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1788 | @{text ">   foo_case_two:"}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1789 | @{text ">     let \"?case\" = \"?P\""}
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1790 | \end{tabular}*}
 | 
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1791 | |
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1792 | text {*
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1793 |   we can proceed by analysing the cases @{text "foo_case_one"} and 
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1794 |   @{text "foo_case_two"}. While if the theorem has no names, then
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1795 |   the cases have standard names @{text 1}, @{text 2} and so 
 | 
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1796 | on. This can be seen in the proof below. | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1797 | *} | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1798 | |
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1799 | lemma | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1800 | shows "Q \<Longrightarrow> Q \<Longrightarrow> Q" | 
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 1801 | proof (cases rule: foo_data) | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1802 | |
| 342 
930b1308fd96
fixed glitch with tocibind
 Christian Urban <urbanc@in.tum.de> parents: 
341diff
changeset | 1803 | (*<*)oops(*>*) | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1804 | text_raw{*
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1805 | \begin{tabular}{@ {}l}
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1806 | \isacommand{print\_cases}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1807 | @{text "> cases:"}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1808 | @{text ">   1:"}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1809 | @{text ">     let \"?case\" = \"?P\""}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1810 | @{text ">   2:"}\\
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1811 | @{text ">     let \"?case\" = \"?P\""}
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1812 | \end{tabular}*}
 | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1813 | |
| 341 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1814 | |
| 
62dea749d5ed
more work on theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
340diff
changeset | 1815 | text {*
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1816 | One great feature of Isabelle is its document preparation system, where | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1817 | proved theorems can be quoted in documents referencing directly their | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1818 | formalisation. This helps tremendously to minimise cut-and-paste errors. However, | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1819 | sometimes the verbatim quoting is not what is wanted or what can be shown to | 
| 354 | 1820 |   readers. For such situations Isabelle allows the installation of \emph{\index*{theorem 
 | 
| 1821 | styles}}. These are, roughly speaking, functions from terms to terms. The input | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1822 | term stands for the theorem to be presented; the output can be constructed to | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1823 | ones wishes. Let us, for example, assume we want to quote theorems without | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1824 |   leading @{text \<forall>}-quantifiers. For this we can implement the following function 
 | 
| 358 | 1825 |   that strips off @{text "\<forall>"}s.
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1826 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1827 | |
| 358 | 1828 | ML %linenosgray{*fun strip_allq (Const (@{const_name "All"}, _) $ Abs body) = 
 | 
| 354 | 1829 | Term.dest_abs body |> snd |> strip_allq | 
| 1830 |   | strip_allq (Const (@{const_name "Trueprop"}, _) $ t) = 
 | |
| 1831 | strip_allq t | |
| 1832 | | strip_allq t = t*} | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1833 | |
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1834 | text {*
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1835 |   We use in Line 2 the function @{ML_ind dest_abs in Term} for deconstructing abstractions,
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1836 | since this function deals correctly with potential name clashes. This function produces | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1837 | a pair consisting of the variable and the body of the abstraction. We are only interested | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1838 | in the body, which we feed into the recursive call. In Line 3 and 4, we also | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1839 |   have to explicitly strip of the outermost @{term Trueprop}-coercion. Now we can 
 | 
| 354 | 1840 |   install this function as the theorem style named @{text "my_strip_allq"}. 
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1841 | *} | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1842 | |
| 400 | 1843 | setup %gray{* 
 | 
| 354 | 1844 | Term_Style.setup "my_strip_allq" (Scan.succeed (K strip_allq)) | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1845 | *} | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1846 | |
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1847 | text {*
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1848 | We can test this theorem style with the following theorem | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1849 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1850 | |
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1851 | theorem style_test: | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1852 | shows "\<forall>x y z. (x, x) = (y, z)" sorry | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1853 | |
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1854 | text {*
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1855 |   Now printing out in a document the theorem @{thm [source] style_test} normally
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1856 |   using @{text "@{thm \<dots>}"} produces
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1857 | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1858 |   \begin{isabelle}
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1859 |   @{text "@{thm style_test}"}\\
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1860 |   @{text ">"}~@{thm style_test}
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1861 |   \end{isabelle}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1862 | |
| 354 | 1863 |   as expected. But with the theorem style @{text "@{thm (my_strip_allq) \<dots>}"} 
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1864 | we obtain | 
| 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1865 | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1866 |   \begin{isabelle}
 | 
| 354 | 1867 |   @{text "@{thm (my_strip_allq) style_test}"}\\
 | 
| 400 | 1868 |   @{text ">"}~@{thm (my_strip_allq) style_test}
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1869 |   \end{isabelle}
 | 
| 352 
9f12e53eb121
polished theorem section
 Christian Urban <urbanc@in.tum.de> parents: 
351diff
changeset | 1870 | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1871 | without the leading quantifiers. We can improve this theorem style by explicitly | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1872 | giving a list of strings that should be used for the replacement of the | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1873 | variables. For this we implement the function which takes a list of strings | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1874 | and uses them as name in the outermost abstractions. | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1875 | *} | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1876 | |
| 358 | 1877 | ML{*fun rename_allq [] t = t
 | 
| 354 | 1878 |   | rename_allq (x::xs) (Const (@{const_name "All"}, U) $ Abs (_, T, t)) = 
 | 
| 1879 |       Const (@{const_name "All"}, U) $ Abs (x, T, rename_allq xs t)
 | |
| 1880 |   | rename_allq xs (Const (@{const_name "Trueprop"}, U) $ t) =
 | |
| 1881 | rename_allq xs t | |
| 1882 | | rename_allq _ t = t*} | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1883 | |
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1884 | text {*
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1885 | We can now install a the modified theorem style as follows | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1886 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1887 | |
| 356 | 1888 | setup %gray {* let
 | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1889 | val parser = Scan.repeat Args.name | 
| 354 | 1890 | fun action xs = K (rename_allq xs #> strip_allq) | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1891 | in | 
| 354 | 1892 | Term_Style.setup "my_strip_allq2" (parser >> action) | 
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1893 | end *} | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1894 | |
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1895 | text {*
 | 
| 355 
42a1c230daff
added something about add_thms_dynamic
 Christian Urban <urbanc@in.tum.de> parents: 
354diff
changeset | 1896 |   The parser reads a list of names. In the function @{text action} we first
 | 
| 354 | 1897 |   call @{ML rename_allq} with the parsed list, then we call @{ML strip_allq}
 | 
| 1898 | on the resulting term. We can now suggest, for example, two variables for | |
| 1899 |   stripping off the first two @{text \<forall>}-quantifiers.
 | |
| 1900 | ||
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1901 | |
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1902 |   \begin{isabelle}
 | 
| 354 | 1903 |   @{text "@{thm (my_strip_allq2 x' x'') style_test}"}\\
 | 
| 1904 |   @{text ">"}~@{thm (my_strip_allq2 x' x'') style_test}
 | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1905 |   \end{isabelle}
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1906 | |
| 404 | 1907 | Such styles allow one to print out theorems in documents formatted to | 
| 1908 | ones heart content. The styles can also be used in the document | |
| 1909 |   antiquotations @{text "@{prop ...}"}, @{text "@{term_type ...}"}
 | |
| 1910 |   and @{text "@{typeof ...}"}.
 | |
| 1911 | ||
| 1912 | Next we explain theorem attributes, which is another | |
| 353 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1913 | mechanism for dealing with theorems. | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1914 | |
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1915 |   \begin{readmore}
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1916 |   Theorem styles are implemented in @{ML_file "Pure/Thy/term_style.ML"}.
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1917 |   \end{readmore}
 | 
| 
e73ccbed776e
completed section on theorems
 Christian Urban <urbanc@in.tum.de> parents: 
352diff
changeset | 1918 | *} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1919 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1920 | section {* Theorem Attributes\label{sec:attributes} *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1921 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1922 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1923 |   Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1924 |   "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags
 | 
| 356 | 1925 | annotated to theorems, but functions that do further processing of | 
| 1926 | theorems. In particular, it is not possible to find out | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1927 | what are all theorems that have a given attribute in common, unless of course | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1928 | the function behind the attribute stores the theorems in a retrievable | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1929 | data structure. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1930 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1931 | If you want to print out all currently known attributes a theorem can have, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1932 | you can use the Isabelle command | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1933 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1934 |   \begin{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1935 |   \isacommand{print\_attributes}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1936 |   @{text "> COMP:  direct composition with rules (no lifting)"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1937 |   @{text "> HOL.dest:  declaration of Classical destruction rule"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1938 |   @{text "> HOL.elim:  declaration of Classical elimination rule"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1939 |   @{text "> \<dots>"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1940 |   \end{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1941 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1942 | The theorem attributes fall roughly into two categories: the first category manipulates | 
| 356 | 1943 |   theorems (for example @{text "[symmetric]"} and @{text "[THEN \<dots>]"}), and the second
 | 
| 1944 |   stores theorems somewhere as data (for example @{text "[simp]"}, which adds
 | |
| 1945 | theorems to the current simpset). | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1946 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1947 | To explain how to write your own attribute, let us start with an extremely simple | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1948 |   version of the attribute @{text "[symmetric]"}. The purpose of this attribute is
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1949 | to produce the ``symmetric'' version of an equation. The main function behind | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1950 | this attribute is | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1951 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1952 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1953 | ML{*val my_symmetric = Thm.rule_attribute (fn _ => fn thm => thm RS @{thm sym})*}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1954 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1955 | text {* 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1956 |   where the function @{ML_ind  rule_attribute in Thm} expects a function taking a 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1957 |   context (which we ignore in the code above) and a theorem (@{text thm}), and 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1958 |   returns another theorem (namely @{text thm} resolved with the theorem 
 | 
| 363 | 1959 |   @{thm [source] sym}: @{thm sym[no_vars]}; the function @{ML_ind RS in Drule} 
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1960 |   is explained in Section~\ref{sec:simpletacs}). The function 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1961 |   @{ML rule_attribute in Thm} then returns  an attribute.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1962 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1963 | Before we can use the attribute, we need to set it up. This can be done | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1964 |   using the Isabelle command \isacommand{attribute\_setup} as follows:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1965 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1966 | |
| 356 | 1967 | attribute_setup %gray my_sym = | 
| 1968 |   {* Scan.succeed my_symmetric *} "applying the sym rule"
 | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1969 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1970 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1971 |   Inside the @{text "\<verbopen> \<dots> \<verbclose>"}, we have to specify a parser
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1972 | for the theorem attribute. Since the attribute does not expect any further | 
| 356 | 1973 |   arguments (unlike @{text "[THEN \<dots>]"}, for instance), we use the parser @{ML
 | 
| 1974 |   Scan.succeed}. An example for the attribute @{text "[my_sym]"} is the proof
 | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1975 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1976 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1977 | lemma test[my_sym]: "2 = Suc (Suc 0)" by simp | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1978 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1979 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1980 |   which stores the theorem @{thm test} under the name @{thm [source] test}. You
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1981 | can see this, if you query the lemma: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1982 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1983 |   \begin{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1984 |   \isacommand{thm}~@{text "test"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1985 |   @{text "> "}~@{thm test}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1986 |   \end{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1987 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1988 | We can also use the attribute when referring to this theorem: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1989 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1990 |   \begin{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1991 |   \isacommand{thm}~@{text "test[my_sym]"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1992 |   @{text "> "}~@{thm test[my_sym]}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1993 |   \end{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1994 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1995 |   An alternative for setting up an attribute is the function @{ML_ind  setup in Attrib}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1996 |   So instead of using \isacommand{attribute\_setup}, you can also set up the
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1997 | attribute as follows: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1998 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 1999 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2000 | ML{*Attrib.setup @{binding "my_sym"} (Scan.succeed my_symmetric)
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2001 | "applying the sym rule" *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2002 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2003 | text {*
 | 
| 356 | 2004 |   This gives a function from @{ML_type "theory -> theory"}, which
 | 
| 361 | 2005 |   can be used for example with \isacommand{setup} or with
 | 
| 368 
b1a458a03a8e
new parts in the tactical section
 Christian Urban <urbanc@in.tum.de> parents: 
363diff
changeset | 2006 |   @{ML "Context.>> o Context.map_theory"}.\footnote{\bf FIXME: explain what happens here.}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2007 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2008 | As an example of a slightly more complicated theorem attribute, we implement | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2009 |   our own version of @{text "[THEN \<dots>]"}. This attribute will take a list of theorems
 | 
| 356 | 2010 | as argument and resolve the theorem with this list (one theorem | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2011 | after another). The code for this attribute is | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2012 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2013 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2014 | ML{*fun MY_THEN thms = 
 | 
| 396 | 2015 | let | 
| 2016 | fun RS_rev thm1 thm2 = thm2 RS thm1 | |
| 2017 | in | |
| 2018 | Thm.rule_attribute (fn _ => fn thm => fold RS_rev thms thm) | |
| 2019 | end*} | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2020 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2021 | text {* 
 | 
| 396 | 2022 |   where for convenience we define the reverse and curried version of @{ML RS}. 
 | 
| 2023 |   The setup of this theorem attribute uses the parser @{ML thms in Attrib}, 
 | |
| 2024 | which parses a list of theorems. | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2025 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2026 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2027 | attribute_setup %gray MY_THEN = {* Attrib.thms >> MY_THEN *} 
 | 
| 356 | 2028 | "resolving the list of theorems with the theorem" | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2029 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2030 | text {* 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2031 | You can, for example, use this theorem attribute to turn an equation into a | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2032 | meta-equation: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2033 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2034 |   \begin{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2035 |   \isacommand{thm}~@{text "test[MY_THEN eq_reflection]"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2036 |   @{text "> "}~@{thm test[MY_THEN eq_reflection]}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2037 |   \end{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2038 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2039 | If you need the symmetric version as a meta-equation, you can write | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2040 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2041 |   \begin{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2042 |   \isacommand{thm}~@{text "test[MY_THEN sym eq_reflection]"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2043 |   @{text "> "}~@{thm test[MY_THEN sym eq_reflection]}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2044 |   \end{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2045 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2046 | It is also possible to combine different theorem attributes, as in: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2047 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2048 |   \begin{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2049 |   \isacommand{thm}~@{text "test[my_sym, MY_THEN eq_reflection]"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2050 |   @{text "> "}~@{thm test[my_sym, MY_THEN eq_reflection]}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2051 |   \end{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2052 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2053 | However, here also a weakness of the concept | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2054 | of theorem attributes shows through: since theorem attributes can be | 
| 329 | 2055 | arbitrary functions, they do not commute in general. If you try | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2056 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2057 |   \begin{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2058 |   \isacommand{thm}~@{text "test[MY_THEN eq_reflection, my_sym]"}\\
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2059 |   @{text "> "}~@{text "exception THM 1 raised: RSN: no unifiers"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2060 |   \end{isabelle}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2061 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2062 |   you get an exception indicating that the theorem @{thm [source] sym}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2063 | does not resolve with meta-equations. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2064 | |
| 329 | 2065 |   The purpose of @{ML_ind rule_attribute in Thm} is to directly manipulate
 | 
| 2066 | theorems. Another usage of theorem attributes is to add and delete theorems | |
| 2067 |   from stored data.  For example the theorem attribute @{text "[simp]"} adds
 | |
| 2068 | or deletes a theorem from the current simpset. For these applications, you | |
| 2069 |   can use @{ML_ind declaration_attribute in Thm}. To illustrate this function,
 | |
| 2070 | let us introduce a theorem list. | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2071 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2072 | |
| 329 | 2073 | ML{*structure MyThms = Named_Thms
 | 
| 2074 | (val name = "attr_thms" | |
| 2075 | val description = "Theorems for an Attribute") *} | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2076 | |
| 329 | 2077 | text {* 
 | 
| 2078 | We are going to modify this list by adding and deleting theorems. | |
| 2079 |   For this we use the two functions @{ML MyThms.add_thm} and
 | |
| 2080 |   @{ML MyThms.del_thm}. You can turn them into attributes 
 | |
| 2081 | with the code | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2082 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2083 | |
| 329 | 2084 | ML{*val my_add = Thm.declaration_attribute MyThms.add_thm
 | 
| 2085 | val my_del = Thm.declaration_attribute MyThms.del_thm *} | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2086 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2087 | text {* 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2088 | and set up the attributes as follows | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2089 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2090 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2091 | attribute_setup %gray my_thms = {* Attrib.add_del my_add my_del *} 
 | 
| 329 | 2092 | "maintaining a list of my_thms" | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2093 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2094 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2095 |   The parser @{ML_ind  add_del in Attrib} is a predefined parser for 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2096 | adding and deleting lemmas. Now if you prove the next lemma | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2097 |   and attach to it the attribute @{text "[my_thms]"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2098 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2099 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2100 | lemma trueI_2[my_thms]: "True" by simp | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2101 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2102 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2103 | then you can see it is added to the initially empty list. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2104 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2105 |   @{ML_response_fake [display,gray]
 | 
| 329 | 2106 |   "MyThms.get @{context}" 
 | 
| 2107 | "[\"True\"]"} | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2108 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2109 |   You can also add theorems using the command \isacommand{declare}.
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2110 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2111 | |
| 329 | 2112 | declare test[my_thms] trueI_2[my_thms add] | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2113 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2114 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2115 |   With this attribute, the @{text "add"} operation is the default and does 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2116 | not need to be explicitly given. These three declarations will cause the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2117 | theorem list to be updated as: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2118 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2119 |   @{ML_response_fake [display,gray]
 | 
| 329 | 2120 |   "MyThms.get @{context}"
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2121 | "[\"True\", \"Suc (Suc 0) = 2\"]"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2122 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2123 |   The theorem @{thm [source] trueI_2} only appears once, since the 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2124 |   function @{ML_ind  add_thm in Thm} tests for duplicates, before extending
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2125 | the list. Deletion from the list works as follows: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2126 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2127 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2128 | declare test[my_thms del] | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2129 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2130 | text {* After this, the theorem list is again: 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2131 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2132 |   @{ML_response_fake [display,gray]
 | 
| 329 | 2133 |   "MyThms.get @{context}"
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2134 | "[\"True\"]"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2135 | |
| 329 | 2136 |   We used in this example two functions declared as @{ML_ind
 | 
| 2137 | declaration_attribute in Thm}, but there can be any number of them. We just | |
| 2138 | have to change the parser for reading the arguments accordingly. | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2139 | |
| 329 | 2140 |   \footnote{\bf FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?}
 | 
| 396 | 2141 |   \footnote{\bf FIXME readmore}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2142 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2143 |   \begin{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2144 |   FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2145 |   @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2146 | parsing. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2147 |   \end{readmore}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2148 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2149 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2150 | section {* Pretty-Printing\label{sec:pretty} *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2151 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2152 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2153 | So far we printed out only plain strings without any formatting except for | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2154 |   occasional explicit line breaks using @{text [quotes] "\\n"}. This is
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2155 | sufficient for ``quick-and-dirty'' printouts. For something more | 
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2156 | sophisticated, Isabelle includes an infrastructure for properly formatting | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2157 |   text. Most of its functions do not operate on @{ML_type string}s, but on
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2158 | instances of the pretty type: | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2159 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2160 |   @{ML_type_ind [display, gray] "Pretty.T"}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2161 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2162 |   The function @{ML str in Pretty} transforms a (plain) string into such a pretty 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2163 | type. For example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2164 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2165 |   @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2166 | "Pretty.str \"test\"" "String (\"test\", 4)"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2167 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2168 | where the result indicates that we transformed a string with length 4. Once | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2169 | you have a pretty type, you can, for example, control where linebreaks may | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2170 | occur in case the text wraps over a line, or with how much indentation a | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2171 | text should be printed. However, if you want to actually output the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2172 |   formatted text, you have to transform the pretty type back into a @{ML_type
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2173 |   string}. This can be done with the function @{ML_ind  string_of in Pretty}. In what
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2174 | follows we will use the following wrapper function for printing a pretty | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2175 | type: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2176 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2177 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2178 | ML{*fun pprint prt = tracing (Pretty.string_of prt)*}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2179 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2180 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2181 | The point of the pretty-printing infrastructure is to give hints about how to | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2182 | layout text and let Isabelle do the actual layout. Let us first explain | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2183 | how you can insert places where a line break can occur. For this assume the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2184 | following function that replicates a string n times: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2185 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2186 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2187 | ML{*fun rep n str = implode (replicate n str) *}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2188 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2189 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2190 | and suppose we want to print out the string: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2191 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2192 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2193 | ML{*val test_str = rep 8 "fooooooooooooooobaaaaaaaaaaaar "*}
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2194 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2195 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2196 | We deliberately chose a large string so that it spans over more than one line. | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2197 | If we print out the string using the usual ``quick-and-dirty'' method, then | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2198 | we obtain the ugly output: | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2199 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2200 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2201 | "tracing test_str" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2202 | "fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar foooooooooo | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2203 | ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2204 | aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2205 | oooooooooooooobaaaaaaaaaaaar"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2206 | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2207 |   We obtain the same if we just use the function @{ML pprint}.
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2208 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2209 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2210 | "pprint (Pretty.str test_str)" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2211 | "fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar foooooooooo | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2212 | ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2213 | aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2214 | oooooooooooooobaaaaaaaaaaaar"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2215 | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2216 | However by using pretty types you have the ability to indicate possible | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2217 | linebreaks for example at each whitespace. You can achieve this with the | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2218 |   function @{ML_ind breaks in Pretty}, which expects a list of pretty types
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2219 | and inserts a possible line break in between every two elements in this | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2220 | list. To print this list of pretty types as a single string, we concatenate | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2221 |   them with the function @{ML_ind blk in Pretty} as follows:
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2222 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2223 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2224 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2225 | val ptrs = map Pretty.str (space_explode \" \" test_str) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2226 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2227 | pprint (Pretty.blk (0, Pretty.breaks ptrs)) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2228 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2229 | "fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2230 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2231 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2232 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2233 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2234 |   Here the layout of @{ML test_str} is much more pleasing to the 
 | 
| 360 | 2235 |   eye. The @{ML "0"} in @{ML_ind  blk in Pretty} stands for no hanging 
 | 
| 2236 | indentation of the printed string. You can increase the indentation | |
| 2237 | and obtain | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2238 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2239 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2240 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2241 | val ptrs = map Pretty.str (space_explode \" \" test_str) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2242 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2243 | pprint (Pretty.blk (3, Pretty.breaks ptrs)) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2244 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2245 | "fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2246 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2247 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2248 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2249 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2250 | where starting from the second line the indent is 3. If you want | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2251 | that every line starts with the same indent, you can use the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2252 |   function @{ML_ind  indent in Pretty} as follows:
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2253 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2254 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2255 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2256 | val ptrs = map Pretty.str (space_explode \" \" test_str) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2257 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2258 | pprint (Pretty.indent 10 (Pretty.blk (0, Pretty.breaks ptrs))) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2259 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2260 | " fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2261 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2262 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2263 | fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2264 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2265 | If you want to print out a list of items separated by commas and | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2266 | have the linebreaks handled properly, you can use the function | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2267 |   @{ML_ind  commas in Pretty}. For example
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2268 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2269 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2270 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2271 | val ptrs = map (Pretty.str o string_of_int) (99998 upto 100020) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2272 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2273 | pprint (Pretty.blk (0, Pretty.commas ptrs)) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2274 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2275 | "99998, 99999, 100000, 100001, 100002, 100003, 100004, 100005, 100006, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2276 | 100007, 100008, 100009, 100010, 100011, 100012, 100013, 100014, 100015, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2277 | 100016, 100017, 100018, 100019, 100020"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2278 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2279 |   where @{ML upto} generates a list of integers. You can print out this
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2280 |   list as a ``set'', that means enclosed inside @{text [quotes] "{"} and
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2281 |   @{text [quotes] "}"}, and separated by commas using the function
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2282 |   @{ML_ind  enum in Pretty}. For example
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2283 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2284 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2285 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2286 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2287 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2288 | "let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2289 | val ptrs = map (Pretty.str o string_of_int) (99998 upto 100020) | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2290 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2291 |   pprint (Pretty.enum \",\" \"{\" \"}\" ptrs)
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2292 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2293 | "{99998, 99999, 100000, 100001, 100002, 100003, 100004, 100005, 100006, 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2294 | 100007, 100008, 100009, 100010, 100011, 100012, 100013, 100014, 100015, | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2295 | 100016, 100017, 100018, 100019, 100020}"} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2296 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2297 | As can be seen, this function prints out the ``set'' so that starting | 
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2298 | from the second, each new line has an indentation of 2. | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2299 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2300 | If you print out something that goes beyond the capabilities of the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2301 | standard functions, you can do relatively easily the formatting | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2302 | yourself. Assume you want to print out a list of items where like in ``English'' | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2303 |   the last two items are separated by @{text [quotes] "and"}. For this you can
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2304 | write the function | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2305 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2306 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2307 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2308 | ML %linenosgray{*fun and_list [] = []
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2309 | | and_list [x] = [x] | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2310 | | and_list xs = | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2311 | let | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2312 | val (front, last) = split_last xs | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2313 | in | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2314 | (Pretty.commas front) @ | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2315 | [Pretty.brk 1, Pretty.str "and", Pretty.brk 1, last] | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2316 | end *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2317 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2318 | text {*
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2319 | where Line 7 prints the beginning of the list and Line | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2320 |   8 the last item. We have to use @{ML "Pretty.brk 1"} in order
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2321 | to insert a space (of length 1) before the | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2322 |   @{text [quotes] "and"}. This space is also a place where a line break 
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2323 |   can occur. We do the same after the @{text [quotes] "and"}. This gives you
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2324 | for example | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2325 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2326 | @{ML_response_fake [display,gray]
 | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2327 | "let | 
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2328 | val ptrs1 = map (Pretty.str o string_of_int) (1 upto 22) | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2329 | val ptrs2 = map (Pretty.str o string_of_int) (10 upto 28) | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2330 | in | 
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2331 | pprint (Pretty.blk (0, and_list ptrs1)); | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2332 | pprint (Pretty.blk (0, and_list ptrs2)) | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2333 | end" | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2334 | "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 | 
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2335 | and 22 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2336 | 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 and | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2337 | 28"} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2338 | |
| 396 | 2339 |   Like @{ML blk in Pretty}, the function @{ML_ind chunks in Pretty} prints out 
 | 
| 2340 | a list of items, but automatically inserts forced breaks between each item. | |
| 2341 | Compare | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2342 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2343 |   @{ML_response_fake [display,gray]
 | 
| 396 | 2344 | "let | 
| 2345 | val a_and_b = [Pretty.str \"a\", Pretty.str \"b\"] | |
| 2346 | in | |
| 2347 | pprint (Pretty.blk (0, a_and_b)); | |
| 2348 | pprint (Pretty.chunks a_and_b) | |
| 2349 | end" | |
| 2350 | "ab | |
| 2351 | a | |
| 2352 | b"} | |
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2353 | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2354 |   The function @{ML_ind big_list in Pretty} helps with printing long lists.
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2355 |   It is used for example in the command \isacommand{print\_theorems}. An
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2356 | example is as follows. | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2357 | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2358 |   @{ML_response_fake [display,gray]
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2359 | "let | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2360 | val pstrs = map (Pretty.str o string_of_int) (4 upto 10) | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2361 | in | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2362 | pprint (Pretty.big_list \"header\" pstrs) | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2363 | end" | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2364 | "header | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2365 | 4 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2366 | 5 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2367 | 6 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2368 | 7 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2369 | 8 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2370 | 9 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2371 | 10"} | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2372 | |
| 396 | 2373 | The point of the pretty-printing functions is to conveninetly obtain | 
| 2374 | a lay-out of terms and types that is pleasing to the eye. If we print | |
| 2375 |   out the the terms produced by the the function @{ML de_bruijn} from 
 | |
| 2376 |   exercise~\ref{ex:debruijn} we obtain the following: 
 | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2377 | |
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2378 |   @{ML_response_fake [display,gray]
 | 
| 396 | 2379 |   "pprint (Syntax.pretty_term  @{context} (de_bruijn 4))"
 | 
| 2380 | "(P 3 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and> | |
| 2381 | (P 2 = P 3 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and> | |
| 2382 | (P 1 = P 2 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<and> | |
| 2383 | (P 1 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<longrightarrow> | |
| 2384 | P 4 \<and> P 3 \<and> P 2 \<and> P 1"} | |
| 2385 | ||
| 2386 |   We use the function @{ML_ind pretty_term in Syntax} for pretty-printing
 | |
| 2387 | terms. Next we like to pretty-print a term and its type. For this we use the | |
| 2388 |   function @{text "tell_type"}.
 | |
| 2389 | *} | |
| 2390 | ||
| 2391 | ML %linenosgray{*fun tell_type ctxt trm = 
 | |
| 2392 | let | |
| 2393 | fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s)) | |
| 2394 | val ptrm = Pretty.quote (Syntax.pretty_term ctxt trm) | |
| 2395 | val pty = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of trm)) | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2396 | in | 
| 396 | 2397 | pprint (Pretty.blk (0, | 
| 2398 | (pstr "The term " @ [ptrm] @ pstr " has type " | |
| 2399 | @ [pty, Pretty.str "."]))) | |
| 2400 | end*} | |
| 2401 | ||
| 2402 | text {*
 | |
| 2403 | In Line 3 we define a function that inserts possible linebreaks in places | |
| 2404 | where a space is. In Lines 4 and 5 we pretty-print the term and its type | |
| 2405 |   using the functions @{ML pretty_term in Syntax} and @{ML_ind 
 | |
| 2406 |   pretty_typ in Syntax}. We also use the function @{ML_ind quote in
 | |
| 2407 | Pretty} in order to enclose the term and type inside quotation marks. In | |
| 2408 | Line 9 we add a period right after the type without the possibility of a | |
| 2409 | line break, because we do not want that a line break occurs there. | |
| 2410 | Now you can write | |
| 2411 | ||
| 2412 |   @{ML_response_fake [display,gray]
 | |
| 2413 |   "tell_type @{context} @{term \"min (Suc 0)\"}"
 | |
| 2414 | "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."} | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2415 | |
| 396 | 2416 | To see the proper line breaking, you can try out the function on a bigger term | 
| 2417 | and type. For example: | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2418 | |
| 396 | 2419 |   @{ML_response_fake [display,gray]
 | 
| 2420 |   "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
 | |
| 2421 | "The term \"op = (op = (op = (op = (op = op =))))\" has type | |
| 2422 | \"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."}
 | |
| 336 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2423 | |
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2424 |   \begin{readmore}
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2425 | The general infrastructure for pretty-printing is implemented in the file | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2426 |   @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2427 | contains pretty-printing functions for terms, types, theorems and so on. | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2428 | |
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2429 |   @{ML_file "Pure/General/markup.ML"}
 | 
| 
a12bb28fe2bd
polished on the pretty printing section
 Christian Urban <urbanc@in.tum.de> parents: 
335diff
changeset | 2430 |   \end{readmore}
 | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2431 | *} | 
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2432 | |
| 349 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2433 | section {* Summary *}
 | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2434 | |
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2435 | text {*
 | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2436 |   \begin{conventions}
 | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2437 |   \begin{itemize}
 | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2438 | \item Start with a proper context and then pass it around | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2439 | through all your functions. | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2440 |   \end{itemize}
 | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2441 |   \end{conventions}
 | 
| 
9e374cd891e1
updated to Isabelle changes
 Christian Urban <urbanc@in.tum.de> parents: 
348diff
changeset | 2442 | *} | 
| 318 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2443 | |
| 
efb5fff99c96
split up the first-steps section into two chapters
 Christian Urban <urbanc@in.tum.de> parents: diff
changeset | 2444 | end |