ProgTutorial/FirstSteps.thy
changeset 298 8057d65607eb
parent 293 0a567f923b42
child 299 d0b81d6e1b28
equal deleted inserted replaced
297:2565c87f8db7 298:8057d65607eb
   347       |> curry list_comb f *}
   347       |> curry list_comb f *}
   348 
   348 
   349 text {*
   349 text {*
   350   This function takes a term and a context as argument. If the term is of function
   350   This function takes a term and a context as argument. If the term is of function
   351   type, then @{ML "apply_fresh_args"} returns the term with distinct variables 
   351   type, then @{ML "apply_fresh_args"} returns the term with distinct variables 
   352   applied to it. For example:
   352   applied to it. For example below variables are applied to the term 
       
   353   @{term [show_types] "P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool"}:
   353 
   354 
   354   @{ML_response_fake [display,gray]
   355   @{ML_response_fake [display,gray]
   355 "let
   356 "let
   356   val t = @{term \"P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool\"}
   357   val t = @{term \"P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool\"}
   357   val ctxt = @{context}
   358   val ctxt = @{context}
   362 end" 
   363 end" 
   363   "P z za zb"}
   364   "P z za zb"}
   364 
   365 
   365   You can read off this behaviour from how @{ML apply_fresh_args} is
   366   You can read off this behaviour from how @{ML apply_fresh_args} is
   366   coded: in Line 2, the function @{ML [index] fastype_of} calculates the type of the
   367   coded: in Line 2, the function @{ML [index] fastype_of} calculates the type of the
   367   function; @{ML [index] binder_types} in the next line produces the list of argument
   368   term; @{ML [index] binder_types} in the next line produces the list of argument
   368   types (in the case above the list @{text "[nat, int, unit]"}); Line 4 
   369   types (in the case above the list @{text "[nat, int, unit]"}); Line 4 
   369   pairs up each type with the string  @{text "z"}; the
   370   pairs up each type with the string  @{text "z"}; the
   370   function @{ML [index] variant_frees in Variable} generates for each @{text "z"} a
   371   function @{ML [index] variant_frees in Variable} generates for each @{text "z"} a
   371   unique name avoiding the given @{text f}; the list of name-type pairs is turned
   372   unique name avoiding the given @{text f}; the list of name-type pairs is turned
   372   into a list of variable terms in Line 6, which in the last line is applied
   373   into a list of variable terms in Line 6, which in the last line is applied
   373   by the function @{ML [index] list_comb} to the function. In this last step we have to 
   374   by the function @{ML [index] list_comb} to the term. In this last step we have to 
   374   use the function @{ML [index] curry}, because @{ML [index] list_comb} expects the 
   375   use the function @{ML [index] curry}, because @{ML [index] list_comb} expects the 
   375   function and the variables list as a pair. This kind of functions is often needed when
   376   function and the variables list as a pair. This kind of functions is often needed when
   376   constructing terms and the infrastructure helps tremendously to avoid
   377   constructing terms with fresh variables. The infrastructure helps tremendously 
   377   any name clashes. Consider for example: 
   378   to avoid any name clashes. Consider for example: 
   378 
   379 
   379    @{ML_response_fake [display,gray]
   380    @{ML_response_fake [display,gray]
   380 "let
   381 "let
   381   val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"}
   382   val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"}
   382   val ctxt = @{context}
   383   val ctxt = @{context}
   494   
   495   
   495   @{ML_response [display,gray]
   496   @{ML_response [display,gray]
   496   "acc_incs 1 ||>> (fn x => (x, x + 2))"
   497   "acc_incs 1 ||>> (fn x => (x, x + 2))"
   497   "(((((\"\", 1), 2), 3), 4), 6)"}
   498   "(((((\"\", 1), 2), 3), 4), 6)"}
   498 
   499 
   499   (FIXME: maybe give a ``real world'' example)
   500   (FIXME: maybe give a ``real world'' example for this combinator)
   500 *}
   501 *}
   501 
   502 
   502 text {*
   503 text {*
   503   Recall that @{ML [index] "|>"} is the reverse function application. Recall also that
   504   Recall that @{ML [index] "|>"} is the reverse function application. Recall also that
   504   the related 
   505   the related 
   533 
   534 
   534 text {*
   535 text {*
   535   The main advantage of embedding all code in a theory is that the code can
   536   The main advantage of embedding all code in a theory is that the code can
   536   contain references to entities defined on the logical level of Isabelle. By
   537   contain references to entities defined on the logical level of Isabelle. By
   537   this we mean definitions, theorems, terms and so on. This kind of reference is
   538   this we mean definitions, theorems, terms and so on. This kind of reference is
   538   realised with antiquotations.  For example, one can print out the name of the current
   539   realised with antiquotations, sometimes also referred to as ML-antiquotations.  
       
   540   For example, one can print out the name of the current
   539   theory by typing
   541   theory by typing
   540 
   542 
   541   
   543   
   542   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   544   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   543  
   545  
   635   (FIXME give a better example why bindings are important; maybe
   637   (FIXME give a better example why bindings are important; maybe
   636   give a pointer to \isacommand{local\_setup}; if not, then explain
   638   give a pointer to \isacommand{local\_setup}; if not, then explain
   637   why @{ML snd} is needed)
   639   why @{ML snd} is needed)
   638 
   640 
   639   It is also possible to define your own antiquotations. But you should
   641   It is also possible to define your own antiquotations. But you should
   640   exercise care when introducing new one, as they can also make your
   642   exercise care when introducing new ones, as they can also make your
   641   code unreadable. In the next section we will see how the (build in) 
   643   code also difficult to read. In the next section we will see how the (build in) 
   642   antiquotation @{text "@{term \<dots>}"} can be used to construct terms.
   644   antiquotation @{text "@{term \<dots>}"} can be used to construct terms.
   643   A restriction of this antiquotation is that it does not allow you to
   645   A restriction of this antiquotation is that it does not allow you to
   644   use schematic variables. If you want a antiquotation that does not
   646   use schematic variables. If you want an antiquotation that does not
   645   have this restriction, you can implement your own using the 
   647   have this restriction, you can implement your own using the 
   646   function @{ML [index] ML_Antiquote.inline}. 
   648   function @{ML [index] ML_Antiquote.inline}. The code is as follows.
   647 *}
   649 *}
   648 
   650 
   649 ML %linenosgray{*ML_Antiquote.inline "term_pat"
   651 ML %linenosgray{*ML_Antiquote.inline "term_pat"
   650   (Args.context -- Scan.lift Args.name_source >>
   652   (Args.context -- Scan.lift Args.name_source >>
   651      (fn (ctxt, s) =>
   653      (fn (ctxt, s) =>
   652        s |> ProofContext.read_term_pattern ctxt
   654        s |> ProofContext.read_term_pattern ctxt
   653          |> ML_Syntax.print_term
   655          |> ML_Syntax.print_term
   654          |> ML_Syntax.atomic))*}
   656          |> ML_Syntax.atomic))*}
   655 
   657 
   656 text {*
   658 text {*
   657   We call the antiquotation @{text "term_pat"} (Line 1); the parser in Line
   659   We call the new antiquotation @{text "term_pat"} (Line 1); the parser in Line
   658   2 provides us with a context and a string; this string is transformed into a 
   660   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);
   661   term using the function @{ML [index] read_term_pattern in ProofContext} (Line 4);
   660   the next two lines print the term so that the ML-system can understand 
   662   the next two lines print the term so that the ML-system can understand 
   661   them. An example of this antiquotation is as follows.
   663   them. An example of this antiquotation is as follows.
   662 
   664 
   663   @{ML_response_fake [display,gray]
   665   @{ML_response_fake [display,gray]
   664   "@{term_pat \"Suc (?x::nat)\"}"
   666   "@{term_pat \"Suc (?x::nat)\"}"
   665   "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
   667   "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"}
       
   668 
       
   669   which is the internal representation of the term @{text "Suc ?x"}.
   666 
   670 
   667   \begin{readmore}
   671   \begin{readmore}
   668   The file @{ML_file "Pure/ML/ml_antiquote.ML"} contains the the definitions
   672   The file @{ML_file "Pure/ML/ml_antiquote.ML"} contains the the definitions
   669   for most antiquotations. 
   673   for most antiquotations. 
   670   \end{readmore}
   674   \end{readmore}
   671 
   675 
   672   Note also that in Isabelle there are two kinds of antiquotations, which have
   676   Note one source of possible confusion about antiquotations. There are two kinds 
   673   very different infrastructures. The first kind, described in this section,
   677   of them in Isabelle, which have very different purpose and infrastructures. The 
   674   is sometimes called \emph{ML-antiquotations}. They are used to refer to
   678   first kind, described in this section, are \emph{ML-antiquotations}. They are 
   675   entities (like terms, types etc) from Isabelle's logic layer inside ML-code. 
   679   used to refer to entities (like terms, types etc) from Isabelle's logic layer 
   676   They are ``linked'' statically at compile-time, which  limits sometimes 
   680   inside ML-code. They are ``linked'' statically at compile-time, which  limits 
   677   their usefulness in  cases where, for example, terms needs to be built up 
   681   sometimes their usefulness in  cases where, for example, terms needs to be 
   678   dynamically.  
   682   built up dynamically.  
   679 
   683 
   680   The other kind of antiquotations are called \emph{document antiquotations}. 
   684   The other kind of antiquotations are \emph{document} antiquotations. 
   681   They are used only in the text parts of Isabelle and help with printing logical 
   685   They are used only in the text parts of Isabelle and their purpose is to print 
   682   entities inside \LaTeX-documents. In this Tutorial we are not interested
   686   logical entities inside \LaTeX-documents. They are part of the user level and
   683   in these antiquotations, except in Appendix \ref{rec:docantiquotations} where
   687   therefore we are not interested in them in this Tutorial, except in 
   684   we show how to implement your own document antiquotations. 
   688   Appendix \ref{rec:docantiquotations} where we show how to implement your 
       
   689   own document antiquotations. 
   685 *}
   690 *}
   686 
   691 
   687 section {* Terms and Types *}
   692 section {* Terms and Types *}
   688 
   693 
   689 text {*
   694 text {*
   706 | Bound of int 
   711 | Bound of int 
   707 | Abs of string * typ * term 
   712 | Abs of string * typ * term 
   708 | $ of term * term *}
   713 | $ of term * term *}
   709 
   714 
   710 text {*
   715 text {*
       
   716   This datatype implements lambda-terms typed in Church-style.
   711   As can be seen in Line 5, terms use the usual de Bruijn index mechanism
   717   As can be seen in Line 5, terms use the usual de Bruijn index mechanism
   712   for representing bound variables.  For
   718   for representing bound variables.  For
   713   example in
   719   example in
   714 
   720 
   715   @{ML_response_fake [display, gray]
   721   @{ML_response_fake [display, gray]
   716   "@{term \"\<lambda>x y. x y\"}"
   722   "@{term \"\<lambda>x y. x y\"}"
   717   "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"}
   723   "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"}
   718 
   724 
   719   the indices refer to the number of Abstractions (@{ML Abs}) that we need to skip
   725   the indices refer to the number of Abstractions (@{ML Abs}) that we need to
   720   until we hit the @{ML Abs} that binds the corresponding variable. Note that
   726   skip until we hit the @{ML Abs} that binds the corresponding variable. Constructing 
   721   the names of bound variables are kept at abstractions for printing purposes,
   727   a term with dangling de Bruijn indices is possible, but will be flagged as
   722   and so should be treated only as ``comments''.  Application in Isabelle is
   728   ill-formed when you try to typecheck or certify it (see
   723   realised with the term-constructor @{ML $}. 
   729   Section~\ref{sec:typechecking}). Note that the names of bound variables are kept at
       
   730   abstractions for printing purposes, and so should be treated only as
       
   731   ``comments''.  Application in Isabelle is realised with the term-constructor
       
   732   @{ML $}.
       
   733 
   724 
   734 
   725   Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free})
   735   Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free})
   726   and variables (term-constructor @{ML Var}). The latter correspond to the schematic 
   736   and variables (term-constructor @{ML Var}). The latter correspond to the schematic 
   727   variables that when printed show up with a question mark in front of them. Consider 
   737   variables that when printed show up with a question mark in front of them. Consider 
   728   the following two examples
   738   the following two examples
   729   
   739   
   730   @{ML_response_fake [display, gray]
   740   @{ML_response_fake [display, gray]
   731 "let
   741 "let
   732   val v1 = Var ((\"x\", 3), @{typ bool})
   742   val v1 = Var ((\"x\", 3), @{typ bool})
   733   val v2 = Var ((\"x1\", 3), @{typ bool})
   743   val v2 = Var ((\"x1\", 3), @{typ bool})
       
   744   val v3 = Free (\"x\", @{typ bool})
   734 in
   745 in
   735   writeln (Syntax.string_of_term @{context} v1);
   746   writeln (Syntax.string_of_term @{context} v1);
   736   writeln (Syntax.string_of_term @{context} v2)
   747   writeln (Syntax.string_of_term @{context} v2);
       
   748   writeln (Syntax.string_of_term @{context} v3)
   737 end"
   749 end"
   738 "?x3
   750 "?x3
   739 ?x1.3"}
   751 ?x1.3
   740 
   752 x"}
   741   This is different from a free variable
   753 
   742 
   754   When constructing terms, you are usually concerned with free variables (as mentioned earlier,
   743   @{ML_response_fake [display, gray]
       
   744   "writeln (Syntax.string_of_term @{context} (Free (\"x\", @{typ bool})))"
       
   745   "x"}
       
   746 
       
   747   When constructing terms, you are usually concerned with free variables (for example
       
   748   you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). 
   755   you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). 
   749   If you deal with theorems, you have to, however, observe the distinction. A similar
   756   If you deal with theorems, you have to, however, observe the distinction. A similar
   750   distinction holds for types (see below).
   757   distinction holds for types (see below).
   751 
   758 
   752   \begin{readmore}
   759   \begin{readmore}
   815   As already seen above, types can be constructed using the antiquotation 
   822   As already seen above, types can be constructed using the antiquotation 
   816   @{text "@{typ \<dots>}"}. For example:
   823   @{text "@{typ \<dots>}"}. For example:
   817 
   824 
   818   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   825   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   819 
   826 
   820   Their definition is
   827   The corresponding datatype is
   821 *}
   828 *}
   822   
   829   
   823 ML_val{*datatype typ =
   830 ML_val{*datatype typ =
   824   Type  of string * typ list 
   831   Type  of string * typ list 
   825 | TFree of string * sort 
   832 | TFree of string * sort 
   828 text {*
   835 text {*
   829   Like with terms, there is the distinction between free type
   836   Like with terms, there is the distinction between free type
   830   variables (term-constructor @{ML "TFree"} and schematic
   837   variables (term-constructor @{ML "TFree"} and schematic
   831   type variables (term-constructor @{ML "TVar"}). A type constant,
   838   type variables (term-constructor @{ML "TVar"}). A type constant,
   832   like @{typ "int"} or @{typ bool}, are types with an empty list
   839   like @{typ "int"} or @{typ bool}, are types with an empty list
   833   of argument types.
   840   of argument types. However, it is a bit difficult to show an
   834   
   841   example, because Isabelle always pretty-prints types (unlike terms).
       
   842   Here is a contrived example:
       
   843 
       
   844   @{ML_response [display, gray]
       
   845   "if Type (\"bool\", []) = @{typ \"bool\"} then true else false"
       
   846   "true"}
   835 
   847 
   836   \begin{readmore}
   848   \begin{readmore}
   837   Types are described in detail in \isccite{sec:types}. Their
   849   Types are described in detail in \isccite{sec:types}. Their
   838   definition and many useful operations are implemented 
   850   definition and many useful operations are implemented 
   839   in @{ML_file "Pure/type.ML"}.
   851   in @{ML_file "Pure/type.ML"}.
   889   constructing terms. One is the function @{ML [index] list_comb}, which takes a term
   901   constructing terms. One is the function @{ML [index] list_comb}, which takes a term
   890   and a list of terms as arguments, and produces as output the term
   902   and a list of terms as arguments, and produces as output the term
   891   list applied to the term. For example
   903   list applied to the term. For example
   892 
   904 
   893 @{ML_response_fake [display,gray]
   905 @{ML_response_fake [display,gray]
   894 "list_comb (@{term \"P::nat\"}, [@{term \"True\"}, @{term \"False\"}])"
   906 "let
       
   907   val t = @{term \"P::nat\"}
       
   908   val args = [@{term \"True\"}, @{term \"False\"}]
       
   909 in
       
   910   list_comb (t, args)
       
   911 end"
   895 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"}
   912 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"}
   896 
   913 
   897   Another handy function is @{ML [index] lambda}, which abstracts a variable 
   914   Another handy function is @{ML [index] lambda}, which abstracts a variable 
   898   in a term. For example
   915   in a term. For example
   899   
   916   
   900   @{ML_response_fake [display,gray]
   917   @{ML_response_fake [display,gray]
   901   "lambda @{term \"x::nat\"} @{term \"(P::nat \<Rightarrow> bool) x\"}"
   918   "lambda @{term \"x::nat\"} @{term \"(P::nat \<Rightarrow> bool) x\"}"
   902   "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
   919   "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"}
   903 
   920 
   904   In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound  0"}), 
   921   In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound 0"}), 
   905   and an abstraction. It also records the type of the abstracted
   922   and an abstraction. It also records the type of the abstracted
   906   variable and for printing purposes also its name.  Note that because of the
   923   variable and for printing purposes also its name.  Note that because of the
   907   typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"}
   924   typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"}
   908   is of the same type as the abstracted variable. If it is of different type,
   925   is of the same type as the abstracted variable. If it is of different type,
   909   as in
   926   as in
  1157   named @{text "add_"}some\_name in @{ML_file "Pure/term.ML"}.
  1174   named @{text "add_"}some\_name in @{ML_file "Pure/term.ML"}.
  1158 
  1175 
  1159 *}
  1176 *}
  1160 
  1177 
  1161 
  1178 
  1162 section {* Type-Checking *}
  1179 section {* Type-Checking\label{sec:typechecking} *}
  1163 
  1180 
  1164 text {* 
  1181 text {* 
  1165   
  1182   
  1166   You can freely construct and manipulate @{ML_type "term"}s and @{ML_type
  1183   You can freely construct and manipulate @{ML_type "term"}s and @{ML_type
  1167   typ}es, since they are just arbitrary unchecked trees. However, you
  1184   typ}es, since they are just arbitrary unchecked trees. However, you