ProgTutorial/FirstSteps.thy
changeset 372 6bf955db9b62
parent 371 e6f583366779
child 373 28a49fe024c9
equal deleted inserted replaced
371:e6f583366779 372:6bf955db9b62
    40 
    40 
    41   We also generally assume you are working with the logic HOL. The examples
    41   We also generally assume you are working with the logic HOL. The examples
    42   that will be given might need to be adapted if you work in a different logic.
    42   that will be given might need to be adapted if you work in a different logic.
    43 *}
    43 *}
    44 
    44 
    45 section {* Including ML-Code *}
    45 section {* Including ML-Code\label{sec:include} *}
    46 
    46 
    47 text {*
    47 text {*
    48   The easiest and quickest way to include code in a theory is by using the
    48   The easiest and quickest way to include code in a theory is by using the
    49   \isacommand{ML}-command. For example:
    49   \isacommand{ML}-command. For example:
    50 
    50 
   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   Sometimes you want to print out a term together with some type information.
   257   You can also print out term together with type information.
   258   This can be achieved by setting the reference @{ML_ind show_types in Syntax} 
   258   This can be achieved by setting 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*}
   266 
   266 
   267   @{ML_response_fake [display, gray]
   267   @{ML_response_fake [display, gray]
   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 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
   273   @{ML_ind show_all_types in Syntax} to @{ML true}. We obtain then
   274 *}
   274 *}
   275 (*<*)ML %linenos {*show_all_types := true*}
   275 (*<*)ML %linenos {*show_all_types := true*}
   276 (*>*)
   276 (*>*)
   277 text {*
   277 text {*
   278   @{ML_response_fake [display, gray]
   278   @{ML_response_fake [display, gray]
   505   variant_frees in Variable} generates for each @{text "z"} a unique name
   505   variant_frees in Variable} generates for each @{text "z"} a unique name
   506   avoiding the given @{text f}; the list of name-type pairs is turned into a
   506   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
   507   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
   508   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}
   509   to use the function @{ML_ind curry in Library}, because @{ML list_comb}
   510   expects the function and the variables list as a pair. This kind of
   510   expects the function and the variables list as a pair. 
   511   functions is often needed when constructing terms with fresh variables. The
   511   Functions like @{ML apply_fresh_args} are often needed when constructing 
       
   512   terms with fresh variables. The
   512   infrastructure helps tremendously to avoid any name clashes. Consider for
   513   infrastructure helps tremendously to avoid any name clashes. Consider for
   513   example:
   514   example:
   514 
   515 
   515    @{ML_response_fake [display,gray]
   516    @{ML_response_fake [display,gray]
   516 "let
   517 "let
   710 end"
   711 end"
   711   "m + n, m * n, m - n"}
   712   "m + n, m * n, m - n"}
   712 *}
   713 *}
   713 
   714 
   714 text {*
   715 text {*
   715   In this example we obtain three terms (using @{ML_ind parse_term in Syntax}) whose 
   716   In this example we obtain three terms (using the function 
   716   variables @{text m} and @{text n} are of type @{typ "nat"}. If you have only 
   717   @{ML_ind parse_term in Syntax}) whose variables @{text m} and @{text n} 
   717   a single term, then @{ML
   718   are of type @{typ "nat"}. If you have only a single term, then @{ML
   718   check_terms in Syntax} needs plumbing. This can be done with the function
   719   check_terms in Syntax} needs plumbing. This can be done with the function
   719   @{ML singleton}.\footnote{There is already a function @{ML check_term in
   720   @{ML_ind singleton in Library}.\footnote{There is already a function @{ML check_term in
   720   Syntax} in the Isabelle sources that is defined in terms of @{ML singleton}
   721   Syntax} in the file @{ML_file "Pure/Syntax/syntax.ML"} that is implemented 
   721   and @{ML check_terms in Syntax}.} For example
   722   in terms of @{ML singleton} and @{ML check_terms in Syntax}.} For example
   722 
   723 
   723   @{ML_response_fake [display, gray]
   724   @{ML_response_fake [display, gray, linenos]
   724   "let 
   725   "let 
   725   val ctxt = @{context}
   726   val ctxt = @{context}
   726 in
   727 in
   727   Syntax.parse_term ctxt \"m - (n::nat)\" 
   728   Syntax.parse_term ctxt \"m - (n::nat)\" 
   728   |> singleton (Syntax.check_terms ctxt)
   729   |> singleton (Syntax.check_terms ctxt)
   729   |> string_of_term ctxt
   730   |> string_of_term ctxt
   730   |> tracing
   731   |> tracing
   731 end"
   732 end"
   732   "m - n"}
   733   "m - n"}
   733    
   734    
       
   735   where in Line 5, the function operating over lists fits with the
       
   736   single term generated in Line 4.
       
   737 
   734   \begin{readmore}
   738   \begin{readmore}
   735   The most frequently used combinators are defined in the files @{ML_file
   739   The most frequently used combinators are defined in the files @{ML_file
   736   "Pure/library.ML"}
   740   "Pure/library.ML"}
   737   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   741   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   738   contains further information about combinators.
   742   contains further information about combinators.
   744 
   748 
   745 
   749 
   746 section {* ML-Antiquotations *}
   750 section {* ML-Antiquotations *}
   747 
   751 
   748 text {*
   752 text {*
   749   Recall that code in Isabelle is always embedded in a theory.  The main
   753   Recall from Section \ref{sec:include} that code in Isabelle is always
   750   advantage of this is that the code can contain references to entities
   754   embedded in a theory.  The main advantage of this is that the code can
   751   defined on the logical level of Isabelle. By this we mean definitions,
   755   contain references to entities defined on the logical level of Isabelle. By
   752   theorems, terms and so on. This kind of reference is realised in Isabelle
   756   this we mean references to definitions, theorems, terms and so on. These
   753   with ML-antiquotations, often just called antiquotations.\footnote{There are
   757   reference are realised in Isabelle with ML-antiquotations, often just called
   754   two kinds of antiquotations in Isabelle, which have very different purposes
   758   antiquotations.\footnote{Note that there are two kinds of antiquotations in
   755   and infrastructures. The first kind, described in this section, are
   759   Isabelle, which have very different purposes and infrastructures. The first
   756   \emph{\index*{ML-antiquotation}}. They are used to refer to entities (like terms,
   760   kind, described in this section, are \emph{\index*{ML-antiquotation}}. They
   757   types etc) from Isabelle's logic layer inside ML-code. The other kind of
   761   are used to refer to entities (like terms, types etc) from Isabelle's logic
   758   antiquotations are \emph{document}\index{document antiquotation} antiquotations. 
   762   layer inside ML-code. The other kind of antiquotations are
   759   They are used only in the
   763   \emph{document}\index{document antiquotation} antiquotations. They are used
   760   text parts of Isabelle and their purpose is to print logical entities inside
   764   only in the text parts of Isabelle and their purpose is to print logical
   761   \LaTeX-documents. Document antiquotations are part of the user level and
   765   entities inside \LaTeX-documents. Document antiquotations are part of the
   762   therefore we are not interested in them in this Tutorial, except in Appendix
   766   user level and therefore we are not interested in them in this Tutorial,
   763   \ref{rec:docantiquotations} where we show how to implement your own document
   767   except in Appendix \ref{rec:docantiquotations} where we show how to
   764   antiquotations.}  For example, one can print out the name of the current
   768   implement your own document antiquotations.}  Syntactically antiquotations
   765   theory with the code
   769   are indicated by the @{ML_text @}-sign followed by text wrapped in @{text
       
   770   "{\<dots>}"}.  For example, one can print out the name of the current theory with
       
   771   the code
   766   
   772   
   767   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   773   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   768  
   774  
   769   where @{text "@{theory}"} is an antiquotation that is substituted with the
   775   where @{text "@{theory}"} is an antiquotation that is substituted with the
   770   current theory (remember that we assumed we are inside the theory 
   776   current theory (remember that we assumed we are inside the theory 
   868   \footnote{\bf FIXME: There should probably a separate section on binding, long-names
   874   \footnote{\bf FIXME: There should probably a separate section on binding, long-names
   869   and sign.}
   875   and sign.}
   870 
   876 
   871   It is also possible to define your own antiquotations. But you should
   877   It is also possible to define your own antiquotations. But you should
   872   exercise care when introducing new ones, as they can also make your code
   878   exercise care when introducing new ones, as they can also make your code
   873   also difficult to read. In the next chapter we describe how the (build in)
   879   also difficult to read. In the next chapter we describe how to construct
   874   antiquotation @{text "@{term \<dots>}"} for constructing terms.  A
   880   terms with the (build in) antiquotation @{text "@{term \<dots>}"}.  A restriction
   875   restriction of this antiquotation is that it does not allow you to use
   881   of this antiquotation is that it does not allow you to use schematic
   876   schematic variables in terms. If you want to have an antiquotation that does not have
   882   variables in terms. If you want to have an antiquotation that does not have
   877   this restriction, you can implement your own using the function @{ML_ind
   883   this restriction, you can implement your own using the function @{ML_ind
   878   inline in ML_Antiquote} in the structure @{ML_struct ML_Antiquote}. The code 
   884   inline in ML_Antiquote} from the structure @{ML_struct ML_Antiquote}. The code
   879   for the antiquotation @{text "term_pat"} is as follows.
   885   for the antiquotation @{text "term_pat"} is as follows.
   880 *}
   886 *}
   881 
   887 
   882 ML %linenosgray{*let
   888 ML %linenosgray{*let
   883   val parser = Args.context -- Scan.lift Args.name_source
   889   val parser = Args.context -- Scan.lift Args.name_source
   892 
   898 
   893 text {*
   899 text {*
   894   The parser in Line 2 provides us with a context and a string; this string is
   900   The parser in Line 2 provides us with a context and a string; this string is
   895   transformed into a term using the function @{ML_ind read_term_pattern in
   901   transformed into a term using the function @{ML_ind read_term_pattern in
   896   ProofContext} (Line 5); the next two lines transform the term into a string
   902   ProofContext} (Line 5); the next two lines transform the term into a string
   897   so that the ML-system can understand it. An example for this antiquotation is:
   903   so that the ML-system can understand it. (All these functions will be explained
       
   904   in more detail in later sections.) An example for this antiquotation is:
   898 
   905 
   899   @{ML_response_fake [display,gray]
   906   @{ML_response_fake [display,gray]
   900   "@{term_pat \"Suc (?x::nat)\"}"
   907   "@{term_pat \"Suc (?x::nat)\"}"
   901   "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
   908   "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
   902 
   909 
   919   @{ML_type "'a"}. Despite this wisdom, however, it is possible to implement a
   926   @{ML_type "'a"}. Despite this wisdom, however, it is possible to implement a
   920   universal type in ML, although by some arguably accidental features of ML.
   927   universal type in ML, although by some arguably accidental features of ML.
   921   This universal type can be used to store data of different type into a single list.
   928   This universal type can be used to store data of different type into a single list.
   922   In fact, it allows one to inject and to project data of \emph{arbitrary} type. This is
   929   In fact, it allows one to inject and to project data of \emph{arbitrary} type. This is
   923   in contrast to datatypes, which only allow injection and projection of data for
   930   in contrast to datatypes, which only allow injection and projection of data for
   924   some fixed collection of types. In light of the conventional wisdom cited
   931   some \emph{fixed} collection of types. In light of the conventional wisdom cited
   925   above it is important to keep in mind that the universal type does not
   932   above it is important to keep in mind that the universal type does not
   926   destroy type-safety of ML: storing and accessing the data can only be done
   933   destroy type-safety of ML: storing and accessing the data can only be done
   927   in a type-safe manner.
   934   in a type-safe manner.
   928 
   935 
   929   \begin{readmore}
   936   \begin{readmore}
   960 in
   967 in
   961   [thirteen, truth_val]
   968   [thirteen, truth_val]
   962 end*}
   969 end*}
   963 
   970 
   964 text {*
   971 text {*
   965   The data can be retrieved using the projection functions.
   972   The data can be retrieved with the projection functions defined above.
   966   
   973   
   967   @{ML_response [display, gray]
   974   @{ML_response_fake [display, gray]
   968 "(project_int (nth foo_list 0), project_bool (nth foo_list 1))" 
   975 "project_int (nth foo_list 0); 
   969 "(13, true)"}
   976 project_bool (nth foo_list 1)" 
       
   977 "13
       
   978 true"}
   970 
   979 
   971   Notice that we access the integer as an integer and the boolean as
   980   Notice that we access the integer as an integer and the boolean as
   972   a boolean. If we attempt to access the integer as a boolean, then we get 
   981   a boolean. If we attempt to access the integer as a boolean, then we get 
   973   a runtime error. 
   982   a runtime error. 
   974   
   983   
   980   containing a universal type.
   989   containing a universal type.
   981 
   990 
   982   Now, Isabelle heavily uses this mechanism for storing all sorts of
   991   Now, Isabelle heavily uses this mechanism for storing all sorts of
   983   data: theorem lists, simpsets, facts etc.  Roughly speaking, there are two
   992   data: theorem lists, simpsets, facts etc.  Roughly speaking, there are two
   984   places where data can be stored in Isabelle: in \emph{theories} and in \emph{proof
   993   places where data can be stored in Isabelle: in \emph{theories} and in \emph{proof
   985   contexts}. Data such as simpsets need to be stored
   994   contexts}. Data such as simpsets are ``global'' and therefore need to be stored
   986   in a theory, since they need to be maintained across proofs and even across
   995   in a theory (simpsets need to be maintained across proofs and even across
   987   theories.  On the other hand, data such as facts change inside a proof and
   996   theories).  On the other hand, data such as facts change inside a proof and
   988   are only relevant to the proof at hand. Therefore such data needs to be 
   997   are only relevant to the proof at hand. Therefore such data needs to be 
   989   maintained inside a proof context.
   998   maintained inside a proof context, which represents ``local'' data.
   990 
   999 
   991   For theories and proof contexts there are, respectively, the functors 
  1000   For theories and proof contexts there are, respectively, the functors 
   992   @{ML_funct_ind TheoryDataFun} and @{ML_funct_ind ProofDataFun} that help
  1001   @{ML_funct_ind TheoryDataFun} and @{ML_funct_ind ProofDataFun} that help
   993   with the data storage. Below we show how to implement a table in which we
  1002   with the data storage. Below we show how to implement a table in which you
   994   can store theorems and look them up according to a string key. The
  1003   can store theorems and look them up according to a string key. The
   995   intention in this example is to be able to look up introduction rules for logical
  1004   intention in this example is to be able to look up introduction rules for logical
   996   connectives. Such a table might be useful in an automatic proof procedure
  1005   connectives. Such a table might be useful in an automatic proof procedure
   997   and therefore it makes sense to store this data inside a theory.  
  1006   and therefore it makes sense to store this data inside a theory.  
   998   Therefore we use the functor @{ML_funct TheoryDataFun}.
  1007   Consequently we use the functor @{ML_funct TheoryDataFun}.
   999   The code for the table is:
  1008   The code for the table is:
  1000 *}
  1009 *}
  1001 
  1010 
  1002 ML %linenosgray{*structure Data = TheoryDataFun
  1011 ML %linenosgray{*structure Data = TheoryDataFun
  1003   (type T = thm Symtab.table
  1012   (type T = thm Symtab.table
  1013   producing an associated @{ML_type thm}. We also have to specify four
  1022   producing an associated @{ML_type thm}. We also have to specify four
  1014   functions to use this functor: namely how to initialise the data storage
  1023   functions to use this functor: namely how to initialise the data storage
  1015   (Line 3), how to copy it (Line 4), how to extend it (Line 5) and how two
  1024   (Line 3), how to copy it (Line 4), how to extend it (Line 5) and how two
  1016   tables should be merged (Line 6). These functions correspond roughly to the
  1025   tables should be merged (Line 6). These functions correspond roughly to the
  1017   operations performed on theories and we just give some sensible 
  1026   operations performed on theories and we just give some sensible 
  1018   defaults\footnote{\bf FIXME: Say more about the
  1027   defaults.\footnote{\bf FIXME: Say more about the
  1019   assumptions of these operations.} The result structure @{ML_text Data}
  1028   assumptions of these operations.} The result structure @{ML_text Data}
  1020   contains functions for accessing the table (@{ML Data.get}) and for updating
  1029   contains functions for accessing the table (@{ML Data.get}) and for updating
  1021   it (@{ML Data.map}). There are also two more functions (@{ML Data.init} and
  1030   it (@{ML Data.map}). There are also two more functions (@{ML Data.init} and
  1022   @{ML Data.put}), which however are not relevant here. Below we define two
  1031   @{ML Data.put}), which however are not relevant here. Below we define two
  1023   auxiliary functions, which help us with accessing the table.
  1032   auxiliary functions, which help us with accessing the table.
  1140    fun init _ = [])*}
  1149    fun init _ = [])*}
  1141 
  1150 
  1142 text {*
  1151 text {*
  1143   The function we have to specify has to produce a list once a context 
  1152   The function we have to specify has to produce a list once a context 
  1144   is initialised (possibly taking the theory into account from which the 
  1153   is initialised (possibly taking the theory into account from which the 
  1145   context is derived). We choose to just return the empty list. Next 
  1154   context is derived). We choose here to just return the empty list. Next 
  1146   we define two auxiliary functions for updating the list with a given
  1155   we define two auxiliary functions for updating the list with a given
  1147   term and printing the list. 
  1156   term and printing the list. 
  1148 *}
  1157 *}
  1149 
  1158 
  1150 ML{*fun update trm = Data.map (fn trms => trm::trms)
  1159 ML{*fun update trm = Data.map (fn trms => trm::trms)