ProgTutorial/General.thy
changeset 378 8d160d79b48c
parent 377 272ba2cceeb2
child 379 d9e0ea61be78
equal deleted inserted replaced
377:272ba2cceeb2 378:8d160d79b48c
   672   for constructing the terms for the logical connectives.\footnote{Thanks to Roy
   672   for constructing the terms for the logical connectives.\footnote{Thanks to Roy
   673   Dyckhoff for suggesting this exercise and working out the details.} 
   673   Dyckhoff for suggesting this exercise and working out the details.} 
   674   \end{exercise}
   674   \end{exercise}
   675 *}
   675 *}
   676 
   676 
   677 section {* Matching and Unification (TBD) *}
   677 section {* Unification and Matching (TBD) *}
   678 
   678 
   679 text {* 
   679 text {* 
   680   Using the antiquotation from Section~\ref{sec:antiquote}.
   680   Isabelle's terms and types contain schematic term variables
   681 *}
   681   (term-constructor @{ML Var}) and schematic type variables (term-constructor
   682 
   682   @{ML TVar}). Both are printed out as variables with a leading question
   683 ML{*val (env, _) = 
   683   mark. They stand for unknown terms and types, which can be made more concrete
   684   Sign.typ_unify @{theory} (@{typ_pat "?'b * ?'c"}, @{typ_pat "?'a * ?'b"}) (Vartab.empty, 0) *}
   684   by instantiations. Such instantiations can be calculated by unification or
   685 
   685   matching. While in case of types, unification and matching is relatively
   686 ML{*Vartab.dest env  *}
   686   straightforward, in case of terms the algorithms are substantially more
   687 
   687   complicated, because terms need higher-order versions of the unification and
   688 ML{*Envir.norm_type env @{typ_pat "?'a"}*}
   688   matching algorithms. Below we shall use the antiquotation @{text "@{typ_pat \<dots>}"} and
   689 
   689   @{text "@{term_pat \<dots>}"} from Section~\ref{sec:antiquote} in order to
   690 ML{*val env = 
   690   construct examples involving schematic variables.
   691   Sign.typ_match @{theory} (@{typ_pat "?'b * ?'c"}, @{typ_pat "?'a * ?'b"}) Vartab.empty *}
   691 
   692 
   692   Let us begin with describing unification and matching of types.  Both
   693 ML{*Envir.subst_type env  @{typ_pat "?'a"} *}
   693   matching and unification of types return a type environment, ML-type
   694 
   694   @{ML_type "Type.tyenv"}, which maps schematic type variables to types (and
   695 text {*
   695   sorts). Below we use the function @{ML_ind typ_unify in Sign} from the 
   696   Note the difference. Norm for unify; Subst for match.
   696   structure @{ML_struct Sign} for unifying
       
   697   the types @{text "?'a * nat"} and @{text "?'b list * ?'b"}. This will
       
   698   produce the mapping @{text "[?'a := ?'b list, ?'b := nat]"}.
       
   699 *}
       
   700 
       
   701 ML{*val (tyenv_unif, _) = let
       
   702   val ty1 = @{typ_pat "?'a * nat"}
       
   703   val ty2 = @{typ_pat "?'b list * ?'b"}
       
   704 in
       
   705   Sign.typ_unify @{theory} (ty1, ty2) (Vartab.empty, 0) 
       
   706 end*}
       
   707 
       
   708 text {* 
       
   709   The value @{ML_ind empty in Vartab} stands for the empty type environment, 
       
   710   which is the value for starting the unification without any 
       
   711   instantiations.\footnote{\bf FIXME: what is 0?} 
       
   712   We can print out the resulting 
       
   713   type environment with the built-in function @{ML_ind dest in Vartab}.
       
   714 
       
   715   @{ML_response_fake [display,gray]
       
   716   "Vartab.dest tyenv_unif"
       
   717   "[((\"'a\", 0), ([\"HOL.type\"], \"?'b List.list\")), 
       
   718  ((\"'b\", 0), ([\"HOL.type\"], \"nat\"))]"}
       
   719 
       
   720   For what follows we will use the following pretty-printing function
       
   721   for @{ML_type "Type.tyenv"}s
       
   722 *}
       
   723 
       
   724 ML{*fun pretty_tyenv ctxt tyenv =
       
   725 let
       
   726   fun aux (v, (s, T)) =
       
   727         Syntax.string_of_typ ctxt (TVar (v, s)) 
       
   728         ^ " := " ^ Syntax.string_of_typ ctxt T
       
   729 in
       
   730   tyenv |> Vartab.dest
       
   731         |> map aux 
       
   732         |> commas
       
   733         |> enclose "[" "]"
       
   734         |> tracing
       
   735 end*}
       
   736 
       
   737 text {*
       
   738   which prints for the type environment above
       
   739 
       
   740   @{ML_response_fake [display, gray]
       
   741   "pretty_tyenv @{context} tyenv_unif"
       
   742   "[?'a := ?'b list, ?'b := nat]"}
       
   743 
       
   744   Observe that the type environment that the function @{ML typ_unify in
       
   745   Sign} returns is in \emph{not} an instantiation in fully solved form: while @{text
       
   746   "?'b"} is instantiated to @{typ nat}, this is not propagated to the
       
   747   instantiation for @{text "?'a"}.  In unification theory, this is often
       
   748   called an instantiation in \emph{triangular form}. These instantiations
       
   749   are used because of performance reasons.
       
   750 
       
   751 
       
   752   To apply a type environment in triangular form to a type, say @{text "?'a *
       
   753   ?'b"}, you should use the function @{ML_ind norm_type in Envir}:
       
   754 
       
   755   @{ML_response_fake [display, gray]
       
   756   "Envir.norm_type tyenv_unif @{typ_pat \"?'a * ?'b\"}"
       
   757   "nat list * nat"}
       
   758 *}
       
   759 
       
   760 text {* 
       
   761   Matching of types can be done with the function @{ML_ind typ_match in Sign}
       
   762   from the structure @{ML_struct Sign}. It also returns a @{ML_type
       
   763   Type.tyenv}. For example
       
   764 *}
       
   765 
       
   766 ML{*val tyenv_match = let
       
   767   val pat = @{typ_pat "?'a * ?'b"}
       
   768   and ty  = @{typ_pat "bool list * nat"}
       
   769 in
       
   770   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
       
   771 end*}
       
   772 
       
   773 text {*
       
   774   Printing out the calculated matcher gives
       
   775 
       
   776   @{ML_response_fake [display,gray]
       
   777   "pretty_tyenv @{context} tyenv_match"
       
   778   "[?'a := bool list, ?'b := nat]"}
       
   779   
       
   780   Applying the matcher to a type needs to be done with the function
       
   781   @{ML_ind subst_type in Envir}.
       
   782 
       
   783   @{ML_response_fake [display, gray]
       
   784   "Envir.subst_type tyenv_match @{typ_pat \"?'a * ?'b\"}"
       
   785   "bool list * nat"}
       
   786 
       
   787   Be careful to observe the difference: use @{ML subst_type in Envir} 
       
   788   for matchers and @{ML norm_type in Envir} for unifiers. To show the 
       
   789   difference let us calculate the following matcher.
       
   790 *}
       
   791 
       
   792 ML{*val tyenv_match' = let
       
   793   val pat = @{typ_pat "?'a * ?'b"}
       
   794   and ty  = @{typ_pat "?'b list * nat"}
       
   795 in
       
   796   Sign.typ_match @{theory} (pat, ty) Vartab.empty 
       
   797 end*}
       
   798 
       
   799 text {*
       
   800   Now @{ML tyenv_unif} is equal to @{ML tyenv_match'}. Consider
       
   801   again the type @{text "?'a * ?'b"}. If we apply 
       
   802   @{ML norm_type in Envir} to the matcher we obtain
       
   803 
       
   804   @{ML_response_fake [display, gray]
       
   805   "Envir.norm_type tyenv_match' @{typ_pat \"?'a * ?'b\"}"
       
   806   "nat list * nat"}
       
   807 
       
   808   which is not a matcher for the second matching problem, and if
       
   809   we apply @{ML subst_type in Envir} to the unifier
       
   810 
       
   811   @{ML_response_fake [display, gray]
       
   812   "Envir.subst_type tyenv_unif @{typ_pat \"?'a * ?'b\"}"
       
   813   "?'b list * nat"}
       
   814   
       
   815   which is not the correct unifier for the unification problem.
       
   816 
       
   817   \begin{readmore}
       
   818   Unification and matching of types is implemented
       
   819   in @{ML_file "Pure/type.ML"}. The ``interface'' functions for them
       
   820   are in @{ML_file "Pure/sign.ML"}. Matching and unification produce type environments
       
   821   as results. These are implemented in @{ML_file "Pure/envir.ML"}.
       
   822   This file also includes the substitution and normalisation functions. 
       
   823   Environments are lookup tables that are implemented in 
       
   824   @{ML_file "Pure/term_ord.ML"}.
       
   825   \end{readmore}
       
   826 *}
       
   827 
       
   828 text {*
       
   829   TBD below
       
   830 
       
   831 
       
   832   \begin{readmore}
       
   833   For term, unification and matching of higher-order patterns is implemented in 
       
   834   @{ML_file "Pure/pattern.ML"}. Full higher-order unification is implemented
       
   835   in @{ML_file "Pure/unify.ML"}. 
       
   836   \end{readmore}
   697 *}
   837 *}
   698 
   838 
   699 section {* Type-Checking\label{sec:typechecking} *}
   839 section {* Type-Checking\label{sec:typechecking} *}
   700 
   840 
   701 text {* 
   841 text {*