CookBook/FirstSteps.thy
changeset 107 258ce361ba1b
parent 104 5dcad9348e4d
child 108 8bea3f74889d
equal deleted inserted replaced
106:bdd82350cf22 107:258ce361ba1b
    41   evaluated by using the advance and undo buttons of your Isabelle
    41   evaluated by using the advance and undo buttons of your Isabelle
    42   environment. The code inside the \isacommand{ML}-command can also contain
    42   environment. The code inside the \isacommand{ML}-command can also contain
    43   value and function bindings, and even those can be undone when the proof
    43   value and function bindings, and even those can be undone when the proof
    44   script is retracted. As mentioned earlier, we will drop the
    44   script is retracted. As mentioned earlier, we will drop the
    45   \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"} scaffolding whenever we
    45   \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"} scaffolding whenever we
    46   show code. The lines prefixed with @{text ">"} are not part of the
    46   show code. The lines prefixed with @{text [quotes] ">"} are not part of the
    47   code, rather they indicate what the response is when the code is evaluated.
    47   code, rather they indicate what the response is when the code is evaluated.
    48 
    48 
    49   Once a portion of code is relatively stable, you usually want to export it
    49   Once a portion of code is relatively stable, you usually want to export it
    50   to a separate ML-file. Such files can then be included in a theory by using
    50   to a separate ML-file. Such files can then be included in a theory by using
    51   the \isacommand{uses}-command in the header of the theory, like:
    51   the \isacommand{uses}-command in the header of the theory, like:
    73   @{ML_response_fake [display,gray] "warning \"any string\"" "\"any string\""}
    73   @{ML_response_fake [display,gray] "warning \"any string\"" "\"any string\""}
    74 
    74 
    75   will print out @{text [quotes] "any string"} inside the response buffer
    75   will print out @{text [quotes] "any string"} inside the response buffer
    76   of Isabelle.  This function expects a string as argument. If you develop under PolyML,
    76   of Isabelle.  This function expects a string as argument. If you develop under PolyML,
    77   then there is a convenient, though again ``quick-and-dirty'', method for
    77   then there is a convenient, though again ``quick-and-dirty'', method for
    78   converting values into strings, namely using the function @{ML makestring}:
    78   converting values into strings, namely the function @{ML makestring}:
    79 
    79 
    80   @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} 
    80   @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} 
    81 
    81 
    82   However @{ML makestring} only works if the type of what is converted is monomorphic 
    82   However @{ML makestring} only works if the type of what is converted is monomorphic 
    83   and not a function.
    83   and not a function.
    90 
    90 
    91   @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""}
    91   @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""}
    92 
    92 
    93   It is also possible to redirect the ``channel'' where the string @{text "foo"} is 
    93   It is also possible to redirect the ``channel'' where the string @{text "foo"} is 
    94   printed to a separate file, e.g.~to prevent ProofGeneral from choking on massive 
    94   printed to a separate file, e.g.~to prevent ProofGeneral from choking on massive 
    95   amounts of trace output. This redirection can be achieved using the code
    95   amounts of trace output. This redirection can be achieved with the code:
    96 *}
    96 *}
    97 
    97 
    98 ML{*val strip_specials =
    98 ML{*val strip_specials =
    99 let
    99 let
   100   fun strip ("\^A" :: _ :: cs) = strip cs
   100   fun strip ("\^A" :: _ :: cs) = strip cs
   110 
   110 
   111 text {*
   111 text {*
   112   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   112   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   113   will cause that all tracing information is printed into the file @{text "foo.bar"}.
   113   will cause that all tracing information is printed into the file @{text "foo.bar"}.
   114 
   114 
   115   You can print out error messages with the function @{ML error}, as in:
   115   You can print out error messages with the function @{ML error}; for example:
   116 
   116 
   117   @{ML_response_fake [display,gray] "if 0=1 then 1 else (error \"foo\")" "\"foo\""}
   117   @{ML_response_fake [display,gray] "if 0=1 then 1 else (error \"foo\")" "\"foo\""}
   118 
   118 
   119   Section~\ref{sec:printing} will give more information about printing 
   119   Section~\ref{sec:printing} will give more information about printing 
   120   the main datas tructures of Isabelle, namely @{ML_type term}, @{ML_type cterm} 
   120   the main data structures of Isabelle, namely @{ML_type term}, @{ML_type cterm} 
   121   and @{ML_type thm}.
   121   and @{ML_type thm}.
   122 *}
   122 *}
   123 
   123 
   124 
   124 
   125 
   125 
   159 
   159 
   160   In a similar way you can use antiquotations to refer to proved theorems:
   160   In a similar way you can use antiquotations to refer to proved theorems:
   161 
   161 
   162   @{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"}
   162   @{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"}
   163 
   163 
   164   or simpsets:
   164   and simpsets:
   165 
   165 
   166   @{ML_response_fake [display,gray] 
   166   @{ML_response_fake [display,gray] 
   167 "let
   167 "let
   168   val ({rules,...}, _) = MetaSimplifier.rep_ss @{simpset}
   168   val ({rules,...}, _) = MetaSimplifier.rep_ss @{simpset}
   169 in
   169 in
   383   Write a function which takes two terms representing natural numbers
   383   Write a function which takes two terms representing natural numbers
   384   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produce the
   384   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produce the
   385   number representing their sum.
   385   number representing their sum.
   386   \end{exercise}
   386   \end{exercise}
   387 
   387 
   388   (FIXME: maybe should go)
   388   A handy function for manipulating terms is @{ML map_types}: it takes a 
   389 
   389   function and applies it to every type in the term. You can, for example,
       
   390   change every @{typ nat} into an @{typ int} using the function
   390 *}
   391 *}
   391 
   392 
   392 ML{*fun nat_to_int t =
   393 ML{*fun nat_to_int t =
   393   (case t of
   394   (case t of
   394      @{typ nat} => @{typ int}
   395      @{typ nat} => @{typ int}
   395    | Type (s, ts) => Type (s, map nat_to_int ts)
   396    | Type (s, ts) => Type (s, map nat_to_int ts)
   396    | _ => t)*}
   397    | _ => t)*}
   397 
   398 
   398 text {*
   399 text {*
       
   400   an then apply it as follows:
       
   401 
   399 
   402 
   400 @{ML_response_fake [display,gray] 
   403 @{ML_response_fake [display,gray] 
   401 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
   404 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
   402 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
   405 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
   403            $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"}
   406            $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"}
   422   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   425   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   423   For example you can write:
   426   For example you can write:
   424 
   427 
   425   @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   428   @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   426 
   429 
   427   This can also be wirtten with an antiquotation:
   430   This can also be written with an antiquotation:
   428 
   431 
   429   @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   432   @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   430 
   433 
   431   Attempting to obtain the certified term for
   434   Attempting to obtain the certified term for
   432 
   435 
   456 section {* Theorems *}
   459 section {* Theorems *}
   457 
   460 
   458 text {*
   461 text {*
   459   Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} 
   462   Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} 
   460   that can only be built by going through interfaces. As a consequence, every proof 
   463   that can only be built by going through interfaces. As a consequence, every proof 
   461   in Isabelle is correct by construction (FIXME reference LCF-philosophy)
   464   in Isabelle is correct by construction. 
       
   465 
       
   466   (FIXME reference LCF-philosophy)
   462 
   467 
   463   To see theorems in ``action'', let us give a proof on the ML-level for the following 
   468   To see theorems in ``action'', let us give a proof on the ML-level for the following 
   464   statement:
   469   statement:
   465 *}
   470 *}
   466 
   471 
   523 section {* Theorem Attributes *}
   528 section {* Theorem Attributes *}
   524 
   529 
   525 section {* Printing Terms and Theorems\label{sec:printing} *}
   530 section {* Printing Terms and Theorems\label{sec:printing} *}
   526 
   531 
   527 text {* 
   532 text {* 
   528   During development, you often want to inspect terms, cterms 
   533   During development, you often want to inspect date of type @{ML_type term}, @{ML_type cterm} 
   529   or theorems. Isabelle contains elaborate pretty-printing functions for printing them, 
   534   or @{ML_type thm}. Isabelle contains elaborate pretty-printing functions for printing them, 
   530   but  for quick-and-dirty solutions they are far too unwieldy. A simple way to transform 
   535   but  for quick-and-dirty solutions they are far too unwieldy. A simple way to transform 
   531   a term into a string is to use the function @{ML Syntax.string_of_term}.
   536   a term into a string is to use the function @{ML Syntax.string_of_term}.
   532 
   537 
   533   @{ML_response_fake [display,gray]
   538   @{ML_response_fake [display,gray]
   534   "Syntax.string_of_term @{context} @{term \"1::nat\"}"
   539   "Syntax.string_of_term @{context} @{term \"1::nat\"}"
   535   "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""}
   540   "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""}
   536 
   541 
   537   This produces a string with some printing directions encoded in it. The string
   542   This produces a string with some printing directions encoded in it. The string
   538   can be properly printed by using @{ML warning} foe example.
   543   can be properly printed by using the function @{ML warning}.
   539 
   544 
   540   @{ML_response_fake [display,gray]
   545   @{ML_response_fake [display,gray]
   541   "warning (Syntax.string_of_term @{context} @{term \"1::nat\"})"
   546   "warning (Syntax.string_of_term @{context} @{term \"1::nat\"})"
   542   "\"1\""}
   547   "\"1\""}
   543 
   548 
   744   This combinator is defined as
   749   This combinator is defined as
   745 *}
   750 *}
   746 
   751 
   747 ML{*fun (x, y) |-> f = f x y*}
   752 ML{*fun (x, y) |-> f = f x y*}
   748 
   753 
   749 text {* and can be used to write the following version of the @{text double} function *}
   754 text {* and can be used to write the following roundabout version 
       
   755   of the @{text double} function 
       
   756 *}
   750 
   757 
   751 ML{*fun double x =
   758 ML{*fun double x =
   752       x |>  (fn x => (x, x))
   759       x |>  (fn x => (x, x))
   753         |-> (fn x => fn y => x + y)*}
   760         |-> (fn x => fn y => x + y)*}
   754 
   761