ProgTutorial/First_Steps.thy
changeset 562 daf404920ab9
parent 559 ffa5c4ec9611
child 564 6e2479089226
equal deleted inserted replaced
561:aec7073d4645 562:daf404920ab9
     2 imports Base
     2 imports Base
     3 begin
     3 begin
     4                                                   
     4                                                   
     5 chapter {* First Steps\label{chp:firststeps} *}
     5 chapter {* First Steps\label{chp:firststeps} *}
     6 
     6 
       
     7 
       
     8 
     7 text {*
     9 text {*
     8   \begin{flushright}
    10   \begin{flushright}
     9   {\em ``The most effective debugging tool is still careful thought,\\ 
    11   {\em ``The most effective debugging tool is still careful thought,\\ 
    10   coupled with judiciously placed print statements.''} \\[1ex]
    12   coupled with judiciously placed print statements.''} \\[1ex]
    11   Brian Kernighan, in {\em Unix for Beginners}, 1979
    13   Brian Kernighan, in {\em Unix for Beginners}, 1979
    12   \end{flushright}
    14   \end{flushright}
    13 
    15 
    14   \medskip
    16   \medskip
    15   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code for
    17   Isabelle programming is done in ML @{cite "isa-imp"}. Just like lemmas and proofs, ML-code for
    16   Isabelle must be part of a theory. If you want to follow the code given in
    18   Isabelle must be part of a theory. If you want to follow the code given in
    17   this chapter, we assume you are working inside the theory starting with
    19   this chapter, we assume you are working inside the theory starting with
    18 
    20 
    19   \begin{quote}
    21   \begin{quote}
    20   \begin{tabular}{@ {}l}
    22   \begin{tabular}{@ {}l}
   177 
   179 
   178   A @{ML_type cterm} can be printed with the following function.
   180   A @{ML_type cterm} can be printed with the following function.
   179 *}
   181 *}
   180 
   182 
   181 ML %grayML %grayML{*fun pretty_cterm ctxt ctrm =  
   183 ML %grayML %grayML{*fun pretty_cterm ctxt ctrm =  
   182   pretty_term ctxt (term_of ctrm)*}
   184   pretty_term ctxt (Thm.term_of ctrm)*}
   183 
   185 
   184 text {*
   186 text {*
   185   Here the function @{ML_ind term_of in Thm} extracts the @{ML_type
   187   Here the function @{ML_ind term_of in Thm} extracts the @{ML_type
   186   term} from a @{ML_type cterm}.  More than one @{ML_type cterm}s can be
   188   term} from a @{ML_type cterm}.  More than one @{ML_type cterm}s can be
   187   printed again with @{ML commas in Pretty}.
   189   printed again with @{ML commas in Pretty}.
   194   The easiest way to get the string of a theorem is to transform it
   196   The easiest way to get the string of a theorem is to transform it
   195   into a @{ML_type term} using the function @{ML_ind prop_of in Thm}. 
   197   into a @{ML_type term} using the function @{ML_ind prop_of in Thm}. 
   196 *}
   198 *}
   197 
   199 
   198 ML %grayML{*fun pretty_thm ctxt thm =
   200 ML %grayML{*fun pretty_thm ctxt thm =
   199   pretty_term ctxt (prop_of thm)*}
   201   pretty_term ctxt (Thm.prop_of thm)*}
   200 
   202 
   201 text {*
   203 text {*
   202   Theorems include schematic variables, such as @{text "?P"}, 
   204   Theorems include schematic variables, such as @{text "?P"}, 
   203   @{text "?Q"} and so on. They are instantiated by Isabelle when a theorem is applied.
   205   @{text "?Q"} and so on. They are instantiated by Isabelle when a theorem is applied.
   204   For example, the theorem 
   206   For example, the theorem 
   215 
   217 
   216 ML %grayML{*fun pretty_thm_no_vars ctxt thm =
   218 ML %grayML{*fun pretty_thm_no_vars ctxt thm =
   217 let
   219 let
   218   val ctxt' = Config.put show_question_marks false ctxt
   220   val ctxt' = Config.put show_question_marks false ctxt
   219 in
   221 in
   220   pretty_term ctxt' (prop_of thm)
   222   pretty_term ctxt' (Thm.prop_of thm)
   221 end*}
   223 end*}
   222 
   224 
   223 text {* 
   225 text {* 
   224   With this function, theorem @{thm [source] conjI} is now printed as follows:
   226   With this function, theorem @{thm [source] conjI} is now printed as follows:
   225 
   227 
   247 
   249 
   248 text {*
   250 text {*
   249   respectively @{ML_type ctyp}
   251   respectively @{ML_type ctyp}
   250 *}
   252 *}
   251 
   253 
   252 ML %grayML{*fun pretty_ctyp ctxt cty = pretty_typ ctxt (typ_of cty)
   254 ML %grayML{*fun pretty_ctyp ctxt cty = pretty_typ ctxt (Thm.typ_of cty)
   253 fun pretty_ctyps ctxt ctys = 
   255 fun pretty_ctyps ctxt ctys = 
   254   Pretty.block (Pretty.commas (map (pretty_ctyp ctxt) ctys))*}
   256   Pretty.block (Pretty.commas (map (pretty_ctyp ctxt) ctys))*}
   255 
   257 
   256 text {*
   258 text {*
   257   \begin{readmore}
   259   \begin{readmore}
   624   obtained by previous calls.
   626   obtained by previous calls.
   625   
   627   
   626   A more realistic example for this combinator is the following code
   628   A more realistic example for this combinator is the following code
   627 *}
   629 *}
   628 
   630 
   629 ML %grayML{*val (((one_def, two_def), three_def), ctxt') = 
   631 ML %grayML{*val ((([one_def], [two_def]), [three_def]), ctxt') = 
   630   @{context}
   632   @{context}
   631   |> Local_Defs.add_def ((@{binding "One"}, NoSyn), @{term "1::nat"}) 
   633   |> Local_Defs.define [((@{binding "One"}, NoSyn), (Binding.empty_atts, @{term "1::nat"}))]
   632   ||>> Local_Defs.add_def ((@{binding "Two"}, NoSyn), @{term "2::nat"})
   634   ||>> Local_Defs.define [((@{binding "Two"}, NoSyn), (Binding.empty_atts,@{term "2::nat"}))]
   633   ||>> Local_Defs.add_def ((@{binding "Three"}, NoSyn), @{term "3::nat"})*}
   635   ||>> Local_Defs.define [((@{binding "Three"}, NoSyn), (Binding.empty_atts,@{term "3::nat"}))]*}
   634 
   636 
   635 text {*
   637 text {*
   636   where we make three definitions, namely @{term "One \<equiv> 1::nat"}, @{term "Two \<equiv> 2::nat"}
   638   where we make three definitions, namely @{term "One \<equiv> 1::nat"}, @{term "Two \<equiv> 2::nat"}
   637   and @{term "Three \<equiv> 3::nat"}. The point of this code is that we augment the initial
   639   and @{term "Three \<equiv> 3::nat"}. The point of this code is that we augment the initial
   638   context with the definitions. The result we are interested in is the
   640   context with the definitions. The result we are interested in is the
   639   augmented context, that is @{ML_text "ctxt'"}, but also the side-results containing 
   641   augmented context, that is @{ML_text "ctxt'"}, but also the side-results containing 
   640   information about the definitions---the function @{ML_ind add_def in Local_Defs} returns
   642   information about the definitions---the function @{ML_ind define in Local_Defs} returns
   641   both as pairs. We can use this information for example to print out the definiens and 
   643   both as pairs. We can use this information for example to print out the definiens and 
   642   the theorem corresponding to the definitions. For example for the first definition:
   644   the theorem corresponding to the definitions. For example for the first definition:
   643 
   645 
   644   @{ML_response_fake [display, gray]
   646   @{ML_response_fake [display, gray]
   645   "let 
   647   "let 
   646   val (one_trm, one_thm) = one_def
   648   val (one_trm, (_, one_thm)) = one_def
   647 in
   649 in
   648   pwriteln (pretty_term ctxt' one_trm);
   650   pwriteln (pretty_term ctxt' one_trm);
   649   pwriteln (pretty_thm ctxt' one_thm)
   651   pwriteln (pretty_thm ctxt' one_thm)
   650 end"
   652 end"
   651   "One
   653   "One
   773   \ref{chp:advanced}.) A context is for example needed to use the
   775   \ref{chp:advanced}.) A context is for example needed to use the
   774   function @{ML print_abbrevs in Proof_Context} that list of all currently
   776   function @{ML print_abbrevs in Proof_Context} that list of all currently
   775   defined abbreviations. For example
   777   defined abbreviations. For example
   776 
   778 
   777   @{ML_response_fake [display, gray]
   779   @{ML_response_fake [display, gray]
   778   "Proof_Context.print_abbrevs @{context}"
   780   "Proof_Context.print_abbrevs false @{context}"
   779 "\<dots>
   781 "\<dots>
   780 INTER \<equiv> INFI
   782 INTER \<equiv> INFI
   781 Inter \<equiv> Inf
   783 Inter \<equiv> Inf
   782 \<dots>"}
   784 \<dots>"}
   783 
   785 
   862   for the antiquotation @{text "term_pat"} is as follows.
   864   for the antiquotation @{text "term_pat"} is as follows.
   863 *}
   865 *}
   864 
   866 
   865 ML %linenosgray{*val term_pat_setup = 
   867 ML %linenosgray{*val term_pat_setup = 
   866 let
   868 let
   867   val parser = Args.context -- Scan.lift Args.name_inner_syntax
   869   val parser = Args.context -- Scan.lift Args.embedded_inner_syntax
   868 
   870 
   869   fun term_pat (ctxt, str) =
   871   fun term_pat (ctxt, str) =
   870      str |> Proof_Context.read_term_pattern ctxt
   872      str |> Proof_Context.read_term_pattern ctxt
   871          |> ML_Syntax.print_term
   873          |> ML_Syntax.print_term
   872          |> ML_Syntax.atomic
   874          |> ML_Syntax.atomic
   895   we can write an antiquotation for type patterns. Its code is
   897   we can write an antiquotation for type patterns. Its code is
   896 *}
   898 *}
   897 
   899 
   898 ML %grayML{*val type_pat_setup = 
   900 ML %grayML{*val type_pat_setup = 
   899 let
   901 let
   900   val parser = Args.context -- Scan.lift Args.name_inner_syntax
   902   val parser = Args.context -- Scan.lift Args.embedded_inner_syntax
   901 
   903 
   902   fun typ_pat (ctxt, str) =
   904   fun typ_pat (ctxt, str) =
   903     let
   905     let
   904       val ctxt' = Proof_Context.set_mode Proof_Context.mode_schematic ctxt
   906       val ctxt' = Proof_Context.set_mode Proof_Context.mode_schematic ctxt
   905     in 
   907     in 
   919 
   921 
   920 text {* 
   922 text {* 
   921 However, a word of warning is in order: new antiquotations should be introduced only after
   923 However, a word of warning is in order: new antiquotations should be introduced only after
   922 careful deliberations. They can potentially make your code harder, rather than easier, to read.
   924 careful deliberations. They can potentially make your code harder, rather than easier, to read.
   923 
   925 
   924   \begin{readmore}
   926   \begin{readmore} @{url "Norbert/ML/ml_antiquotation.ML"}
   925   The files @{ML_file "Pure/ML/ml_antiquotation.ML"} and @{ML_file "Pure/ML/ml_antiquotations.ML"}
   927   The files @{ML_file "Pure/ML/ml_antiquotation.ML"} and @{ML_file "Pure/ML/ml_antiquotations.ML"}
   926   contain the infrastructure and definitions for most antiquotations. Most of the basic operations 
   928   contain the infrastructure and definitions for most antiquotations. Most of the basic operations 
   927   on ML-syntax are implemented in @{ML_file "Pure/ML/ml_syntax.ML"}.
   929   on ML-syntax are implemented in @{ML_file "Pure/ML/ml_syntax.ML"}.
   928   \end{readmore}
   930   \end{readmore}
   929 *}
   931 *}
   945   above it is important to keep in mind that the universal type does not
   947   above it is important to keep in mind that the universal type does not
   946   destroy type-safety of ML: storing and accessing the data can only be done
   948   destroy type-safety of ML: storing and accessing the data can only be done
   947   in a type-safe manner...though run-time checks are needed for that.
   949   in a type-safe manner...though run-time checks are needed for that.
   948 
   950 
   949   \begin{readmore}
   951   \begin{readmore}
   950   In Isabelle the universal type is implemented as the type @{ML_type
   952   In ML the universal type is implemented as the type @{ML_type
   951   Universal.universal} in the file
   953   Universal.universal}.
   952   @{ML_file "Pure/ML-Systems/universal.ML"}.
       
   953   \end{readmore}
   954   \end{readmore}
   954 
   955 
   955   We will show the usage of the universal type by storing an integer and
   956   We will show the usage of the universal type by storing an integer and
   956   a boolean into a single list. Let us first define injection and projection 
   957   a boolean into a single list. Let us first define injection and projection 
   957   functions for booleans and integers into and from the type @{ML_type Universal.universal}.
   958   functions for booleans and integers into and from the type @{ML_type Universal.universal}.
  1342   A concrete example for a configuration value is 
  1343   A concrete example for a configuration value is 
  1343   @{ML_ind simp_trace in Raw_Simplifier}, which switches on trace information
  1344   @{ML_ind simp_trace in Raw_Simplifier}, which switches on trace information
  1344   in the simplifier. This can be used for example in the following proof
  1345   in the simplifier. This can be used for example in the following proof
  1345 *}
  1346 *}
  1346 
  1347 
       
  1348 
  1347 lemma
  1349 lemma
  1348   shows "(False \<or> True) \<and> True"
  1350   shows "(False \<or> True) \<and> True"
  1349 proof (rule conjI)
  1351 proof (rule conjI)
  1350   show "False \<or> True" using [[simp_trace = true]] by simp
  1352   show "False \<or> True" using [[simp_trace = true]] by simp
  1351 next
  1353 next