ProgTutorial/FirstSteps.thy
changeset 250 ab9e09076462
parent 249 5c211dd7e5ad
child 251 cccb25ee1309
equal deleted inserted replaced
249:5c211dd7e5ad 250:ab9e09076462
     7 text {*
     7 text {*
     8   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code
     8   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code
     9   in Isabelle is part of a theory. If you want to follow the code given in
     9   in Isabelle is part of a theory. If you want to follow the code given in
    10   this chapter, we assume you are working inside the theory starting with
    10   this chapter, we assume you are working inside the theory starting with
    11 
    11 
    12   \begin{center}
    12   \begin{quote}
    13   \begin{tabular}{@ {}l}
    13   \begin{tabular}{@ {}l}
    14   \isacommand{theory} FirstSteps\\
    14   \isacommand{theory} FirstSteps\\
    15   \isacommand{imports} Main\\
    15   \isacommand{imports} Main\\
    16   \isacommand{begin}\\
    16   \isacommand{begin}\\
    17   \ldots
    17   \ldots
    18   \end{tabular}
    18   \end{tabular}
    19   \end{center}
    19   \end{quote}
    20 
    20 
    21   We also generally assume you are working with HOL. The given examples might
    21   We also generally assume you are working with HOL. The given examples might
    22   need to be adapted if you work in a different logic.
    22   need to be adapted if you work in a different logic.
    23 *}
    23 *}
    24 
    24 
    57 
    57 
    58   Once a portion of code is relatively stable, you usually want to export it
    58   Once a portion of code is relatively stable, you usually want to export it
    59   to a separate ML-file. Such files can then be included somewhere inside a 
    59   to a separate ML-file. Such files can then be included somewhere inside a 
    60   theory by using the command \isacommand{use}. For example
    60   theory by using the command \isacommand{use}. For example
    61 
    61 
    62   \begin{center}
    62   \begin{quote}
    63   \begin{tabular}{@ {}l}
    63   \begin{tabular}{@ {}l}
    64   \isacommand{theory} FirstSteps\\
    64   \isacommand{theory} FirstSteps\\
    65   \isacommand{imports} Main\\
    65   \isacommand{imports} Main\\
    66   \isacommand{uses}~@{text "(\"file_to_be_included.ML\")"} @{text "\<dots>"}\\
    66   \isacommand{uses}~@{text "(\"file_to_be_included.ML\")"} @{text "\<dots>"}\\
    67   \isacommand{begin}\\
    67   \isacommand{begin}\\
    68   \ldots\\
    68   \ldots\\
    69   \isacommand{use}~@{text "\"file_to_be_included.ML\""}\\
    69   \isacommand{use}~@{text "\"file_to_be_included.ML\""}\\
    70   \ldots
    70   \ldots
    71   \end{tabular}
    71   \end{tabular}
    72   \end{center}
    72   \end{quote}
    73 
    73 
    74   The \isacommand{uses}-command in the header of the theory is needed in order 
    74   The \isacommand{uses}-command in the header of the theory is needed in order 
    75   to indicate the dependency of the theory on the ML-file. Alternatively, the 
    75   to indicate the dependency of the theory on the ML-file. Alternatively, the 
    76   file can be included by just writing in the header
    76   file can be included by just writing in the header
    77 
    77 
    78   \begin{center}
    78   \begin{quote}
    79   \begin{tabular}{@ {}l}
    79   \begin{tabular}{@ {}l}
    80   \isacommand{theory} FirstSteps\\
    80   \isacommand{theory} FirstSteps\\
    81   \isacommand{imports} Main\\
    81   \isacommand{imports} Main\\
    82   \isacommand{uses} @{text "\"file_to_be_included.ML\""} @{text "\<dots>"}\\
    82   \isacommand{uses} @{text "\"file_to_be_included.ML\""} @{text "\<dots>"}\\
    83   \isacommand{begin}\\
    83   \isacommand{begin}\\
    84   \ldots
    84   \ldots
    85   \end{tabular}
    85   \end{tabular}
    86   \end{center}
    86   \end{quote}
    87 
    87 
    88   Note that no parentheses are given this time.
    88   Note that no parentheses are given this time.
    89 *}
    89 *}
    90 
    90 
    91 section {* Debugging and Printing\label{sec:printing} *}
    91 section {* Debugging and Printing\label{sec:printing} *}
   179   "\"1\""}
   179   "\"1\""}
   180 
   180 
   181   A @{ML_type cterm} can be transformed into a string by the following function.
   181   A @{ML_type cterm} can be transformed into a string by the following function.
   182 *}
   182 *}
   183 
   183 
   184 ML{*fun str_of_cterm ctxt t =  
   184 ML{*fun string_of_cterm ctxt t =  
   185    Syntax.string_of_term ctxt (term_of t)*}
   185    Syntax.string_of_term ctxt (term_of t)*}
   186 
   186 
   187 text {*
   187 text {*
   188   In this example the function @{ML term_of} extracts the @{ML_type term} from
   188   In this example the function @{ML term_of} extracts the @{ML_type term} from
   189   a @{ML_type cterm}.  If there are more than one @{ML_type cterm}s to be
   189   a @{ML_type cterm}.  If there are more than one @{ML_type cterm}s to be
   190   printed, you can use the function @{ML commas} to separate them.
   190   printed, you can use the function @{ML commas} to separate them.
   191 *} 
   191 *} 
   192 
   192 
   193 ML{*fun str_of_cterms ctxt ts =  
   193 ML{*fun string_of_cterms ctxt ts =  
   194    commas (map (str_of_cterm ctxt) ts)*}
   194    commas (map (string_of_cterm ctxt) ts)*}
   195 
   195 
   196 text {*
   196 text {*
   197   The easiest way to get the string of a theorem is to transform it
   197   The easiest way to get the string of a theorem is to transform it
   198   into a @{ML_type cterm} using the function @{ML crep_thm}. 
   198   into a @{ML_type cterm} using the function @{ML crep_thm}. 
   199 *}
   199 *}
   200 
   200 
   201 ML{*fun str_of_thm ctxt thm =
   201 ML{*fun string_of_thm ctxt thm =
   202   str_of_cterm ctxt (#prop (crep_thm thm))*}
   202   string_of_cterm ctxt (#prop (crep_thm thm))*}
   203 
   203 
   204 text {*
   204 text {*
   205   Theorems also include schematic variables, such as @{text "?P"}, 
   205   Theorems also include schematic variables, such as @{text "?P"}, 
   206   @{text "?Q"} and so on. 
   206   @{text "?Q"} and so on. 
   207 
   207 
   208   @{ML_response_fake [display, gray]
   208   @{ML_response_fake [display, gray]
   209   "writeln (str_of_thm @{context} @{thm conjI})"
   209   "writeln (string_of_thm @{context} @{thm conjI})"
   210   "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"}
   210   "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"}
   211 
   211 
   212   In order to improve the readability of theorems we convert
   212   In order to improve the readability of theorems we convert
   213   these schematic variables into free variables using the 
   213   these schematic variables into free variables using the 
   214   function @{ML Variable.import_thms}.
   214   function @{ML Variable.import_thms}.
   219   val ((_, [thm']), _) = Variable.import_thms true [thm] ctxt
   219   val ((_, [thm']), _) = Variable.import_thms true [thm] ctxt
   220 in
   220 in
   221   thm'
   221   thm'
   222 end
   222 end
   223 
   223 
   224 fun str_of_thm_no_vars ctxt thm =
   224 fun string_of_thm_no_vars ctxt thm =
   225   str_of_cterm ctxt (#prop (crep_thm (no_vars ctxt thm)))*}
   225   string_of_cterm ctxt (#prop (crep_thm (no_vars ctxt thm)))*}
   226 
   226 
   227 text {* 
   227 text {* 
   228   Theorem @{thm [source] conjI} is now printed as follows:
   228   Theorem @{thm [source] conjI} is now printed as follows:
   229 
   229 
   230   @{ML_response_fake [display, gray]
   230   @{ML_response_fake [display, gray]
   231   "writeln (str_of_thm_no_vars @{context} @{thm conjI})"
   231   "writeln (string_of_thm_no_vars @{context} @{thm conjI})"
   232   "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
   232   "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
   233   
   233   
   234   Again the function @{ML commas} helps with printing more than one theorem. 
   234   Again the function @{ML commas} helps with printing more than one theorem. 
   235 *}
   235 *}
   236 
   236 
   237 ML{*fun str_of_thms ctxt thms =  
   237 ML{*fun string_of_thms ctxt thms =  
   238   commas (map (str_of_thm ctxt) thms)
   238   commas (map (string_of_thm ctxt) thms)
   239 
   239 
   240 fun str_of_thms_no_vars ctxt thms =  
   240 fun string_of_thms_no_vars ctxt thms =  
   241   commas (map (str_of_thm_no_vars ctxt) thms) *}
   241   commas (map (string_of_thm_no_vars ctxt) thms) *}
   242 
   242 
   243 section {* Combinators\label{sec:combinators} *}
   243 section {* Combinators\label{sec:combinators} *}
   244 
   244 
   245 text {*
   245 text {*
   246   (FIXME: Calling convention)
       
   247 
       
   248   For beginners perhaps the most puzzling parts in the existing code of Isabelle are
   246   For beginners perhaps the most puzzling parts in the existing code of Isabelle are
   249   the combinators. At first they seem to greatly obstruct the
   247   the combinators. At first they seem to greatly obstruct the
   250   comprehension of the code, but after getting familiar with them, they
   248   comprehension of the code, but after getting familiar with them, they
   251   actually ease the understanding and also the programming.
   249   actually ease the understanding and also the programming.
   252 
   250 
   285   the first component of the pair (Line 4) and finally incrementing the first 
   283   the first component of the pair (Line 4) and finally incrementing the first 
   286   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   284   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   287   common when dealing with theories (for example by adding a definition, followed by
   285   common when dealing with theories (for example by adding a definition, followed by
   288   lemmas and so on). The reverse application allows you to read what happens in 
   286   lemmas and so on). The reverse application allows you to read what happens in 
   289   a top-down manner. This kind of coding should also be familiar, 
   287   a top-down manner. This kind of coding should also be familiar, 
   290   if you have been exposed to Haskell's do-notation. Writing the function @{ML inc_by_five} using 
   288   if you have been exposed to Haskell's {\it do}-notation. Writing the function 
   291   the reverse application is much clearer than writing
   289   @{ML inc_by_five} using the reverse application is much clearer than writing
   292 *}
   290 *}
   293 
   291 
   294 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   292 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   295 
   293 
   296 text {* or *}
   294 text {* or *}
   479   "Pure/library.ML"}
   477   "Pure/library.ML"}
   480   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   478   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   481   contains further information about combinators.
   479   contains further information about combinators.
   482   \end{readmore}
   480   \end{readmore}
   483  
   481  
       
   482   (FIXME: say something abou calling conventions)
   484 *}
   483 *}
   485 
   484 
   486 
   485 
   487 section {* Antiquotations *}
   486 section {* Antiquotations *}
   488 
   487 
   541 end*}
   540 end*}
   542 
   541 
   543 text {*
   542 text {*
   544   The function @{ML dest_ss in MetaSimplifier} returns a record containing all
   543   The function @{ML dest_ss in MetaSimplifier} returns a record containing all
   545   information stored in the simpset, but we are only interested in the names of the
   544   information stored in the simpset, but we are only interested in the names of the
   546   simp-rules. So now you can feed in the current simpset into this function. 
   545   simp-rules. Now you can feed in the current simpset into this function. 
   547   The current simpset can be referred to using the antiquotation @{text "@{simpset}"}.
   546   The current simpset can be referred to using the antiquotation @{text "@{simpset}"}.
   548 
   547 
   549   @{ML_response_fake [display,gray] 
   548   @{ML_response_fake [display,gray] 
   550   "get_thm_names_from_ss @{simpset}" 
   549   "get_thm_names_from_ss @{simpset}" 
   551   "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   550   "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   553   Again, this way of referencing simpsets makes you independent from additions
   552   Again, this way of referencing simpsets makes you independent from additions
   554   of lemmas to the simpset by the user that potentially cause loops.
   553   of lemmas to the simpset by the user that potentially cause loops.
   555 
   554 
   556   On the ML-level of Isabelle, you often have to work with qualified names;
   555   On the ML-level of Isabelle, you often have to work with qualified names;
   557   these are strings with some additional information, such as positional information
   556   these are strings with some additional information, such as positional information
   558   and qualifiers. Such bindings can be generated with the antiquotation 
   557   and qualifiers. Such qualified names can be generated with the antiquotation 
   559   @{text "@{binding \<dots>}"}.
   558   @{text "@{binding \<dots>}"}.
   560 
   559 
   561   @{ML_response [display,gray]
   560   @{ML_response [display,gray]
   562   "@{binding \"name\"}"
   561   "@{binding \"name\"}"
   563   "name"}
   562   "name"}
   580   \isacommand{thm}~@{text "TrueConj_def"}\\
   579   \isacommand{thm}~@{text "TrueConj_def"}\\
   581   @{text "> "}~@{thm TrueConj_def}
   580   @{text "> "}~@{thm TrueConj_def}
   582   \end{isabelle}
   581   \end{isabelle}
   583 
   582 
   584   (FIXME give a better example why bindings are important; maybe
   583   (FIXME give a better example why bindings are important; maybe
   585   give a pointer to \isacommand{local\_setup})
   584   give a pointer to \isacommand{local\_setup}; if not, then explain
       
   585   why @{ML snd} is needed)
   586 
   586 
   587   While antiquotations have many applications, they were originally introduced
   587   While antiquotations have many applications, they were originally introduced
   588   in order to avoid explicit bindings of theorems such as:
   588   in order to avoid explicit bindings of theorems such as:
   589 *}
   589 *}
   590 
   590 
   603 
   603 
   604 section {* Terms and Types *}
   604 section {* Terms and Types *}
   605 
   605 
   606 text {*
   606 text {*
   607   One way to construct Isabelle terms, is by using the antiquotation 
   607   One way to construct Isabelle terms, is by using the antiquotation 
   608   \mbox{@{text "@{term \<dots>}"}}. For example:
   608   \mbox{@{text "@{term \<dots>}"}}. For example
   609 
   609 
   610   @{ML_response [display,gray] 
   610   @{ML_response [display,gray] 
   611 "@{term \"(a::nat) + b = c\"}" 
   611 "@{term \"(a::nat) + b = c\"}" 
   612 "Const (\"op =\", \<dots>) $ 
   612 "Const (\"op =\", \<dots>) $ 
   613   (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
   613   (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
   614 
   614 
   615   will show the term @{term "(a::nat) + b = c"}, but printed using the internal
   615   will show the term @{term "(a::nat) + b = c"}, but printed using the internal
   616   representation corresponding to the data type @{ML_type "term"}.
   616   representation corresponding to the datatype @{ML_type "term"}. Since Isabelle
   617   
   617   uses Church-style terms, the datatype @{ML_type term} must be defined in 
   618   This internal representation uses the usual de Bruijn index mechanism---where
   618   conjunction with types, that is the datatype @{ML_type typ}:
   619   bound variables are represented by the constructor @{ML Bound}.  The index in
   619 *}  
       
   620 
       
   621 ML_val{*datatype typ =
       
   622   Type  of string * typ list 
       
   623 | TFree of string * sort 
       
   624 | TVar  of indexname * sort
       
   625 datatype term =
       
   626   Const of string * typ 
       
   627 | Free of string * typ 
       
   628 | Var of indexname * typ 
       
   629 | Bound of int 
       
   630 | Abs of string * typ * term 
       
   631 | $ of term * term *}
       
   632 
       
   633 text {*
       
   634   The datatype for terms uses the usual de Bruijn index mechanism---where
       
   635   bound variables are represented by the constructor @{ML Bound}.  
       
   636 
       
   637   @{ML_response_fake [display, gray]
       
   638   "@{term \"\<lambda>x y. x y\"}"
       
   639   "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"}
       
   640 
       
   641   The index in
   620   @{ML Bound} refers to the number of Abstractions (@{ML Abs}) we have to skip
   642   @{ML Bound} refers to the number of Abstractions (@{ML Abs}) we have to skip
   621   until we hit the @{ML Abs} that binds the corresponding variable. Note that
   643   until we hit the @{ML Abs} that binds the corresponding variable. Note that
   622   the names of bound variables are kept at abstractions for printing purposes,
   644   the names of bound variables are kept at abstractions for printing purposes,
   623   and so should be treated only as ``comments''.  Application in Isabelle is
   645   and so should be treated only as ``comments''.  Application in Isabelle is
   624   realised with the term-constructor @{ML $}.
   646   realised with the term-constructor @{ML $}. 
       
   647 
       
   648   Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free})
       
   649   and variables (term-constructor @{ML Var}). The latter correspond to the schematic 
       
   650   variables that show up with a question mark in front of them. Consider the following
       
   651   two examples
       
   652   
       
   653   @{ML_response_fake [display, gray]
       
   654 "let
       
   655   val v1 = Var ((\"x\", 3), @{typ bool})
       
   656   val v2 = Var ((\"x1\",3), @{typ bool})
       
   657 in
       
   658   writeln (Syntax.string_of_term @{context} v1);
       
   659   writeln (Syntax.string_of_term @{context} v2)
       
   660 end"
       
   661 "?x3
       
   662 ?x1.3"}
       
   663 
       
   664   This is different from a free variable
       
   665 
       
   666   @{ML_response_fake [display, gray]
       
   667   "@{term \"x\"}"
       
   668   "x"}
       
   669 
       
   670   When constructing terms, you are usually concerned with free variables (for example
       
   671   you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). 
       
   672   If you deal with theorems, you have to observe the distinction. The same holds
       
   673   for types.
   625 
   674 
   626   \begin{readmore}
   675   \begin{readmore}
   627   Terms are described in detail in \isccite{sec:terms}. Their
   676   Terms and types are described in detail in \isccite{sec:terms}. Their
   628   definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}.
   677   definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}.
   629   \end{readmore}
   678   \end{readmore}
   630   
   679   
   631   Constructing terms via antiquotations has the advantage that only typable
   680   Constructing terms via antiquotations has the advantage that only typable
   632   terms can be constructed. For example
   681   terms can be constructed. For example
   633 
   682 
   634   @{ML_response_fake_both [display,gray]
   683   @{ML_response_fake_both [display,gray]
   635   "@{term \"(x::nat) x\"}"
   684   "@{term \"x x\"}"
   636   "Type unification failed \<dots>"}
   685   "Type unification failed: Occurs check!"}
   637 
   686 
   638   raises a typing error, while it perfectly ok to construct the term
   687   raises a typing error, while it perfectly ok to construct the term
   639   
   688   
   640   @{ML [display,gray] "Free (\"x\", @{typ nat}) $ Free (\"x\", @{typ nat})"}
   689   @{ML [display,gray] "Free (\"x\", @{typ nat}) $ Free (\"x\", @{typ nat})"}
   641 
   690 
   686   Types are described in detail in \isccite{sec:types}. Their
   735   Types are described in detail in \isccite{sec:types}. Their
   687   definition and many useful operations are implemented 
   736   definition and many useful operations are implemented 
   688   in @{ML_file "Pure/type.ML"}.
   737   in @{ML_file "Pure/type.ML"}.
   689   \end{readmore}
   738   \end{readmore}
   690 *}
   739 *}
   691 
       
   692 
   740 
   693 section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *} 
   741 section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *} 
   694 
   742 
   695 text {*
   743 text {*
   696   While antiquotations are very convenient for constructing terms, they can
   744   While antiquotations are very convenient for constructing terms, they can
   863   by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at
   911   by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at
   864 
   912 
   865   @{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"}
   913   @{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"}
   866 
   914 
   867   the name of the constant @{text "Nil"} depends on the theory in which the
   915   the name of the constant @{text "Nil"} depends on the theory in which the
   868   term constructor is defined (@{text "List"}) and also in which data type
   916   term constructor is defined (@{text "List"}) and also in which datatype
   869   (@{text "list"}). Even worse, some constants have a name involving
   917   (@{text "list"}). Even worse, some constants have a name involving
   870   type-classes. Consider for example the constants for @{term "zero"} and
   918   type-classes. Consider for example the constants for @{term "zero"} and
   871   \mbox{@{text "(op *)"}}:
   919   \mbox{@{text "(op *)"}}:
   872 
   920 
   873   @{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"op *\"})" 
   921   @{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"op *\"})" 
   875  Const (\"HOL.times_class.times\", \<dots>))"}
   923  Const (\"HOL.times_class.times\", \<dots>))"}
   876 
   924 
   877   While you could use the complete name, for example 
   925   While you could use the complete name, for example 
   878   @{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or
   926   @{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or
   879   matching against @{text "Nil"}, this would make the code rather brittle. 
   927   matching against @{text "Nil"}, this would make the code rather brittle. 
   880   The reason is that the theory and the name of the data type can easily change. 
   928   The reason is that the theory and the name of the datatype can easily change. 
   881   To make the code more robust, it is better to use the antiquotation 
   929   To make the code more robust, it is better to use the antiquotation 
   882   @{text "@{const_name \<dots>}"}. With this antiquotation you can harness the 
   930   @{text "@{const_name \<dots>}"}. With this antiquotation you can harness the 
   883   variable parts of the constant's name. Therefore a function for 
   931   variable parts of the constant's name. Therefore a function for 
   884   matching against constants that have a polymorphic type should 
   932   matching against constants that have a polymorphic type should 
   885   be written as follows.
   933   be written as follows.
   916   when defining constants. For example the function returning a function 
   964   when defining constants. For example the function returning a function 
   917   type is as follows:
   965   type is as follows:
   918 
   966 
   919 *} 
   967 *} 
   920 
   968 
   921 ML{*fun make_fun_type tau1 tau2 = Type ("fun", [tau1, tau2]) *}
   969 ML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
   922 
   970 
   923 text {* This can be equally written with the combinator @{ML "-->"} as: *}
   971 text {* This can be equally written with the combinator @{ML "-->"} as: *}
   924 
   972 
   925 ML{*fun make_fun_type tau1 tau2 = tau1 --> tau2 *}
   973 ML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
   926 
   974 
   927 text {*
   975 text {*
   928   A handy function for manipulating terms is @{ML map_types}: it takes a 
   976   A handy function for manipulating terms is @{ML map_types}: it takes a 
   929   function and applies it to every type in a term. You can, for example,
   977   function and applies it to every type in a term. You can, for example,
   930   change every @{typ nat} in a term into an @{typ int} using the function:
   978   change every @{typ nat} in a term into an @{typ int} using the function:
   943 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
   991 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
   944 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
   992 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
   945            $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"}
   993            $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"}
   946 
   994 
   947   (FIXME: a readmore about types)
   995   (FIXME: a readmore about types)
       
   996 
       
   997   (Explain @{ML Term.add_tvarsT} and @{ML Term.add_tfreesT})
   948 *}
   998 *}
   949 
   999 
   950 
  1000 
   951 section {* Type-Checking *}
  1001 section {* Type-Checking *}
   952 
  1002 
  1661 
  1711 
  1662 section {* Storing Theorems\label{sec:storing} (TBD) *}
  1712 section {* Storing Theorems\label{sec:storing} (TBD) *}
  1663 
  1713 
  1664 text {* @{ML PureThy.add_thms_dynamic} *}
  1714 text {* @{ML PureThy.add_thms_dynamic} *}
  1665 
  1715 
       
  1716 local_setup {* 
       
  1717   LocalTheory.note Thm.theoremK 
       
  1718     ((@{binding "allI_alt"}, []), [@{thm allI}]) #> snd *}
  1666 
  1719 
  1667 
  1720 
  1668 (* FIXME: some code below *)
  1721 (* FIXME: some code below *)
  1669 
  1722 
  1670 (*<*)
  1723 (*<*)
  1908   @{ML_response_fake [display,gray]
  1961   @{ML_response_fake [display,gray]
  1909   "tell_type @{context} @{term \"min (Suc 0)\"}"
  1962   "tell_type @{context} @{term \"min (Suc 0)\"}"
  1910   "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."}
  1963   "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."}
  1911   
  1964   
  1912   To see the proper linebreaking, you can try out the function on a bigger term 
  1965   To see the proper linebreaking, you can try out the function on a bigger term 
  1913   and type.
  1966   and type. For example:
  1914 
  1967 
  1915   @{ML_response_fake [display,gray]
  1968   @{ML_response_fake [display,gray]
  1916   "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
  1969   "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
  1917   "The term \"op = (op = (op = (op = (op = op =))))\" has type 
  1970   "The term \"op = (op = (op = (op = (op = op =))))\" has type 
  1918 \"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."}
  1971 \"((((('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool) \<Rightarrow> bool\"."}
  1919 
  1972 
  1920 *}
  1973 *}
  1921 
  1974 
       
  1975 ML {* pprint (Pretty.big_list "header"  (map (Pretty.str o string_of_int) (4 upto 10))) *}
       
  1976 
       
  1977 text {*
       
  1978 chunks inserts forced breaks (unlike blk where you have to do this yourself)
       
  1979 *}
       
  1980 
       
  1981 ML {* (Pretty.chunks [Pretty.str "a", Pretty.str "b"], 
       
  1982        Pretty.blk (0, [Pretty.str "a", Pretty.str "b"])) *}
       
  1983 
       
  1984 ML {*
       
  1985 fun setmp_show_all_types f =
       
  1986    setmp show_all_types
       
  1987          (! show_types orelse ! show_sorts orelse ! show_all_types) f;
       
  1988 
       
  1989 val ctxt = @{context};
       
  1990 val t1 = @{term "undefined::nat"};
       
  1991 val t2 = @{term "Suc y"};
       
  1992 val pty =        Pretty.block (Pretty.breaks
       
  1993              [(setmp show_question_marks false o setmp_show_all_types)
       
  1994                   (Syntax.pretty_term ctxt) t1,
       
  1995               Pretty.str "=", Syntax.pretty_term ctxt t2]);
       
  1996 pty |> Pretty.string_of |> priority
       
  1997 *}
       
  1998 
       
  1999 text {* the infrastructure of Syntax-pretty-term makes sure it is printed nicely  *}
       
  2000 
       
  2001 
       
  2002 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of  |> writeln *}
       
  2003 ML {* (Pretty.str "bar") |> Pretty.string_of |> writeln *}
       
  2004 
       
  2005 
       
  2006 ML {* Pretty.mark Markup.subgoal (Pretty.str "foo") |> Pretty.string_of  |> writeln *}
       
  2007 ML {* (Pretty.str "bar") |> Pretty.string_of |> writeln *}
       
  2008 
  1922 text {*
  2009 text {*
  1923   Still to be done:
  2010   Still to be done:
  1924 
       
  1925   @{ML Pretty.big_list},
       
  1926 
       
  1927   @{ML Pretty.chunks}
       
  1928 
       
  1929   equations
       
  1930 
       
  1931   colours
       
  1932 
  2011 
  1933   What happens with big formulae?
  2012   What happens with big formulae?
  1934 
  2013 
  1935   \begin{readmore}
  2014   \begin{readmore}
  1936   The general infrastructure for pretty-printing is implemented in the file
  2015   The general infrastructure for pretty-printing is implemented in the file
  1937   @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
  2016   @{ML_file "Pure/General/pretty.ML"}. The file @{ML_file "Pure/Syntax/syntax.ML"}
  1938   contains pretty-printing functions for terms, types, theorems and so on.
  2017   contains pretty-printing functions for terms, types, theorems and so on.
       
  2018   
       
  2019   @{ML_file "Pure/General/markup.ML"}
  1939   \end{readmore}
  2020   \end{readmore}
  1940 *}
  2021 *}
  1941 
  2022 
       
  2023 text {*
       
  2024   printing into the goal buffer as part of the proof state
       
  2025 *}
       
  2026 
       
  2027 
       
  2028 ML {* Pretty.mark Markup.hilite (Pretty.str "foo") |> Pretty.string_of  |> writeln *}
       
  2029 ML {* (Pretty.str "bar") |> Pretty.string_of |> writeln *}
       
  2030 
       
  2031 text {* writing into the goal buffer *}
       
  2032 
       
  2033 ML {* fun my_hook interactive state =
       
  2034          (interactive ? Proof.goal_message (fn () => Pretty.str  
       
  2035 "foo")) state
       
  2036 *}
       
  2037 
       
  2038 setup {* Context.theory_map (Specification.add_theorem_hook my_hook) *}
       
  2039 
       
  2040 lemma "False"
       
  2041 oops
       
  2042 
       
  2043 
  1942 section {* Misc (TBD) *}
  2044 section {* Misc (TBD) *}
  1943 
  2045 
  1944 ML {*DatatypePackage.get_datatype @{theory} "List.list"*}
  2046 ML {*DatatypePackage.get_datatype @{theory} "List.list"*}
  1945 
  2047 
  1946 end
  2048 end