ProgTutorial/FirstSteps.thy
changeset 292 41a802bbb7df
parent 290 6af069ab43d4
child 293 0a567f923b42
equal deleted inserted replaced
291:077c764c8d8b 292:41a802bbb7df
   572 @{ML_response_fake [display,gray] "@{thms conj_ac}" 
   572 @{ML_response_fake [display,gray] "@{thms conj_ac}" 
   573 "(?P \<and> ?Q) = (?Q \<and> ?P)
   573 "(?P \<and> ?Q) = (?Q \<and> ?P)
   574 (?P \<and> ?Q \<and> ?R) = (?Q \<and> ?P \<and> ?R)
   574 (?P \<and> ?Q \<and> ?R) = (?Q \<and> ?P \<and> ?R)
   575 ((?P \<and> ?Q) \<and> ?R) = (?P \<and> ?Q \<and> ?R)"}  
   575 ((?P \<and> ?Q) \<and> ?R) = (?P \<and> ?Q \<and> ?R)"}  
   576 
   576 
   577   You can also refer to the current simpset. To illustrate this we implement the
   577   The point of these antiquotations is that referring to theorems in this way
   578   function that extracts the theorem names stored in a simpset.
   578   makes your code independent from what theorems the user might have stored
       
   579   under this name (this becomes especially important when you deal with
       
   580   theorem lists; see Section \ref{sec:attributes}).
       
   581 
       
   582   You can also refer to the current simpset via an antiquotation. To illustrate 
       
   583   this we implement the function that extracts the theorem names stored in a 
       
   584   simpset.
   579 *}
   585 *}
   580 
   586 
   581 ML{*fun get_thm_names_from_ss simpset =
   587 ML{*fun get_thm_names_from_ss simpset =
   582 let
   588 let
   583   val {simps,...} = MetaSimplifier.dest_ss simpset
   589   val {simps,...} = MetaSimplifier.dest_ss simpset
   594   @{ML_response_fake [display,gray] 
   600   @{ML_response_fake [display,gray] 
   595   "get_thm_names_from_ss @{simpset}" 
   601   "get_thm_names_from_ss @{simpset}" 
   596   "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   602   "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   597 
   603 
   598   Again, this way of referencing simpsets makes you independent from additions
   604   Again, this way of referencing simpsets makes you independent from additions
   599   of lemmas to the simpset by the user that potentially cause loops.
   605   of lemmas to the simpset by the user that can potentially cause loops in your
       
   606   code.
   600 
   607 
   601   On the ML-level of Isabelle, you often have to work with qualified names.
   608   On the ML-level of Isabelle, you often have to work with qualified names.
   602   These are strings with some additional information, such as positional information
   609   These are strings with some additional information, such as positional information
   603   and qualifiers. Such qualified names can be generated with the antiquotation 
   610   and qualifiers. Such qualified names can be generated with the antiquotation 
   604   @{text "@{binding \<dots>}"}.
   611   @{text "@{binding \<dots>}"}. For example
   605 
   612 
   606   @{ML_response [display,gray]
   613   @{ML_response [display,gray]
   607   "@{binding \"name\"}"
   614   "@{binding \"name\"}"
   608   "name"}
   615   "name"}
   609 
   616 
   610   An example where a binding is needed is the function @{ML [index] define in
   617   An example where a qualified name is needed is the function 
   611   LocalTheory}.  This function is below used to define the constant @{term
   618   @{ML [index] define in LocalTheory}.  This function is used below to define 
   612   "TrueConj"} as the conjunction
   619   the constant @{term "TrueConj"} as the conjunction @{term "True \<and> True"}.
   613   @{term "True \<and> True"}.
       
   614 *}
   620 *}
   615   
   621   
   616 local_setup %gray {* 
   622 local_setup %gray {* 
   617   snd o LocalTheory.define Thm.internalK 
   623   snd o LocalTheory.define Thm.internalK 
   618     ((@{binding "TrueConj"}, NoSyn), 
   624     ((@{binding "TrueConj"}, NoSyn), 
   628 
   634 
   629   (FIXME give a better example why bindings are important; maybe
   635   (FIXME give a better example why bindings are important; maybe
   630   give a pointer to \isacommand{local\_setup}; if not, then explain
   636   give a pointer to \isacommand{local\_setup}; if not, then explain
   631   why @{ML snd} is needed)
   637   why @{ML snd} is needed)
   632 
   638 
   633   While antiquotations have many applications, they were originally introduced
   639   It is also possible to define your own antiquotations. But you should
   634   in order to avoid explicit bindings of theorems such as:
   640   exercise care when introducing new one, as they can also make your
   635 *}
   641   code unreadable. In the next section we will see how the (build in) 
   636 
   642   antiquotation @{text "@{term \<dots>}"} can be used to construct terms.
   637 ML{*val allI = thm "allI" *}
   643   A restriction of this antiquotation is that it does not allow you to
   638 
   644   use schematic variables. If you want a antiquotation that does not
   639 text {*
   645   have this restriction, you can implement your own using the 
   640   Such bindings are difficult to maintain and can be overwritten by the
   646   function @{ML [index] ML_Antiquote.inline}. 
   641   user accidentally. This often broke Isabelle
   647 *}
   642   packages. Antiquotations solve this problem, since they are ``linked''
   648 
   643   statically at compile-time.  However, this static linkage also limits their
   649 ML %linenosgray{*ML_Antiquote.inline "term_pat"
   644   usefulness in cases where data needs to be built up dynamically. In the
       
   645   course of this chapter you will learn more about antiquotations:
       
   646   they can simplify Isabelle programming since one can directly access all
       
   647   kinds of logical elements from the ML-level.
       
   648 *}
       
   649 
       
   650 text {* FIXME: give an example of a user defined antiquotation *}
       
   651 
       
   652 ML{*ML_Antiquote.inline "term_pat"
       
   653   (Args.context -- Scan.lift Args.name_source >>
   650   (Args.context -- Scan.lift Args.name_source >>
   654      (fn (ctxt, s) =>
   651      (fn (ctxt, s) =>
   655        s |> ProofContext.read_term_pattern ctxt
   652        s |> ProofContext.read_term_pattern ctxt
   656          |> ML_Syntax.print_term
   653          |> ML_Syntax.print_term
   657          |> ML_Syntax.atomic))*}
   654          |> ML_Syntax.atomic))*}
   658 
   655 
   659 ML{*@{term_pat "?x + ?y"}*}
   656 text {*
   660 
   657   We call the antiquotation @{text "term_pat"} (Line 1); the parser in Line
   661 text {*
   658   2 provides us with a context and a string; this string is transformed into a 
       
   659   term using the function @{ML read_term_pattern in ProofContext} (Line 4);
       
   660   the next two lines print the term so that the ML-system can understand 
       
   661   them. An example of this antiquotation is as follows.
       
   662 
       
   663   @{ML_response_fake [display,gray]
       
   664   "@{term_pat \"Suc (?x::nat)\"}"
       
   665   "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
       
   666 
   662   \begin{readmore}
   667   \begin{readmore}
   663   @{ML_file "Pure/ML/ml_antiquote.ML"}
   668   The file @{ML_file "Pure/ML/ml_antiquote.ML"} contains the the definitions
       
   669   for most antiquotations. 
   664   \end{readmore}
   670   \end{readmore}
       
   671 
       
   672   Note also that in Isabelle there are two kinds of antiquotations, which have
       
   673   very different infrastructures. The first kind, described in this section,
       
   674   is sometimes called \emph{ML-antiquotations}. They are used to refer to
       
   675   entities (like terms, types etc) from Isabelle's logic layer inside ML-code. 
       
   676   They are ``linked'' statically at compile-time, which  limits sometimes 
       
   677   their usefulness in  cases where, for example, terms needs to be built up 
       
   678   dynamically.  
       
   679 
       
   680   The other kind of antiquotations are called \emph{document antiquotations}. 
       
   681   They are used only in the text parts of Isabelle and help with printing logical 
       
   682   entities inside \LaTeX-documents. In this Tutorial we are not interested
       
   683   in these antiquotations, except in Appendix \ref{rec:docantiquotations} where
       
   684   we show how to implement your own document antiquotations. 
   665 *}
   685 *}
   666 
   686 
   667 section {* Terms and Types *}
   687 section {* Terms and Types *}
   668 
   688 
   669 text {*
   689 text {*
   876 
   896 
   877   Another handy function is @{ML [index] lambda}, which abstracts a variable 
   897   Another handy function is @{ML [index] lambda}, which abstracts a variable 
   878   in a term. For example
   898   in a term. For example
   879   
   899   
   880   @{ML_response_fake [display,gray]
   900   @{ML_response_fake [display,gray]
   881   "lambda @{term \"x::nat\"} @{term \"(P::nat\<Rightarrow>bool) x\"}"
   901   "lambda @{term \"x::nat\"} @{term \"(P::nat \<Rightarrow> bool) x\"}"
   882   "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
   902   "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
   883 
   903 
   884   In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound  0"}), 
   904   In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound  0"}), 
   885   and an abstraction. It also records the type of the abstracted
   905   and an abstraction. It also records the type of the abstracted
   886   variable and for printing purposes also its name.  Note that because of the
   906   variable and for printing purposes also its name.  Note that because of the
   887   typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"}
   907   typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"}
   888   is of the same type as the abstracted variable. If it is of different type,
   908   is of the same type as the abstracted variable. If it is of different type,
   889   as in
   909   as in
   890 
   910 
   891   @{ML_response_fake [display,gray]
   911   @{ML_response_fake [display,gray]
   892   "lambda @{term \"x::nat\"} @{term \"(P::bool\<Rightarrow>bool) x\"}"
   912   "lambda @{term \"x::nat\"} @{term \"(P::bool \<Rightarrow> bool) x\"}"
   893   "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Free (\"x\", \"bool\"))"}
   913   "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Free (\"x\", \"bool\"))"}
   894 
   914 
   895   then the variable @{text "Free (\"x\", \"bool\")"} is \emph{not} abstracted. 
   915   then the variable @{text "Free (\"x\", \"bool\")"} is \emph{not} abstracted. 
   896   This is a fundamental principle
   916   This is a fundamental principle
   897   of Church-style typing, where variables with the same name still differ, if they 
   917   of Church-style typing, where variables with the same name still differ, if they 
   898   have different type.
   918   have different type.
   899 
   919 
   900   There is also the function @{ML [index] subst_free} with which terms can 
   920   There is also the function @{ML [index] subst_free} with which terms can 
   901   be replaced by other terms. For example below, we will replace in  
   921   be replaced by other terms. For example below, we will replace in  
   902   @{term "(f::nat\<Rightarrow>nat\<Rightarrow>nat) 0 x"} 
   922   @{term "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0 x"} 
   903   the subterm @{term "(f::nat\<Rightarrow>nat\<Rightarrow>nat) 0"} by @{term y}, and @{term x} by @{term True}.
   923   the subterm @{term "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0"} by @{term y}, and @{term x} by @{term True}.
   904 
   924 
   905   @{ML_response_fake [display,gray]
   925   @{ML_response_fake [display,gray]
   906 "subst_free [(@{term \"(f::nat\<Rightarrow>nat\<Rightarrow>nat) 0\"}, @{term \"y::nat\<Rightarrow>nat\"}),
   926 "let
   907             (@{term \"x::nat\"}, @{term \"True\"})] 
   927   val s1 = (@{term \"(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0\"}, @{term \"y::nat \<Rightarrow> nat\"})
   908   @{term \"((f::nat\<Rightarrow>nat\<Rightarrow>nat) 0) x\"}"
   928   val s2 = (@{term \"x::nat\"}, @{term \"True\"})
       
   929   val trm =  @{term \"((f::nat \<Rightarrow> nat \<Rightarrow> nat) 0) x\"}
       
   930 in
       
   931   subst_free [s1, s2] trm
       
   932 end"
   909   "Free (\"y\", \"nat \<Rightarrow> nat\") $ Const (\"True\", \"bool\")"}
   933   "Free (\"y\", \"nat \<Rightarrow> nat\") $ Const (\"True\", \"bool\")"}
   910 
   934 
   911   As can be seen, @{ML subst_free} does not take typability into account.
   935   As can be seen, @{ML subst_free} does not take typability into account.
   912   However it takes alpha-equivalence into account:
   936   However it takes alpha-equivalence into account:
   913 
   937 
   914   @{ML_response_fake [display, gray]
   938   @{ML_response_fake [display, gray]
   915   "subst_free [(@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})] 
   939 "let
   916   @{term \"(\<lambda>x::nat. x)\"}"
   940   val s = (@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})
       
   941   val trm = @{term \"(\<lambda>x::nat. x)\"}
       
   942 in
       
   943   subst_free [s] trm
       
   944 end"
   917   "Free (\"x\", \"nat\")"}
   945   "Free (\"x\", \"nat\")"}
   918 
   946 
   919   There are many convenient functions that construct specific HOL-terms. For
   947   There are many convenient functions that construct specific HOL-terms. For
   920   example @{ML [index] mk_eq in HOLogic} constructs an equality out of two terms.
   948   example @{ML [index] mk_eq in HOLogic} constructs an equality out of two terms.
   921   The types needed in this equality are calculated from the type of the
   949   The types needed in this equality are calculated from the type of the
   923 
   951 
   924 @{ML_response_fake [gray,display]
   952 @{ML_response_fake [gray,display]
   925   "writeln (Syntax.string_of_term @{context}
   953   "writeln (Syntax.string_of_term @{context}
   926    (HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})))"
   954    (HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})))"
   927   "True = False"}
   955   "True = False"}
       
   956 *}
       
   957 
       
   958 text {*
       
   959   \begin{readmore}
       
   960   Most of the HOL-specific operations on terms and types are defined 
       
   961   in @{ML_file "HOL/Tools/hologic.ML"}.
       
   962   \end{readmore}
   928 *}
   963 *}
   929 
   964 
   930 section {* Constants *}
   965 section {* Constants *}
   931 
   966 
   932 text {*
   967 text {*
  1397   use the commands \isacommand{method\_setup} for installing methods in the
  1432   use the commands \isacommand{method\_setup} for installing methods in the
  1398   current theory and \isacommand{simproc\_setup} for adding new simprocs to
  1433   current theory and \isacommand{simproc\_setup} for adding new simprocs to
  1399   the current simpset.
  1434   the current simpset.
  1400 *}
  1435 *}
  1401 
  1436 
  1402 section {* Theorem Attributes *}
  1437 section {* Theorem Attributes\label{sec:attributes} *}
  1403 
  1438 
  1404 text {*
  1439 text {*
  1405   Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text
  1440   Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text
  1406   "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags
  1441   "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags
  1407   annotated to theorems, but functions that do further processing once a
  1442   annotated to theorems, but functions that do further processing once a