ProgTutorial/FirstSteps.thy
changeset 374 304426a9aecf
parent 373 28a49fe024c9
child 375 92f7328dc5cc
equal deleted inserted replaced
373:28a49fe024c9 374:304426a9aecf
    87   \isacommand{oops}
    87   \isacommand{oops}
    88   \end{isabelle}
    88   \end{isabelle}
    89   \end{quote}
    89   \end{quote}
    90 
    90 
    91   However, both commands will only play minor roles in this tutorial (we will
    91   However, both commands will only play minor roles in this tutorial (we will
    92   always arrange that the ML-code is defined outside of proofs).
    92   always arrange that the ML-code is defined outside proofs).
    93 
    93 
    94   Once a portion of code is relatively stable, you usually want to export it
    94   Once a portion of code is relatively stable, you usually want to export it
    95   to a separate ML-file. Such files can then be included somewhere inside a 
    95   to a separate ML-file. Such files can then be included somewhere inside a 
    96   theory by using the command \isacommand{use}. For example
    96   theory by using the command \isacommand{use}. For example
    97 
    97 
   128 *}
   128 *}
   129 
   129 
   130 section {* Printing and Debugging\label{sec:printing} *}
   130 section {* Printing and Debugging\label{sec:printing} *}
   131 
   131 
   132 text {*
   132 text {*
   133   During development you might find it necessary to inspect some data in your
   133   During development you might find it necessary to inspect data in your
   134   code. This can be done in a ``quick-and-dirty'' fashion using the function
   134   code. This can be done in a ``quick-and-dirty'' fashion using the function
   135   @{ML_ind writeln in Output}. For example
   135   @{ML_ind writeln in Output}. For example
   136 
   136 
   137   @{ML_response_eq [display,gray] "writeln \"any string\"" "\"any string\"" with "(op =)"}
   137   @{ML_response_eq [display,gray] "writeln \"any string\"" "\"any string\"" with "(op =)"}
   138 
   138 
   154   output into a separate tracing buffer. For example:
   154   output into a separate tracing buffer. For example:
   155 
   155 
   156   @{ML_response_eq [display,gray] "tracing \"foo\"" "\"foo\"" with "(op =)"}
   156   @{ML_response_eq [display,gray] "tracing \"foo\"" "\"foo\"" with "(op =)"}
   157 
   157 
   158   It is also possible to redirect the ``channel'' where the string @{text
   158   It is also possible to redirect the ``channel'' where the string @{text
   159   "foo"} is printed to a separate file, e.g., to prevent ProofGeneral from
   159   "foo"} is printed to a separate file, e.g., in order to prevent ProofGeneral from
   160   choking on massive amounts of trace output. This redirection can be achieved
   160   choking on massive amounts of trace output. This redirection can be achieved
   161   with the code:
   161   with the code:
   162 *}
   162 *}
   163 
   163 
   164 ML{*val strip_specials =
   164 ML{*val strip_specials =
   217   Most often you want to inspect data of Isabelle's basic data
   217   Most often you want to inspect data of Isabelle's basic data
   218   structures, namely @{ML_type term}, @{ML_type cterm} and @{ML_type
   218   structures, namely @{ML_type term}, @{ML_type cterm} and @{ML_type
   219   thm}. Isabelle contains elaborate pretty-printing functions for printing
   219   thm}. Isabelle contains elaborate pretty-printing functions for printing
   220   them (see Section \ref{sec:pretty}), but for quick-and-dirty solutions they
   220   them (see Section \ref{sec:pretty}), but for quick-and-dirty solutions they
   221   are a bit unwieldy. One way to transform a term into a string is to use the
   221   are a bit unwieldy. One way to transform a term into a string is to use the
   222   function @{ML_ind  string_of_term in Syntax} in the structure @{ML_struct
   222   function @{ML_ind  string_of_term in Syntax} from the structure @{ML_struct
   223   Syntax}. For more convenience, we bind this function to the toplevel.
   223   Syntax}. For more convenience, we bind this function to the toplevel.
   224 *}
   224 *}
   225 
   225 
   226 ML{*val string_of_term = Syntax.string_of_term*}
   226 ML{*val string_of_term = Syntax.string_of_term*}
   227 
   227 
   252 
   252 
   253 ML{*fun string_of_terms ctxt ts =  
   253 ML{*fun string_of_terms ctxt ts =  
   254   commas (map (string_of_term ctxt) ts)*}
   254   commas (map (string_of_term ctxt) ts)*}
   255 
   255 
   256 text {*
   256 text {*
   257   You can also print out term together with type information.
   257   You can also print out terms together with typing information.
   258   This can be achieved by setting the reference @{ML_ind show_types in Syntax} 
   258   For this you need to set the reference @{ML_ind show_types in Syntax} 
   259   to @{ML true}.
   259   to @{ML true}.
   260 *}
   260 *}
   261 
   261 
   262 ML{*show_types := true*}
   262 ML{*show_types := true*}
   263 
   263 
   268   "tracing (string_of_term @{context} @{term \"(1::nat, x)\"})"
   268   "tracing (string_of_term @{context} @{term \"(1::nat, x)\"})"
   269   "(1::nat, x::'a)"}
   269   "(1::nat, x::'a)"}
   270 
   270 
   271   where @{text 1} and @{text x} are displayed with their inferred type.
   271   where @{text 1} and @{text x} are displayed with their inferred type.
   272   Even more type information can be printed by setting 
   272   Even more type information can be printed by setting 
   273   @{ML_ind show_all_types in Syntax} to @{ML true}. We obtain then
   273   the reference @{ML_ind show_all_types in Syntax} to @{ML true}. 
       
   274   We obtain then
   274 *}
   275 *}
   275 (*<*)ML %linenos {*show_all_types := true*}
   276 (*<*)ML %linenos {*show_all_types := true*}
   276 (*>*)
   277 (*>*)
   277 text {*
   278 text {*
   278   @{ML_response_fake [display, gray]
   279   @{ML_response_fake [display, gray]
   279   "tracing (string_of_term @{context} @{term \"(1::nat, x)\"})"
   280   "tracing (string_of_term @{context} @{term \"(1::nat, x)\"})"
   280   "(Pair::nat \<Rightarrow> 'a \<Rightarrow> nat \<times> 'a) (1::nat) (x::'a)"}
   281   "(Pair::nat \<Rightarrow> 'a \<Rightarrow> nat \<times> 'a) (1::nat) (x::'a)"}
   281 
   282 
       
   283   where @{term Pair} is the term-constructor for products. 
   282   Other references that influence printing are @{ML_ind show_brackets in Syntax} 
   284   Other references that influence printing are @{ML_ind show_brackets in Syntax} 
   283   and @{ML_ind show_sorts in Syntax}. 
   285   and @{ML_ind show_sorts in Syntax}. 
   284 *}
   286 *}
   285 (*<*)ML %linenos {*show_types := false; show_all_types := false*}
   287 (*<*)ML %linenos {*show_types := false; show_all_types := false*}
   286 (*>*)
   288 (*>*)
   334 
   336 
   335 fun string_of_thm_no_vars ctxt thm =
   337 fun string_of_thm_no_vars ctxt thm =
   336   string_of_term ctxt (prop_of (no_vars ctxt thm))*}
   338   string_of_term ctxt (prop_of (no_vars ctxt thm))*}
   337 
   339 
   338 text {* 
   340 text {* 
   339   Theorem @{thm [source] conjI} is now printed as follows:
   341   With this function, theorem @{thm [source] conjI} is now printed as follows:
   340 
   342 
   341   @{ML_response_fake [display, gray]
   343   @{ML_response_fake [display, gray]
   342   "tracing (string_of_thm_no_vars @{context} @{thm conjI})"
   344   "tracing (string_of_thm_no_vars @{context} @{thm conjI})"
   343   "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
   345   "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
   344   
   346   
   357   @{ML_type string}s are implemented in @{ML_file "Pure/Syntax/syntax.ML"}. 
   359   @{ML_type string}s are implemented in @{ML_file "Pure/Syntax/syntax.ML"}. 
   358   The references that change the printing information are declared in 
   360   The references that change the printing information are declared in 
   359   @{ML_file "Pure/Syntax/printer.ML"}.
   361   @{ML_file "Pure/Syntax/printer.ML"}.
   360   \end{readmore}
   362   \end{readmore}
   361 
   363 
   362   Note that when printing out several ``parcels'' of information that
   364   Note that for printing out several ``parcels'' of information that
   363   semantically belong together, like a warning message consisting of 
   365   semantically belong together, like a warning message consisting of 
   364   a term and its type, you should try to keep this information together in a
   366   a term and its type, you should try to keep this information together in a
   365   single string. Therefore do \emph{not} print out information as
   367   single string. Therefore do \emph{not} print out information as
   366 
   368 
   367 @{ML_response_fake [display,gray]
   369 @{ML_response_fake [display,gray]
   376 "tracing (\"First half,\" ^ \"\\n\" ^ \"and second half.\")"
   378 "tracing (\"First half,\" ^ \"\\n\" ^ \"and second half.\")"
   377 "First half,
   379 "First half,
   378 and second half."}
   380 and second half."}
   379   
   381   
   380   To ease this kind of string manipulations, there are a number
   382   To ease this kind of string manipulations, there are a number
   381   of library functions. For example,  the function @{ML_ind cat_lines in Library}
   383   of library functions in Isabelle. For example,  the function 
   382   concatenates a list of strings and inserts newlines. 
   384   @{ML_ind cat_lines in Library} concatenates a list of strings 
       
   385   and inserts newlines in between each element. 
   383 
   386 
   384   @{ML_response [display, gray]
   387   @{ML_response [display, gray]
   385   "cat_lines [\"foo\", \"bar\"]"
   388   "cat_lines [\"foo\", \"bar\"]"
   386   "\"foo\\nbar\""}
   389   "\"foo\\nbar\""}
   387 
   390 
   388   Section \ref{sec:pretty} will also explain the infrastructure of Isabelle 
   391   Section \ref{sec:pretty} will also explain the infrastructure that Isabelle 
   389   that helps with more elaborate pretty printing. 
   392   provides for more elaborate pretty printing. 
   390 
   393 
   391   \begin{readmore}
   394   \begin{readmore}
   392   Most of the basic string functions of Isabelle are defined in 
   395   Most of the basic string functions of Isabelle are defined in 
   393   @{ML_file "Pure/library.ML"}.
   396   @{ML_file "Pure/library.ML"}.
   394   \end{readmore}
   397   \end{readmore}
   506   avoiding the given @{text f}; the list of name-type pairs is turned into a
   509   avoiding the given @{text f}; the list of name-type pairs is turned into a
   507   list of variable terms in Line 6, which in the last line is applied by the
   510   list of variable terms in Line 6, which in the last line is applied by the
   508   function @{ML_ind list_comb in Term} to the term. In this last step we have
   511   function @{ML_ind list_comb in Term} to the term. In this last step we have
   509   to use the function @{ML_ind curry in Library}, because @{ML list_comb}
   512   to use the function @{ML_ind curry in Library}, because @{ML list_comb}
   510   expects the function and the variables list as a pair. 
   513   expects the function and the variables list as a pair. 
       
   514   
   511   Functions like @{ML apply_fresh_args} are often needed when constructing 
   515   Functions like @{ML apply_fresh_args} are often needed when constructing 
   512   terms with fresh variables. The
   516   terms with fresh variables. The
   513   infrastructure helps tremendously to avoid any name clashes. Consider for
   517   infrastructure helps tremendously to avoid any name clashes. Consider for
   514   example:
   518   example:
   515 
   519 
   529   The combinator @{ML_ind "#>" in Basics} is the reverse function composition. 
   533   The combinator @{ML_ind "#>" in Basics} is the reverse function composition. 
   530   It can be used to define the following function
   534   It can be used to define the following function
   531 *}
   535 *}
   532 
   536 
   533 ML{*val inc_by_six = 
   537 ML{*val inc_by_six = 
   534       (fn x => x + 1)
   538   (fn x => x + 1) #> 
   535    #> (fn x => x + 2)
   539   (fn x => x + 2) #> 
   536    #> (fn x => x + 3)*}
   540   (fn x => x + 3)*}
   537 
   541 
   538 text {* 
   542 text {* 
   539   which is the function composed of first the increment-by-one function and then
   543   which is the function composed of first the increment-by-one function and then
   540   increment-by-two, followed by increment-by-three. Again, the reverse function 
   544   increment-by-two, followed by increment-by-three. Again, the reverse function 
   541   composition allows you to read the code top-down.
   545   composition allows you to read the code top-down.