ProgTutorial/Essential.thy
changeset 565 cecd7a941885
parent 562 daf404920ab9
child 566 6103b0eadbf2
equal deleted inserted replaced
564:6e2479089226 565:cecd7a941885
     1 theory Essential
     1 theory Essential
     2 imports Base First_Steps
     2 imports Base First_Steps
     3 begin
     3 begin
     4 
     4 
     5 chapter {* Isabelle Essentials *}
     5 chapter \<open>Isabelle Essentials\<close>
     6 
     6 
     7 text {*
     7 text \<open>
     8    \begin{flushright}
     8    \begin{flushright}
     9   {\em One man's obfuscation is another man's abstraction.} \\[1ex]
     9   {\em One man's obfuscation is another man's abstraction.} \\[1ex]
    10   Frank Ch.~Eigler on the Linux Kernel Mailing List,\\ 
    10   Frank Ch.~Eigler on the Linux Kernel Mailing List,\\ 
    11   24~Nov.~2009
    11   24~Nov.~2009
    12   \end{flushright}
    12   \end{flushright}
    15   Isabelle is built around a few central ideas. One central idea is the
    15   Isabelle is built around a few central ideas. One central idea is the
    16   LCF-approach to theorem proving \cite{GordonMilnerWadsworth79} where there
    16   LCF-approach to theorem proving \cite{GordonMilnerWadsworth79} where there
    17   is a small trusted core and everything else is built on top of this trusted
    17   is a small trusted core and everything else is built on top of this trusted
    18   core. The fundamental data structures involved in this core are certified
    18   core. The fundamental data structures involved in this core are certified
    19   terms and certified types, as well as theorems.
    19   terms and certified types, as well as theorems.
    20 *}
    20 \<close>
    21 
    21 
    22 
    22 
    23 section {* Terms and Types *}
    23 section \<open>Terms and Types\<close>
    24 
    24 
    25 text {*
    25 text \<open>
    26   In Isabelle, there are certified terms and uncertified terms (respectively types). 
    26   In Isabelle, there are certified terms and uncertified terms (respectively types). 
    27   Uncertified terms are often just called terms. One way to construct them is by 
    27   Uncertified terms are often just called terms. One way to construct them is by 
    28   using the antiquotation \mbox{@{text "@{term \<dots>}"}}. For example
    28   using the antiquotation \mbox{\<open>@{term \<dots>}\<close>}. For example
    29 
    29 
    30   @{ML_response [display,gray] 
    30   @{ML_response [display,gray] 
    31 "@{term \"(a::nat) + b = c\"}" 
    31 "@{term \"(a::nat) + b = c\"}" 
    32 "Const (\"HOL.eq\", \<dots>) $ 
    32 "Const (\"HOL.eq\", \<dots>) $ 
    33   (Const (\"Groups.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
    33   (Const (\"Groups.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
    34 
    34 
    35   constructs the term @{term "(a::nat) + b = c"}. The resulting term is printed using 
    35   constructs the term @{term "(a::nat) + b = c"}. The resulting term is printed using 
    36   the internal representation corresponding to the datatype @{ML_type_ind "term"}, 
    36   the internal representation corresponding to the datatype @{ML_type_ind "term"}, 
    37   which is defined as follows: 
    37   which is defined as follows: 
    38 *}  
    38 \<close>  
    39 
    39 
    40 ML_val %linenosgray{*datatype term =
    40 ML_val %linenosgray\<open>datatype term =
    41   Const of string * typ 
    41   Const of string * typ 
    42 | Free of string * typ 
    42 | Free of string * typ 
    43 | Var of indexname * typ 
    43 | Var of indexname * typ 
    44 | Bound of int 
    44 | Bound of int 
    45 | Abs of string * typ * term 
    45 | Abs of string * typ * term 
    46 | $ of term * term *}
    46 | $ of term * term\<close>
    47 
    47 
    48 text {*
    48 text \<open>
    49   This datatype implements Church-style lambda-terms, where types are
    49   This datatype implements Church-style lambda-terms, where types are
    50   explicitly recorded in variables, constants and abstractions.  The
    50   explicitly recorded in variables, constants and abstractions.  The
    51   important point of having terms is that you can pattern-match against them;
    51   important point of having terms is that you can pattern-match against them;
    52   this cannot be done with certified terms. As can be seen in Line 5,
    52   this cannot be done with certified terms. As can be seen in Line 5,
    53   terms use the usual de Bruijn index mechanism for representing bound
    53   terms use the usual de Bruijn index mechanism for representing bound
   125 end"
   125 end"
   126 "?x3, ?x1.3, x"}
   126 "?x3, ?x1.3, x"}
   127 
   127 
   128   When constructing terms, you are usually concerned with free
   128   When constructing terms, you are usually concerned with free
   129   variables (as mentioned earlier, you cannot construct schematic
   129   variables (as mentioned earlier, you cannot construct schematic
   130   variables using the built-in antiquotation \mbox{@{text "@{term
   130   variables using the built-in antiquotation \mbox{\<open>@{term
   131   \<dots>}"}}). If you deal with theorems, you have to, however, observe the
   131   \<dots>}\<close>}). If you deal with theorems, you have to, however, observe the
   132   distinction. The reason is that only schematic variables can be
   132   distinction. The reason is that only schematic variables can be
   133   instantiated with terms when a theorem is applied. A similar
   133   instantiated with terms when a theorem is applied. A similar
   134   distinction between free and schematic variables holds for types
   134   distinction between free and schematic variables holds for types
   135   (see below).
   135   (see below).
   136 
   136 
   175 
   175 
   176   Hint: The third term is already quite big, and the pretty printer
   176   Hint: The third term is already quite big, and the pretty printer
   177   may omit parts of it by default. If you want to see all of it, you
   177   may omit parts of it by default. If you want to see all of it, you
   178   need to set the printing depth to a higher value by 
   178   need to set the printing depth to a higher value by 
   179   \end{exercise}
   179   \end{exercise}
   180 *}
   180 \<close>
   181 
   181 
   182 declare [[ML_print_depth = 50]]
   182 declare [[ML_print_depth = 50]]
   183 
   183 
   184 text {*
   184 text \<open>
   185   The antiquotation @{text "@{prop \<dots>}"} constructs terms by inserting the 
   185   The antiquotation \<open>@{prop \<dots>}\<close> constructs terms by inserting the 
   186   usually invisible @{text "Trueprop"}-coercions whenever necessary. 
   186   usually invisible \<open>Trueprop\<close>-coercions whenever necessary. 
   187   Consider for example the pairs
   187   Consider for example the pairs
   188 
   188 
   189 @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" 
   189 @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" 
   190 "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   190 "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   191  Const (\"HOL.Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   191  Const (\"HOL.Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   195   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   195   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   196   "(Const (\"Pure.imp\", \<dots>) $ \<dots> $ \<dots>, 
   196   "(Const (\"Pure.imp\", \<dots>) $ \<dots> $ \<dots>, 
   197  Const (\"Pure.imp\", \<dots>) $ \<dots> $ \<dots>)"}
   197  Const (\"Pure.imp\", \<dots>) $ \<dots> $ \<dots>)"}
   198 
   198 
   199   where it is not (since it is already constructed by a meta-implication). 
   199   where it is not (since it is already constructed by a meta-implication). 
   200   The purpose of the @{text "Trueprop"}-coercion is to embed formulae of
   200   The purpose of the \<open>Trueprop\<close>-coercion is to embed formulae of
   201   an object logic, for example HOL, into the meta-logic of Isabelle. The coercion
   201   an object logic, for example HOL, into the meta-logic of Isabelle. The coercion
   202   is needed whenever a term is constructed that will be proved as a theorem. 
   202   is needed whenever a term is constructed that will be proved as a theorem. 
   203 
   203 
   204   As already seen above, types can be constructed using the antiquotation 
   204   As already seen above, types can be constructed using the antiquotation 
   205   @{text "@{typ \<dots>}"}. For example:
   205   \<open>@{typ \<dots>}\<close>. For example:
   206 
   206 
   207   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   207   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   208 
   208 
   209   The corresponding datatype is
   209   The corresponding datatype is
   210 *}
   210 \<close>
   211   
   211   
   212 ML_val %grayML{*datatype typ =
   212 ML_val %grayML\<open>datatype typ =
   213   Type  of string * typ list 
   213   Type  of string * typ list 
   214 | TFree of string * sort 
   214 | TFree of string * sort 
   215 | TVar  of indexname * sort *}
   215 | TVar  of indexname * sort\<close>
   216 
   216 
   217 text {*
   217 text \<open>
   218   Like with terms, there is the distinction between free type
   218   Like with terms, there is the distinction between free type
   219   variables (term-constructor @{ML "TFree"}) and schematic
   219   variables (term-constructor @{ML "TFree"}) and schematic
   220   type variables (term-constructor @{ML "TVar"} and printed with
   220   type variables (term-constructor @{ML "TVar"} and printed with
   221   a leading question mark). A type constant,
   221   a leading question mark). A type constant,
   222   like @{typ "int"} or @{typ bool}, are types with an empty list
   222   like @{typ "int"} or @{typ bool}, are types with an empty list
   223   of argument types. However, it needs a bit of effort to show an
   223   of argument types. However, it needs a bit of effort to show an
   224   example, because Isabelle always pretty prints types (unlike terms).
   224   example, because Isabelle always pretty prints types (unlike terms).
   225   Using just the antiquotation @{text "@{typ \"bool\"}"} we only see
   225   Using just the antiquotation \<open>@{typ "bool"}\<close> we only see
   226 
   226 
   227   @{ML_response [display, gray]
   227   @{ML_response [display, gray]
   228   "@{typ \"bool\"}"
   228   "@{typ \"bool\"}"
   229   "bool"}
   229   "bool"}
   230   which is the pretty printed version of @{text "bool"}. However, in PolyML
   230   which is the pretty printed version of \<open>bool\<close>. However, in PolyML
   231   (version @{text "\<ge>"}5.3) it is easy to install your own pretty printer. With the
   231   (version \<open>\<ge>\<close>5.3) it is easy to install your own pretty printer. With the
   232   function below we mimic the behaviour of the usual pretty printer for
   232   function below we mimic the behaviour of the usual pretty printer for
   233   datatypes (it uses pretty-printing functions which will be explained in more
   233   datatypes (it uses pretty-printing functions which will be explained in more
   234   detail in Section~\ref{sec:pretty}).
   234   detail in Section~\ref{sec:pretty}).
   235 *}
   235 \<close>
   236 
   236 
   237 ML %grayML{*local
   237 ML %grayML\<open>local
   238   fun pp_pair (x, y) = Pretty.list "(" ")" [x, y]
   238   fun pp_pair (x, y) = Pretty.list "(" ")" [x, y]
   239   fun pp_list xs = Pretty.list "[" "]" xs
   239   fun pp_list xs = Pretty.list "[" "]" xs
   240   fun pp_str s   = Pretty.str s
   240   fun pp_str s   = Pretty.str s
   241   fun pp_qstr s  = Pretty.quote (pp_str s)
   241   fun pp_qstr s  = Pretty.quote (pp_str s)
   242   fun pp_int i   = pp_str (string_of_int i)
   242   fun pp_int i   = pp_str (string_of_int i)
   247       pp_constr "TVar" (pp_pair (pp_pair (pp_qstr a, pp_int i), pp_sort S))
   247       pp_constr "TVar" (pp_pair (pp_pair (pp_qstr a, pp_int i), pp_sort S))
   248   | raw_pp_typ (TFree (a, S)) = 
   248   | raw_pp_typ (TFree (a, S)) = 
   249       pp_constr "TFree" (pp_pair (pp_qstr a, pp_sort S))
   249       pp_constr "TFree" (pp_pair (pp_qstr a, pp_sort S))
   250   | raw_pp_typ (Type (a, tys)) = 
   250   | raw_pp_typ (Type (a, tys)) = 
   251       pp_constr "Type" (pp_pair (pp_qstr a, pp_list (map raw_pp_typ tys)))
   251       pp_constr "Type" (pp_pair (pp_qstr a, pp_list (map raw_pp_typ tys)))
   252 end*}
   252 end\<close>
   253 
   253 
   254 text {*
   254 text \<open>
   255   We can install this pretty printer with the function 
   255   We can install this pretty printer with the function 
   256   @{ML_ind ML_system_pp} as follows.
   256   @{ML_ind ML_system_pp} as follows.
   257 *}
   257 \<close>
   258 
   258 
   259 ML %grayML{*ML_system_pp
   259 ML %grayML\<open>ML_system_pp
   260   (fn _ => fn _ => Pretty.to_polyml o raw_pp_typ)*}
   260   (fn _ => fn _ => Pretty.to_polyml o raw_pp_typ)\<close>
   261 
   261 
   262 ML \<open>@{typ "bool"}\<close>
   262 ML \<open>@{typ "bool"}\<close>
   263 text {*
   263 text \<open>
   264   Now the type bool is printed out in full detail.
   264   Now the type bool is printed out in full detail.
   265 
   265 
   266   @{ML_response [display,gray]
   266   @{ML_response [display,gray]
   267   "@{typ \"bool\"}"
   267   "@{typ \"bool\"}"
   268   "Type (\"HOL.bool\", [])"}
   268   "Type (\"HOL.bool\", [])"}
   271   
   271   
   272   @{ML_response [display,gray]
   272   @{ML_response [display,gray]
   273   "@{typ \"'a list\"}"
   273   "@{typ \"'a list\"}"
   274   "Type (\"List.list\", [TFree (\"'a\", [\"HOL.type\"])])"}
   274   "Type (\"List.list\", [TFree (\"'a\", [\"HOL.type\"])])"}
   275 
   275 
   276   we can see the full name of the type is actually @{text "List.list"}, indicating
   276   we can see the full name of the type is actually \<open>List.list\<close>, indicating
   277   that it is defined in the theory @{text "List"}. However, one has to be 
   277   that it is defined in the theory \<open>List\<close>. However, one has to be 
   278   careful with names of types, because even if
   278   careful with names of types, because even if
   279   @{text "fun"} is defined in the theory @{text "HOL"}, it is  
   279   \<open>fun\<close> is defined in the theory \<open>HOL\<close>, it is  
   280   still represented by its simple name.
   280   still represented by its simple name.
   281 
   281 
   282    @{ML_response [display,gray]
   282    @{ML_response [display,gray]
   283   "@{typ \"bool \<Rightarrow> nat\"}"
   283   "@{typ \"bool \<Rightarrow> nat\"}"
   284   "Type (\"fun\", [Type (\"HOL.bool\", []), Type (\"Nat.nat\", [])])"}
   284   "Type (\"fun\", [Type (\"HOL.bool\", []), Type (\"Nat.nat\", [])])"}
   285 
   285 
   286   We can restore the usual behaviour of Isabelle's pretty printer
   286   We can restore the usual behaviour of Isabelle's pretty printer
   287   with the code
   287   with the code
   288 *}
   288 \<close>
   289 
   289 
   290 ML %grayML{*ML_system_pp
   290 ML %grayML\<open>ML_system_pp
   291   (fn depth => fn _ => ML_Pretty.to_polyml o Pretty.to_ML depth o Proof_Display.pp_typ Theory.get_pure)*}
   291   (fn depth => fn _ => ML_Pretty.to_polyml o Pretty.to_ML depth o Proof_Display.pp_typ Theory.get_pure)\<close>
   292 
   292 
   293 text {*
   293 text \<open>
   294   After that the types for booleans, lists and so on are printed out again 
   294   After that the types for booleans, lists and so on are printed out again 
   295   the standard Isabelle way.
   295   the standard Isabelle way.
   296 
   296 
   297   @{ML_response_fake [display, gray]
   297   @{ML_response_fake [display, gray]
   298   "@{typ \"bool\"};
   298   "@{typ \"bool\"};
   303   \begin{readmore}
   303   \begin{readmore}
   304   Types are described in detail in \isccite{sec:types}. Their
   304   Types are described in detail in \isccite{sec:types}. Their
   305   definition and many useful operations are implemented 
   305   definition and many useful operations are implemented 
   306   in @{ML_file "Pure/type.ML"}.
   306   in @{ML_file "Pure/type.ML"}.
   307   \end{readmore}
   307   \end{readmore}
   308 *}
   308 \<close>
   309 
   309 
   310 section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *} 
   310 section \<open>Constructing Terms and Types Manually\label{sec:terms_types_manually}\<close> 
   311 
   311 
   312 text {*
   312 text \<open>
   313   While antiquotations are very convenient for constructing terms, they can
   313   While antiquotations are very convenient for constructing terms, they can
   314   only construct fixed terms (remember they are ``linked'' at compile-time).
   314   only construct fixed terms (remember they are ``linked'' at compile-time).
   315   However, you often need to construct terms manually. For example, a
   315   However, you often need to construct terms manually. For example, a
   316   function that returns the implication @{text "\<And>(x::nat). P x \<Longrightarrow> Q x"} taking
   316   function that returns the implication \<open>\<And>(x::nat). P x \<Longrightarrow> Q x\<close> taking
   317   @{term P} and @{term Q} as arguments can only be written as:
   317   @{term P} and @{term Q} as arguments can only be written as:
   318 
   318 
   319 *}
   319 \<close>
   320 
   320 
   321 ML %grayML{*fun make_imp P Q =
   321 ML %grayML\<open>fun make_imp P Q =
   322 let
   322 let
   323   val x = Free ("x", @{typ nat})
   323   val x = Free ("x", @{typ nat})
   324 in 
   324 in 
   325   Logic.all x (Logic.mk_implies (P $ x, Q $ x))
   325   Logic.all x (Logic.mk_implies (P $ x, Q $ x))
   326 end *}
   326 end\<close>
   327 
   327 
   328 text {*
   328 text \<open>
   329   The reason is that you cannot pass the arguments @{term P} and @{term Q} 
   329   The reason is that you cannot pass the arguments @{term P} and @{term Q} 
   330   into an antiquotation.\footnote{At least not at the moment.} For example 
   330   into an antiquotation.\footnote{At least not at the moment.} For example 
   331   the following does \emph{not} work.
   331   the following does \emph{not} work.
   332 *}
   332 \<close>
   333 
   333 
   334 ML %grayML{*fun make_wrong_imp P Q = @{prop "\<And>(x::nat). P x \<Longrightarrow> Q x"} *}
   334 ML %grayML\<open>fun make_wrong_imp P Q = @{prop "\<And>(x::nat). P x \<Longrightarrow> Q x"}\<close>
   335 
   335 
   336 text {*
   336 text \<open>
   337   To see this, apply @{text "@{term S}"} and @{text "@{term T}"} 
   337   To see this, apply \<open>@{term S}\<close> and \<open>@{term T}\<close> 
   338   to both functions. With @{ML make_imp} you obtain the intended term involving 
   338   to both functions. With @{ML make_imp} you obtain the intended term involving 
   339   the given arguments
   339   the given arguments
   340 
   340 
   341   @{ML_response [display,gray] "make_imp @{term S} @{term T}" 
   341   @{ML_response [display,gray] "make_imp @{term S} @{term T}" 
   342 "Const \<dots> $ 
   342 "Const \<dots> $ 
   343   Abs (\"x\", Type (\"Nat.nat\",[]),
   343   Abs (\"x\", Type (\"Nat.nat\",[]),
   344     Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ (Free (\"T\",\<dots>) $ \<dots>))"}
   344     Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ (Free (\"T\",\<dots>) $ \<dots>))"}
   345 
   345 
   346   whereas with @{ML make_wrong_imp} you obtain a term involving the @{term "P"} 
   346   whereas with @{ML make_wrong_imp} you obtain a term involving the @{term "P"} 
   347   and @{text "Q"} from the antiquotation.
   347   and \<open>Q\<close> from the antiquotation.
   348 
   348 
   349   @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T}" 
   349   @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T}" 
   350 "Const \<dots> $ 
   350 "Const \<dots> $ 
   351   Abs (\"x\", \<dots>,
   351   Abs (\"x\", \<dots>,
   352     Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ 
   352     Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ 
   381   "Abs (\"x\", \"Nat.nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
   381   "Abs (\"x\", \"Nat.nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
   382 
   382 
   383   In this example, @{ML lambda} produces a de Bruijn index (i.e.\ @{ML "Bound 0"}), 
   383   In this example, @{ML lambda} produces a de Bruijn index (i.e.\ @{ML "Bound 0"}), 
   384   and an abstraction, where it also records the type of the abstracted
   384   and an abstraction, where it also records the type of the abstracted
   385   variable and for printing purposes also its name.  Note that because of the
   385   variable and for printing purposes also its name.  Note that because of the
   386   typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"}
   386   typing annotation on \<open>P\<close>, the variable \<open>x\<close> in \<open>P x\<close>
   387   is of the same type as the abstracted variable. If it is of different type,
   387   is of the same type as the abstracted variable. If it is of different type,
   388   as in
   388   as in
   389 
   389 
   390   @{ML_response_fake [display,gray]
   390   @{ML_response_fake [display,gray]
   391 "let
   391 "let
   394 in
   394 in
   395   lambda x_int trm
   395   lambda x_int trm
   396 end"
   396 end"
   397   "Abs (\"x\", \"int\", Free (\"P\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"}
   397   "Abs (\"x\", \"int\", Free (\"P\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"}
   398 
   398 
   399   then the variable @{text "Free (\"x\", \"nat\")"} is \emph{not} abstracted. 
   399   then the variable \<open>Free ("x", "nat")\<close> is \emph{not} abstracted. 
   400   This is a fundamental principle
   400   This is a fundamental principle
   401   of Church-style typing, where variables with the same name still differ, if they 
   401   of Church-style typing, where variables with the same name still differ, if they 
   402   have different type.
   402   have different type.
   403 
   403 
   404   There is also the function @{ML_ind subst_free in Term} with which terms can be
   404   There is also the function @{ML_ind subst_free in Term} with which terms can be
   429   "Free (\"x\", \"nat\")"}
   429   "Free (\"x\", \"nat\")"}
   430 
   430 
   431   Similarly the function @{ML_ind subst_bounds in Term}, replaces lose bound 
   431   Similarly the function @{ML_ind subst_bounds in Term}, replaces lose bound 
   432   variables with terms. To see how this function works, let us implement a
   432   variables with terms. To see how this function works, let us implement a
   433   function that strips off the outermost forall quantifiers in a term.
   433   function that strips off the outermost forall quantifiers in a term.
   434 *}
   434 \<close>
   435 
   435 
   436 ML %grayML{*fun strip_alls t =
   436 ML %grayML\<open>fun strip_alls t =
   437 let 
   437 let 
   438   fun aux (x, T, t) = strip_alls t |>> cons (Free (x, T))
   438   fun aux (x, T, t) = strip_alls t |>> cons (Free (x, T))
   439 in
   439 in
   440   case t of
   440   case t of
   441     Const (@{const_name All}, _) $ Abs body => aux body
   441     Const (@{const_name All}, _) $ Abs body => aux body
   442   | _ => ([], t)
   442   | _ => ([], t)
   443 end*}
   443 end\<close>
   444 
   444 
   445 text {*
   445 text \<open>
   446   The function returns a pair consisting of the stripped off variables and
   446   The function returns a pair consisting of the stripped off variables and
   447   the body of the universal quantification. For example
   447   the body of the universal quantification. For example
   448 
   448 
   449   @{ML_response_fake [display, gray]
   449   @{ML_response_fake [display, gray]
   450   "strip_alls @{term \"\<forall>x y. x = (y::bool)\"}"
   450   "strip_alls @{term \"\<forall>x y. x = (y::bool)\"}"
   452   Const (\"op =\", \<dots>) $ Bound 1 $ Bound 0)"}
   452   Const (\"op =\", \<dots>) $ Bound 1 $ Bound 0)"}
   453 
   453 
   454   Note that we produced in the body two dangling de Bruijn indices. 
   454   Note that we produced in the body two dangling de Bruijn indices. 
   455   Later on we will also use the inverse function that
   455   Later on we will also use the inverse function that
   456   builds the quantification from a body and a list of (free) variables.
   456   builds the quantification from a body and a list of (free) variables.
   457 *}
   457 \<close>
   458   
   458   
   459 ML %grayML{*fun build_alls ([], t) = t
   459 ML %grayML\<open>fun build_alls ([], t) = t
   460   | build_alls (Free (x, T) :: vs, t) = 
   460   | build_alls (Free (x, T) :: vs, t) = 
   461       Const (@{const_name "All"}, (T --> @{typ bool}) --> @{typ bool}) 
   461       Const (@{const_name "All"}, (T --> @{typ bool}) --> @{typ bool}) 
   462         $ Abs (x, T, build_alls (vs, t))*}
   462         $ Abs (x, T, build_alls (vs, t))\<close>
   463 
   463 
   464 text {*
   464 text \<open>
   465   As said above, after calling @{ML strip_alls}, you obtain a term with loose
   465   As said above, after calling @{ML strip_alls}, you obtain a term with loose
   466   bound variables. With the function @{ML subst_bounds}, you can replace these
   466   bound variables. With the function @{ML subst_bounds}, you can replace these
   467   loose @{ML_ind Bound in Term}s with the stripped off variables.
   467   loose @{ML_ind Bound in Term}s with the stripped off variables.
   468 
   468 
   469   @{ML_response_fake [display, gray, linenos]
   469   @{ML_response_fake [display, gray, linenos]
   550   \end{readmore}
   550   \end{readmore}
   551 
   551 
   552   When constructing terms manually, there are a few subtle issues with
   552   When constructing terms manually, there are a few subtle issues with
   553   constants. They usually crop up when pattern matching terms or types, or
   553   constants. They usually crop up when pattern matching terms or types, or
   554   when constructing them. While it is perfectly ok to write the function
   554   when constructing them. While it is perfectly ok to write the function
   555   @{text is_true} as follows
   555   \<open>is_true\<close> as follows
   556 *}
   556 \<close>
   557 
   557 
   558 ML %grayML{*fun is_true @{term True} = true
   558 ML %grayML\<open>fun is_true @{term True} = true
   559   | is_true _ = false*}
   559   | is_true _ = false\<close>
   560 
   560 
   561 text {*
   561 text \<open>
   562   this does not work for picking out @{text "\<forall>"}-quantified terms. Because
   562   this does not work for picking out \<open>\<forall>\<close>-quantified terms. Because
   563   the function 
   563   the function 
   564 *}
   564 \<close>
   565 
   565 
   566 ML %grayML{*fun is_all (@{term All} $ _) = true
   566 ML %grayML\<open>fun is_all (@{term All} $ _) = true
   567   | is_all _ = false*}
   567   | is_all _ = false\<close>
   568 
   568 
   569 text {* 
   569 text \<open>
   570   will not correctly match the formula @{prop[source] "\<forall>x::nat. P x"}: 
   570   will not correctly match the formula @{prop[source] "\<forall>x::nat. P x"}: 
   571 
   571 
   572   @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "false"}
   572   @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "false"}
   573 
   573 
   574   The problem is that the @{text "@term"}-antiquotation in the pattern 
   574   The problem is that the \<open>@term\<close>-antiquotation in the pattern 
   575   fixes the type of the constant @{term "All"} to be @{typ "('a \<Rightarrow> bool) \<Rightarrow> bool"} for 
   575   fixes the type of the constant @{term "All"} to be @{typ "('a \<Rightarrow> bool) \<Rightarrow> bool"} for 
   576   an arbitrary, but fixed type @{typ "'a"}. A properly working alternative 
   576   an arbitrary, but fixed type @{typ "'a"}. A properly working alternative 
   577   for this function is
   577   for this function is
   578 *}
   578 \<close>
   579 
   579 
   580 ML %grayML{*fun is_all (Const ("HOL.All", _) $ _) = true
   580 ML %grayML\<open>fun is_all (Const ("HOL.All", _) $ _) = true
   581   | is_all _ = false*}
   581   | is_all _ = false\<close>
   582 
   582 
   583 text {* 
   583 text \<open>
   584   because now
   584   because now
   585 
   585 
   586   @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "true"}
   586   @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "true"}
   587 
   587 
   588   matches correctly (the first wildcard in the pattern matches any type and the
   588   matches correctly (the first wildcard in the pattern matches any type and the
   589   second any term).
   589   second any term).
   590 
   590 
   591   However there is still a problem: consider the similar function that
   591   However there is still a problem: consider the similar function that
   592   attempts to pick out @{text "Nil"}-terms:
   592   attempts to pick out \<open>Nil\<close>-terms:
   593 *}
   593 \<close>
   594 
   594 
   595 ML %grayML{*fun is_nil (Const ("Nil", _)) = true
   595 ML %grayML\<open>fun is_nil (Const ("Nil", _)) = true
   596   | is_nil _ = false *}
   596   | is_nil _ = false\<close>
   597 
   597 
   598 text {* 
   598 text \<open>
   599   Unfortunately, also this function does \emph{not} work as expected, since
   599   Unfortunately, also this function does \emph{not} work as expected, since
   600 
   600 
   601   @{ML_response [display,gray] "is_nil @{term \"Nil\"}" "false"}
   601   @{ML_response [display,gray] "is_nil @{term \"Nil\"}" "false"}
   602 
   602 
   603   The problem is that on the ML-level the name of a constant is more
   603   The problem is that on the ML-level the name of a constant is more
   605   because @{term "All"} is such a fundamental constant, which can be referenced
   605   because @{term "All"} is such a fundamental constant, which can be referenced
   606   by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at
   606   by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at
   607 
   607 
   608   @{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"}
   608   @{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"}
   609 
   609 
   610   the name of the constant @{text "Nil"} depends on the theory in which the
   610   the name of the constant \<open>Nil\<close> depends on the theory in which the
   611   term constructor is defined (@{text "List"}) and also in which datatype
   611   term constructor is defined (\<open>List\<close>) and also in which datatype
   612   (@{text "list"}). Even worse, some constants have a name involving
   612   (\<open>list\<close>). Even worse, some constants have a name involving
   613   type-classes. Consider for example the constants for @{term "zero"} and
   613   type-classes. Consider for example the constants for @{term "zero"} and
   614   \mbox{@{term "times"}}:
   614   \mbox{@{term "times"}}:
   615 
   615 
   616   @{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"times\"})" 
   616   @{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"times\"})" 
   617  "(Const (\"Groups.zero_class.zero\", \<dots>), 
   617  "(Const (\"Groups.zero_class.zero\", \<dots>), 
   618  Const (\"Groups.times_class.times\", \<dots>))"}
   618  Const (\"Groups.times_class.times\", \<dots>))"}
   619 
   619 
   620   While you could use the complete name, for example 
   620   While you could use the complete name, for example 
   621   @{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or
   621   @{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or
   622   matching against @{text "Nil"}, this would make the code rather brittle. 
   622   matching against \<open>Nil\<close>, this would make the code rather brittle. 
   623   The reason is that the theory and the name of the datatype can easily change. 
   623   The reason is that the theory and the name of the datatype can easily change. 
   624   To make the code more robust, it is better to use the antiquotation 
   624   To make the code more robust, it is better to use the antiquotation 
   625   @{text "@{const_name \<dots>}"}. With this antiquotation you can harness the 
   625   \<open>@{const_name \<dots>}\<close>. With this antiquotation you can harness the 
   626   variable parts of the constant's name. Therefore a function for 
   626   variable parts of the constant's name. Therefore a function for 
   627   matching against constants that have a polymorphic type should 
   627   matching against constants that have a polymorphic type should 
   628   be written as follows.
   628   be written as follows.
   629 *}
   629 \<close>
   630 
   630 
   631 ML %grayML{*fun is_nil_or_all (Const (@{const_name "Nil"}, _)) = true
   631 ML %grayML\<open>fun is_nil_or_all (Const (@{const_name "Nil"}, _)) = true
   632   | is_nil_or_all (Const (@{const_name "All"}, _) $ _) = true
   632   | is_nil_or_all (Const (@{const_name "All"}, _) $ _) = true
   633   | is_nil_or_all _ = false *}
   633   | is_nil_or_all _ = false\<close>
   634 
   634 
   635 text {*
   635 text \<open>
   636   The antiquotation for properly referencing type constants is @{text "@{type_name \<dots>}"}.
   636   The antiquotation for properly referencing type constants is \<open>@{type_name \<dots>}\<close>.
   637   For example
   637   For example
   638 
   638 
   639   @{ML_response [display,gray]
   639   @{ML_response [display,gray]
   640   "@{type_name \"list\"}" "\"List.list\""}
   640   "@{type_name \"list\"}" "\"List.list\""}
   641 
   641 
   642   Although types of terms can often be inferred, there are many
   642   Although types of terms can often be inferred, there are many
   643   situations where you need to construct types manually, especially  
   643   situations where you need to construct types manually, especially  
   644   when defining constants. For example the function returning a function 
   644   when defining constants. For example the function returning a function 
   645   type is as follows:
   645   type is as follows:
   646 
   646 
   647 *} 
   647 \<close> 
   648 
   648 
   649 ML %grayML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
   649 ML %grayML\<open>fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2])\<close>
   650 
   650 
   651 text {* This can be equally written with the combinator @{ML_ind "-->" in Term} as: *}
   651 text \<open>This can be equally written with the combinator @{ML_ind "-->" in Term} as:\<close>
   652 
   652 
   653 ML %grayML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
   653 ML %grayML\<open>fun make_fun_type ty1 ty2 = ty1 --> ty2\<close>
   654 
   654 
   655 text {*
   655 text \<open>
   656   If you want to construct a function type with more than one argument
   656   If you want to construct a function type with more than one argument
   657   type, then you can use @{ML_ind "--->" in Term}.
   657   type, then you can use @{ML_ind "--->" in Term}.
   658 *}
   658 \<close>
   659 
   659 
   660 ML %grayML{*fun make_fun_types tys ty = tys ---> ty *}
   660 ML %grayML\<open>fun make_fun_types tys ty = tys ---> ty\<close>
   661 
   661 
   662 text {*
   662 text \<open>
   663   A handy function for manipulating terms is @{ML_ind map_types in Term}: it takes a 
   663   A handy function for manipulating terms is @{ML_ind map_types in Term}: it takes a 
   664   function and applies it to every type in a term. You can, for example,
   664   function and applies it to every type in a term. You can, for example,
   665   change every @{typ nat} in a term into an @{typ int} using the function:
   665   change every @{typ nat} in a term into an @{typ int} using the function:
   666 *}
   666 \<close>
   667 
   667 
   668 ML %grayML{*fun nat_to_int ty =
   668 ML %grayML\<open>fun nat_to_int ty =
   669   (case ty of
   669   (case ty of
   670      @{typ nat} => @{typ int}
   670      @{typ nat} => @{typ int}
   671    | Type (s, tys) => Type (s, map nat_to_int tys)
   671    | Type (s, tys) => Type (s, map nat_to_int tys)
   672    | _ => ty)*}
   672    | _ => ty)\<close>
   673 
   673 
   674 text {*
   674 text \<open>
   675   Here is an example:
   675   Here is an example:
   676 
   676 
   677 @{ML_response_fake [display,gray] 
   677 @{ML_response_fake [display,gray] 
   678 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
   678 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
   679 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
   679 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
   695   "Term.add_tfrees @{term \"(a, b)\"} []"
   695   "Term.add_tfrees @{term \"(a, b)\"} []"
   696   "[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"}
   696   "[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"}
   697 
   697 
   698   The reason for this definition is that @{ML add_tfrees in Term} can
   698   The reason for this definition is that @{ML add_tfrees in Term} can
   699   be easily folded over a list of terms. Similarly for all functions
   699   be easily folded over a list of terms. Similarly for all functions
   700   named @{text "add_*"} in @{ML_file "Pure/term.ML"}.
   700   named \<open>add_*\<close> in @{ML_file "Pure/term.ML"}.
   701 
   701 
   702   \begin{exercise}\label{fun:revsum}
   702   \begin{exercise}\label{fun:revsum}
   703   Write a function @{text "rev_sum : term -> term"} that takes a
   703   Write a function \<open>rev_sum : term -> term\<close> that takes a
   704   term of the form @{text "t\<^sub>1 + t\<^sub>2 + \<dots> + t\<^sub>n"} (whereby @{text "n"} might be one)
   704   term of the form \<open>t\<^sub>1 + t\<^sub>2 + \<dots> + t\<^sub>n\<close> (whereby \<open>n\<close> might be one)
   705   and returns the reversed sum @{text "t\<^sub>n + \<dots> + t\<^sub>2 + t\<^sub>1"}. Assume
   705   and returns the reversed sum \<open>t\<^sub>n + \<dots> + t\<^sub>2 + t\<^sub>1\<close>. Assume
   706   the @{text "t\<^sub>i"} can be arbitrary expressions and also note that @{text "+"} 
   706   the \<open>t\<^sub>i\<close> can be arbitrary expressions and also note that \<open>+\<close> 
   707   associates to the left. Try your function on some examples. 
   707   associates to the left. Try your function on some examples. 
   708   \end{exercise}
   708   \end{exercise}
   709 
   709 
   710   \begin{exercise}\label{fun:makesum}
   710   \begin{exercise}\label{fun:makesum}
   711   Write a function that takes two terms representing natural numbers
   711   Write a function that takes two terms representing natural numbers
   720   quantification @{term "y"}. Hint: use the functions @{ML incr_boundvars}
   720   quantification @{term "y"}. Hint: use the functions @{ML incr_boundvars}
   721   and @{ML loose_bvar1}.
   721   and @{ML loose_bvar1}.
   722   \end{exercise}
   722   \end{exercise}
   723 
   723 
   724   \begin{exercise}\label{fun:makelist}
   724   \begin{exercise}\label{fun:makelist}
   725   Write a function that takes an integer @{text i} and
   725   Write a function that takes an integer \<open>i\<close> and
   726   produces an Isabelle integer list from @{text 1} upto @{text i}, 
   726   produces an Isabelle integer list from \<open>1\<close> upto \<open>i\<close>, 
   727   and then builds the reverse of this list using @{const rev}. 
   727   and then builds the reverse of this list using @{const rev}. 
   728   The relevant helper functions are @{ML upto}, 
   728   The relevant helper functions are @{ML upto}, 
   729   @{ML HOLogic.mk_number} and @{ML HOLogic.mk_list}.
   729   @{ML HOLogic.mk_number} and @{ML HOLogic.mk_list}.
   730   \end{exercise}
   730   \end{exercise}
   731 
   731 
   754 
   754 
   755   Make sure you use the functions defined in @{ML_file "HOL/Tools/hologic.ML"}
   755   Make sure you use the functions defined in @{ML_file "HOL/Tools/hologic.ML"}
   756   for constructing the terms for the logical connectives.\footnote{Thanks to Roy
   756   for constructing the terms for the logical connectives.\footnote{Thanks to Roy
   757   Dyckhoff for suggesting this exercise and working out the details.} 
   757   Dyckhoff for suggesting this exercise and working out the details.} 
   758   \end{exercise}
   758   \end{exercise}
   759 *}
   759 \<close>
   760 
   760 
   761 section {* Unification and Matching\label{sec:univ} *}
   761 section \<open>Unification and Matching\label{sec:univ}\<close>
   762 
   762 
   763 text {* 
   763 text \<open>
   764   As seen earlier, Isabelle's terms and types may contain schematic term variables
   764   As seen earlier, Isabelle's terms and types may contain schematic term variables
   765   (term-constructor @{ML Var}) and schematic type variables (term-constructor
   765   (term-constructor @{ML Var}) and schematic type variables (term-constructor
   766   @{ML TVar}). These variables stand for unknown entities, which can be made
   766   @{ML TVar}). These variables stand for unknown entities, which can be made
   767   more concrete by instantiations. Such instantiations might be a result of
   767   more concrete by instantiations. Such instantiations might be a result of
   768   unification or matching. While in case of types, unification and matching is
   768   unification or matching. While in case of types, unification and matching is
   769   relatively straightforward, in case of terms the algorithms are
   769   relatively straightforward, in case of terms the algorithms are
   770   substantially more complicated, because terms need higher-order versions of
   770   substantially more complicated, because terms need higher-order versions of
   771   the unification and matching algorithms. Below we shall use the
   771   the unification and matching algorithms. Below we shall use the
   772   antiquotations @{text "@{typ_pat \<dots>}"} and @{text "@{term_pat \<dots>}"} from
   772   antiquotations \<open>@{typ_pat \<dots>}\<close> and \<open>@{term_pat \<dots>}\<close> from
   773   Section~\ref{sec:antiquote} in order to construct examples involving
   773   Section~\ref{sec:antiquote} in order to construct examples involving
   774   schematic variables.
   774   schematic variables.
   775 
   775 
   776   Let us begin with describing the unification and matching functions for
   776   Let us begin with describing the unification and matching functions for
   777   types.  Both return type environments (ML-type @{ML_type "Type.tyenv"})
   777   types.  Both return type environments (ML-type @{ML_type "Type.tyenv"})
   778   which map schematic type variables to types and sorts. Below we use the
   778   which map schematic type variables to types and sorts. Below we use the
   779   function @{ML_ind typ_unify in Sign} from the structure @{ML_struct Sign}
   779   function @{ML_ind typ_unify in Sign} from the structure @{ML_struct Sign}
   780   for unifying the types @{text "?'a * ?'b"} and @{text "?'b list *
   780   for unifying the types \<open>?'a * ?'b\<close> and \<open>?'b list *
   781   nat"}. This will produce the mapping, or type environment, @{text "[?'a :=
   781   nat\<close>. This will produce the mapping, or type environment, \<open>[?'a :=
   782   ?'b list, ?'b := nat]"}.
   782   ?'b list, ?'b := nat]\<close>.
   783 *}
   783 \<close>
   784 
   784 
   785 ML %linenosgray{*val (tyenv_unif, _) = let
   785 ML %linenosgray\<open>val (tyenv_unif, _) = let
   786   val ty1 = @{typ_pat "?'a * ?'b"}
   786   val ty1 = @{typ_pat "?'a * ?'b"}
   787   val ty2 = @{typ_pat "?'b list * nat"}
   787   val ty2 = @{typ_pat "?'b list * nat"}
   788 in
   788 in
   789   Sign.typ_unify @{theory} (ty1, ty2) (Vartab.empty, 0) 
   789   Sign.typ_unify @{theory} (ty1, ty2) (Vartab.empty, 0) 
   790 end*}
   790 end\<close>
   791 
   791 
   792 text {* 
   792 text \<open>
   793   The environment @{ML_ind "Vartab.empty"} in line 5 stands for the empty type
   793   The environment @{ML_ind "Vartab.empty"} in line 5 stands for the empty type
   794   environment, which is needed for starting the unification without any
   794   environment, which is needed for starting the unification without any
   795   (pre)instantiations. The @{text 0} is an integer index that will be explained
   795   (pre)instantiations. The \<open>0\<close> is an integer index that will be explained
   796   below. In case of failure, @{ML typ_unify in Sign} will raise the exception
   796   below. In case of failure, @{ML typ_unify in Sign} will raise the exception
   797   @{text TUNIFY}.  We can print out the resulting type environment bound to 
   797   \<open>TUNIFY\<close>.  We can print out the resulting type environment bound to 
   798   @{ML tyenv_unif} with the built-in function @{ML_ind dest in Vartab} from the
   798   @{ML tyenv_unif} with the built-in function @{ML_ind dest in Vartab} from the
   799   structure @{ML_struct Vartab}.
   799   structure @{ML_struct Vartab}.
   800 
   800 
   801   @{ML_response_fake [display,gray]
   801   @{ML_response_fake [display,gray]
   802   "Vartab.dest tyenv_unif"
   802   "Vartab.dest tyenv_unif"
   803   "[((\"'a\", 0), ([\"HOL.type\"], \"?'b List.list\")), 
   803   "[((\"'a\", 0), ([\"HOL.type\"], \"?'b List.list\")), 
   804  ((\"'b\", 0), ([\"HOL.type\"], \"nat\"))]"} 
   804  ((\"'b\", 0), ([\"HOL.type\"], \"nat\"))]"} 
   805 *}
   805 \<close>
   806 
   806 
   807 text_raw {*
   807 text_raw \<open>
   808   \begin{figure}[t]
   808   \begin{figure}[t]
   809   \begin{minipage}{\textwidth}
   809   \begin{minipage}{\textwidth}
   810   \begin{isabelle}*}
   810   \begin{isabelle}\<close>
   811 ML %grayML{*fun pretty_helper aux env =
   811 ML %grayML\<open>fun pretty_helper aux env =
   812   env |> Vartab.dest  
   812   env |> Vartab.dest  
   813       |> map aux
   813       |> map aux
   814       |> map (fn (s1, s2) => Pretty.block [s1, Pretty.str " := ", s2]) 
   814       |> map (fn (s1, s2) => Pretty.block [s1, Pretty.str " := ", s2]) 
   815       |> Pretty.enum "," "[" "]" 
   815       |> Pretty.enum "," "[" "]" 
   816       |> pwriteln
   816       |> pwriteln
   819 let
   819 let
   820   fun get_typs (v, (s, T)) = (TVar (v, s), T)
   820   fun get_typs (v, (s, T)) = (TVar (v, s), T)
   821   val print = apply2 (pretty_typ ctxt)
   821   val print = apply2 (pretty_typ ctxt)
   822 in 
   822 in 
   823   pretty_helper (print o get_typs) tyenv
   823   pretty_helper (print o get_typs) tyenv
   824 end*}
   824 end\<close>
   825 text_raw {*
   825 text_raw \<open>
   826   \end{isabelle}
   826   \end{isabelle}
   827   \end{minipage}
   827   \end{minipage}
   828   \caption{A pretty printing function for type environments, which are 
   828   \caption{A pretty printing function for type environments, which are 
   829   produced by unification and matching.\label{fig:prettyenv}}
   829   produced by unification and matching.\label{fig:prettyenv}}
   830   \end{figure}
   830   \end{figure}
   831 *}
   831 \<close>
   832 
   832 
   833 text {*
   833 text \<open>
   834   The first components in this list stand for the schematic type variables and
   834   The first components in this list stand for the schematic type variables and
   835   the second are the associated sorts and types. In this example the sort is
   835   the second are the associated sorts and types. In this example the sort is
   836   the default sort @{text "HOL.type"}. Instead of @{ML "Vartab.dest"}, we will
   836   the default sort \<open>HOL.type\<close>. Instead of @{ML "Vartab.dest"}, we will
   837   use in what follows our own pretty-printing function from
   837   use in what follows our own pretty-printing function from
   838   Figure~\ref{fig:prettyenv} for @{ML_type "Type.tyenv"}s. For the type
   838   Figure~\ref{fig:prettyenv} for @{ML_type "Type.tyenv"}s. For the type
   839   environment in the example this function prints out the more legible:
   839   environment in the example this function prints out the more legible:
   840 
   840 
   841 
   841 
   844   "[?'a := ?'b list, ?'b := nat]"}
   844   "[?'a := ?'b list, ?'b := nat]"}
   845 
   845 
   846   The way the unification function @{ML typ_unify in Sign} is implemented 
   846   The way the unification function @{ML typ_unify in Sign} is implemented 
   847   using an initial type environment and initial index makes it easy to
   847   using an initial type environment and initial index makes it easy to
   848   unify more than two terms. For example 
   848   unify more than two terms. For example 
   849 *}
   849 \<close>
   850 
   850 
   851 ML %linenosgray{*val (tyenvs, _) = let
   851 ML %linenosgray\<open>val (tyenvs, _) = let
   852   val tys1 = (@{typ_pat "?'a"}, @{typ_pat "?'b list"})
   852   val tys1 = (@{typ_pat "?'a"}, @{typ_pat "?'b list"})
   853   val tys2 = (@{typ_pat "?'b"}, @{typ_pat "nat"})
   853   val tys2 = (@{typ_pat "?'b"}, @{typ_pat "nat"})
   854 in
   854 in
   855   fold (Sign.typ_unify @{theory}) [tys1, tys2] (Vartab.empty, 0) 
   855   fold (Sign.typ_unify @{theory}) [tys1, tys2] (Vartab.empty, 0) 
   856 end*}
   856 end\<close>
   857 
   857 
   858 text {*
   858 text \<open>
   859   The index @{text 0} in Line 5 is the maximal index of the schematic type
   859   The index \<open>0\<close> in Line 5 is the maximal index of the schematic type
   860   variables occurring in @{text tys1} and @{text tys2}. This index will be
   860   variables occurring in \<open>tys1\<close> and \<open>tys2\<close>. This index will be
   861   increased whenever a new schematic type variable is introduced during
   861   increased whenever a new schematic type variable is introduced during
   862   unification.  This is for example the case when two schematic type variables
   862   unification.  This is for example the case when two schematic type variables
   863   have different, incomparable sorts. Then a new schematic type variable is
   863   have different, incomparable sorts. Then a new schematic type variable is
   864   introduced with the combined sorts. To show this let us assume two sorts,
   864   introduced with the combined sorts. To show this let us assume two sorts,
   865   say @{text "s1"} and @{text "s2"}, which we attach to the schematic type
   865   say \<open>s1\<close> and \<open>s2\<close>, which we attach to the schematic type
   866   variables @{text "?'a"} and @{text "?'b"}. Since we do not make any
   866   variables \<open>?'a\<close> and \<open>?'b\<close>. Since we do not make any
   867   assumption about the sorts, they are incomparable.
   867   assumption about the sorts, they are incomparable.
   868 *}
   868 \<close>
   869 
   869 
   870 class s1
   870 class s1
   871 class s2 
   871 class s2 
   872 
   872 
   873 ML %grayML{*val (tyenv, index) = let
   873 ML %grayML\<open>val (tyenv, index) = let
   874   val ty1 = @{typ_pat "?'a::s1"}
   874   val ty1 = @{typ_pat "?'a::s1"}
   875   val ty2 = @{typ_pat "?'b::s2"}
   875   val ty2 = @{typ_pat "?'b::s2"}
   876 in
   876 in
   877   Sign.typ_unify @{theory} (ty1, ty2) (Vartab.empty, 0) 
   877   Sign.typ_unify @{theory} (ty1, ty2) (Vartab.empty, 0) 
   878 end*}
   878 end\<close>
   879 
   879 
   880 text {*
   880 text \<open>
   881   To print out the result type environment we switch on the printing 
   881   To print out the result type environment we switch on the printing 
   882   of sort information by setting @{ML_ind show_sorts in Syntax} to 
   882   of sort information by setting @{ML_ind show_sorts in Syntax} to 
   883   true. This allows us to inspect the typing environment.
   883   true. This allows us to inspect the typing environment.
   884 
   884 
   885   @{ML_response_fake [display,gray]
   885   @{ML_response_fake [display,gray]
   886   "pretty_tyenv @{context} tyenv"
   886   "pretty_tyenv @{context} tyenv"
   887   "[?'a::s1 := ?'a1::{s1, s2}, ?'b::s2 := ?'a1::{s1, s2}]"}
   887   "[?'a::s1 := ?'a1::{s1, s2}, ?'b::s2 := ?'a1::{s1, s2}]"}
   888 
   888 
   889   As can be seen, the type variables @{text "?'a"} and @{text "?'b"} are instantiated
   889   As can be seen, the type variables \<open>?'a\<close> and \<open>?'b\<close> are instantiated
   890   with a new type variable @{text "?'a1"} with sort @{text "{s1, s2}"}. Since a new
   890   with a new type variable \<open>?'a1\<close> with sort \<open>{s1, s2}\<close>. Since a new
   891   type variable has been introduced the @{ML index}, originally being @{text 0}, 
   891   type variable has been introduced the @{ML index}, originally being \<open>0\<close>, 
   892   has been increased to @{text 1}.
   892   has been increased to \<open>1\<close>.
   893 
   893 
   894   @{ML_response [display,gray]
   894   @{ML_response [display,gray]
   895   "index"
   895   "index"
   896   "1"}
   896   "1"}
   897 
   897 
   898   Let us now return to the unification problem @{text "?'a * ?'b"} and 
   898   Let us now return to the unification problem \<open>?'a * ?'b\<close> and 
   899   @{text "?'b list * nat"} from the beginning of this section, and the 
   899   \<open>?'b list * nat\<close> from the beginning of this section, and the 
   900   calculated type environment @{ML tyenv_unif}:
   900   calculated type environment @{ML tyenv_unif}:
   901 
   901 
   902   @{ML_response_fake [display, gray]
   902   @{ML_response_fake [display, gray]
   903   "pretty_tyenv @{context} tyenv_unif"
   903   "pretty_tyenv @{context} tyenv_unif"
   904   "[?'a := ?'b list, ?'b := nat]"}
   904   "[?'a := ?'b list, ?'b := nat]"}
   905 
   905 
   906   Observe that the type environment which the function @{ML typ_unify in
   906   Observe that the type environment which the function @{ML typ_unify in
   907   Sign} returns is \emph{not} an instantiation in fully solved form: while @{text
   907   Sign} returns is \emph{not} an instantiation in fully solved form: while \<open>?'b\<close> is instantiated to @{typ nat}, this is not propagated to the
   908   "?'b"} is instantiated to @{typ nat}, this is not propagated to the
   908   instantiation for \<open>?'a\<close>.  In unification theory, this is often
   909   instantiation for @{text "?'a"}.  In unification theory, this is often
       
   910   called an instantiation in \emph{triangular form}. These triangular 
   909   called an instantiation in \emph{triangular form}. These triangular 
   911   instantiations, or triangular type environments, are used because of 
   910   instantiations, or triangular type environments, are used because of 
   912   performance reasons. To apply such a type environment to a type, say @{text "?'a *
   911   performance reasons. To apply such a type environment to a type, say \<open>?'a *
   913   ?'b"}, you should use the function @{ML_ind norm_type in Envir}:
   912   ?'b\<close>, you should use the function @{ML_ind norm_type in Envir}:
   914 
   913 
   915   @{ML_response_fake [display, gray]
   914   @{ML_response_fake [display, gray]
   916   "Envir.norm_type tyenv_unif @{typ_pat \"?'a * ?'b\"}"
   915   "Envir.norm_type tyenv_unif @{typ_pat \"?'a * ?'b\"}"
   917   "nat list * nat"}
   916   "nat list * nat"}
   918 
   917 
   919   Matching of types can be done with the function @{ML_ind typ_match in Sign}
   918   Matching of types can be done with the function @{ML_ind typ_match in Sign}
   920   also from the structure @{ML_struct Sign}. This function returns a @{ML_type
   919   also from the structure @{ML_struct Sign}. This function returns a @{ML_type
   921   Type.tyenv} as well, but might raise the exception @{text TYPE_MATCH} in case
   920   Type.tyenv} as well, but might raise the exception \<open>TYPE_MATCH\<close> in case
   922   of failure. For example
   921   of failure. For example
   923 *}
   922 \<close>
   924 
   923 
   925 ML %grayML{*val tyenv_match = let
   924 ML %grayML\<open>val tyenv_match = let
   926   val pat = @{typ_pat "?'a * ?'b"}
   925   val pat = @{typ_pat "?'a * ?'b"}
   927   and ty  = @{typ_pat "bool list * nat"}
   926   and ty  = @{typ_pat "bool list * nat"}
   928 in
   927 in
   929   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
   928   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
   930 end*}
   929 end\<close>
   931 
   930 
   932 text {*
   931 text \<open>
   933   Printing out the calculated matcher gives
   932   Printing out the calculated matcher gives
   934 
   933 
   935   @{ML_response_fake [display,gray]
   934   @{ML_response_fake [display,gray]
   936   "pretty_tyenv @{context} tyenv_match"
   935   "pretty_tyenv @{context} tyenv_match"
   937   "[?'a := bool list, ?'b := nat]"}
   936   "[?'a := bool list, ?'b := nat]"}
   946 
   945 
   947   Be careful to observe the difference: always use
   946   Be careful to observe the difference: always use
   948   @{ML subst_type in Envir} for matchers and @{ML norm_type in Envir} 
   947   @{ML subst_type in Envir} for matchers and @{ML norm_type in Envir} 
   949   for unifiers. To show the difference, let us calculate the 
   948   for unifiers. To show the difference, let us calculate the 
   950   following matcher:
   949   following matcher:
   951 *}
   950 \<close>
   952 
   951 
   953 ML %grayML{*val tyenv_match' = let
   952 ML %grayML\<open>val tyenv_match' = let
   954   val pat = @{typ_pat "?'a * ?'b"}
   953   val pat = @{typ_pat "?'a * ?'b"}
   955   and ty  = @{typ_pat "?'b list * nat"}
   954   and ty  = @{typ_pat "?'b list * nat"}
   956 in
   955 in
   957   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
   956   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
   958 end*}
   957 end\<close>
   959 
   958 
   960 text {*
   959 text \<open>
   961   Now @{ML tyenv_unif} is equal to @{ML tyenv_match'}. If we apply 
   960   Now @{ML tyenv_unif} is equal to @{ML tyenv_match'}. If we apply 
   962   @{ML norm_type in Envir} to the type @{text "?'a * ?'b"} we obtain
   961   @{ML norm_type in Envir} to the type \<open>?'a * ?'b\<close> we obtain
   963 
   962 
   964   @{ML_response_fake [display, gray]
   963   @{ML_response_fake [display, gray]
   965   "Envir.norm_type tyenv_match' @{typ_pat \"?'a * ?'b\"}"
   964   "Envir.norm_type tyenv_match' @{typ_pat \"?'a * ?'b\"}"
   966   "nat list * nat"}
   965   "nat list * nat"}
   967 
   966 
   981   as results. These are implemented in @{ML_file "Pure/envir.ML"}.
   980   as results. These are implemented in @{ML_file "Pure/envir.ML"}.
   982   This file also includes the substitution and normalisation functions,
   981   This file also includes the substitution and normalisation functions,
   983   which apply a type environment to a type. Type environments are lookup 
   982   which apply a type environment to a type. Type environments are lookup 
   984   tables which are implemented in @{ML_file "Pure/term_ord.ML"}.
   983   tables which are implemented in @{ML_file "Pure/term_ord.ML"}.
   985   \end{readmore}
   984   \end{readmore}
   986 *}
   985 \<close>
   987 
   986 
   988 text {*
   987 text \<open>
   989   Unification and matching of terms is substantially more complicated than the
   988   Unification and matching of terms is substantially more complicated than the
   990   type-case. The reason is that terms have abstractions and, in this context,  
   989   type-case. The reason is that terms have abstractions and, in this context,  
   991   unification or matching modulo plain equality is often not meaningful. 
   990   unification or matching modulo plain equality is often not meaningful. 
   992   Nevertheless, Isabelle implements the function @{ML_ind
   991   Nevertheless, Isabelle implements the function @{ML_ind
   993   first_order_match in Pattern} for terms.  This matching function returns a
   992   first_order_match in Pattern} for terms.  This matching function returns a
   994   type environment and a term environment.  To pretty print the latter we use
   993   type environment and a term environment.  To pretty print the latter we use
   995   the function @{text "pretty_env"}:
   994   the function \<open>pretty_env\<close>:
   996 *}
   995 \<close>
   997 
   996 
   998 ML %grayML{*fun pretty_env ctxt env =
   997 ML %grayML\<open>fun pretty_env ctxt env =
   999 let
   998 let
  1000   fun get_trms (v, (T, t)) = (Var (v, T), t) 
   999   fun get_trms (v, (T, t)) = (Var (v, T), t) 
  1001   val print = apply2 (pretty_term ctxt)
  1000   val print = apply2 (pretty_term ctxt)
  1002 in
  1001 in
  1003   pretty_helper (print o get_trms) env 
  1002   pretty_helper (print o get_trms) env 
  1004 end*}
  1003 end\<close>
  1005 
  1004 
  1006 text {*
  1005 text \<open>
  1007   As can be seen from the @{text "get_trms"}-function, a term environment associates 
  1006   As can be seen from the \<open>get_trms\<close>-function, a term environment associates 
  1008   a schematic term variable with a type and a term.  An example of a first-order 
  1007   a schematic term variable with a type and a term.  An example of a first-order 
  1009   matching problem is the term @{term "P (\<lambda>a b. Q b a)"} and the pattern 
  1008   matching problem is the term @{term "P (\<lambda>a b. Q b a)"} and the pattern 
  1010   @{text "?X ?Y"}.
  1009   \<open>?X ?Y\<close>.
  1011 *}
  1010 \<close>
  1012 
  1011 
  1013 ML %grayML{*val (_, fo_env) = let
  1012 ML %grayML\<open>val (_, fo_env) = let
  1014   val fo_pat = @{term_pat "(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y"}
  1013   val fo_pat = @{term_pat "(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y"}
  1015   val trm_a = @{term "P::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool"} 
  1014   val trm_a = @{term "P::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool"} 
  1016   val trm_b = @{term "\<lambda>a b. (Q::nat\<Rightarrow>nat\<Rightarrow>nat) b a"}
  1015   val trm_b = @{term "\<lambda>a b. (Q::nat\<Rightarrow>nat\<Rightarrow>nat) b a"}
  1017   val init = (Vartab.empty, Vartab.empty) 
  1016   val init = (Vartab.empty, Vartab.empty) 
  1018 in
  1017 in
  1019   Pattern.first_order_match @{theory} (fo_pat, trm_a $ trm_b) init
  1018   Pattern.first_order_match @{theory} (fo_pat, trm_a $ trm_b) init
  1020 end *}
  1019 end\<close>
  1021 
  1020 
  1022 text {*
  1021 text \<open>
  1023   In this example we annotated types explicitly because then 
  1022   In this example we annotated types explicitly because then 
  1024   the type environment is empty and can be ignored. The 
  1023   the type environment is empty and can be ignored. The 
  1025   resulting term environment is
  1024   resulting term environment is
  1026 
  1025 
  1027   @{ML_response_fake [display, gray]
  1026   @{ML_response_fake [display, gray]
  1046 
  1045 
  1047   First-order matching is useful for matching against applications and
  1046   First-order matching is useful for matching against applications and
  1048   variables. It can also deal with abstractions and a limited form of
  1047   variables. It can also deal with abstractions and a limited form of
  1049   alpha-equivalence, but this kind of matching should be used with care, since
  1048   alpha-equivalence, but this kind of matching should be used with care, since
  1050   it is not clear whether the result is meaningful. A meaningful example is
  1049   it is not clear whether the result is meaningful. A meaningful example is
  1051   matching @{text "\<lambda>x. P x"} against the pattern @{text "\<lambda>y. ?X y"}. In this
  1050   matching \<open>\<lambda>x. P x\<close> against the pattern \<open>\<lambda>y. ?X y\<close>. In this
  1052   case, first-order matching produces @{text "[?X := P]"}.
  1051   case, first-order matching produces \<open>[?X := P]\<close>.
  1053 
  1052 
  1054   @{ML_response_fake [display, gray]
  1053   @{ML_response_fake [display, gray]
  1055   "let
  1054   "let
  1056   val fo_pat = @{term_pat \"\<lambda>y. (?X::nat\<Rightarrow>bool) y\"}
  1055   val fo_pat = @{term_pat \"\<lambda>y. (?X::nat\<Rightarrow>bool) y\"}
  1057   val trm = @{term \"\<lambda>x. (P::nat\<Rightarrow>bool) x\"} 
  1056   val trm = @{term \"\<lambda>x. (P::nat\<Rightarrow>bool) x\"} 
  1060   Pattern.first_order_match @{theory} (fo_pat, trm) init
  1059   Pattern.first_order_match @{theory} (fo_pat, trm) init
  1061   |> snd 
  1060   |> snd 
  1062   |> pretty_env @{context} 
  1061   |> pretty_env @{context} 
  1063 end"
  1062 end"
  1064   "[?X := P]"}
  1063   "[?X := P]"}
  1065 *}
  1064 \<close>
  1066 
  1065 
  1067 text {*
  1066 text \<open>
  1068   Unification of abstractions is more thoroughly studied in the context of
  1067   Unification of abstractions is more thoroughly studied in the context of
  1069   higher-order pattern unification and higher-order pattern matching.  A
  1068   higher-order pattern unification and higher-order pattern matching.  A
  1070   \emph{\index*{pattern}} is a well-formed term in which the arguments to
  1069   \emph{\index*{pattern}} is a well-formed term in which the arguments to
  1071   every schematic variable are distinct bounds.
  1070   every schematic variable are distinct bounds.
  1072   In particular this excludes terms where a
  1071   In particular this excludes terms where a
  1112   pretty_env @{context} (Envir.term_env env)
  1111   pretty_env @{context} (Envir.term_env env)
  1113 end"
  1112 end"
  1114   "[?X := \<lambda>y x. x, ?Y := \<lambda>x. x]"}
  1113   "[?X := \<lambda>y x. x, ?Y := \<lambda>x. x]"}
  1115 
  1114 
  1116   The function @{ML_ind "Envir.empty"} generates a record with a specified
  1115   The function @{ML_ind "Envir.empty"} generates a record with a specified
  1117   max-index for the schematic variables (in the example the index is @{text
  1116   max-index for the schematic variables (in the example the index is \<open>0\<close>) and empty type and term environments. The function @{ML_ind
  1118   0}) and empty type and term environments. The function @{ML_ind
       
  1119   "Envir.term_env"} pulls out the term environment from the result record. The
  1117   "Envir.term_env"} pulls out the term environment from the result record. The
  1120   corresponding function for type environment is @{ML_ind
  1118   corresponding function for type environment is @{ML_ind
  1121   "Envir.type_env"}. An assumption of this function is that the terms to be
  1119   "Envir.type_env"}. An assumption of this function is that the terms to be
  1122   unified have already the same type. In case of failure, the exceptions that
  1120   unified have already the same type. In case of failure, the exceptions that
  1123   are raised are either @{text Pattern}, @{text MATCH} or @{text Unif}.
  1121   are raised are either \<open>Pattern\<close>, \<open>MATCH\<close> or \<open>Unif\<close>.
  1124 
  1122 
  1125   As mentioned before, unrestricted higher-order unification, respectively
  1123   As mentioned before, unrestricted higher-order unification, respectively
  1126   unrestricted higher-order matching, is in general undecidable and might also
  1124   unrestricted higher-order matching, is in general undecidable and might also
  1127   not possess a single most general solution. Therefore Isabelle implements the
  1125   not possess a single most general solution. Therefore Isabelle implements the
  1128   unification function @{ML_ind unifiers in Unify} so that it returns a lazy
  1126   unification function @{ML_ind unifiers in Unify} so that it returns a lazy
  1129   list of potentially infinite unifiers.  An example is as follows
  1127   list of potentially infinite unifiers.  An example is as follows
  1130 *}
  1128 \<close>
  1131 
  1129 
  1132 ML %grayML{*val uni_seq =
  1130 ML %grayML\<open>val uni_seq =
  1133 let 
  1131 let 
  1134   val trm1 = @{term_pat "?X ?Y"}
  1132   val trm1 = @{term_pat "?X ?Y"}
  1135   val trm2 = @{term "f a"}
  1133   val trm2 = @{term "f a"}
  1136   val init = Envir.empty 0
  1134   val init = Envir.empty 0
  1137 in
  1135 in
  1138   Unify.unifiers (Context.Proof @{context}, init, [(trm1, trm2)])
  1136   Unify.unifiers (Context.Proof @{context}, init, [(trm1, trm2)])
  1139 end *}
  1137 end\<close>
  1140 
  1138 
  1141 text {*
  1139 text \<open>
  1142   The unifiers can be extracted from the lazy sequence using the 
  1140   The unifiers can be extracted from the lazy sequence using the 
  1143   function @{ML_ind "Seq.pull"}. In the example we obtain three 
  1141   function @{ML_ind "Seq.pull"}. In the example we obtain three 
  1144   unifiers @{text "un1\<dots>un3"}.
  1142   unifiers \<open>un1\<dots>un3\<close>.
  1145 *}
  1143 \<close>
  1146 
  1144 
  1147 ML %grayML{*val SOME ((un1, _), next1) = Seq.pull uni_seq;
  1145 ML %grayML\<open>val SOME ((un1, _), next1) = Seq.pull uni_seq;
  1148 val SOME ((un2, _), next2) = Seq.pull next1;
  1146 val SOME ((un2, _), next2) = Seq.pull next1;
  1149 val SOME ((un3, _), next3) = Seq.pull next2;
  1147 val SOME ((un3, _), next3) = Seq.pull next2;
  1150 val NONE = Seq.pull next3 *}
  1148 val NONE = Seq.pull next3\<close>
  1151 
  1149 
  1152 text {*
  1150 text \<open>
  1153   \footnote{\bf FIXME: what is the list of term pairs in the unifier: flex-flex pairs?}
  1151   \footnote{\bf FIXME: what is the list of term pairs in the unifier: flex-flex pairs?}
  1154 
  1152 
  1155   We can print them out as follows.
  1153   We can print them out as follows.
  1156 
  1154 
  1157   @{ML_response_fake [display, gray]
  1155   @{ML_response_fake [display, gray]
  1205   Here we only have a look at a simple case, namely the theorem 
  1203   Here we only have a look at a simple case, namely the theorem 
  1206   @{thm [source] spec}:
  1204   @{thm [source] spec}:
  1207 
  1205 
  1208   \begin{isabelle}
  1206   \begin{isabelle}
  1209   \isacommand{thm}~@{thm [source] spec}\\
  1207   \isacommand{thm}~@{thm [source] spec}\\
  1210   @{text "> "}~@{thm spec}
  1208   \<open>> \<close>~@{thm spec}
  1211   \end{isabelle}
  1209   \end{isabelle}
  1212 
  1210 
  1213   as an introduction rule. Applying it directly can lead to unexpected
  1211   as an introduction rule. Applying it directly can lead to unexpected
  1214   behaviour since the unification has more than one solution. One way round
  1212   behaviour since the unification has more than one solution. One way round
  1215   this problem is to instantiate the schematic variables @{text "?P"} and
  1213   this problem is to instantiate the schematic variables \<open>?P\<close> and
  1216   @{text "?x"}.  Instantiation function for theorems is 
  1214   \<open>?x\<close>.  Instantiation function for theorems is 
  1217   @{ML_ind instantiate_normalize in Drule} from the structure 
  1215   @{ML_ind instantiate_normalize in Drule} from the structure 
  1218   @{ML_struct Drule}. One problem, however, is
  1216   @{ML_struct Drule}. One problem, however, is
  1219   that this function expects the instantiations as lists of @{ML_type "((indexname * sort) * ctyp)"}
  1217   that this function expects the instantiations as lists of @{ML_type "((indexname * sort) * ctyp)"}
  1220   respective @{ML_type "(indexname * typ) * cterm"}:
  1218   respective @{ML_type "(indexname * typ) * cterm"}:
  1221 
  1219 
  1222   \begin{isabelle}
  1220   \begin{isabelle}
  1223   @{ML instantiate_normalize in Drule}@{text ":"}
  1221   @{ML instantiate_normalize in Drule}\<open>:\<close>
  1224   @{ML_type "((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list -> thm -> thm"}
  1222   @{ML_type "((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list -> thm -> thm"}
  1225   \end{isabelle}
  1223   \end{isabelle}
  1226 
  1224 
  1227   This means we have to transform the environment the higher-order matching 
  1225   This means we have to transform the environment the higher-order matching 
  1228   function returns into such an instantiation. For this we use the functions
  1226   function returns into such an instantiation. For this we use the functions
  1229   @{ML_ind term_env in Envir} and @{ML_ind type_env in Envir}, which extract
  1227   @{ML_ind term_env in Envir} and @{ML_ind type_env in Envir}, which extract
  1230   from an environment the corresponding variable mappings for schematic type 
  1228   from an environment the corresponding variable mappings for schematic type 
  1231   and term variables. These mappings can be turned into proper 
  1229   and term variables. These mappings can be turned into proper 
  1232   @{ML_type ctyp}-pairs with the function
  1230   @{ML_type ctyp}-pairs with the function
  1233 *}
  1231 \<close>
  1234 
  1232 
  1235 ML %grayML{*fun prep_trm ctxt (x, (T, t)) = 
  1233 ML %grayML\<open>fun prep_trm ctxt (x, (T, t)) = 
  1236   ((x, T), Thm.cterm_of ctxt t)*} 
  1234   ((x, T), Thm.cterm_of ctxt t)\<close> 
  1237 
  1235 
  1238 text {*
  1236 text \<open>
  1239   and into proper @{ML_type cterm}-pairs with
  1237   and into proper @{ML_type cterm}-pairs with
  1240 *}
  1238 \<close>
  1241 
  1239 
  1242 ML %grayML{*fun prep_ty ctxt (x, (S, ty)) = 
  1240 ML %grayML\<open>fun prep_ty ctxt (x, (S, ty)) = 
  1243   ((x, S), Thm.ctyp_of ctxt ty)*}
  1241   ((x, S), Thm.ctyp_of ctxt ty)\<close>
  1244 
  1242 
  1245 text {*
  1243 text \<open>
  1246   We can now calculate the instantiations from the matching function. 
  1244   We can now calculate the instantiations from the matching function. 
  1247 *}
  1245 \<close>
  1248 
  1246 
  1249 ML %linenosgray{*fun matcher_inst ctxt pat trm i = 
  1247 ML %linenosgray\<open>fun matcher_inst ctxt pat trm i = 
  1250 let
  1248 let
  1251   val univ = Unify.matchers (Context.Proof ctxt) [(pat, trm)] 
  1249   val univ = Unify.matchers (Context.Proof ctxt) [(pat, trm)] 
  1252   val env = nth (Seq.list_of univ) i
  1250   val env = nth (Seq.list_of univ) i
  1253   val tenv = Vartab.dest (Envir.term_env env)
  1251   val tenv = Vartab.dest (Envir.term_env env)
  1254   val tyenv = Vartab.dest (Envir.type_env env)
  1252   val tyenv = Vartab.dest (Envir.type_env env)
  1255 in
  1253 in
  1256   (map (prep_ty ctxt) tyenv, map (prep_trm ctxt) tenv)
  1254   (map (prep_ty ctxt) tyenv, map (prep_trm ctxt) tenv)
  1257 end*}
  1255 end\<close>
  1258 
  1256 
  1259 ML \<open>Context.get_generic_context\<close>
  1257 ML \<open>Context.get_generic_context\<close>
  1260 text {*
  1258 text \<open>
  1261   In Line 3 we obtain the higher-order matcher. We assume there is a finite
  1259   In Line 3 we obtain the higher-order matcher. We assume there is a finite
  1262   number of them and select the one we are interested in via the parameter 
  1260   number of them and select the one we are interested in via the parameter 
  1263   @{text i} in the next line. In Lines 5 and 6 we destruct the resulting 
  1261   \<open>i\<close> in the next line. In Lines 5 and 6 we destruct the resulting 
  1264   environments using the function @{ML_ind dest in Vartab}. Finally, we need 
  1262   environments using the function @{ML_ind dest in Vartab}. Finally, we need 
  1265   to map the functions @{ML prep_trm} and @{ML prep_ty} over the respective 
  1263   to map the functions @{ML prep_trm} and @{ML prep_ty} over the respective 
  1266   environments (Line 8). As a simple example we instantiate the
  1264   environments (Line 8). As a simple example we instantiate the
  1267   @{thm [source] spec} rule so that its conclusion is of the form 
  1265   @{thm [source] spec} rule so that its conclusion is of the form 
  1268   @{term "Q True"}. 
  1266   @{term "Q True"}. 
  1276 in
  1274 in
  1277   Drule.instantiate_normalize inst @{thm spec}
  1275   Drule.instantiate_normalize inst @{thm spec}
  1278 end"
  1276 end"
  1279   "\<forall>x. Q x \<Longrightarrow> Q True"}
  1277   "\<forall>x. Q x \<Longrightarrow> Q True"}
  1280 
  1278 
  1281   Note that we had to insert a @{text "Trueprop"}-coercion in Line 3 since the 
  1279   Note that we had to insert a \<open>Trueprop\<close>-coercion in Line 3 since the 
  1282   conclusion of @{thm [source] spec} contains one.
  1280   conclusion of @{thm [source] spec} contains one.
  1283  
  1281  
  1284   \begin{readmore}
  1282   \begin{readmore}
  1285   Unification and matching of higher-order patterns is implemented in 
  1283   Unification and matching of higher-order patterns is implemented in 
  1286   @{ML_file "Pure/pattern.ML"}. This file also contains a first-order matcher
  1284   @{ML_file "Pure/pattern.ML"}. This file also contains a first-order matcher
  1287   for terms. Full higher-order unification is implemented
  1285   for terms. Full higher-order unification is implemented
  1288   in @{ML_file "Pure/unify.ML"}. It uses lazy sequences which are implemented
  1286   in @{ML_file "Pure/unify.ML"}. It uses lazy sequences which are implemented
  1289   in @{ML_file "Pure/General/seq.ML"}.
  1287   in @{ML_file "Pure/General/seq.ML"}.
  1290   \end{readmore}
  1288   \end{readmore}
  1291 *}
  1289 \<close>
  1292 
  1290 
  1293 section {* Sorts (TBD)\label{sec:sorts} *}
  1291 section \<open>Sorts (TBD)\label{sec:sorts}\<close>
  1294 
  1292 
  1295 text {*
  1293 text \<open>
  1296   Type classes are formal names in the type system which are linked to
  1294   Type classes are formal names in the type system which are linked to
  1297   predicates of one type variable (via the axclass mechanism) and thereby
  1295   predicates of one type variable (via the axclass mechanism) and thereby
  1298   express extra properties on types, to be propagated by the type system.
  1296   express extra properties on types, to be propagated by the type system.
  1299   The type-in-class judgement is defined
  1297   The type-in-class judgement is defined
  1300   via a simple logic over types, with inferences solely based on
  1298   via a simple logic over types, with inferences solely based on
  1318   inhabited by all types and is called the topsort.
  1316   inhabited by all types and is called the topsort.
  1319 
  1317 
  1320   Free and schematic type variables are always annotated with sorts, thereby restricting
  1318   Free and schematic type variables are always annotated with sorts, thereby restricting
  1321   the domain of types they quantify over and corresponding to an implicit hypothesis
  1319   the domain of types they quantify over and corresponding to an implicit hypothesis
  1322   about the type variable.
  1320   about the type variable.
  1323 *}
  1321 \<close>
  1324 
  1322 
  1325 
  1323 
  1326 ML {* Sign.classes_of @{theory} *}
  1324 ML \<open>Sign.classes_of @{theory}\<close>
  1327 
  1325 
  1328 ML {* Sign.of_sort @{theory} *}
  1326 ML \<open>Sign.of_sort @{theory}\<close>
  1329 
  1327 
  1330 text {*
  1328 text \<open>
  1331   \begin{readmore}
  1329   \begin{readmore}
  1332   Classes, sorts and arities are defined in @{ML_file "Pure/term.ML"}.
  1330   Classes, sorts and arities are defined in @{ML_file "Pure/term.ML"}.
  1333   
  1331   
  1334   @{ML_file "Pure/sorts.ML"} contains comparison and normalization functionality for sorts,
  1332   @{ML_file "Pure/sorts.ML"} contains comparison and normalization functionality for sorts,
  1335     manages the order sorted algebra and offers an interface for reinterpreting
  1333     manages the order sorted algebra and offers an interface for reinterpreting
  1342     (especially names, constants, paths, type classes) a
  1340     (especially names, constants, paths, type classes) a
  1343     theory acquires by theory extension mechanisms and manages associated certification
  1341     theory acquires by theory extension mechanisms and manages associated certification
  1344     functionality.
  1342     functionality.
  1345     It also provides the most needed functionality from individual underlying modules.
  1343     It also provides the most needed functionality from individual underlying modules.
  1346   \end{readmore}
  1344   \end{readmore}
  1347 *}
  1345 \<close>
  1348 
  1346 
  1349 
  1347 
  1350 section {* Type-Checking\label{sec:typechecking} *}
  1348 section \<open>Type-Checking\label{sec:typechecking}\<close>
  1351 
  1349 
  1352 text {* 
  1350 text \<open>
  1353   Remember Isabelle follows the Church-style typing for terms, i.e.\ a term contains 
  1351   Remember Isabelle follows the Church-style typing for terms, i.e.\ a term contains 
  1354   enough typing information (constants, free variables and abstractions all have typing 
  1352   enough typing information (constants, free variables and abstractions all have typing 
  1355   information) so that it is always clear what the type of a term is. 
  1353   information) so that it is always clear what the type of a term is. 
  1356   Given a well-typed term, the function @{ML_ind type_of in Term} returns the 
  1354   Given a well-typed term, the function @{ML_ind type_of in Term} returns the 
  1357   type of a term. Consider for example:
  1355   type of a term. Consider for example:
  1398   Syntax.check_term @{context} (c $ o $ v)
  1396   Syntax.check_term @{context} (c $ o $ v)
  1399 end"
  1397 end"
  1400 "Const (\"HOL.plus_class.plus\", \"nat \<Rightarrow> nat \<Rightarrow> nat\") $
  1398 "Const (\"HOL.plus_class.plus\", \"nat \<Rightarrow> nat \<Rightarrow> nat\") $
  1401   Const (\"HOL.one_class.one\", \"nat\") $ Free (\"x\", \"nat\")"}
  1399   Const (\"HOL.one_class.one\", \"nat\") $ Free (\"x\", \"nat\")"}
  1402 
  1400 
  1403   Instead of giving explicitly the type for the constant @{text "plus"} and the free 
  1401   Instead of giving explicitly the type for the constant \<open>plus\<close> and the free 
  1404   variable @{text "x"}, type-inference fills in the missing information.
  1402   variable \<open>x\<close>, type-inference fills in the missing information.
  1405 
  1403 
  1406   \begin{readmore}
  1404   \begin{readmore}
  1407   See @{ML_file "Pure/Syntax/syntax.ML"} where more functions about reading,
  1405   See @{ML_file "Pure/Syntax/syntax.ML"} where more functions about reading,
  1408   checking and pretty-printing of terms are defined. Functions related to
  1406   checking and pretty-printing of terms are defined. Functions related to
  1409   type-inference are implemented in @{ML_file "Pure/type.ML"} and 
  1407   type-inference are implemented in @{ML_file "Pure/type.ML"} and 
  1415   Check that the function defined in Exercise~\ref{fun:revsum} returns a
  1413   Check that the function defined in Exercise~\ref{fun:revsum} returns a
  1416   result that type-checks. See what happens to the  solutions of this 
  1414   result that type-checks. See what happens to the  solutions of this 
  1417   exercise given in Appendix \ref{ch:solutions} when they receive an 
  1415   exercise given in Appendix \ref{ch:solutions} when they receive an 
  1418   ill-typed term as input.
  1416   ill-typed term as input.
  1419   \end{exercise}
  1417   \end{exercise}
  1420 *}
  1418 \<close>
  1421 
  1419 
  1422 section {* Certified Terms and Certified Types *}
  1420 section \<open>Certified Terms and Certified Types\<close>
  1423 
  1421 
  1424 text {*
  1422 text \<open>
  1425   You can freely construct and manipulate @{ML_type "term"}s and @{ML_type
  1423   You can freely construct and manipulate @{ML_type "term"}s and @{ML_type
  1426   typ}es, since they are just arbitrary unchecked trees. However, you
  1424   typ}es, since they are just arbitrary unchecked trees. However, you
  1427   eventually want to see if a term is well-formed, or type-checks, relative to
  1425   eventually want to see if a term is well-formed, or type-checks, relative to
  1428   a theory.  Type-checking is done via the function @{ML_ind cterm_of in Thm}, which
  1426   a theory.  Type-checking is done via the function @{ML_ind cterm_of in Thm}, which
  1429   converts a @{ML_type term} into a @{ML_type cterm}, a \emph{certified}
  1427   converts a @{ML_type term} into a @{ML_type cterm}, a \emph{certified}
  1500   \begin{readmore}
  1498   \begin{readmore}
  1501   For functions related to @{ML_type cterm}s and @{ML_type ctyp}s see 
  1499   For functions related to @{ML_type cterm}s and @{ML_type ctyp}s see 
  1502   the files @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and
  1500   the files @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and
  1503   @{ML_file "Pure/drule.ML"}.
  1501   @{ML_file "Pure/drule.ML"}.
  1504   \end{readmore}
  1502   \end{readmore}
  1505 *}
  1503 \<close>
  1506 
  1504 
  1507 section {* Theorems\label{sec:theorems} *}
  1505 section \<open>Theorems\label{sec:theorems}\<close>
  1508 
  1506 
  1509 text {*
  1507 text \<open>
  1510   Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} 
  1508   Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} 
  1511   that can only be built by going through interfaces. As a consequence, every proof 
  1509   that can only be built by going through interfaces. As a consequence, every proof 
  1512   in Isabelle is correct by construction. This follows the tradition of the LCF-approach.
  1510   in Isabelle is correct by construction. This follows the tradition of the LCF-approach.
  1513 
  1511 
  1514 
  1512 
  1515   To see theorems in ``action'', let us give a proof on the ML-level for the following 
  1513   To see theorems in ``action'', let us give a proof on the ML-level for the following 
  1516   statement:
  1514   statement:
  1517 *}
  1515 \<close>
  1518 
  1516 
  1519   lemma 
  1517   lemma 
  1520     assumes assm\<^sub>1: "\<And>(x::nat). P x \<Longrightarrow> Q x" 
  1518     assumes assm\<^sub>1: "\<And>(x::nat). P x \<Longrightarrow> Q x" 
  1521     and     assm\<^sub>2: "P t"
  1519     and     assm\<^sub>2: "P t"
  1522     shows "Q t"(*<*)oops(*>*) 
  1520     shows "Q t"(*<*)oops(*>*) 
  1523 
  1521 
  1524 text {*
  1522 text \<open>
  1525   The corresponding ML-code is as follows:
  1523   The corresponding ML-code is as follows:
  1526 *}
  1524 \<close>
  1527 
  1525 
  1528 ML %linenosgray{*val my_thm = 
  1526 ML %linenosgray\<open>val my_thm = 
  1529 let
  1527 let
  1530   val assm1 = @{cprop "\<And>(x::nat). P x \<Longrightarrow> Q x"}
  1528   val assm1 = @{cprop "\<And>(x::nat). P x \<Longrightarrow> Q x"}
  1531   val assm2 = @{cprop "(P::nat \<Rightarrow> bool) t"}
  1529   val assm2 = @{cprop "(P::nat \<Rightarrow> bool) t"}
  1532 
  1530 
  1533   val Pt_implies_Qt = 
  1531   val Pt_implies_Qt = 
  1537   val Qt = Thm.implies_elim Pt_implies_Qt (Thm.assume assm2)
  1535   val Qt = Thm.implies_elim Pt_implies_Qt (Thm.assume assm2)
  1538 in
  1536 in
  1539   Qt 
  1537   Qt 
  1540   |> Thm.implies_intr assm2
  1538   |> Thm.implies_intr assm2
  1541   |> Thm.implies_intr assm1
  1539   |> Thm.implies_intr assm1
  1542 end*}
  1540 end\<close>
  1543 
  1541 
  1544 text {*
  1542 text \<open>
  1545   Note that in Line 3 and 4 we use the antiquotation @{text "@{cprop \<dots>}"}, which
  1543   Note that in Line 3 and 4 we use the antiquotation \<open>@{cprop \<dots>}\<close>, which
  1546   inserts necessary @{text "Trueprop"}s.
  1544   inserts necessary \<open>Trueprop\<close>s.
  1547 
  1545 
  1548   If we print out the value of @{ML my_thm} then we see only the 
  1546   If we print out the value of @{ML my_thm} then we see only the 
  1549   final statement of the theorem.
  1547   final statement of the theorem.
  1550 
  1548 
  1551   @{ML_response_fake [display, gray]
  1549   @{ML_response_fake [display, gray]
  1554 
  1552 
  1555   However, internally the code-snippet constructs the following 
  1553   However, internally the code-snippet constructs the following 
  1556   proof.
  1554   proof.
  1557 
  1555 
  1558   \[
  1556   \[
  1559   \infer[(@{text "\<Longrightarrow>"}$-$intro)]{\vdash @{prop "(\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> P t \<Longrightarrow> Q t"}}
  1557   \infer[(\<open>\<Longrightarrow>\<close>$-$intro)]{\vdash @{prop "(\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> P t \<Longrightarrow> Q t"}}
  1560     {\infer[(@{text "\<Longrightarrow>"}$-$intro)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
  1558     {\infer[(\<open>\<Longrightarrow>\<close>$-$intro)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
  1561        {\infer[(@{text "\<Longrightarrow>"}$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"}, @{prop "P t"} \vdash @{prop "Q t"}}
  1559        {\infer[(\<open>\<Longrightarrow>\<close>$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"}, @{prop "P t"} \vdash @{prop "Q t"}}
  1562           {\infer[(@{text "\<And>"}$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
  1560           {\infer[(\<open>\<And>\<close>$-$elim)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "P t \<Longrightarrow> Q t"}}
  1563                  {\infer[(assume)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "\<And>x. P x \<Longrightarrow> Q x"}}{}}
  1561                  {\infer[(assume)]{@{prop "\<And>x. P x \<Longrightarrow> Q x"} \vdash @{prop "\<And>x. P x \<Longrightarrow> Q x"}}{}}
  1564                  &
  1562                  &
  1565            \infer[(assume)]{@{prop "P t"} \vdash @{prop "P t"}}{}
  1563            \infer[(assume)]{@{prop "P t"} \vdash @{prop "P t"}}{}
  1566           }
  1564           }
  1567        }
  1565        }
  1573   referenced on the user level. One way to store it in the theorem database is
  1571   referenced on the user level. One way to store it in the theorem database is
  1574   by using the function @{ML_ind note in Local_Theory} from the structure 
  1572   by using the function @{ML_ind note in Local_Theory} from the structure 
  1575   @{ML_struct Local_Theory} (the Isabelle command
  1573   @{ML_struct Local_Theory} (the Isabelle command
  1576   \isacommand{local\_setup} will be explained in more detail in 
  1574   \isacommand{local\_setup} will be explained in more detail in 
  1577   Section~\ref{sec:local}).
  1575   Section~\ref{sec:local}).
  1578 *}
  1576 \<close>
  1579 
  1577 
  1580 (*FIXME: add forward reference to Proof_Context.export *)
  1578 (*FIXME: add forward reference to Proof_Context.export *)
  1581 ML %linenosgray{*val my_thm_vars =
  1579 ML %linenosgray\<open>val my_thm_vars =
  1582 let
  1580 let
  1583   val ctxt0 = @{context}
  1581   val ctxt0 = @{context}
  1584   val (_, ctxt1) = Variable.add_fixes ["P", "Q", "t"] ctxt0
  1582   val (_, ctxt1) = Variable.add_fixes ["P", "Q", "t"] ctxt0
  1585 in
  1583 in
  1586   singleton (Proof_Context.export ctxt1 ctxt0) my_thm
  1584   singleton (Proof_Context.export ctxt1 ctxt0) my_thm
  1587 end*}
  1585 end\<close>
  1588 
  1586 
  1589 local_setup %gray {*
  1587 local_setup %gray \<open>
  1590   Local_Theory.note ((@{binding "my_thm"}, []), [my_thm_vars]) #> snd *}
  1588   Local_Theory.note ((@{binding "my_thm"}, []), [my_thm_vars]) #> snd\<close>
  1591 
  1589 
  1592 
  1590 
  1593 text {*
  1591 text \<open>
  1594   The third argument of @{ML note in Local_Theory} is the list of theorems we
  1592   The third argument of @{ML note in Local_Theory} is the list of theorems we
  1595   want to store under a name. We can store more than one under a single name. 
  1593   want to store under a name. We can store more than one under a single name. 
  1596   The first argument of @{ML note in Local_Theory} is the name under
  1594   The first argument of @{ML note in Local_Theory} is the name under
  1597   which we store the theorem or theorems. The second argument can contain a
  1595   which we store the theorem or theorems. The second argument can contain a
  1598   list of theorem attributes, which we will explain in detail in
  1596   list of theorem attributes, which we will explain in detail in
  1599   Section~\ref{sec:attributes}. Below we just use one such attribute,
  1597   Section~\ref{sec:attributes}. Below we just use one such attribute,
  1600   @{ML_ind simp_add in Simplifier}, for adding the theorem to the simpset:
  1598   @{ML_ind simp_add in Simplifier}, for adding the theorem to the simpset:
  1601 *}
  1599 \<close>
  1602 
  1600 
  1603 local_setup %gray {*
  1601 local_setup %gray \<open>
  1604   Local_Theory.note ((@{binding "my_thm_simp"}, 
  1602   Local_Theory.note ((@{binding "my_thm_simp"}, 
  1605        [Attrib.internal (K Simplifier.simp_add)]), [my_thm_vars]) #> snd *}
  1603        [Attrib.internal (K Simplifier.simp_add)]), [my_thm_vars]) #> snd\<close>
  1606 
  1604 
  1607 text {*
  1605 text \<open>
  1608   Note that we have to use another name under which the theorem is stored,
  1606   Note that we have to use another name under which the theorem is stored,
  1609   since Isabelle does not allow us to call  @{ML_ind note in Local_Theory} twice
  1607   since Isabelle does not allow us to call  @{ML_ind note in Local_Theory} twice
  1610   with the same name. The attribute needs to be wrapped inside the function @{ML_ind
  1608   with the same name. The attribute needs to be wrapped inside the function @{ML_ind
  1611   internal in Attrib} from the structure @{ML_struct Attrib}. If we use the function 
  1609   internal in Attrib} from the structure @{ML_struct Attrib}. If we use the function 
  1612   @{ML get_thm_names_from_ss} from
  1610   @{ML get_thm_names_from_ss} from
  1626   [source] my_thm_simp} is that they can now also be referenced with the
  1624   [source] my_thm_simp} is that they can now also be referenced with the
  1627   \isacommand{thm}-command on the user-level of Isabelle
  1625   \isacommand{thm}-command on the user-level of Isabelle
  1628 
  1626 
  1629     
  1627     
  1630   \begin{isabelle}
  1628   \begin{isabelle}
  1631   \isacommand{thm}~@{text "my_thm my_thm_simp"}\isanewline
  1629   \isacommand{thm}~\<open>my_thm my_thm_simp\<close>\isanewline
  1632   @{text ">"}~@{prop "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"}\isanewline
  1630   \<open>>\<close>~@{prop "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"}\isanewline
  1633   @{text ">"}~@{prop "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"}
  1631   \<open>>\<close>~@{prop "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"}
  1634   \end{isabelle}
  1632   \end{isabelle}
  1635 
  1633 
  1636   or with the @{text "@{thm \<dots>}"}-antiquotation on the ML-level. Otherwise the 
  1634   or with the \<open>@{thm \<dots>}\<close>-antiquotation on the ML-level. Otherwise the 
  1637   user has no access to these theorems. 
  1635   user has no access to these theorems. 
  1638 
  1636 
  1639   Recall that Isabelle does not let you call @{ML note in Local_Theory} twice
  1637   Recall that Isabelle does not let you call @{ML note in Local_Theory} twice
  1640   with the same theorem name. In effect, once a theorem is stored under a name, 
  1638   with the same theorem name. In effect, once a theorem is stored under a name, 
  1641   this association is fixed. While this is a ``safety-net'' to make sure a
  1639   this association is fixed. While this is a ``safety-net'' to make sure a
  1642   theorem name refers to a particular theorem or collection of theorems, it is 
  1640   theorem name refers to a particular theorem or collection of theorems, it is 
  1643   also a bit too restrictive in cases where a theorem name should refer to a 
  1641   also a bit too restrictive in cases where a theorem name should refer to a 
  1644   dynamically expanding list of theorems (like a simpset). Therefore Isabelle 
  1642   dynamically expanding list of theorems (like a simpset). Therefore Isabelle 
  1645   also implements a mechanism where a theorem name can refer to a custom theorem 
  1643   also implements a mechanism where a theorem name can refer to a custom theorem 
  1646   list. For this you can use the function @{ML_ind add_thms_dynamic in Global_Theory}. 
  1644   list. For this you can use the function @{ML_ind add_thms_dynamic in Global_Theory}. 
  1647   To see how it works let us assume we defined our own theorem list @{text MyThmList}.
  1645   To see how it works let us assume we defined our own theorem list \<open>MyThmList\<close>.
  1648 *}
  1646 \<close>
  1649 
  1647 
  1650 ML %grayML{*structure MyThmList = Generic_Data
  1648 ML %grayML\<open>structure MyThmList = Generic_Data
  1651   (type T = thm list
  1649   (type T = thm list
  1652    val empty = []
  1650    val empty = []
  1653    val extend = I
  1651    val extend = I
  1654    val merge = merge Thm.eq_thm_prop)
  1652    val merge = merge Thm.eq_thm_prop)
  1655 
  1653 
  1656 fun update thm = Context.theory_map (MyThmList.map (Thm.add_thm thm))*}
  1654 fun update thm = Context.theory_map (MyThmList.map (Thm.add_thm thm))\<close>
  1657 
  1655 
  1658 text {*
  1656 text \<open>
  1659   The function @{ML update} allows us to update the theorem list, for example
  1657   The function @{ML update} allows us to update the theorem list, for example
  1660   by adding the theorem @{thm [source] TrueI}.
  1658   by adding the theorem @{thm [source] TrueI}.
  1661 *}
  1659 \<close>
  1662 
  1660 
  1663 setup %gray {* update @{thm TrueI} *}
  1661 setup %gray \<open>update @{thm TrueI}\<close>
  1664  
  1662  
  1665 text {*
  1663 text \<open>
  1666   We can now install the theorem list so that it is visible to the user and 
  1664   We can now install the theorem list so that it is visible to the user and 
  1667   can be refered to by a theorem name. For this need to call 
  1665   can be refered to by a theorem name. For this need to call 
  1668   @{ML_ind add_thms_dynamic in Global_Theory}
  1666   @{ML_ind add_thms_dynamic in Global_Theory}
  1669 *}
  1667 \<close>
  1670 
  1668 
  1671 setup %gray {* 
  1669 setup %gray \<open>
  1672   Global_Theory.add_thms_dynamic (@{binding "mythmlist"}, MyThmList.get) 
  1670   Global_Theory.add_thms_dynamic (@{binding "mythmlist"}, MyThmList.get) 
  1673 *}
  1671 \<close>
  1674 
  1672 
  1675 text {*
  1673 text \<open>
  1676   with a name and a function that accesses the theorem list. Now if the
  1674   with a name and a function that accesses the theorem list. Now if the
  1677   user issues the command
  1675   user issues the command
  1678 
  1676 
  1679   \begin{isabelle}
  1677   \begin{isabelle}
  1680   \isacommand{thm}~@{text "mythmlist"}\\
  1678   \isacommand{thm}~\<open>mythmlist\<close>\\
  1681   @{text "> True"}
  1679   \<open>> True\<close>
  1682   \end{isabelle}
  1680   \end{isabelle}
  1683 
  1681 
  1684   the current content of the theorem list is displayed. If more theorems are stored in 
  1682   the current content of the theorem list is displayed. If more theorems are stored in 
  1685   the list, say
  1683   the list, say
  1686 *}
  1684 \<close>
  1687 
  1685 
  1688 setup %gray {* update @{thm FalseE} *}
  1686 setup %gray \<open>update @{thm FalseE}\<close>
  1689 
  1687 
  1690 text {*
  1688 text \<open>
  1691   then the same command produces
  1689   then the same command produces
  1692   
  1690   
  1693   \begin{isabelle}
  1691   \begin{isabelle}
  1694   \isacommand{thm}~@{text "mythmlist"}\\
  1692   \isacommand{thm}~\<open>mythmlist\<close>\\
  1695   @{text "> False \<Longrightarrow> ?P"}\\
  1693   \<open>> False \<Longrightarrow> ?P\<close>\\
  1696   @{text "> True"}
  1694   \<open>> True\<close>
  1697   \end{isabelle}
  1695   \end{isabelle}
  1698 
  1696 
  1699   Note that if we add the theorem @{thm [source] FalseE} again to the list
  1697   Note that if we add the theorem @{thm [source] FalseE} again to the list
  1700 *}
  1698 \<close>
  1701 
  1699 
  1702 setup %gray {* update @{thm FalseE} *}
  1700 setup %gray \<open>update @{thm FalseE}\<close>
  1703 
  1701 
  1704 text {*
  1702 text \<open>
  1705   we still obtain the same list. The reason is that we used the function @{ML_ind
  1703   we still obtain the same list. The reason is that we used the function @{ML_ind
  1706   add_thm in Thm} in our update function. This is a dedicated function which
  1704   add_thm in Thm} in our update function. This is a dedicated function which
  1707   tests whether the theorem is already in the list.  This test is done
  1705   tests whether the theorem is already in the list.  This test is done
  1708   according to alpha-equivalence of the proposition of the theorem. The
  1706   according to alpha-equivalence of the proposition of the theorem. The
  1709   corresponding testing function is @{ML_ind eq_thm_prop in Thm}.
  1707   corresponding testing function is @{ML_ind eq_thm_prop in Thm}.
  1710   Suppose you proved the following three theorems.
  1708   Suppose you proved the following three theorems.
  1711 *}
  1709 \<close>
  1712 
  1710 
  1713 lemma
  1711 lemma
  1714   shows thm1: "\<forall>x. P x" 
  1712   shows thm1: "\<forall>x. P x" 
  1715   and   thm2: "\<forall>y. P y" 
  1713   and   thm2: "\<forall>y. P y" 
  1716   and   thm3: "\<forall>y. Q y" sorry
  1714   and   thm3: "\<forall>y. Q y" sorry
  1717 
  1715 
  1718 text {*
  1716 text \<open>
  1719   Testing them for alpha equality produces:
  1717   Testing them for alpha equality produces:
  1720 
  1718 
  1721   @{ML_response [display,gray]
  1719   @{ML_response [display,gray]
  1722 "(Thm.eq_thm_prop (@{thm thm1}, @{thm thm2}),
  1720 "(Thm.eq_thm_prop (@{thm thm1}, @{thm thm2}),
  1723  Thm.eq_thm_prop (@{thm thm2}, @{thm thm3}))"
  1721  Thm.eq_thm_prop (@{thm thm2}, @{thm thm3}))"
  1736 end"
  1734 end"
  1737   "(True, (\<lambda>x. x) = (\<lambda>x. x))"}
  1735   "(True, (\<lambda>x. x) = (\<lambda>x. x))"}
  1738 
  1736 
  1739   Other function produce terms that can be pattern-matched. 
  1737   Other function produce terms that can be pattern-matched. 
  1740   Suppose the following two theorems.
  1738   Suppose the following two theorems.
  1741 *}
  1739 \<close>
  1742 
  1740 
  1743 lemma  
  1741 lemma  
  1744   shows foo_test1: "A \<Longrightarrow> B \<Longrightarrow> C" 
  1742   shows foo_test1: "A \<Longrightarrow> B \<Longrightarrow> C" 
  1745   and   foo_test2: "A \<longrightarrow> B \<longrightarrow> C" sorry
  1743   and   foo_test2: "A \<longrightarrow> B \<longrightarrow> C" sorry
  1746 
  1744 
  1747 text {*
  1745 text \<open>
  1748   We can destruct them into premises and conclusions as follows. 
  1746   We can destruct them into premises and conclusions as follows. 
  1749 
  1747 
  1750  @{ML_response_fake [display,gray]
  1748  @{ML_response_fake [display,gray]
  1751 "let
  1749 "let
  1752   val ctxt = @{context}
  1750   val ctxt = @{context}
  1763 "Premises: ?A, ?B
  1761 "Premises: ?A, ?B
  1764 Conclusion: ?C
  1762 Conclusion: ?C
  1765 Premises: 
  1763 Premises: 
  1766 Conclusion: ?A \<longrightarrow> ?B \<longrightarrow> ?C"}
  1764 Conclusion: ?A \<longrightarrow> ?B \<longrightarrow> ?C"}
  1767 
  1765 
  1768   Note that in the second case, there is no premise. The reason is that @{text "\<Longrightarrow>"}
  1766   Note that in the second case, there is no premise. The reason is that \<open>\<Longrightarrow>\<close>
  1769   separates premises and conclusion, while @{text "\<longrightarrow>"} is the object implication
  1767   separates premises and conclusion, while \<open>\<longrightarrow>\<close> is the object implication
  1770   from HOL, which just constructs a formula.
  1768   from HOL, which just constructs a formula.
  1771 
  1769 
  1772   \begin{readmore}
  1770   \begin{readmore}
  1773   The basic functions for theorems are defined in
  1771   The basic functions for theorems are defined in
  1774   @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and @{ML_file "Pure/drule.ML"}. 
  1772   @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and @{ML_file "Pure/drule.ML"}. 
  1786   |> pretty_thm @{context}
  1784   |> pretty_thm @{context}
  1787   |> pwriteln"
  1785   |> pwriteln"
  1788   "(\<lambda>x. x) = (\<lambda>x. x) \<equiv> (\<lambda>x. x) = (\<lambda>x. x)"}
  1786   "(\<lambda>x. x) = (\<lambda>x. x) \<equiv> (\<lambda>x. x) = (\<lambda>x. x)"}
  1789 
  1787 
  1790   Often it is necessary to transform theorems to and from the object 
  1788   Often it is necessary to transform theorems to and from the object 
  1791   logic, that is replacing all @{text "\<longrightarrow>"} and @{text "\<forall>"} by @{text "\<Longrightarrow>"} 
  1789   logic, that is replacing all \<open>\<longrightarrow>\<close> and \<open>\<forall>\<close> by \<open>\<Longrightarrow>\<close> 
  1792   and @{text "\<And>"}, or the other way around.  A reason for such a transformation 
  1790   and \<open>\<And>\<close>, or the other way around.  A reason for such a transformation 
  1793   might be stating a definition. The reason is that definitions can only be 
  1791   might be stating a definition. The reason is that definitions can only be 
  1794   stated using object logic connectives, while theorems using the connectives 
  1792   stated using object logic connectives, while theorems using the connectives 
  1795   from the meta logic are more convenient for reasoning. Therefore there are
  1793   from the meta logic are more convenient for reasoning. Therefore there are
  1796   some build in functions which help with these transformations. The function 
  1794   some build in functions which help with these transformations. The function 
  1797   @{ML_ind rulify in Object_Logic} 
  1795   @{ML_ind rulify in Object_Logic} 
  1820   involving meta variables, such as @{thm [source] list.induct}, which 
  1818   involving meta variables, such as @{thm [source] list.induct}, which 
  1821   is of the form 
  1819   is of the form 
  1822 
  1820 
  1823   @{thm [display] list.induct}
  1821   @{thm [display] list.induct}
  1824 
  1822 
  1825   we have to first abstract over the meta variables @{text "?P"} and 
  1823   we have to first abstract over the meta variables \<open>?P\<close> and 
  1826   @{text "?list"}. For this we can use the function 
  1824   \<open>?list\<close>. For this we can use the function 
  1827   @{ML_ind forall_intr_vars in Drule}. This allows us to implement the
  1825   @{ML_ind forall_intr_vars in Drule}. This allows us to implement the
  1828   following function for atomizing a theorem.
  1826   following function for atomizing a theorem.
  1829 *}
  1827 \<close>
  1830 
  1828 
  1831 ML %grayML{*fun atomize_thm ctxt thm =
  1829 ML %grayML\<open>fun atomize_thm ctxt thm =
  1832 let
  1830 let
  1833   val thm' = forall_intr_vars thm
  1831   val thm' = forall_intr_vars thm
  1834   val thm'' = Object_Logic.atomize ctxt (Thm.cprop_of thm')
  1832   val thm'' = Object_Logic.atomize ctxt (Thm.cprop_of thm')
  1835 in
  1833 in
  1836   Raw_Simplifier.rewrite_rule ctxt [thm''] thm'
  1834   Raw_Simplifier.rewrite_rule ctxt [thm''] thm'
  1837 end*}
  1835 end\<close>
  1838 
  1836 
  1839 text {*
  1837 text \<open>
  1840   This function produces for the theorem @{thm [source] list.induct}
  1838   This function produces for the theorem @{thm [source] list.induct}
  1841 
  1839 
  1842   @{ML_response_fake [display, gray]
  1840   @{ML_response_fake [display, gray]
  1843   "atomize_thm @{context} @{thm list.induct}"
  1841   "atomize_thm @{context} @{thm list.induct}"
  1844   "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"}
  1842   "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"}
  1857 end"
  1855 end"
  1858   "?P \<Longrightarrow> ?P"}
  1856   "?P \<Longrightarrow> ?P"}
  1859 
  1857 
  1860   This function takes first a context and second a list of strings. This list
  1858   This function takes first a context and second a list of strings. This list
  1861   specifies which variables should be turned into schematic variables once the term
  1859   specifies which variables should be turned into schematic variables once the term
  1862   is proved (in this case only @{text "\"P\""}).  The fourth argument is the term to be 
  1860   is proved (in this case only \<open>"P"\<close>).  The fourth argument is the term to be 
  1863   proved. The fifth is a corresponding proof given in form of a tactic (we explain 
  1861   proved. The fifth is a corresponding proof given in form of a tactic (we explain 
  1864   tactics in Chapter~\ref{chp:tactical}). In the code above, the tactic proves the 
  1862   tactics in Chapter~\ref{chp:tactical}). In the code above, the tactic proves the 
  1865   theorem by assumption. 
  1863   theorem by assumption. 
  1866 
  1864 
  1867   There is also the possibility of proving multiple goals at the same time
  1865   There is also the possibility of proving multiple goals at the same time
  1868   using the function @{ML_ind prove_common in Goal}. For this let us define the
  1866   using the function @{ML_ind prove_common in Goal}. For this let us define the
  1869   following three helper functions.
  1867   following three helper functions.
  1870 *}
  1868 \<close>
  1871 
  1869 
  1872 ML %grayML{*fun rep_goals i = replicate i @{prop "f x = f x"}
  1870 ML %grayML\<open>fun rep_goals i = replicate i @{prop "f x = f x"}
  1873 fun rep_tacs i = replicate i (resolve_tac @{context} [@{thm refl}])
  1871 fun rep_tacs i = replicate i (resolve_tac @{context} [@{thm refl}])
  1874 
  1872 
  1875 fun multi_test ctxt i =
  1873 fun multi_test ctxt i =
  1876   Goal.prove_common ctxt NONE ["f", "x"] [] (rep_goals i) 
  1874   Goal.prove_common ctxt NONE ["f", "x"] [] (rep_goals i) 
  1877     (K ((Goal.conjunction_tac THEN' RANGE (rep_tacs i)) 1))*}
  1875     (K ((Goal.conjunction_tac THEN' RANGE (rep_tacs i)) 1))\<close>
  1878 
  1876 
  1879 text {*
  1877 text \<open>
  1880   With them we can now produce three theorem instances of the 
  1878   With them we can now produce three theorem instances of the 
  1881   proposition.
  1879   proposition.
  1882 
  1880 
  1883   @{ML_response_fake [display, gray]
  1881   @{ML_response_fake [display, gray]
  1884   "multi_test @{context} 3"
  1882   "multi_test @{context} 3"
  1885   "[\"?f ?x = ?f ?x\", \"?f ?x = ?f ?x\", \"?f ?x = ?f ?x\"]"}
  1883   "[\"?f ?x = ?f ?x\", \"?f ?x = ?f ?x\", \"?f ?x = ?f ?x\"]"}
  1886 
  1884 
  1887   However you should be careful with @{ML prove_common in Goal} and very
  1885   However you should be careful with @{ML prove_common in Goal} and very
  1888   large goals. If you increase the counter in the code above to @{text 3000}, 
  1886   large goals. If you increase the counter in the code above to \<open>3000\<close>, 
  1889   you will notice that takes approximately ten(!) times longer than
  1887   you will notice that takes approximately ten(!) times longer than
  1890   using @{ML map} and @{ML prove in Goal}.
  1888   using @{ML map} and @{ML prove in Goal}.
  1891 *}
  1889 \<close>
  1892   
  1890   
  1893 ML %grayML{*let 
  1891 ML %grayML\<open>let 
  1894   fun test_prove ctxt thm =
  1892   fun test_prove ctxt thm =
  1895     Goal.prove ctxt ["P", "x"] [] thm (K (resolve_tac  @{context} [@{thm refl}] 1))
  1893     Goal.prove ctxt ["P", "x"] [] thm (K (resolve_tac  @{context} [@{thm refl}] 1))
  1896 in
  1894 in
  1897   map (test_prove @{context}) (rep_goals 3000)
  1895   map (test_prove @{context}) (rep_goals 3000)
  1898 end*}
  1896 end\<close>
  1899 
  1897 
  1900 text {*
  1898 text \<open>
  1901   While the LCF-approach of going through interfaces ensures soundness in Isabelle, there
  1899   While the LCF-approach of going through interfaces ensures soundness in Isabelle, there
  1902   is the function @{ML_ind make_thm in Skip_Proof} in the structure 
  1900   is the function @{ML_ind make_thm in Skip_Proof} in the structure 
  1903   @{ML_struct Skip_Proof} that allows us to turn any proposition into a theorem.
  1901   @{ML_struct Skip_Proof} that allows us to turn any proposition into a theorem.
  1904   Potentially making the system unsound.  This is sometimes useful for developing 
  1902   Potentially making the system unsound.  This is sometimes useful for developing 
  1905   purposes, or when explicit proof construction should be omitted due to performace 
  1903   purposes, or when explicit proof construction should be omitted due to performace 
  1917 
  1915 
  1918   Theorems also contain auxiliary data, such as the name of the theorem, its
  1916   Theorems also contain auxiliary data, such as the name of the theorem, its
  1919   kind, the names for cases and so on. This data is stored in a string-string
  1917   kind, the names for cases and so on. This data is stored in a string-string
  1920   list and can be retrieved with the function @{ML_ind get_tags in
  1918   list and can be retrieved with the function @{ML_ind get_tags in
  1921   Thm}. Assume you prove the following lemma.
  1919   Thm}. Assume you prove the following lemma.
  1922 *}
  1920 \<close>
  1923 
  1921 
  1924 lemma foo_data: 
  1922 lemma foo_data: 
  1925   shows "P \<Longrightarrow> P \<Longrightarrow> P" by assumption
  1923   shows "P \<Longrightarrow> P \<Longrightarrow> P" by assumption
  1926 
  1924 
  1927 text {*
  1925 text \<open>
  1928   The auxiliary data of this lemma can be retrieved using the function 
  1926   The auxiliary data of this lemma can be retrieved using the function 
  1929   @{ML_ind get_tags in Thm}. So far the the auxiliary data of this lemma is 
  1927   @{ML_ind get_tags in Thm}. So far the the auxiliary data of this lemma is 
  1930 
  1928 
  1931   @{ML_response_fake [display,gray]
  1929   @{ML_response_fake [display,gray]
  1932   "Thm.get_tags @{thm foo_data}"
  1930   "Thm.get_tags @{thm foo_data}"
  1934 
  1932 
  1935   consisting of a name and a kind.  When we store lemmas in the theorem database, 
  1933   consisting of a name and a kind.  When we store lemmas in the theorem database, 
  1936   we might want to explicitly extend this data by attaching case names to the 
  1934   we might want to explicitly extend this data by attaching case names to the 
  1937   two premises of the lemma.  This can be done with the function @{ML_ind name in Rule_Cases}
  1935   two premises of the lemma.  This can be done with the function @{ML_ind name in Rule_Cases}
  1938   from the structure @{ML_struct Rule_Cases}.
  1936   from the structure @{ML_struct Rule_Cases}.
  1939 *}
  1937 \<close>
  1940 
  1938 
  1941 local_setup %gray {*
  1939 local_setup %gray \<open>
  1942   Local_Theory.note ((@{binding "foo_data'"}, []), 
  1940   Local_Theory.note ((@{binding "foo_data'"}, []), 
  1943     [(Rule_Cases.name ["foo_case_one", "foo_case_two"] 
  1941     [(Rule_Cases.name ["foo_case_one", "foo_case_two"] 
  1944        @{thm foo_data})]) #> snd *}
  1942        @{thm foo_data})]) #> snd\<close>
  1945 
  1943 
  1946 text {*
  1944 text \<open>
  1947   The data of the theorem @{thm [source] foo_data'} is then as follows:
  1945   The data of the theorem @{thm [source] foo_data'} is then as follows:
  1948 
  1946 
  1949   @{ML_response_fake [display,gray]
  1947   @{ML_response_fake [display,gray]
  1950   "Thm.get_tags @{thm foo_data'}"
  1948   "Thm.get_tags @{thm foo_data'}"
  1951   "[(\"name\", \"General.foo_data'\"), (\"kind\", \"lemma\"), 
  1949   "[(\"name\", \"General.foo_data'\"), (\"kind\", \"lemma\"), 
  1952  (\"case_names\", \"foo_case_one;foo_case_two\")]"}
  1950  (\"case_names\", \"foo_case_one;foo_case_two\")]"}
  1953 
  1951 
  1954   You can observe the case names of this lemma on the user level when using 
  1952   You can observe the case names of this lemma on the user level when using 
  1955   the proof methods @{text cases} and @{text induct}. In the proof below
  1953   the proof methods \<open>cases\<close> and \<open>induct\<close>. In the proof below
  1956 *}
  1954 \<close>
  1957 
  1955 
  1958 lemma
  1956 lemma
  1959 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q"
  1957 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q"
  1960 proof (cases rule: foo_data')
  1958 proof (cases rule: foo_data')
  1961 
  1959 
  1962 (*<*)oops(*>*)
  1960 (*<*)oops(*>*)
  1963 text_raw{*
  1961 text_raw\<open>
  1964 \begin{tabular}{@ {}l}
  1962 \begin{tabular}{@ {}l}
  1965 \isacommand{print\_cases}\\
  1963 \isacommand{print\_cases}\\
  1966 @{text "> cases:"}\\
  1964 \<open>> cases:\<close>\\
  1967 @{text ">   foo_case_one:"}\\
  1965 \<open>>   foo_case_one:\<close>\\
  1968 @{text ">     let \"?case\" = \"?P\""}\\
  1966 \<open>>     let "?case" = "?P"\<close>\\
  1969 @{text ">   foo_case_two:"}\\
  1967 \<open>>   foo_case_two:\<close>\\
  1970 @{text ">     let \"?case\" = \"?P\""}
  1968 \<open>>     let "?case" = "?P"\<close>
  1971 \end{tabular}*}
  1969 \end{tabular}\<close>
  1972 
  1970 
  1973 text {*
  1971 text \<open>
  1974   we can proceed by analysing the cases @{text "foo_case_one"} and 
  1972   we can proceed by analysing the cases \<open>foo_case_one\<close> and 
  1975   @{text "foo_case_two"}. While if the theorem has no names, then
  1973   \<open>foo_case_two\<close>. While if the theorem has no names, then
  1976   the cases have standard names @{text 1}, @{text 2} and so 
  1974   the cases have standard names \<open>1\<close>, \<open>2\<close> and so 
  1977   on. This can be seen in the proof below.
  1975   on. This can be seen in the proof below.
  1978 *}
  1976 \<close>
  1979 
  1977 
  1980 lemma
  1978 lemma
  1981 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q"
  1979 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q"
  1982 proof (cases rule: foo_data)
  1980 proof (cases rule: foo_data)
  1983 
  1981 
  1984 (*<*)oops(*>*)
  1982 (*<*)oops(*>*)
  1985 text_raw{*
  1983 text_raw\<open>
  1986 \begin{tabular}{@ {}l}
  1984 \begin{tabular}{@ {}l}
  1987 \isacommand{print\_cases}\\
  1985 \isacommand{print\_cases}\\
  1988 @{text "> cases:"}\\
  1986 \<open>> cases:\<close>\\
  1989 @{text ">   1:"}\\
  1987 \<open>>   1:\<close>\\
  1990 @{text ">     let \"?case\" = \"?P\""}\\
  1988 \<open>>     let "?case" = "?P"\<close>\\
  1991 @{text ">   2:"}\\
  1989 \<open>>   2:\<close>\\
  1992 @{text ">     let \"?case\" = \"?P\""}
  1990 \<open>>     let "?case" = "?P"\<close>
  1993 \end{tabular}*}
  1991 \end{tabular}\<close>
  1994 
  1992 
  1995  
  1993  
  1996 text {*
  1994 text \<open>
  1997   Sometimes one wants to know the theorems that are involved in
  1995   Sometimes one wants to know the theorems that are involved in
  1998   proving a theorem, especially when the proof is by @{text
  1996   proving a theorem, especially when the proof is by \<open>auto\<close>. These theorems can be obtained by introspecting the proved theorem.
  1999   auto}. These theorems can be obtained by introspecting the proved theorem.
       
  2000   To introspect a theorem, let us define the following three functions
  1997   To introspect a theorem, let us define the following three functions
  2001   that analyse the @{ML_type_ind proof_body} data-structure from the
  1998   that analyse the @{ML_type_ind proof_body} data-structure from the
  2002   structure @{ML_struct Proofterm}.
  1999   structure @{ML_struct Proofterm}.
  2003 *}
  2000 \<close>
  2004 
  2001 
  2005 ML %grayML{*fun pthms_of (PBody {thms, ...}) = map #2 thms 
  2002 ML %grayML\<open>fun pthms_of (PBody {thms, ...}) = map #2 thms 
  2006 val get_names = (map Proofterm.thm_node_name) o pthms_of 
  2003 val get_names = (map Proofterm.thm_node_name) o pthms_of 
  2007 val get_pbodies = map (Future.join o Proofterm.thm_node_body) o pthms_of *}
  2004 val get_pbodies = map (Future.join o Proofterm.thm_node_body) o pthms_of\<close>
  2008 
  2005 
  2009 text {* 
  2006 text \<open>
  2010   To see what their purpose is, consider the following three short proofs.
  2007   To see what their purpose is, consider the following three short proofs.
  2011 *}
  2008 \<close>
  2012 
  2009 
  2013 lemma my_conjIa:
  2010 lemma my_conjIa:
  2014 shows "A \<and> B \<Longrightarrow> A \<and> B"
  2011 shows "A \<and> B \<Longrightarrow> A \<and> B"
  2015 apply(rule conjI)
  2012 apply(rule conjI)
  2016 apply(drule conjunct1)
  2013 apply(drule conjunct1)
  2028 shows "A \<and> B \<Longrightarrow> A \<and> B"
  2025 shows "A \<and> B \<Longrightarrow> A \<and> B"
  2029 apply(auto)
  2026 apply(auto)
  2030 done
  2027 done
  2031 
  2028 
  2032 
  2029 
  2033 text {*
  2030 text \<open>
  2034   While the information about which theorems are used is obvious in
  2031   While the information about which theorems are used is obvious in
  2035   the first two proofs, it is not obvious in the third, because of the
  2032   the first two proofs, it is not obvious in the third, because of the
  2036   @{text auto}-step.  Fortunately, ``behind'' every proved theorem is
  2033   \<open>auto\<close>-step.  Fortunately, ``behind'' every proved theorem is
  2037   a proof-tree that records all theorems that are employed for
  2034   a proof-tree that records all theorems that are employed for
  2038   establishing this theorem.  We can traverse this proof-tree
  2035   establishing this theorem.  We can traverse this proof-tree
  2039   extracting this information.  Let us first extract the name of the
  2036   extracting this information.  Let us first extract the name of the
  2040   established theorem. This can be done with
  2037   established theorem. This can be done with
  2041 
  2038 
  2043   "@{thm my_conjIa}
  2040   "@{thm my_conjIa}
  2044   |> Thm.proof_body_of
  2041   |> Thm.proof_body_of
  2045   |> get_names"
  2042   |> get_names"
  2046   "[\"Essential.my_conjIa\"]"}
  2043   "[\"Essential.my_conjIa\"]"}
  2047 
  2044 
  2048   whereby @{text "Essential"} refers to the theory name in which
  2045   whereby \<open>Essential\<close> refers to the theory name in which
  2049   we established the theorem @{thm [source] my_conjIa}. The function @{ML_ind
  2046   we established the theorem @{thm [source] my_conjIa}. The function @{ML_ind
  2050   proof_body_of in Thm} returns a part of the data that is stored in a
  2047   proof_body_of in Thm} returns a part of the data that is stored in a
  2051   theorem.  Notice that the first proof above references
  2048   theorem.  Notice that the first proof above references
  2052   three theorems, namely @{thm [source] conjI}, @{thm [source] conjunct1} 
  2049   three theorems, namely @{thm [source] conjI}, @{thm [source] conjunct1} 
  2053   and @{thm [source] conjunct2}. We can obtain them by descending into the
  2050   and @{thm [source] conjunct2}. We can obtain them by descending into the
  2062   "[\"HOL.conjunct2\", \"HOL.conjunct1\", \"HOL.conjI\", \"Pure.protectD\", 
  2059   "[\"HOL.conjunct2\", \"HOL.conjunct1\", \"HOL.conjI\", \"Pure.protectD\", 
  2063   \"Pure.protectI\"]"}
  2060   \"Pure.protectI\"]"}
  2064 
  2061 
  2065   The theorems @{thm [source] Pure.protectD} and @{thm [source]
  2062   The theorems @{thm [source] Pure.protectD} and @{thm [source]
  2066   Pure.protectI} that are internal theorems are always part of a
  2063   Pure.protectI} that are internal theorems are always part of a
  2067   proof in Isabelle. Note also that applications of @{text assumption} do not
  2064   proof in Isabelle. Note also that applications of \<open>assumption\<close> do not
  2068   count as a separate theorem, as you can see in the following code.
  2065   count as a separate theorem, as you can see in the following code.
  2069 
  2066 
  2070   @{ML_response_fake [display,gray]
  2067   @{ML_response_fake [display,gray]
  2071   "@{thm my_conjIb}
  2068   "@{thm my_conjIb}
  2072   |> Thm.proof_body_of
  2069   |> Thm.proof_body_of
  2124   sometimes the verbatim quoting is not what is wanted or what can be shown to
  2121   sometimes the verbatim quoting is not what is wanted or what can be shown to
  2125   readers. For such situations Isabelle allows the installation of \emph{\index*{theorem 
  2122   readers. For such situations Isabelle allows the installation of \emph{\index*{theorem 
  2126   styles}}. These are, roughly speaking, functions from terms to terms. The input 
  2123   styles}}. These are, roughly speaking, functions from terms to terms. The input 
  2127   term stands for the theorem to be presented; the output can be constructed to
  2124   term stands for the theorem to be presented; the output can be constructed to
  2128   ones wishes.  Let us, for example, assume we want to quote theorems without
  2125   ones wishes.  Let us, for example, assume we want to quote theorems without
  2129   leading @{text \<forall>}-quantifiers. For this we can implement the following function 
  2126   leading \<open>\<forall>\<close>-quantifiers. For this we can implement the following function 
  2130   that strips off @{text "\<forall>"}s.
  2127   that strips off \<open>\<forall>\<close>s.
  2131 *}
  2128 \<close>
  2132 
  2129 
  2133 ML %linenosgray{*fun strip_allq (Const (@{const_name "All"}, _) $ Abs body) = 
  2130 ML %linenosgray\<open>fun strip_allq (Const (@{const_name "All"}, _) $ Abs body) = 
  2134       Term.dest_abs body |> snd |> strip_allq
  2131       Term.dest_abs body |> snd |> strip_allq
  2135   | strip_allq (Const (@{const_name "Trueprop"}, _) $ t) = 
  2132   | strip_allq (Const (@{const_name "Trueprop"}, _) $ t) = 
  2136       strip_allq t
  2133       strip_allq t
  2137   | strip_allq t = t*}
  2134   | strip_allq t = t\<close>
  2138 
  2135 
  2139 text {*
  2136 text \<open>
  2140   We use in Line 2 the function @{ML_ind dest_abs in Term} for deconstructing abstractions,
  2137   We use in Line 2 the function @{ML_ind dest_abs in Term} for deconstructing abstractions,
  2141   since this function deals correctly with potential name clashes. This function produces
  2138   since this function deals correctly with potential name clashes. This function produces
  2142   a pair consisting of the variable and the body of the abstraction. We are only interested
  2139   a pair consisting of the variable and the body of the abstraction. We are only interested
  2143   in the body, which we feed into the recursive call. In Line 3 and 4, we also
  2140   in the body, which we feed into the recursive call. In Line 3 and 4, we also
  2144   have to explicitly strip of the outermost @{term Trueprop}-coercion. Now we can 
  2141   have to explicitly strip of the outermost @{term Trueprop}-coercion. Now we can 
  2145   install this function as the theorem style named @{text "my_strip_allq"}. 
  2142   install this function as the theorem style named \<open>my_strip_allq\<close>. 
  2146 *}
  2143 \<close>
  2147 
  2144 
  2148 setup %gray{* 
  2145 setup %gray\<open>
  2149   Term_Style.setup @{binding "my_strip_allq"} (Scan.succeed (K strip_allq)) 
  2146   Term_Style.setup @{binding "my_strip_allq"} (Scan.succeed (K strip_allq)) 
  2150 *}
  2147 \<close>
  2151 
  2148 
  2152 text {*
  2149 text \<open>
  2153   We can test this theorem style with the following theorem
  2150   We can test this theorem style with the following theorem
  2154 *}
  2151 \<close>
  2155 
  2152 
  2156 theorem style_test:
  2153 theorem style_test:
  2157 shows "\<forall>x y z. (x, x) = (y, z)" sorry
  2154 shows "\<forall>x y z. (x, x) = (y, z)" sorry
  2158 
  2155 
  2159 text {*
  2156 text \<open>
  2160   Now printing out in a document the theorem @{thm [source] style_test} normally
  2157   Now printing out in a document the theorem @{thm [source] style_test} normally
  2161   using @{text "@{thm \<dots>}"} produces
  2158   using \<open>@{thm \<dots>}\<close> produces
  2162 
  2159 
  2163   \begin{isabelle}
  2160   \begin{isabelle}
  2164   \begin{graybox}
  2161   \begin{graybox}
  2165   @{text "@{thm style_test}"}\\
  2162   \<open>@{thm style_test}\<close>\\
  2166   @{text ">"}~@{thm style_test}
  2163   \<open>>\<close>~@{thm style_test}
  2167   \end{graybox}
  2164   \end{graybox}
  2168   \end{isabelle}
  2165   \end{isabelle}
  2169 
  2166 
  2170   as expected. But with the theorem style @{text "@{thm (my_strip_allq) \<dots>}"} 
  2167   as expected. But with the theorem style \<open>@{thm (my_strip_allq) \<dots>}\<close> 
  2171   we obtain
  2168   we obtain
  2172 
  2169 
  2173   \begin{isabelle}
  2170   \begin{isabelle}
  2174   \begin{graybox}
  2171   \begin{graybox}
  2175   @{text "@{thm (my_strip_allq) style_test}"}\\
  2172   \<open>@{thm (my_strip_allq) style_test}\<close>\\
  2176   @{text ">"}~@{thm (my_strip_allq) style_test}
  2173   \<open>>\<close>~@{thm (my_strip_allq) style_test}
  2177   \end{graybox}
  2174   \end{graybox}
  2178   \end{isabelle}
  2175   \end{isabelle}
  2179   
  2176   
  2180   without the leading quantifiers. We can improve this theorem style by explicitly 
  2177   without the leading quantifiers. We can improve this theorem style by explicitly 
  2181   giving a list of strings that should be used for the replacement of the
  2178   giving a list of strings that should be used for the replacement of the
  2182   variables. For this we implement the function which takes a list of strings
  2179   variables. For this we implement the function which takes a list of strings
  2183   and uses them as name in the outermost abstractions.
  2180   and uses them as name in the outermost abstractions.
  2184 *}
  2181 \<close>
  2185 
  2182 
  2186 ML %grayML{*fun rename_allq [] t = t
  2183 ML %grayML\<open>fun rename_allq [] t = t
  2187   | rename_allq (x::xs) (Const (@{const_name "All"}, U) $ Abs (_, T, t)) = 
  2184   | rename_allq (x::xs) (Const (@{const_name "All"}, U) $ Abs (_, T, t)) = 
  2188       Const (@{const_name "All"}, U) $ Abs (x, T, rename_allq xs t)
  2185       Const (@{const_name "All"}, U) $ Abs (x, T, rename_allq xs t)
  2189   | rename_allq xs (Const (@{const_name "Trueprop"}, U) $ t) =
  2186   | rename_allq xs (Const (@{const_name "Trueprop"}, U) $ t) =
  2190       rename_allq xs t
  2187       rename_allq xs t
  2191   | rename_allq _ t = t*}
  2188   | rename_allq _ t = t\<close>
  2192 
  2189 
  2193 text {*
  2190 text \<open>
  2194   We can now install a the modified theorem style as follows
  2191   We can now install a the modified theorem style as follows
  2195 *}
  2192 \<close>
  2196 
  2193 
  2197 setup %gray {* let
  2194 setup %gray \<open>let
  2198   val parser = Scan.repeat Args.name
  2195   val parser = Scan.repeat Args.name
  2199   fun action xs = K (rename_allq xs #> strip_allq)
  2196   fun action xs = K (rename_allq xs #> strip_allq)
  2200 in
  2197 in
  2201   Term_Style.setup @{binding "my_strip_allq2"} (parser >> action)
  2198   Term_Style.setup @{binding "my_strip_allq2"} (parser >> action)
  2202 end *}
  2199 end\<close>
  2203 
  2200 
  2204 text {*
  2201 text \<open>
  2205   The parser reads a list of names. In the function @{text action} we first
  2202   The parser reads a list of names. In the function \<open>action\<close> we first
  2206   call @{ML rename_allq} with the parsed list, then we call @{ML strip_allq}
  2203   call @{ML rename_allq} with the parsed list, then we call @{ML strip_allq}
  2207   on the resulting term. We can now suggest, for example, two variables for
  2204   on the resulting term. We can now suggest, for example, two variables for
  2208   stripping off the first two @{text \<forall>}-quantifiers.
  2205   stripping off the first two \<open>\<forall>\<close>-quantifiers.
  2209 
  2206 
  2210   \begin{isabelle}
  2207   \begin{isabelle}
  2211   \begin{graybox}
  2208   \begin{graybox}
  2212   @{text "@{thm (my_strip_allq2 x' x'') style_test}"}\\
  2209   \<open>@{thm (my_strip_allq2 x' x'') style_test}\<close>\\
  2213   @{text ">"}~@{thm (my_strip_allq2 x' x'') style_test}
  2210   \<open>>\<close>~@{thm (my_strip_allq2 x' x'') style_test}
  2214   \end{graybox}
  2211   \end{graybox}
  2215   \end{isabelle}
  2212   \end{isabelle}
  2216 
  2213 
  2217   Such styles allow one to print out theorems in documents formatted to 
  2214   Such styles allow one to print out theorems in documents formatted to 
  2218   ones heart content. The styles can also be used in the document 
  2215   ones heart content. The styles can also be used in the document 
  2219   antiquotations @{text "@{prop ...}"}, @{text "@{term_type ...}"}
  2216   antiquotations \<open>@{prop ...}\<close>, \<open>@{term_type ...}\<close>
  2220   and @{text "@{typeof ...}"}.
  2217   and \<open>@{typeof ...}\<close>.
  2221 
  2218 
  2222   Next we explain theorem attributes, which is another
  2219   Next we explain theorem attributes, which is another
  2223   mechanism for dealing with theorems.
  2220   mechanism for dealing with theorems.
  2224 
  2221 
  2225   \begin{readmore}
  2222   \begin{readmore}
  2226   Theorem styles are implemented in @{ML_file "Pure/Thy/term_style.ML"}.
  2223   Theorem styles are implemented in @{ML_file "Pure/Thy/term_style.ML"}.
  2227   \end{readmore}
  2224   \end{readmore}
  2228 *}
  2225 \<close>
  2229 
  2226 
  2230 section {* Theorem Attributes\label{sec:attributes} *}
  2227 section \<open>Theorem Attributes\label{sec:attributes}\<close>
  2231 
  2228 
  2232 text {*
  2229 text \<open>
  2233   Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text
  2230   Theorem attributes are \<open>[symmetric]\<close>, \<open>[THEN \<dots>]\<close>, \<open>[simp]\<close> and so on. Such attributes are \emph{neither} tags \emph{nor} flags
  2234   "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags
       
  2235   annotated to theorems, but functions that do further processing of 
  2231   annotated to theorems, but functions that do further processing of 
  2236   theorems. In particular, it is not possible to find out
  2232   theorems. In particular, it is not possible to find out
  2237   what are all theorems that have a given attribute in common, unless of course
  2233   what are all theorems that have a given attribute in common, unless of course
  2238   the function behind the attribute stores the theorems in a retrievable 
  2234   the function behind the attribute stores the theorems in a retrievable 
  2239   data structure. 
  2235   data structure. 
  2241   If you want to print out all currently known attributes a theorem can have, 
  2237   If you want to print out all currently known attributes a theorem can have, 
  2242   you can use the Isabelle command
  2238   you can use the Isabelle command
  2243 
  2239 
  2244   \begin{isabelle}
  2240   \begin{isabelle}
  2245   \isacommand{print\_attributes}\\
  2241   \isacommand{print\_attributes}\\
  2246   @{text "> COMP:  direct composition with rules (no lifting)"}\\
  2242   \<open>> COMP:  direct composition with rules (no lifting)\<close>\\
  2247   @{text "> HOL.dest:  declaration of Classical destruction rule"}\\
  2243   \<open>> HOL.dest:  declaration of Classical destruction rule\<close>\\
  2248   @{text "> HOL.elim:  declaration of Classical elimination rule"}\\
  2244   \<open>> HOL.elim:  declaration of Classical elimination rule\<close>\\
  2249   @{text "> \<dots>"}
  2245   \<open>> \<dots>\<close>
  2250   \end{isabelle}
  2246   \end{isabelle}
  2251   
  2247   
  2252   The theorem attributes fall roughly into two categories: the first category manipulates
  2248   The theorem attributes fall roughly into two categories: the first category manipulates
  2253   theorems (for example @{text "[symmetric]"} and @{text "[THEN \<dots>]"}), and the second
  2249   theorems (for example \<open>[symmetric]\<close> and \<open>[THEN \<dots>]\<close>), and the second
  2254   stores theorems somewhere as data (for example @{text "[simp]"}, which adds
  2250   stores theorems somewhere as data (for example \<open>[simp]\<close>, which adds
  2255   theorems to the current simpset).
  2251   theorems to the current simpset).
  2256 
  2252 
  2257   To explain how to write your own attribute, let us start with an extremely simple 
  2253   To explain how to write your own attribute, let us start with an extremely simple 
  2258   version of the attribute @{text "[symmetric]"}. The purpose of this attribute is
  2254   version of the attribute \<open>[symmetric]\<close>. The purpose of this attribute is
  2259   to produce the ``symmetric'' version of an equation. The main function behind 
  2255   to produce the ``symmetric'' version of an equation. The main function behind 
  2260   this attribute is
  2256   this attribute is
  2261 *}
  2257 \<close>
  2262 
  2258 
  2263 ML %grayML{*val my_symmetric = Thm.rule_attribute [] (fn _ => fn thm => thm RS @{thm sym})*}
  2259 ML %grayML\<open>val my_symmetric = Thm.rule_attribute [] (fn _ => fn thm => thm RS @{thm sym})\<close>
  2264 
  2260 
  2265 text {* 
  2261 text \<open>
  2266   where the function @{ML_ind  rule_attribute in Thm} expects a function taking a 
  2262   where the function @{ML_ind  rule_attribute in Thm} expects a function taking a 
  2267   context (which we ignore in the code above) and a theorem (@{text thm}), and 
  2263   context (which we ignore in the code above) and a theorem (\<open>thm\<close>), and 
  2268   returns another theorem (namely @{text thm} resolved with the theorem 
  2264   returns another theorem (namely \<open>thm\<close> resolved with the theorem 
  2269   @{thm [source] sym}: @{thm sym[no_vars]}; the function @{ML_ind RS in Drule} 
  2265   @{thm [source] sym}: @{thm sym[no_vars]}; the function @{ML_ind RS in Drule} 
  2270   is explained in Section~\ref{sec:simpletacs}). The function 
  2266   is explained in Section~\ref{sec:simpletacs}). The function 
  2271   @{ML rule_attribute in Thm} then returns  an attribute.
  2267   @{ML rule_attribute in Thm} then returns  an attribute.
  2272 
  2268 
  2273   Before we can use the attribute, we need to set it up. This can be done
  2269   Before we can use the attribute, we need to set it up. This can be done
  2274   using the Isabelle command \isacommand{attribute\_setup} as follows:
  2270   using the Isabelle command \isacommand{attribute\_setup} as follows:
  2275 *}
  2271 \<close>
  2276 
  2272 
  2277 attribute_setup %gray my_sym = 
  2273 attribute_setup %gray my_sym = 
  2278   {* Scan.succeed my_symmetric *} "applying the sym rule"
  2274   \<open>Scan.succeed my_symmetric\<close> "applying the sym rule"
  2279 
  2275 
  2280 text {*
  2276 text \<open>
  2281   Inside the @{text "\<verbopen> \<dots> \<verbclose>"}, we have to specify a parser
  2277   Inside the \<open>\<verbopen> \<dots> \<verbclose>\<close>, we have to specify a parser
  2282   for the theorem attribute. Since the attribute does not expect any further 
  2278   for the theorem attribute. Since the attribute does not expect any further 
  2283   arguments (unlike @{text "[THEN \<dots>]"}, for instance), we use the parser @{ML
  2279   arguments (unlike \<open>[THEN \<dots>]\<close>, for instance), we use the parser @{ML
  2284   Scan.succeed}. An example for the attribute @{text "[my_sym]"} is the proof
  2280   Scan.succeed}. An example for the attribute \<open>[my_sym]\<close> is the proof
  2285 *} 
  2281 \<close> 
  2286 
  2282 
  2287 lemma test[my_sym]: "2 = Suc (Suc 0)" by simp
  2283 lemma test[my_sym]: "2 = Suc (Suc 0)" by simp
  2288 
  2284 
  2289 text {*
  2285 text \<open>
  2290   which stores the theorem @{thm test} under the name @{thm [source] test}. You
  2286   which stores the theorem @{thm test} under the name @{thm [source] test}. You
  2291   can see this, if you query the lemma: 
  2287   can see this, if you query the lemma: 
  2292 
  2288 
  2293   \begin{isabelle}
  2289   \begin{isabelle}
  2294   \isacommand{thm}~@{text "test"}\\
  2290   \isacommand{thm}~\<open>test\<close>\\
  2295   @{text "> "}~@{thm test}
  2291   \<open>> \<close>~@{thm test}
  2296   \end{isabelle}
  2292   \end{isabelle}
  2297 
  2293 
  2298   We can also use the attribute when referring to this theorem:
  2294   We can also use the attribute when referring to this theorem:
  2299 
  2295 
  2300   \begin{isabelle}
  2296   \begin{isabelle}
  2301   \isacommand{thm}~@{text "test[my_sym]"}\\
  2297   \isacommand{thm}~\<open>test[my_sym]\<close>\\
  2302   @{text "> "}~@{thm test[my_sym]}
  2298   \<open>> \<close>~@{thm test[my_sym]}
  2303   \end{isabelle}
  2299   \end{isabelle}
  2304 
  2300 
  2305   An alternative for setting up an attribute is the function @{ML_ind  setup in Attrib}.
  2301   An alternative for setting up an attribute is the function @{ML_ind  setup in Attrib}.
  2306   So instead of using \isacommand{attribute\_setup}, you can also set up the
  2302   So instead of using \isacommand{attribute\_setup}, you can also set up the
  2307   attribute as follows:
  2303   attribute as follows:
  2308 *}
  2304 \<close>
  2309 
  2305 
  2310 ML %grayML{*Attrib.setup @{binding "my_sym"} (Scan.succeed my_symmetric)
  2306 ML %grayML\<open>Attrib.setup @{binding "my_sym"} (Scan.succeed my_symmetric)
  2311   "applying the sym rule" *}
  2307   "applying the sym rule"\<close>
  2312 
  2308 
  2313 text {*
  2309 text \<open>
  2314   This gives a function from @{ML_type "theory -> theory"}, which
  2310   This gives a function from @{ML_type "theory -> theory"}, which
  2315   can be used for example with \isacommand{setup} or with
  2311   can be used for example with \isacommand{setup} or with
  2316   @{ML "Context.>> o Context.map_theory"}.\footnote{\bf FIXME: explain what happens here.}
  2312   @{ML "Context.>> o Context.map_theory"}.\footnote{\bf FIXME: explain what happens here.}
  2317 
  2313 
  2318   As an example of a slightly more complicated theorem attribute, we implement 
  2314   As an example of a slightly more complicated theorem attribute, we implement 
  2319   our own version of @{text "[THEN \<dots>]"}. This attribute will take a list of theorems
  2315   our own version of \<open>[THEN \<dots>]\<close>. This attribute will take a list of theorems
  2320   as argument and resolve the theorem with this list (one theorem 
  2316   as argument and resolve the theorem with this list (one theorem 
  2321   after another). The code for this attribute is
  2317   after another). The code for this attribute is
  2322 *}
  2318 \<close>
  2323 
  2319 
  2324 ML %grayML{*fun MY_THEN thms = 
  2320 ML %grayML\<open>fun MY_THEN thms = 
  2325 let
  2321 let
  2326   fun RS_rev thm1 thm2 = thm2 RS thm1
  2322   fun RS_rev thm1 thm2 = thm2 RS thm1
  2327 in
  2323 in
  2328   Thm.rule_attribute [] (fn _ => fn thm => fold RS_rev thms thm)
  2324   Thm.rule_attribute [] (fn _ => fn thm => fold RS_rev thms thm)
  2329 end*}
  2325 end\<close>
  2330 
  2326 
  2331 text {* 
  2327 text \<open>
  2332   where for convenience we define the reverse and curried version of @{ML RS}. 
  2328   where for convenience we define the reverse and curried version of @{ML RS}. 
  2333   The setup of this theorem attribute uses the parser @{ML thms in Attrib}, 
  2329   The setup of this theorem attribute uses the parser @{ML thms in Attrib}, 
  2334   which parses a list of theorems. 
  2330   which parses a list of theorems. 
  2335 *}
  2331 \<close>
  2336 
  2332 
  2337 attribute_setup %gray MY_THEN = {* Attrib.thms >> MY_THEN *} 
  2333 attribute_setup %gray MY_THEN = \<open>Attrib.thms >> MY_THEN\<close> 
  2338   "resolving the list of theorems with the theorem"
  2334   "resolving the list of theorems with the theorem"
  2339 
  2335 
  2340 text {* 
  2336 text \<open>
  2341   You can, for example, use this theorem attribute to turn an equation into a 
  2337   You can, for example, use this theorem attribute to turn an equation into a 
  2342   meta-equation:
  2338   meta-equation:
  2343 
  2339 
  2344   \begin{isabelle}
  2340   \begin{isabelle}
  2345   \isacommand{thm}~@{text "test[MY_THEN eq_reflection]"}\\
  2341   \isacommand{thm}~\<open>test[MY_THEN eq_reflection]\<close>\\
  2346   @{text "> "}~@{thm test[MY_THEN eq_reflection]}
  2342   \<open>> \<close>~@{thm test[MY_THEN eq_reflection]}
  2347   \end{isabelle}
  2343   \end{isabelle}
  2348 
  2344 
  2349   If you need the symmetric version as a meta-equation, you can write
  2345   If you need the symmetric version as a meta-equation, you can write
  2350 
  2346 
  2351   \begin{isabelle}
  2347   \begin{isabelle}
  2352   \isacommand{thm}~@{text "test[MY_THEN sym eq_reflection]"}\\
  2348   \isacommand{thm}~\<open>test[MY_THEN sym eq_reflection]\<close>\\
  2353   @{text "> "}~@{thm test[MY_THEN sym eq_reflection]}
  2349   \<open>> \<close>~@{thm test[MY_THEN sym eq_reflection]}
  2354   \end{isabelle}
  2350   \end{isabelle}
  2355 
  2351 
  2356   It is also possible to combine different theorem attributes, as in:
  2352   It is also possible to combine different theorem attributes, as in:
  2357   
  2353   
  2358   \begin{isabelle}
  2354   \begin{isabelle}
  2359   \isacommand{thm}~@{text "test[my_sym, MY_THEN eq_reflection]"}\\
  2355   \isacommand{thm}~\<open>test[my_sym, MY_THEN eq_reflection]\<close>\\
  2360   @{text "> "}~@{thm test[my_sym, MY_THEN eq_reflection]}
  2356   \<open>> \<close>~@{thm test[my_sym, MY_THEN eq_reflection]}
  2361   \end{isabelle}
  2357   \end{isabelle}
  2362   
  2358   
  2363   However, here also a weakness of the concept
  2359   However, here also a weakness of the concept
  2364   of theorem attributes shows through: since theorem attributes can be
  2360   of theorem attributes shows through: since theorem attributes can be
  2365   arbitrary functions, they do not commute in general. If you try
  2361   arbitrary functions, they do not commute in general. If you try
  2366 
  2362 
  2367   \begin{isabelle}
  2363   \begin{isabelle}
  2368   \isacommand{thm}~@{text "test[MY_THEN eq_reflection, my_sym]"}\\
  2364   \isacommand{thm}~\<open>test[MY_THEN eq_reflection, my_sym]\<close>\\
  2369   @{text "> "}~@{text "exception THM 1 raised: RSN: no unifiers"}
  2365   \<open>> \<close>~\<open>exception THM 1 raised: RSN: no unifiers\<close>
  2370   \end{isabelle}
  2366   \end{isabelle}
  2371 
  2367 
  2372   you get an exception indicating that the theorem @{thm [source] sym}
  2368   you get an exception indicating that the theorem @{thm [source] sym}
  2373   does not resolve with meta-equations. 
  2369   does not resolve with meta-equations. 
  2374 
  2370 
  2375   The purpose of @{ML_ind rule_attribute in Thm} is to directly manipulate
  2371   The purpose of @{ML_ind rule_attribute in Thm} is to directly manipulate
  2376   theorems.  Another usage of theorem attributes is to add and delete theorems
  2372   theorems.  Another usage of theorem attributes is to add and delete theorems
  2377   from stored data.  For example the theorem attribute @{text "[simp]"} adds
  2373   from stored data.  For example the theorem attribute \<open>[simp]\<close> adds
  2378   or deletes a theorem from the current simpset. For these applications, you
  2374   or deletes a theorem from the current simpset. For these applications, you
  2379   can use @{ML_ind declaration_attribute in Thm}. To illustrate this function,
  2375   can use @{ML_ind declaration_attribute in Thm}. To illustrate this function,
  2380   let us introduce a theorem list.
  2376   let us introduce a theorem list.
  2381 *}
  2377 \<close>
  2382 
  2378 
  2383 ML %grayML{*structure MyThms = Named_Thms
  2379 ML %grayML\<open>structure MyThms = Named_Thms
  2384   (val name = @{binding "attr_thms"} 
  2380   (val name = @{binding "attr_thms"} 
  2385    val description = "Theorems for an Attribute") *}
  2381    val description = "Theorems for an Attribute")\<close>
  2386 
  2382 
  2387 text {* 
  2383 text \<open>
  2388   We are going to modify this list by adding and deleting theorems.
  2384   We are going to modify this list by adding and deleting theorems.
  2389   For this we use the two functions @{ML MyThms.add_thm} and
  2385   For this we use the two functions @{ML MyThms.add_thm} and
  2390   @{ML MyThms.del_thm}. You can turn them into attributes 
  2386   @{ML MyThms.del_thm}. You can turn them into attributes 
  2391   with the code
  2387   with the code
  2392 *}
  2388 \<close>
  2393 
  2389 
  2394 ML %grayML{*val my_add = Thm.declaration_attribute MyThms.add_thm
  2390 ML %grayML\<open>val my_add = Thm.declaration_attribute MyThms.add_thm
  2395 val my_del = Thm.declaration_attribute MyThms.del_thm *}
  2391 val my_del = Thm.declaration_attribute MyThms.del_thm\<close>
  2396 
  2392 
  2397 text {* 
  2393 text \<open>
  2398   and set up the attributes as follows
  2394   and set up the attributes as follows
  2399 *}
  2395 \<close>
  2400 
  2396 
  2401 attribute_setup %gray my_thms = {* Attrib.add_del my_add my_del *} 
  2397 attribute_setup %gray my_thms = \<open>Attrib.add_del my_add my_del\<close> 
  2402   "maintaining a list of my_thms" 
  2398   "maintaining a list of my_thms" 
  2403 
  2399 
  2404 text {*
  2400 text \<open>
  2405   The parser @{ML_ind  add_del in Attrib} is a predefined parser for 
  2401   The parser @{ML_ind  add_del in Attrib} is a predefined parser for 
  2406   adding and deleting lemmas. Now if you prove the next lemma 
  2402   adding and deleting lemmas. Now if you prove the next lemma 
  2407   and attach to it the attribute @{text "[my_thms]"}
  2403   and attach to it the attribute \<open>[my_thms]\<close>
  2408 *}
  2404 \<close>
  2409 
  2405 
  2410 lemma trueI_2[my_thms]: "True" by simp
  2406 lemma trueI_2[my_thms]: "True" by simp
  2411 
  2407 
  2412 text {*
  2408 text \<open>
  2413   then you can see it is added to the initially empty list.
  2409   then you can see it is added to the initially empty list.
  2414 
  2410 
  2415   @{ML_response_fake [display,gray]
  2411   @{ML_response_fake [display,gray]
  2416   "MyThms.get @{context}" 
  2412   "MyThms.get @{context}" 
  2417   "[\"True\"]"}
  2413   "[\"True\"]"}
  2418 
  2414 
  2419   You can also add theorems using the command \isacommand{declare}.
  2415   You can also add theorems using the command \isacommand{declare}.
  2420 *}
  2416 \<close>
  2421 
  2417 
  2422 declare test[my_thms] trueI_2[my_thms add]
  2418 declare test[my_thms] trueI_2[my_thms add]
  2423 
  2419 
  2424 text {*
  2420 text \<open>
  2425   With this attribute, the @{text "add"} operation is the default and does 
  2421   With this attribute, the \<open>add\<close> operation is the default and does 
  2426   not need to be explicitly given. These three declarations will cause the 
  2422   not need to be explicitly given. These three declarations will cause the 
  2427   theorem list to be updated as:
  2423   theorem list to be updated as:
  2428 
  2424 
  2429   @{ML_response_fake [display,gray]
  2425   @{ML_response_fake [display,gray]
  2430   "MyThms.get @{context}"
  2426   "MyThms.get @{context}"
  2431   "[\"True\", \"Suc (Suc 0) = 2\"]"}
  2427   "[\"True\", \"Suc (Suc 0) = 2\"]"}
  2432 
  2428 
  2433   The theorem @{thm [source] trueI_2} only appears once, since the 
  2429   The theorem @{thm [source] trueI_2} only appears once, since the 
  2434   function @{ML_ind  add_thm in Thm} tests for duplicates, before extending
  2430   function @{ML_ind  add_thm in Thm} tests for duplicates, before extending
  2435   the list. Deletion from the list works as follows:
  2431   the list. Deletion from the list works as follows:
  2436 *}
  2432 \<close>
  2437 
  2433 
  2438 declare test[my_thms del]
  2434 declare test[my_thms del]
  2439 
  2435 
  2440 text {* After this, the theorem list is again: 
  2436 text \<open>After this, the theorem list is again: 
  2441 
  2437 
  2442   @{ML_response_fake [display,gray]
  2438   @{ML_response_fake [display,gray]
  2443   "MyThms.get @{context}"
  2439   "MyThms.get @{context}"
  2444   "[\"True\"]"}
  2440   "[\"True\"]"}
  2445 
  2441 
  2446   We used in this example two functions declared as @{ML_ind
  2442   We used in this example two functions declared as @{ML_ind
  2447   declaration_attribute in Thm}, but there can be any number of them. We just
  2443   declaration_attribute in Thm}, but there can be any number of them. We just
  2448   have to change the parser for reading the arguments accordingly.
  2444   have to change the parser for reading the arguments accordingly.
  2449 
  2445 
  2450   \footnote{\bf FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?}
  2446   \footnote{\bf FIXME What are: \<open>theory_attributes\<close>, \<open>proof_attributes\<close>?}
  2451   \footnote{\bf FIXME readmore}
  2447   \footnote{\bf FIXME readmore}
  2452 
  2448 
  2453   \begin{readmore}
  2449   \begin{readmore}
  2454   FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in 
  2450   FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in 
  2455   @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
  2451   @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
  2456   parsing.
  2452   parsing.
  2457   \end{readmore}
  2453   \end{readmore}
  2458 *}
  2454 \<close>
  2459 
  2455 
  2460 section {* Pretty-Printing\label{sec:pretty} *}
  2456 section \<open>Pretty-Printing\label{sec:pretty}\<close>
  2461 
  2457 
  2462 text {*
  2458 text \<open>
  2463   So far we printed out only plain strings without any formatting except for
  2459   So far we printed out only plain strings without any formatting except for
  2464   occasional explicit line breaks using @{text [quotes] "\\n"}. This is
  2460   occasional explicit line breaks using @{text [quotes] "\\n"}. This is
  2465   sufficient for ``quick-and-dirty'' printouts. For something more
  2461   sufficient for ``quick-and-dirty'' printouts. For something more
  2466   sophisticated, Isabelle includes an infrastructure for properly formatting
  2462   sophisticated, Isabelle includes an infrastructure for properly formatting
  2467   text. Most of its functions do not operate on @{ML_type string}s, but on
  2463   text. Most of its functions do not operate on @{ML_type string}s, but on
  2481   text should be printed.  However, if you want to actually output the
  2477   text should be printed.  However, if you want to actually output the
  2482   formatted text, you have to transform the pretty type back into a @{ML_type
  2478   formatted text, you have to transform the pretty type back into a @{ML_type
  2483   string}. This can be done with the function @{ML_ind  string_of in Pretty}. In what
  2479   string}. This can be done with the function @{ML_ind  string_of in Pretty}. In what
  2484   follows we will use the following wrapper function for printing a pretty
  2480   follows we will use the following wrapper function for printing a pretty
  2485   type:
  2481   type:
  2486 *}
  2482 \<close>
  2487 
  2483 
  2488 ML %grayML{*fun pprint prt = tracing (Pretty.string_of prt)*}
  2484 ML %grayML\<open>fun pprint prt = tracing (Pretty.string_of prt)\<close>
  2489 
  2485 
  2490 text {*
  2486 text \<open>
  2491   The point of the pretty-printing infrastructure is to give hints about how to
  2487   The point of the pretty-printing infrastructure is to give hints about how to
  2492   layout text and let Isabelle do the actual layout. Let us first explain
  2488   layout text and let Isabelle do the actual layout. Let us first explain
  2493   how you can insert places where a line break can occur. For this assume the
  2489   how you can insert places where a line break can occur. For this assume the
  2494   following function that replicates a string n times:
  2490   following function that replicates a string n times:
  2495 *}
  2491 \<close>
  2496 
  2492 
  2497 ML %grayML{*fun rep n str = implode (replicate n str) *}
  2493 ML %grayML\<open>fun rep n str = implode (replicate n str)\<close>
  2498 
  2494 
  2499 text {*
  2495 text \<open>
  2500   and suppose we want to print out the string:
  2496   and suppose we want to print out the string:
  2501 *}
  2497 \<close>
  2502 
  2498 
  2503 ML %grayML{*val test_str = rep 8 "fooooooooooooooobaaaaaaaaaaaar "*}
  2499 ML %grayML\<open>val test_str = rep 8 "fooooooooooooooobaaaaaaaaaaaar "\<close>
  2504 
  2500 
  2505 text {*
  2501 text \<open>
  2506   We deliberately chose a large string so that it spans over more than one line. 
  2502   We deliberately chose a large string so that it spans over more than one line. 
  2507   If we print out the string using the usual ``quick-and-dirty'' method, then
  2503   If we print out the string using the usual ``quick-and-dirty'' method, then
  2508   we obtain the ugly output:
  2504   we obtain the ugly output:
  2509 
  2505 
  2510 @{ML_response_fake [display,gray]
  2506 @{ML_response_fake [display,gray]
  2588 
  2584 
  2589   where @{ML upto} generates a list of integers. You can print out this
  2585   where @{ML upto} generates a list of integers. You can print out this
  2590   list as a ``set'', that means enclosed inside @{text [quotes] "{"} and
  2586   list as a ``set'', that means enclosed inside @{text [quotes] "{"} and
  2591   @{text [quotes] "}"}, and separated by commas using the function
  2587   @{text [quotes] "}"}, and separated by commas using the function
  2592   @{ML_ind  enum in Pretty}. For example
  2588   @{ML_ind  enum in Pretty}. For example
  2593 *}
  2589 \<close>
  2594 
  2590 
  2595 text {*
  2591 text \<open>
  2596   
  2592   
  2597 @{ML_response_fake [display,gray]
  2593 @{ML_response_fake [display,gray]
  2598 "let
  2594 "let
  2599   val ptrs = map (Pretty.str o string_of_int) (99998 upto 100020)
  2595   val ptrs = map (Pretty.str o string_of_int) (99998 upto 100020)
  2600 in
  2596 in
  2611   standard functions, you can do relatively easily the formatting
  2607   standard functions, you can do relatively easily the formatting
  2612   yourself. Assume you want to print out a list of items where like in ``English''
  2608   yourself. Assume you want to print out a list of items where like in ``English''
  2613   the last two items are separated by @{text [quotes] "and"}. For this you can
  2609   the last two items are separated by @{text [quotes] "and"}. For this you can
  2614   write the function
  2610   write the function
  2615 
  2611 
  2616 *}
  2612 \<close>
  2617 
  2613 
  2618 ML %linenosgray{*fun and_list [] = []
  2614 ML %linenosgray\<open>fun and_list [] = []
  2619   | and_list [x] = [x]
  2615   | and_list [x] = [x]
  2620   | and_list xs = 
  2616   | and_list xs = 
  2621       let 
  2617       let 
  2622         val (front, last) = split_last xs
  2618         val (front, last) = split_last xs
  2623       in
  2619       in
  2624         (Pretty.commas front) @ 
  2620         (Pretty.commas front) @ 
  2625         [Pretty.brk 1, Pretty.str "and", Pretty.brk 1, last]
  2621         [Pretty.brk 1, Pretty.str "and", Pretty.brk 1, last]
  2626       end *}
  2622       end\<close>
  2627 
  2623 
  2628 text {*
  2624 text \<open>
  2629   where Line 7 prints the beginning of the list and Line
  2625   where Line 7 prints the beginning of the list and Line
  2630   8 the last item. We have to use @{ML "Pretty.brk 1"} in order
  2626   8 the last item. We have to use @{ML "Pretty.brk 1"} in order
  2631   to insert a space (of length 1) before the 
  2627   to insert a space (of length 1) before the 
  2632   @{text [quotes] "and"}. This space is also a place where a line break 
  2628   @{text [quotes] "and"}. This space is also a place where a line break 
  2633   can occur. We do the same after the @{text [quotes] "and"}. This gives you
  2629   can occur. We do the same after the @{text [quotes] "and"}. This gives you
  2693 (P 1 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<longrightarrow>
  2689 (P 1 = P 4 \<longrightarrow> P 4 \<and> P 3 \<and> P 2 \<and> P 1) \<longrightarrow>
  2694 P 4 \<and> P 3 \<and> P 2 \<and> P 1"}
  2690 P 4 \<and> P 3 \<and> P 2 \<and> P 1"}
  2695 
  2691 
  2696   We use the function @{ML_ind pretty_term in Syntax} for pretty-printing
  2692   We use the function @{ML_ind pretty_term in Syntax} for pretty-printing
  2697   terms. Next we like to pretty-print a term and its type. For this we use the
  2693   terms. Next we like to pretty-print a term and its type. For this we use the
  2698   function @{text "tell_type"}.
  2694   function \<open>tell_type\<close>.
  2699 *}
  2695 \<close>
  2700 
  2696 
  2701 ML %linenosgray{*fun tell_type ctxt trm = 
  2697 ML %linenosgray\<open>fun tell_type ctxt trm = 
  2702 let
  2698 let
  2703   fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s))
  2699   fun pstr s = Pretty.breaks (map Pretty.str (space_explode " " s))
  2704   val ptrm = Pretty.quote (Syntax.pretty_term ctxt trm)
  2700   val ptrm = Pretty.quote (Syntax.pretty_term ctxt trm)
  2705   val pty  = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of trm))
  2701   val pty  = Pretty.quote (Syntax.pretty_typ ctxt (fastype_of trm))
  2706 in
  2702 in
  2707   pprint (Pretty.blk (0, 
  2703   pprint (Pretty.blk (0, 
  2708     (pstr "The term " @ [ptrm] @ pstr " has type " 
  2704     (pstr "The term " @ [ptrm] @ pstr " has type " 
  2709       @ [pty, Pretty.str "."])))
  2705       @ [pty, Pretty.str "."])))
  2710 end*}
  2706 end\<close>
  2711 
  2707 
  2712 text {*
  2708 text \<open>
  2713   In Line 3 we define a function that inserts possible linebreaks in places
  2709   In Line 3 we define a function that inserts possible linebreaks in places
  2714   where a space is. In Lines 4 and 5 we pretty-print the term and its type
  2710   where a space is. In Lines 4 and 5 we pretty-print the term and its type
  2715   using the functions @{ML pretty_term in Syntax} and @{ML_ind 
  2711   using the functions @{ML pretty_term in Syntax} and @{ML_ind 
  2716   pretty_typ in Syntax}. We also use the function @{ML_ind quote in
  2712   pretty_typ in Syntax}. We also use the function @{ML_ind quote in
  2717   Pretty} in order to enclose the term and type inside quotation marks. In
  2713   Pretty} in order to enclose the term and type inside quotation marks. In
  2736   @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
  2732   @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
  2737   contains pretty-printing functions for terms, types, theorems and so on.
  2733   contains pretty-printing functions for terms, types, theorems and so on.
  2738   
  2734   
  2739   @{ML_file "Pure/PIDE/markup.ML"}
  2735   @{ML_file "Pure/PIDE/markup.ML"}
  2740   \end{readmore}
  2736   \end{readmore}
  2741 *}
  2737 \<close>
  2742 
  2738 
  2743 section {* Summary *}
  2739 section \<open>Summary\<close>
  2744 
  2740 
  2745 text {*
  2741 text \<open>
  2746   \begin{conventions}
  2742   \begin{conventions}
  2747   \begin{itemize}
  2743   \begin{itemize}
  2748   \item Start with a proper context and then pass it around 
  2744   \item Start with a proper context and then pass it around 
  2749   through all your functions.
  2745   through all your functions.
  2750   \end{itemize}
  2746   \end{itemize}
  2751   \end{conventions}
  2747   \end{conventions}
  2752 *}
  2748 \<close>
  2753 
  2749 
  2754 end
  2750 end