ProgTutorial/First_Steps.thy
changeset 517 d8c376662bb4
parent 504 1d1165432c9f
child 538 e9fd5eff62c1
equal deleted inserted replaced
516:fb6c29a90003 517:d8c376662bb4
     1 theory First_Steps
     1 theory First_Steps
     2 imports Base
     2 imports Base
     3 begin
     3 begin
     4 
     4 
     5 (*<*)
       
     6 setup{*
       
     7 open_file_with_prelude 
       
     8   "First_Steps_Code.thy"
       
     9   ["theory First_Steps", "imports Main", "begin"]
       
    10 *}
       
    11 (*>*)
       
    12 
     5 
    13 chapter {* First Steps\label{chp:firststeps} *}
     6 chapter {* First Steps\label{chp:firststeps} *}
    14 
     7 
    15 text {*
     8 text {*
    16   \begin{flushright}
     9   \begin{flushright}
   159   we just use the functions @{ML_ind writeln in Pretty}  from the structure
   152   we just use the functions @{ML_ind writeln in Pretty}  from the structure
   160   @{ML_struct Pretty} and @{ML_ind pretty_term in Syntax} from the structure
   153   @{ML_struct Pretty} and @{ML_ind pretty_term in Syntax} from the structure
   161   @{ML_struct Syntax}. For more convenience, we bind them to the toplevel.
   154   @{ML_struct Syntax}. For more convenience, we bind them to the toplevel.
   162 *}
   155 *}
   163 
   156 
   164 ML{*val pretty_term = Syntax.pretty_term
   157 ML %grayML{*val pretty_term = Syntax.pretty_term
   165 val pwriteln = Pretty.writeln*}
   158 val pwriteln = Pretty.writeln*}
   166 
   159 
   167 text {*
   160 text {*
   168   They can now be used as follows
   161   They can now be used as follows
   169 
   162 
   174   If there is more than one term to be printed, you can use the 
   167   If there is more than one term to be printed, you can use the 
   175   function @{ML_ind commas in Pretty} and @{ML_ind block in Pretty} 
   168   function @{ML_ind commas in Pretty} and @{ML_ind block in Pretty} 
   176   to separate them.
   169   to separate them.
   177 *} 
   170 *} 
   178 
   171 
   179 ML{*fun pretty_terms ctxt trms =  
   172 ML %grayML{*fun pretty_terms ctxt trms =  
   180   Pretty.block (Pretty.commas (map (pretty_term ctxt) trms))*}
   173   Pretty.block (Pretty.commas (map (pretty_term ctxt) trms))*}
   181 
   174 
   182 text {*
   175 text {*
   183   You can also print out terms together with their typing information.
   176   You can also print out terms together with their typing information.
   184   For this you need to set the configuration value 
   177   For this you need to set the configuration value 
   185   @{ML_ind show_types in Syntax} to @{ML true}.
   178   @{ML_ind show_types in Syntax} to @{ML true}.
   186 *}
   179 *}
   187 
   180 
   188 ML{*val show_types_ctxt = Config.put show_types true @{context}*}
   181 ML %grayML{*val show_types_ctxt = Config.put show_types true @{context}*}
   189 
   182 
   190 text {*
   183 text {*
   191   Now by using this context @{ML pretty_term} prints out
   184   Now by using this context @{ML pretty_term} prints out
   192 
   185 
   193   @{ML_response_fake [display, gray]
   186   @{ML_response_fake [display, gray]
   220   \end{itemize}
   213   \end{itemize}
   221 
   214 
   222   A @{ML_type cterm} can be printed with the following function.
   215   A @{ML_type cterm} can be printed with the following function.
   223 *}
   216 *}
   224 
   217 
   225 ML{*fun pretty_cterm ctxt ctrm =  
   218 ML %grayML %grayML{*fun pretty_cterm ctxt ctrm =  
   226   pretty_term ctxt (term_of ctrm)*}
   219   pretty_term ctxt (term_of ctrm)*}
   227 
   220 
   228 text {*
   221 text {*
   229   Here the function @{ML_ind term_of in Thm} extracts the @{ML_type
   222   Here the function @{ML_ind term_of in Thm} extracts the @{ML_type
   230   term} from a @{ML_type cterm}.  More than one @{ML_type cterm}s can be
   223   term} from a @{ML_type cterm}.  More than one @{ML_type cterm}s can be
   231   printed again with @{ML commas in Pretty}.
   224   printed again with @{ML commas in Pretty}.
   232 *} 
   225 *} 
   233 
   226 
   234 ML{*fun pretty_cterms ctxt ctrms =  
   227 ML %grayML{*fun pretty_cterms ctxt ctrms =  
   235   Pretty.block (Pretty.commas (map (pretty_cterm ctxt) ctrms))*}
   228   Pretty.block (Pretty.commas (map (pretty_cterm ctxt) ctrms))*}
   236 
   229 
   237 text {*
   230 text {*
   238   The easiest way to get the string of a theorem is to transform it
   231   The easiest way to get the string of a theorem is to transform it
   239   into a @{ML_type term} using the function @{ML_ind prop_of in Thm}. 
   232   into a @{ML_type term} using the function @{ML_ind prop_of in Thm}. 
   240 *}
   233 *}
   241 
   234 
   242 ML{*fun pretty_thm ctxt thm =
   235 ML %grayML{*fun pretty_thm ctxt thm =
   243   pretty_term ctxt (prop_of thm)*}
   236   pretty_term ctxt (prop_of thm)*}
   244 
   237 
   245 text {*
   238 text {*
   246   Theorems include schematic variables, such as @{text "?P"}, 
   239   Theorems include schematic variables, such as @{text "?P"}, 
   247   @{text "?Q"} and so on. They are needed in Isabelle in order to able to
   240   @{text "?Q"} and so on. They are needed in Isabelle in order to able to
   255 
   248 
   256   However, in order to improve the readability when printing theorems, we
   249   However, in order to improve the readability when printing theorems, we
   257   can switch off the question marks as follows:
   250   can switch off the question marks as follows:
   258 *}
   251 *}
   259 
   252 
   260 ML{*fun pretty_thm_no_vars ctxt thm =
   253 ML %grayML{*fun pretty_thm_no_vars ctxt thm =
   261 let
   254 let
   262   val ctxt' = Config.put show_question_marks false ctxt
   255   val ctxt' = Config.put show_question_marks false ctxt
   263 in
   256 in
   264   pretty_term ctxt' (prop_of thm)
   257   pretty_term ctxt' (prop_of thm)
   265 end*}
   258 end*}
   273   
   266   
   274   Again the functions @{ML commas} and @{ML block in Pretty} help 
   267   Again the functions @{ML commas} and @{ML block in Pretty} help 
   275   with printing more than one theorem. 
   268   with printing more than one theorem. 
   276 *}
   269 *}
   277 
   270 
   278 ML{*fun pretty_thms ctxt thms =  
   271 ML %grayML{*fun pretty_thms ctxt thms =  
   279   Pretty.block (Pretty.commas (map (pretty_thm ctxt) thms))
   272   Pretty.block (Pretty.commas (map (pretty_thm ctxt) thms))
   280 
   273 
   281 fun pretty_thms_no_vars ctxt thms =  
   274 fun pretty_thms_no_vars ctxt thms =  
   282   Pretty.block (Pretty.commas (map (pretty_thm_no_vars ctxt) thms))*}
   275   Pretty.block (Pretty.commas (map (pretty_thm_no_vars ctxt) thms))*}
   283 
   276 
   284 text {*
   277 text {*
   285   Printing functions for @{ML_type typ} are
   278   Printing functions for @{ML_type typ} are
   286 *}
   279 *}
   287 
   280 
   288 ML{*fun pretty_typ ctxt ty = Syntax.pretty_typ ctxt ty
   281 ML %grayML{*fun pretty_typ ctxt ty = Syntax.pretty_typ ctxt ty
   289 fun pretty_typs ctxt tys = 
   282 fun pretty_typs ctxt tys = 
   290   Pretty.block (Pretty.commas (map (pretty_typ ctxt) tys))*}
   283   Pretty.block (Pretty.commas (map (pretty_typ ctxt) tys))*}
   291 
   284 
   292 text {*
   285 text {*
   293   respectively @{ML_type ctyp}
   286   respectively @{ML_type ctyp}
   294 *}
   287 *}
   295 
   288 
   296 ML{*fun pretty_ctyp ctxt cty = pretty_typ ctxt (typ_of cty)
   289 ML %grayML{*fun pretty_ctyp ctxt cty = pretty_typ ctxt (typ_of cty)
   297 fun pretty_ctyps ctxt ctys = 
   290 fun pretty_ctyps ctxt ctys = 
   298   Pretty.block (Pretty.commas (map (pretty_ctyp ctxt) ctys))*}
   291   Pretty.block (Pretty.commas (map (pretty_ctyp ctxt) ctys))*}
   299 
   292 
   300 text {*
   293 text {*
   301   \begin{readmore}
   294   \begin{readmore}
   353 
   346 
   354   The simplest combinator is @{ML_ind I in Library}, which is just the 
   347   The simplest combinator is @{ML_ind I in Library}, which is just the 
   355   identity function defined as
   348   identity function defined as
   356 *}
   349 *}
   357 
   350 
   358 ML{*fun I x = x*}
   351 ML %grayML{*fun I x = x*}
   359 
   352 
   360 text {* 
   353 text {* 
   361   Another simple combinator is @{ML_ind K in Library}, defined as 
   354   Another simple combinator is @{ML_ind K in Library}, defined as 
   362 *}
   355 *}
   363 
   356 
   364 ML{*fun K x = fn _ => x*}
   357 ML %grayML{*fun K x = fn _ => x*}
   365 
   358 
   366 text {*
   359 text {*
   367   @{ML K} ``wraps'' a function around @{text "x"} that ignores its argument. As a 
   360   @{ML K} ``wraps'' a function around @{text "x"} that ignores its argument. As a 
   368   result, @{ML K} defines a constant function always returning @{text x}.
   361   result, @{ML K} defines a constant function always returning @{text x}.
   369 
   362 
   370   The next combinator is reverse application, @{ML_ind  "|>" in Basics}, defined as: 
   363   The next combinator is reverse application, @{ML_ind  "|>" in Basics}, defined as: 
   371 *}
   364 *}
   372 
   365 
   373 ML{*fun x |> f = f x*}
   366 ML %grayML{*fun x |> f = f x*}
   374 
   367 
   375 text {* While just syntactic sugar for the usual function application,
   368 text {* While just syntactic sugar for the usual function application,
   376   the purpose of this combinator is to implement functions in a  
   369   the purpose of this combinator is to implement functions in a  
   377   ``waterfall fashion''. Consider for example the function *}
   370   ``waterfall fashion''. Consider for example the function *}
   378 
   371 
   392   manner. This kind of coding should be familiar, if you have been exposed to
   385   manner. This kind of coding should be familiar, if you have been exposed to
   393   Haskell's {\it do}-notation. Writing the function @{ML inc_by_five} using
   386   Haskell's {\it do}-notation. Writing the function @{ML inc_by_five} using
   394   the reverse application is much clearer than writing
   387   the reverse application is much clearer than writing
   395 *}
   388 *}
   396 
   389 
   397 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   390 ML %grayML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   398 
   391 
   399 text {* or *}
   392 text {* or *}
   400 
   393 
   401 ML{*fun inc_by_five x = 
   394 ML %grayML{*fun inc_by_five x = 
   402   ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*}
   395   ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*}
   403 
   396 
   404 text {* and typographically more economical than *}
   397 text {* and typographically more economical than *}
   405 
   398 
   406 ML{*fun inc_by_five x =
   399 ML %grayML{*fun inc_by_five x =
   407 let val y1 = x + 1
   400 let val y1 = x + 1
   408     val y2 = (y1, y1)
   401     val y2 = (y1, y1)
   409     val y3 = fst y2
   402     val y3 = fst y2
   410     val y4 = y3 + 4
   403     val y4 = y3 + 4
   411 in y4 end*}
   404 in y4 end*}
   475 
   468 
   476   The combinator @{ML_ind "#>" in Basics} is the reverse function composition. 
   469   The combinator @{ML_ind "#>" in Basics} is the reverse function composition. 
   477   It can be used to define the following function
   470   It can be used to define the following function
   478 *}
   471 *}
   479 
   472 
   480 ML{*val inc_by_six = 
   473 ML %grayML{*val inc_by_six = 
   481   (fn x => x + 1) #> 
   474   (fn x => x + 1) #> 
   482   (fn x => x + 2) #> 
   475   (fn x => x + 2) #> 
   483   (fn x => x + 3)*}
   476   (fn x => x + 3)*}
   484 
   477 
   485 text {* 
   478 text {* 
   533   The combinator @{ML_ind "`" in Basics} (a backtick) is similar to @{ML tap},
   526   The combinator @{ML_ind "`" in Basics} (a backtick) is similar to @{ML tap},
   534   but applies a function to the value and returns the result together with the
   527   but applies a function to the value and returns the result together with the
   535   value (as a pair). It is defined as
   528   value (as a pair). It is defined as
   536 *}
   529 *}
   537 
   530 
   538 ML{*fun `f = fn x => (f x, x)*}
   531 ML %grayML{*fun `f = fn x => (f x, x)*}
   539 
   532 
   540 text {*
   533 text {*
   541   An example for this combinator is the function
   534   An example for this combinator is the function
   542 *}
   535 *}
   543 
   536 
   544 ML{*fun inc_as_pair x =
   537 ML %grayML{*fun inc_as_pair x =
   545      x |> `(fn x => x + 1)
   538      x |> `(fn x => x + 1)
   546        |> (fn (x, y) => (x, y + 1))*}
   539        |> (fn (x, y) => (x, y + 1))*}
   547 
   540 
   548 text {*
   541 text {*
   549   which takes @{text x} as argument, and then increments @{text x}, but also keeps
   542   which takes @{text x} as argument, and then increments @{text x}, but also keeps
   554   The combinators @{ML_ind "|>>" in Basics} and @{ML_ind "||>" in Basics} are
   547   The combinators @{ML_ind "|>>" in Basics} and @{ML_ind "||>" in Basics} are
   555   defined for functions manipulating pairs. The first applies the function to
   548   defined for functions manipulating pairs. The first applies the function to
   556   the first component of the pair, defined as
   549   the first component of the pair, defined as
   557 *}
   550 *}
   558 
   551 
   559 ML{*fun (x, y) |>> f = (f x, y)*}
   552 ML %grayML{*fun (x, y) |>> f = (f x, y)*}
   560 
   553 
   561 text {*
   554 text {*
   562   and the second combinator to the second component, defined as
   555   and the second combinator to the second component, defined as
   563 *}
   556 *}
   564 
   557 
   565 ML{*fun (x, y) ||> f = (x, f y)*}
   558 ML %grayML{*fun (x, y) ||> f = (x, f y)*}
   566 
   559 
   567 text {*
   560 text {*
   568   These two functions can, for example, be used to avoid explicit @{text "lets"} for
   561   These two functions can, for example, be used to avoid explicit @{text "lets"} for
   569   intermediate values in functions that return pairs. As an example, suppose you
   562   intermediate values in functions that return pairs. As an example, suppose you
   570   want to separate a list of integers into two lists according to a
   563   want to separate a list of integers into two lists according to a
   571   threshold. If the threshold is @{ML "5"}, the list @{ML "[1,6,2,5,3,4]"}
   564   threshold. If the threshold is @{ML "5"}, the list @{ML "[1,6,2,5,3,4]"}
   572   should be separated as @{ML "([1,2,3,4], [6,5])"}.  Such a function can be
   565   should be separated as @{ML "([1,2,3,4], [6,5])"}.  Such a function can be
   573   implemented as
   566   implemented as
   574 *}
   567 *}
   575 
   568 
   576 ML{*fun separate i [] = ([], [])
   569 ML %grayML{*fun separate i [] = ([], [])
   577   | separate i (x::xs) =
   570   | separate i (x::xs) =
   578       let 
   571       let 
   579         val (los, grs) = separate i xs
   572         val (los, grs) = separate i xs
   580       in
   573       in
   581         if i <= x then (los, x::grs) else (x::los, grs)
   574         if i <= x then (los, x::grs) else (x::los, grs)
   585   where the return value of the recursive call is bound explicitly to
   578   where the return value of the recursive call is bound explicitly to
   586   the pair @{ML "(los, grs)" for los grs}. However, this function
   579   the pair @{ML "(los, grs)" for los grs}. However, this function
   587   can be implemented more concisely as
   580   can be implemented more concisely as
   588 *}
   581 *}
   589 
   582 
   590 ML{*fun separate i [] = ([], [])
   583 ML %grayML{*fun separate i [] = ([], [])
   591   | separate i (x::xs) =
   584   | separate i (x::xs) =
   592       if i <= x 
   585       if i <= x 
   593       then separate i xs ||> cons x
   586       then separate i xs ||> cons x
   594       else separate i xs |>> cons x*}
   587       else separate i xs |>> cons x*}
   595 
   588 
   600 
   593 
   601   With the combinator @{ML_ind "|->" in Basics} you can re-combine the 
   594   With the combinator @{ML_ind "|->" in Basics} you can re-combine the 
   602   elements from a pair. This combinator is defined as
   595   elements from a pair. This combinator is defined as
   603 *}
   596 *}
   604 
   597 
   605 ML{*fun (x, y) |-> f = f x y*}
   598 ML %grayML{*fun (x, y) |-> f = f x y*}
   606 
   599 
   607 text {* 
   600 text {* 
   608   and can be used to write the following roundabout version 
   601   and can be used to write the following roundabout version 
   609   of the @{text double} function: 
   602   of the @{text double} function: 
   610 *}
   603 *}
   611 
   604 
   612 ML{*fun double x =
   605 ML %grayML{*fun double x =
   613       x |>  (fn x => (x, x))
   606       x |>  (fn x => (x, x))
   614         |-> (fn x => fn y => x + y)*}
   607         |-> (fn x => fn y => x + y)*}
   615 
   608 
   616 text {* 
   609 text {* 
   617   The combinator @{ML_ind ||>> in Basics} plays a central rôle whenever your
   610   The combinator @{ML_ind ||>> in Basics} plays a central rôle whenever your
   668   obtained by previous calls.
   661   obtained by previous calls.
   669   
   662   
   670   A more realistic example for this combinator is the following code
   663   A more realistic example for this combinator is the following code
   671 *}
   664 *}
   672 
   665 
   673 ML{*val (((one_def, two_def), three_def), ctxt') = 
   666 ML %grayML{*val (((one_def, two_def), three_def), ctxt') = 
   674   @{context}
   667   @{context}
   675   |> Local_Defs.add_def ((@{binding "One"}, NoSyn), @{term "1::nat"}) 
   668   |> Local_Defs.add_def ((@{binding "One"}, NoSyn), @{term "1::nat"}) 
   676   ||>> Local_Defs.add_def ((@{binding "Two"}, NoSyn), @{term "2::nat"})
   669   ||>> Local_Defs.add_def ((@{binding "Two"}, NoSyn), @{term "2::nat"})
   677   ||>> Local_Defs.add_def ((@{binding "Three"}, NoSyn), @{term "3::nat"})*}
   670   ||>> Local_Defs.add_def ((@{binding "Three"}, NoSyn), @{term "3::nat"})*}
   678 
   671 
   701   @{ML_ind "#->" in Basics}, @{ML_ind "#>>" in Basics}, @{ML_ind "##>" in
   694   @{ML_ind "#->" in Basics}, @{ML_ind "#>>" in Basics}, @{ML_ind "##>" in
   702   Basics} and @{ML_ind "##>>" in Basics}. Using @{ML "#->"}, for example, the
   695   Basics} and @{ML_ind "##>>" in Basics}. Using @{ML "#->"}, for example, the
   703   function @{text double} can also be written as:
   696   function @{text double} can also be written as:
   704 *}
   697 *}
   705 
   698 
   706 ML{*val double =
   699 ML %grayML{*val double =
   707    (fn x => (x, x)) #-> 
   700    (fn x => (x, x)) #-> 
   708    (fn x => fn y => x + y)*}
   701    (fn x => fn y => x + y)*}
   709 
   702 
   710 
   703 
   711 text {* 
   704 text {* 
   799 
   792 
   800   Note, however, that antiquotations are statically linked, that is their value is
   793   Note, however, that antiquotations are statically linked, that is their value is
   801   determined at ``compile-time'', not at ``run-time''. For example the function
   794   determined at ``compile-time'', not at ``run-time''. For example the function
   802 *}
   795 *}
   803 
   796 
   804 ML{*fun not_current_thyname () = Context.theory_name @{theory} *}
   797 ML %grayML{*fun not_current_thyname () = Context.theory_name @{theory} *}
   805 
   798 
   806 text {*
   799 text {*
   807   does \emph{not} return the name of the current theory, if it is run in a 
   800   does \emph{not} return the name of the current theory, if it is run in a 
   808   different theory. Instead, the code above defines the constant function 
   801   different theory. Instead, the code above defines the constant function 
   809   that always returns the string @{text [quotes] "First_Steps"}, no matter where the
   802   that always returns the string @{text [quotes] "First_Steps"}, no matter where the
   854   It is also possible to prove lemmas with the antiquotation @{text "@{lemma \<dots> by \<dots>}"}
   847   It is also possible to prove lemmas with the antiquotation @{text "@{lemma \<dots> by \<dots>}"}
   855   whose first argument is a statement (possibly many of them separated by @{text "and"})
   848   whose first argument is a statement (possibly many of them separated by @{text "and"})
   856   and the second is a proof. For example
   849   and the second is a proof. For example
   857 *}
   850 *}
   858 
   851 
   859 ML{*val foo_thm = @{lemma "True" and "False \<Longrightarrow> P" by simp_all} *}
   852 ML %grayML{*val foo_thm = @{lemma "True" and "False \<Longrightarrow> P" by simp_all} *}
   860 
   853 
   861 text {*
   854 text {*
   862   The result can be printed out as follows.
   855   The result can be printed out as follows.
   863 
   856 
   864   @{ML_response_fake [gray,display]
   857   @{ML_response_fake [gray,display]
   869   You can also refer to the current simpset via an antiquotation. To illustrate 
   862   You can also refer to the current simpset via an antiquotation. To illustrate 
   870   this we implement the function that extracts the theorem names stored in a 
   863   this we implement the function that extracts the theorem names stored in a 
   871   simpset.
   864   simpset.
   872 *}
   865 *}
   873 
   866 
   874 ML{*fun get_thm_names_from_ss simpset =
   867 ML %grayML{*fun get_thm_names_from_ss simpset =
   875 let
   868 let
   876   val {simps,...} = Raw_Simplifier.dest_ss simpset
   869   val {simps,...} = Raw_Simplifier.dest_ss simpset
   877 in
   870 in
   878   map #1 simps
   871   map #1 simps
   879 end*}
   872 end*}
   934 
   927 
   935   which shows the internal representation of the term @{text "Suc ?x"}. Similarly
   928   which shows the internal representation of the term @{text "Suc ?x"}. Similarly
   936   we can write an antiquotation for type patterns. Its code is
   929   we can write an antiquotation for type patterns. Its code is
   937 *}
   930 *}
   938 
   931 
   939 ML{*val type_pat_setup = 
   932 ML %grayML{*val type_pat_setup = 
   940 let
   933 let
   941   val parser = Args.context -- Scan.lift Args.name_source
   934   val parser = Args.context -- Scan.lift Args.name_source
   942 
   935 
   943   fun typ_pat (ctxt, str) =
   936   fun typ_pat (ctxt, str) =
   944     let
   937     let
   997   We will show the usage of the universal type by storing an integer and
   990   We will show the usage of the universal type by storing an integer and
   998   a boolean into a single list. Let us first define injection and projection 
   991   a boolean into a single list. Let us first define injection and projection 
   999   functions for booleans and integers into and from the type @{ML_type Universal.universal}.
   992   functions for booleans and integers into and from the type @{ML_type Universal.universal}.
  1000 *}
   993 *}
  1001 
   994 
  1002 ML{*local
   995 ML %grayML{*local
  1003   val fn_int  = Universal.tag () : int  Universal.tag
   996   val fn_int  = Universal.tag () : int  Universal.tag
  1004   val fn_bool = Universal.tag () : bool Universal.tag
   997   val fn_bool = Universal.tag () : bool Universal.tag
  1005 in
   998 in
  1006   val inject_int   = Universal.tagInject fn_int;
   999   val inject_int   = Universal.tagInject fn_int;
  1007   val inject_bool  = Universal.tagInject fn_bool;
  1000   val inject_bool  = Universal.tagInject fn_bool;
  1013   Using the injection functions, we can inject the integer @{ML_text "13"} 
  1006   Using the injection functions, we can inject the integer @{ML_text "13"} 
  1014   and the boolean value @{ML_text "true"} into @{ML_type Universal.universal}, and
  1007   and the boolean value @{ML_text "true"} into @{ML_type Universal.universal}, and
  1015   then store them in a @{ML_type "Universal.universal list"} as follows:
  1008   then store them in a @{ML_type "Universal.universal list"} as follows:
  1016 *}
  1009 *}
  1017 
  1010 
  1018 ML{*val foo_list = 
  1011 ML %grayML{*val foo_list = 
  1019 let
  1012 let
  1020   val thirteen = inject_int 13
  1013   val thirteen = inject_int 13
  1021   val truth_val = inject_bool true
  1014   val truth_val = inject_bool true
  1022 in
  1015 in
  1023   [thirteen, truth_val]
  1016   [thirteen, truth_val]
  1087   it (@{ML Data.map}). There is also the functions @{ML Data.put}, which however is 
  1080   it (@{ML Data.map}). There is also the functions @{ML Data.put}, which however is 
  1088   not relevant here. Below we define two
  1081   not relevant here. Below we define two
  1089   auxiliary functions, which help us with accessing the table.
  1082   auxiliary functions, which help us with accessing the table.
  1090 *}
  1083 *}
  1091 
  1084 
  1092 ML{*val lookup = Symtab.lookup o Data.get
  1085 ML %grayML{*val lookup = Symtab.lookup o Data.get
  1093 fun update k v = Data.map (Symtab.update (k, v))*}
  1086 fun update k v = Data.map (Symtab.update (k, v))*}
  1094 
  1087 
  1095 text {*
  1088 text {*
  1096   Since we want to store introduction rules associated with their 
  1089   Since we want to store introduction rules associated with their 
  1097   logical connective, we can fill the table as follows.
  1090   logical connective, we can fill the table as follows.
  1132   defeat its undo-mechanism. To see the latter, consider the 
  1125   defeat its undo-mechanism. To see the latter, consider the 
  1133   following data container where we maintain a reference to a list of 
  1126   following data container where we maintain a reference to a list of 
  1134   integers.
  1127   integers.
  1135 *}
  1128 *}
  1136 
  1129 
  1137 ML{*structure WrongRefData = Theory_Data
  1130 ML %grayML{*structure WrongRefData = Theory_Data
  1138   (type T = (int list) Unsynchronized.ref
  1131   (type T = (int list) Unsynchronized.ref
  1139    val empty = Unsynchronized.ref []
  1132    val empty = Unsynchronized.ref []
  1140    val extend = I
  1133    val extend = I
  1141    val merge = fst)*}
  1134    val merge = fst)*}
  1142 
  1135 
  1149   "ref []"}
  1142   "ref []"}
  1150 
  1143 
  1151   For updating the reference we use the following function
  1144   For updating the reference we use the following function
  1152 *}
  1145 *}
  1153 
  1146 
  1154 ML{*fun ref_update n = WrongRefData.map 
  1147 ML %grayML{*fun ref_update n = WrongRefData.map 
  1155       (fn r => let val _ = r := n::(!r) in r end)*}
  1148       (fn r => let val _ = r := n::(!r) in r end)*}
  1156 
  1149 
  1157 text {*
  1150 text {*
  1158   which takes an integer and adds it to the content of the reference.
  1151   which takes an integer and adds it to the content of the reference.
  1159   As before, we update the reference with the command 
  1152   As before, we update the reference with the command 
  1200   Storing data in a proof context is done in a similar fashion. As mentioned
  1193   Storing data in a proof context is done in a similar fashion. As mentioned
  1201   before, the corresponding functor is @{ML_funct_ind Proof_Data}. With the
  1194   before, the corresponding functor is @{ML_funct_ind Proof_Data}. With the
  1202   following code we can store a list of terms in a proof context.
  1195   following code we can store a list of terms in a proof context.
  1203 *}
  1196 *}
  1204 
  1197 
  1205 ML{*structure Data = Proof_Data
  1198 ML %grayML{*structure Data = Proof_Data
  1206   (type T = term list
  1199   (type T = term list
  1207    fun init _ = [])*}
  1200    fun init _ = [])*}
  1208 
  1201 
  1209 text {*
  1202 text {*
  1210   The init-function we have to specify must produce a list for when a context 
  1203   The init-function we have to specify must produce a list for when a context 
  1212   context is derived). We choose here to just return the empty list. Next 
  1205   context is derived). We choose here to just return the empty list. Next 
  1213   we define two auxiliary functions for updating the list with a given
  1206   we define two auxiliary functions for updating the list with a given
  1214   term and printing the list. 
  1207   term and printing the list. 
  1215 *}
  1208 *}
  1216 
  1209 
  1217 ML{*fun update trm = Data.map (fn trms => trm::trms)
  1210 ML %grayML{*fun update trm = Data.map (fn trms => trm::trms)
  1218 
  1211 
  1219 fun print ctxt =
  1212 fun print ctxt =
  1220   case (Data.get ctxt) of
  1213   case (Data.get ctxt) of
  1221     [] => pwriteln (Pretty.str "Empty!")
  1214     [] => pwriteln (Pretty.str "Empty!")
  1222   | trms => pwriteln (pretty_terms ctxt trms)*}
  1215   | trms => pwriteln (pretty_terms ctxt trms)*}
  1270   above. The first instance implements named theorem lists using the functor
  1263   above. The first instance implements named theorem lists using the functor
  1271   @{ML_funct_ind Named_Thms}. This is because storing theorems in a list 
  1264   @{ML_funct_ind Named_Thms}. This is because storing theorems in a list 
  1272   is such a common task.  To obtain a named theorem list, you just declare
  1265   is such a common task.  To obtain a named theorem list, you just declare
  1273 *}
  1266 *}
  1274 
  1267 
  1275 ML{*structure FooRules = Named_Thms
  1268 ML %grayML{*structure FooRules = Named_Thms
  1276   (val name = @{binding "foo"} 
  1269   (val name = @{binding "foo"} 
  1277    val description = "Theorems for foo") *}
  1270    val description = "Theorems for foo") *}
  1278 
  1271 
  1279 text {*
  1272 text {*
  1280   and set up the @{ML_struct FooRules} with the command
  1273   and set up the @{ML_struct FooRules} with the command
  1337   user to control three values, say @{text bval} containing a boolean, @{text
  1330   user to control three values, say @{text bval} containing a boolean, @{text
  1338   ival} containing an integer and @{text sval} containing a string. These
  1331   ival} containing an integer and @{text sval} containing a string. These
  1339   values can be declared by
  1332   values can be declared by
  1340 *}
  1333 *}
  1341 
  1334 
  1342 ML{*val bval = Attrib.setup_config_bool @{binding "bval"} (K false)
  1335 ML %grayML{*val bval = Attrib.setup_config_bool @{binding "bval"} (K false)
  1343 val ival = Attrib.setup_config_int @{binding "ival"} (K 0)
  1336 val ival = Attrib.setup_config_int @{binding "ival"} (K 0)
  1344 val sval = Attrib.setup_config_string @{binding "sval"} (K "some string") *}
  1337 val sval = Attrib.setup_config_string @{binding "sval"} (K "some string") *}
  1345 
  1338 
  1346 text {* 
  1339 text {* 
  1347   where each value needs to be given a default. 
  1340   where each value needs to be given a default.