ProgTutorial/FirstSteps.thy
changeset 324 4172c0743cf2
parent 323 92f6a772e013
child 325 352e31d9dacc
equal deleted inserted replaced
323:92f6a772e013 324:4172c0743cf2
     9    \begin{flushright}
     9    \begin{flushright}
    10   {\em
    10   {\em
    11   ``We will most likely never realize the full importance of painting the Tower,\\ 
    11   ``We will most likely never realize the full importance of painting the Tower,\\ 
    12   that it is the essential element in the conservation of metal works and the\\ 
    12   that it is the essential element in the conservation of metal works and the\\ 
    13   more meticulous the paint job, the longer the Tower shall endure.''} \\[1ex]
    13   more meticulous the paint job, the longer the Tower shall endure.''} \\[1ex]
    14   Gustave Eiffel, In The 300-Meter Tower.\footnote{The Eiffel Tower has been 
    14   Gustave Eiffel, In his book {\em The 300-Meter Tower}.\footnote{The Eiffel Tower has been 
    15   re-painted 18 times since its initial construction, an average of once every 
    15   re-painted 18 times since its initial construction, an average of once every 
    16   seven years. It takes more than a year for a team of 25 painters to paint the Tower 
    16   seven years. It takes more than a year for a team of 25 painters to paint the Tower 
    17   from top to bottom.}\\[1ex]
    17   from top to bottom.}
    18   \end{flushright}
    18   \end{flushright}
    19 
    19 
       
    20   \medskip
    20   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code for
    21   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code for
    21   Isabelle must be part of a theory. If you want to follow the code given in
    22   Isabelle must be part of a theory. If you want to follow the code given in
    22   this chapter, we assume you are working inside the theory starting with
    23   this chapter, we assume you are working inside the theory starting with
    23 
    24 
    24   \begin{quote}
    25   \begin{quote}
    28   \isacommand{begin}\\
    29   \isacommand{begin}\\
    29   \ldots
    30   \ldots
    30   \end{tabular}
    31   \end{tabular}
    31   \end{quote}
    32   \end{quote}
    32 
    33 
    33   We also generally assume you are working with HOL. The given examples might
    34   We also generally assume you are working with the logic HOL. The examples
    34   need to be adapted if you work in a different logic.
    35   that will be given might need to be adapted if you work in a different logic.
    35 *}
    36 *}
    36 
    37 
    37 section {* Including ML-Code *}
    38 section {* Including ML-Code *}
    38 
    39 
    39 text {*
    40 text {*
   250 
   251 
   251 ML{*fun string_of_cterm ctxt ct =  
   252 ML{*fun string_of_cterm ctxt ct =  
   252   string_of_term ctxt (term_of ct)*}
   253   string_of_term ctxt (term_of ct)*}
   253 
   254 
   254 text {*
   255 text {*
   255   In this example the function @{ML_ind  term_of} extracts the @{ML_type
   256   In this example the function @{ML_ind term_of} extracts the @{ML_type
   256   term} from a @{ML_type cterm}.  More than one @{ML_type cterm}s can again be
   257   term} from a @{ML_type cterm}.  More than one @{ML_type cterm}s can again be
   257   printed with @{ML_ind  commas}.
   258   printed with @{ML_ind commas}.
   258 *} 
   259 *} 
   259 
   260 
   260 ML{*fun string_of_cterms ctxt cts =  
   261 ML{*fun string_of_cterms ctxt cts =  
   261   commas (map (string_of_cterm ctxt) cts)*}
   262   commas (map (string_of_cterm ctxt) cts)*}
   262 
   263 
   263 text {*
   264 text {*
   264   The easiest way to get the string of a theorem is to transform it
   265   The easiest way to get the string of a theorem is to transform it
   265   into a @{ML_type cterm} using the function @{ML_ind  crep_thm}. 
   266   into a @{ML_type term} using the function @{ML_ind prop_of}. 
   266 *}
   267 *}
       
   268 
       
   269 ML {* Thm.rep_thm @{thm mp} *}
   267 
   270 
   268 ML{*fun string_of_thm ctxt thm =
   271 ML{*fun string_of_thm ctxt thm =
   269   string_of_cterm ctxt (#prop (crep_thm thm))*}
   272   Syntax.string_of_term ctxt (prop_of thm)*}
   270 
   273 
   271 text {*
   274 text {*
   272   Theorems also include schematic variables, such as @{text "?P"}, 
   275   Theorems also include schematic variables, such as @{text "?P"}, 
   273   @{text "?Q"} and so on. They are needed in order to able to
   276   @{text "?Q"} and so on. They are needed in order to able to
   274   instantiate theorems when they are applied. For example the theorem 
   277   instantiate theorems when they are applied. For example the theorem 
   291 in
   294 in
   292   thm'
   295   thm'
   293 end
   296 end
   294 
   297 
   295 fun string_of_thm_no_vars ctxt thm =
   298 fun string_of_thm_no_vars ctxt thm =
   296   string_of_cterm ctxt (#prop (crep_thm (no_vars ctxt thm)))*}
   299   Syntax.string_of_term ctxt (prop_of (no_vars ctxt thm))*}
   297 
   300 
   298 text {* 
   301 text {* 
   299   Theorem @{thm [source] conjI} is now printed as follows:
   302   Theorem @{thm [source] conjI} is now printed as follows:
   300 
   303 
   301   @{ML_response_fake [display, gray]
   304   @{ML_response_fake [display, gray]
   313 
   316 
   314 text {*
   317 text {*
   315   Note, that when printing out several parcels of information that
   318   Note, that when printing out several parcels of information that
   316   semantically belong together, like a warning message consisting for example
   319   semantically belong together, like a warning message consisting for example
   317   of a term and a type, you should try to keep this information together in a
   320   of a term and a type, you should try to keep this information together in a
   318   single string. So do not print out information as
   321   single string. Therefore do not print out information as
   319 
   322 
   320 @{ML_response_fake [display,gray]
   323 @{ML_response_fake [display,gray]
   321 "tracing \"First half,\"; 
   324 "tracing \"First half,\"; 
   322 tracing \"and second half.\""
   325 tracing \"and second half.\""
   323 "First half,
   326 "First half,
   395 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   398 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   396 
   399 
   397 text {* or *}
   400 text {* or *}
   398 
   401 
   399 ML{*fun inc_by_five x = 
   402 ML{*fun inc_by_five x = 
   400        ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*}
   403   ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*}
   401 
   404 
   402 text {* and typographically more economical than *}
   405 text {* and typographically more economical than *}
   403 
   406 
   404 ML{*fun inc_by_five x =
   407 ML{*fun inc_by_five x =
   405 let val y1 = x + 1
   408 let val y1 = x + 1
   442 end" 
   445 end" 
   443   "P z za zb"}
   446   "P z za zb"}
   444 
   447 
   445   You can read off this behaviour from how @{ML apply_fresh_args} is
   448   You can read off this behaviour from how @{ML apply_fresh_args} is
   446   coded: in Line 2, the function @{ML_ind  fastype_of} calculates the type of the
   449   coded: in Line 2, the function @{ML_ind  fastype_of} calculates the type of the
   447   term; @{ML_ind  binder_types} in the next line produces the list of argument
   450   term; @{ML_ind binder_types} in the next line produces the list of argument
   448   types (in the case above the list @{text "[nat, int, unit]"}); Line 4 
   451   types (in the case above the list @{text "[nat, int, unit]"}); Line 4 
   449   pairs up each type with the string  @{text "z"}; the
   452   pairs up each type with the string  @{text "z"}; the
   450   function @{ML_ind  variant_frees in Variable} generates for each @{text "z"} a
   453   function @{ML_ind  variant_frees in Variable} generates for each @{text "z"} a
   451   unique name avoiding the given @{text f}; the list of name-type pairs is turned
   454   unique name avoiding the given @{text f}; the list of name-type pairs is turned
   452   into a list of variable terms in Line 6, which in the last line is applied
   455   into a list of variable terms in Line 6, which in the last line is applied
   641 
   644 
   642   @{ML_response_fake [display, gray]
   645   @{ML_response_fake [display, gray]
   643   "let
   646   "let
   644   val ctxt = @{context}
   647   val ctxt = @{context}
   645 in
   648 in
   646   map (Syntax.parse_term ctxt) [\"m + n\", \"m - (n::nat)\"] 
   649   map (Syntax.parse_term ctxt) [\"m + n\", \"m * n\", \"m - (n::nat)\"] 
   647   |> Syntax.check_terms ctxt
   650   |> Syntax.check_terms ctxt
   648   |> string_of_terms ctxt
   651   |> string_of_terms ctxt
   649   |> tracing
   652   |> tracing
   650 end"
   653 end"
   651   "m + n, m - n"}
   654   "m + n, m * n, m - n"}
   652 *}
   655 *}
   653 
   656 
   654 text {*
   657 text {*
   655   In this example we obtain two terms with appropriate typing. However, if you
   658   In this example we obtain three terms where @{text m} and @{text n} are of
   656   have only a single term, then @{ML check_terms in Syntax} needs to be
   659   type @{typ "nat"}. However, if you have only a single term, then @{ML
   657   adapted. This can be done with the ``plumbing'' function @{ML
   660   check_terms in Syntax} needs plumbing. This can be done with the function
   658   singleton}.\footnote{There is already a function @{ML check_term in Syntax}
   661   @{ML singleton}.\footnote{There is already a function @{ML check_term in
   659   in the Isabelle sources that is defined in terms of @{ML singleton} and @{ML
   662   Syntax} in the Isabelle sources that is defined in terms of @{ML singleton}
   660   check_terms in Syntax}.} For example
   663   and @{ML check_terms in Syntax}.} For example
   661 
   664 
   662   @{ML_response_fake [display, gray]
   665   @{ML_response_fake [display, gray]
   663   "let 
   666   "let 
   664   val ctxt = @{context}
   667   val ctxt = @{context}
   665 in
   668 in
   687 
   690 
   688 text {*
   691 text {*
   689   The main advantage of embedding all code in a theory is that the code can
   692   The main advantage of embedding all code in a theory is that the code can
   690   contain references to entities defined on the logical level of Isabelle. By
   693   contain references to entities defined on the logical level of Isabelle. By
   691   this we mean definitions, theorems, terms and so on. This kind of reference
   694   this we mean definitions, theorems, terms and so on. This kind of reference
   692   is realised with ML-antiquotations, often also referred to as just
   695   is realised with ML-antiquotations, often just called
   693   antiquotations.\footnote{There are two kinds of antiquotations in Isabelle,
   696   antiquotations.\footnote{There are two kinds of antiquotations in Isabelle,
   694   which have very different purpose and infrastructures. The first kind,
   697   which have very different purpose and infrastructures. The first kind,
   695   described in this section, are \emph{ML-antiquotations}. They are used to
   698   described in this section, are \emph{ML-antiquotations}. They are used to
   696   refer to entities (like terms, types etc) from Isabelle's logic layer inside
   699   refer to entities (like terms, types etc) from Isabelle's logic layer inside
   697   ML-code. The other kind of antiquotations are \emph{document} antiquotations. They
   700   ML-code. The other kind of antiquotations are \emph{document}
   698   are used only in the text parts of Isabelle and their purpose is to print
   701   antiquotations. They are used only in the text parts of Isabelle and their
   699   logical entities inside \LaTeX-documents. They are part of the user level
   702   purpose is to print logical entities inside \LaTeX-documents. They are part
   700   and therefore we are not interested in them in this Tutorial, except in
   703   of the user level and therefore we are not interested in them in this
   701   Appendix \ref{rec:docantiquotations} where we show how to implement your own
   704   Tutorial, except in Appendix \ref{rec:docantiquotations} where we show how
   702   document antiquotations.}
   705   to implement your own document antiquotations.}  For example, one can print
   703   For example, one can print out the name of the current
   706   out the name of the current theory by typing
   704   theory by typing
       
   705 
       
   706   
   707   
   707   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   708   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   708  
   709  
   709   where @{text "@{theory}"} is an antiquotation that is substituted with the
   710   where @{text "@{theory}"} is an antiquotation that is substituted with the
   710   current theory (remember that we assumed we are inside the theory 
   711   current theory (remember that we assumed we are inside the theory 
   819          |> ML_Syntax.print_term
   820          |> ML_Syntax.print_term
   820          |> ML_Syntax.atomic))*}
   821          |> ML_Syntax.atomic))*}
   821 
   822 
   822 text {*
   823 text {*
   823   The parser in Line 2 provides us with a context and a string; this string is
   824   The parser in Line 2 provides us with a context and a string; this string is
   824   transformed into a term using the function @{ML_ind  read_term_pattern in
   825   transformed into a term using the function @{ML_ind read_term_pattern in
   825   ProofContext} (Line 4); the next two lines print the term so that the
   826   ProofContext} (Line 4); the next two lines transform the term into a string
   826   ML-system can understand them. The function @{ML atomic in ML_Syntax}
   827   so that the ML-system can understand them. The function @{ML_ind atomic in
   827   just encloses the term in parentheses. An example for the usage of this 
   828   ML_Syntax} just encloses the term in parentheses. An example for the usage
   828   antiquotation is:
   829   of this antiquotation is:
   829 
   830 
   830   @{ML_response_fake [display,gray]
   831   @{ML_response_fake [display,gray]
   831   "@{term_pat \"Suc (?x::nat)\"}"
   832   "@{term_pat \"Suc (?x::nat)\"}"
   832   "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
   833   "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
   833 
   834 
   842 
   843 
   843 section {* Storing Data (TBD) *}
   844 section {* Storing Data (TBD) *}
   844 
   845 
   845 text {*
   846 text {*
   846   Isabelle provides a mechanism to store (and retrieve) arbitrary data. Before we 
   847   Isabelle provides a mechanism to store (and retrieve) arbitrary data. Before we 
   847   explain this mechanism. 
   848   explain this mechanism, let us digress a bit. Convenitional wisdom is that the 
       
   849   type-system of ML ensures that for example an @{ML_type "'a list"} can only
       
   850   hold elements of type @{ML_type "'a"}.
   848 *}
   851 *}
   849 
   852 
   850 ML{*signature UNIVERSAL_TYPE =
   853 ML{*signature UNIVERSAL_TYPE =
   851 sig
   854 sig
   852   type t
   855   type t