ProgTutorial/FirstSteps.thy
changeset 313 1ca2f41770cc
parent 312 05cbe2430b76
child 314 79202e2eab6a
equal deleted inserted replaced
312:05cbe2430b76 313:1ca2f41770cc
   862   @{ML_response_fake [display, gray]
   862   @{ML_response_fake [display, gray]
   863   "@{term \"\<lambda>x y. x y\"}"
   863   "@{term \"\<lambda>x y. x y\"}"
   864   "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"}
   864   "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"}
   865 
   865 
   866   the indices refer to the number of Abstractions (@{ML Abs}) that we need to
   866   the indices refer to the number of Abstractions (@{ML Abs}) that we need to
   867   skip until we hit the @{ML Abs} that binds the corresponding variable. Constructing 
   867   skip until we hit the @{ML Abs} that binds the corresponding
   868   a term with dangling de Bruijn indices is possible, but will be flagged as
   868   variable. Constructing a term with dangling de Bruijn indices is possible,
   869   ill-formed when you try to typecheck or certify it (see
   869   but will be flagged as ill-formed when you try to typecheck or certify it
   870   Section~\ref{sec:typechecking}). Note that the names of bound variables are kept at
   870   (see Section~\ref{sec:typechecking}). Note that the names of bound variables
   871   abstractions for printing purposes, and so should be treated only as
   871   are kept at abstractions for printing purposes, and so should be treated
   872   ``comments''.  Application in Isabelle is realised with the term-constructor
   872   only as ``comments''.  Application in Isabelle is realised with the
   873   @{ML $}.
   873   term-constructor @{ML $}.
   874 
       
   875 
   874 
   876   Isabelle makes a distinction between \emph{free} variables (term-constructor
   875   Isabelle makes a distinction between \emph{free} variables (term-constructor
   877   @{ML Free} and written in blue colour) and \emph{schematic} variables
   876   @{ML Free} and written on the user level in blue colour) and
   878   (term-constructor @{ML Var} and written with a leading question mark). The
   877   \emph{schematic} variables (term-constructor @{ML Var} and written with a
   879   latter correspond to the schematic variables that when printed show up with
   878   leading question mark). Consider the following two examples
   880   a question mark in front of them. Consider the following two examples
   879 
   881 
   880 
   882   
   881   
   883   @{ML_response_fake [display, gray]
   882   @{ML_response_fake [display, gray]
   884 "let
   883 "let
   885   val v1 = Var ((\"x\", 3), @{typ bool})
   884   val v1 = Var ((\"x\", 3), @{typ bool})
   889   string_of_terms @{context} [v1, v2, v3]
   888   string_of_terms @{context} [v1, v2, v3]
   890   |> tracing
   889   |> tracing
   891 end"
   890 end"
   892 "?x3, ?x1.3, x"}
   891 "?x3, ?x1.3, x"}
   893 
   892 
   894   When constructing terms, you are usually concerned with free variables (as mentioned earlier,
   893   When constructing terms, you are usually concerned with free variables (as
   895   you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). 
   894   mentioned earlier, you cannot construct schematic variables using the
   896   If you deal with theorems, you have to, however, observe the distinction. A similar
   895   antiquotation @{text "@{term \<dots>}"}). If you deal with theorems, you have to,
   897   distinction holds for types (see below).
   896   however, observe the distinction. The reason is that only schematic
       
   897   varaibles can be instantiated with terms when a theorem is applied. A
       
   898   similar distinction between free and schematic variables holds for types
       
   899   (see below).
   898 
   900 
   899   \begin{readmore}
   901   \begin{readmore}
   900   Terms and types are described in detail in \isccite{sec:terms}. Their
   902   Terms and types are described in detail in \isccite{sec:terms}. Their
   901   definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}.
   903   definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}.
   902   For constructing terms involving HOL constants, many helper functions are defined
   904   For constructing terms involving HOL constants, many helper functions are defined
   942   value:
   944   value:
   943 
   945 
   944   @{ML [display,gray] "print_depth 50"}
   946   @{ML [display,gray] "print_depth 50"}
   945   \end{exercise}
   947   \end{exercise}
   946 
   948 
   947   The antiquotation @{text "@{prop \<dots>}"} constructs terms of propositional type, 
   949   The antiquotation @{text "@{prop \<dots>}"} constructs terms by inserting the 
   948   inserting the invisible @{text "Trueprop"}-coercions whenever necessary. 
   950   usually invisible @{text "Trueprop"}-coercions whenever necessary. 
   949   Consider for example the pairs
   951   Consider for example the pairs
   950 
   952 
   951 @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" 
   953 @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" 
   952 "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   954 "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   953  Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   955  Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   954  
   956  
   955   where a coercion is inserted in the second component and 
   957   where a coercion is inserted in the second component and 
   956 
   958 
   957   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   959   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   958   "(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"}
   960   "(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, 
       
   961  Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"}
   959 
   962 
   960   where it is not (since it is already constructed by a meta-implication). 
   963   where it is not (since it is already constructed by a meta-implication). 
       
   964   The purpose of the @{text "Trueprop"}-coercion is to embed formulae of
       
   965   an object logic, for example HOL, into the meta-logic of Isabelle. It
       
   966   is needed whenever a term is constructed that will be proved as a theorem. 
   961 
   967 
   962   As already seen above, types can be constructed using the antiquotation 
   968   As already seen above, types can be constructed using the antiquotation 
   963   @{text "@{typ \<dots>}"}. For example:
   969   @{text "@{typ \<dots>}"}. For example:
   964 
   970 
   965   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   971   @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
  1089   "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0 x"} the subterm @{term "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0"} by
  1095   "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0 x"} the subterm @{term "(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0"} by
  1090   @{term y}, and @{term x} by @{term True}.
  1096   @{term y}, and @{term x} by @{term True}.
  1091 
  1097 
  1092   @{ML_response_fake [display,gray]
  1098   @{ML_response_fake [display,gray]
  1093 "let
  1099 "let
  1094   val s1 = (@{term \"(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0\"}, @{term \"y::nat \<Rightarrow> nat\"})
  1100   val sub1 = (@{term \"(f::nat \<Rightarrow> nat \<Rightarrow> nat) 0\"}, @{term \"y::nat \<Rightarrow> nat\"})
  1095   val s2 = (@{term \"x::nat\"}, @{term \"True\"})
  1101   val sub2 = (@{term \"x::nat\"}, @{term \"True\"})
  1096   val trm = @{term \"((f::nat \<Rightarrow> nat \<Rightarrow> nat) 0) x\"}
  1102   val trm = @{term \"((f::nat \<Rightarrow> nat \<Rightarrow> nat) 0) x\"}
  1097 in
  1103 in
  1098   subst_free [s1, s2] trm
  1104   subst_free [sub1, sub2] trm
  1099 end"
  1105 end"
  1100   "Free (\"y\", \"nat \<Rightarrow> nat\") $ Const (\"True\", \"bool\")"}
  1106   "Free (\"y\", \"nat \<Rightarrow> nat\") $ Const (\"True\", \"bool\")"}
  1101 
  1107 
  1102   As can be seen, @{ML subst_free} does not take typability into account.
  1108   As can be seen, @{ML subst_free} does not take typability into account.
  1103   However it takes alpha-equivalence into account:
  1109   However it takes alpha-equivalence into account:
  1104 
  1110 
  1105   @{ML_response_fake [display, gray]
  1111   @{ML_response_fake [display, gray]
  1106 "let
  1112 "let
  1107   val s = (@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})
  1113   val sub = (@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})
  1108   val trm = @{term \"(\<lambda>x::nat. x)\"}
  1114   val trm = @{term \"(\<lambda>x::nat. x)\"}
  1109 in
  1115 in
  1110   subst_free [s] trm
  1116   subst_free [sub] trm
  1111 end"
  1117 end"
  1112   "Free (\"x\", \"nat\")"}
  1118   "Free (\"x\", \"nat\")"}
  1113 
  1119 
  1114   Similarly the function @{ML [index] subst_bounds}, replaces lose bound 
  1120   Similarly the function @{ML [index] subst_bounds}, replaces lose bound 
  1115   variables with terms. To see how this function works, let us implement a
  1121   variables with terms. To see how this function works, let us implement a
  1116   function that strips off the outermost quantifiers in a term.
  1122   function that strips off the outermost quantifiers in a term.
  1117 *}
  1123 *}
  1118 
  1124 
  1119 ML{*fun strip_alls (Const ("All", _) $ Abs (n, T, t)) =
  1125 ML{*fun strip_alls (Const ("All", _) $ Abs (n, T, t)) =
  1120      strip_alls t |>> cons (Free (n, T))
  1126          strip_alls t |>> cons (Free (n, T))
  1121   | strip_alls t = ([], t) *}
  1127   | strip_alls t = ([], t) *}
  1122 
  1128 
  1123 text {*
  1129 text {*
  1124   The function returns a pair consisting of the stripped off variables and
  1130   The function returns a pair consisting of the stripped off variables and
  1125   the body of the universal quantifications. For example
  1131   the body of the universal quantifications. For example
  1154 
  1160 
  1155 @{ML_response_fake [gray,display]
  1161 @{ML_response_fake [gray,display]
  1156 "let
  1162 "let
  1157   val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
  1163   val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
  1158 in
  1164 in
  1159   tracing (string_of_term @{context} eq)
  1165   string_of_term @{context} eq
       
  1166   |> tracing
  1160 end"
  1167 end"
  1161   "True = False"}
  1168   "True = False"}
  1162 *}
  1169 *}
  1163 
  1170 
  1164 text {*
  1171 text {*
  1165   \begin{readmore}
  1172   \begin{readmore}
  1166   Most of the HOL-specific operations on terms and types are defined 
  1173   Most of the HOL-specific operations on terms and types are defined 
  1167   in @{ML_file "HOL/Tools/hologic.ML"}.
  1174   in @{ML_file "HOL/Tools/hologic.ML"}.
  1168   \end{readmore}
  1175   \end{readmore}
  1169 
       
  1170   \begin{exercise}\label{ex:debruijn}
       
  1171   Implement the function,\footnote{Personal communication of
       
  1172   de Bruijn to Dyckhoff.} called deBruijn n, that constructs terms of the form:
       
  1173   
       
  1174   \begin{center}
       
  1175   \begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l}
       
  1176   {\it rhs n} & $\dn$ & $\bigwedge${\it i=1\ldots n.  P\,i}\\
       
  1177   {\it lhs n} & $\dn$ & $\bigwedge${\it i=1\ldots n. P\,i = P (i + 1 mod n)}
       
  1178                         $\longrightarrow$ {\it rhs n}\\
       
  1179   {\it deBruijn n} & $\dn$ & {\it lhs n} $\longrightarrow$ {\it rhs n}\\
       
  1180   \end{tabular}
       
  1181   \end{center}
       
  1182 
       
  1183   For n=3 this function returns the term
       
  1184 
       
  1185   \begin{center}
       
  1186   \begin{tabular}{l}
       
  1187   (P 2 = P 3 $\longrightarrow$ P 3 $\wedge$ P 2 $\wedge$ P 1) $\wedge$\\
       
  1188   (P 1 = P 2 $\longrightarrow$ P 3 $\wedge$ P 2 $\wedge$ P 1) $\wedge$\\ 
       
  1189   (P 1 = P 3 $\longrightarrow$ P 3 $\wedge$ P 2 $\wedge$ P 1) $\longrightarrow$ P 3 $\wedge$ P 2 $\wedge$ P 1
       
  1190   \end{tabular}
       
  1191   \end{center}
       
  1192 
       
  1193   \end{exercise}
       
  1194 
  1176 
  1195   When constructing terms manually, there are a few subtle issues with
  1177   When constructing terms manually, there are a few subtle issues with
  1196   constants. They usually crop up when pattern matching terms or types, or
  1178   constants. They usually crop up when pattern matching terms or types, or
  1197   when constructing them. While it is perfectly ok to write the function
  1179   when constructing them. While it is perfectly ok to write the function
  1198   @{text is_true} as follows
  1180   @{text is_true} as follows
  1277 
  1259 
  1278 text {*
  1260 text {*
  1279   \begin{readmore}
  1261   \begin{readmore}
  1280   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file "Pure/logic.ML"} and
  1262   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file "Pure/logic.ML"} and
  1281   @{ML_file "HOL/Tools/hologic.ML"} that make such manual constructions of terms 
  1263   @{ML_file "HOL/Tools/hologic.ML"} that make such manual constructions of terms 
  1282   and types easier.\end{readmore}
  1264   and types easier.
  1283 
  1265   \end{readmore}
  1284   Have a look at these files and try to solve the following two exercises:
  1266 
       
  1267   The antiquotation for properly referencing type constants is @{text "@{type_name \<dots>}"}.
       
  1268   For example
       
  1269 
       
  1270   @{ML_response [display,gray]
       
  1271   "@{type_name \"list\"}" "\"List.list\""}
       
  1272 
       
  1273   (FIXME: Explain the following better.)
       
  1274 
       
  1275   Occasionally you have to calculate what the ``base'' name of a given
       
  1276   constant is. For this you can use the function @{ML [index] "Sign.extern_const"} or
       
  1277   @{ML [index] Long_Name.base_name}. For example:
       
  1278 
       
  1279   @{ML_response [display,gray] "Sign.extern_const @{theory} \"List.list.Nil\"" "\"Nil\""}
       
  1280 
       
  1281   The difference between both functions is that @{ML extern_const in Sign} returns
       
  1282   the smallest name that is still unique, whereas @{ML base_name in Long_Name} always
       
  1283   strips off all qualifiers.
       
  1284 
       
  1285   \begin{readmore}
       
  1286   Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};
       
  1287   functions about signatures in @{ML_file "Pure/sign.ML"}.
       
  1288   \end{readmore}
       
  1289 
       
  1290   Although types of terms can often be inferred, there are many
       
  1291   situations where you need to construct types manually, especially  
       
  1292   when defining constants. For example the function returning a function 
       
  1293   type is as follows:
       
  1294 
       
  1295 *} 
       
  1296 
       
  1297 ML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
       
  1298 
       
  1299 text {* This can be equally written with the combinator @{ML [index] "-->"} as: *}
       
  1300 
       
  1301 ML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
       
  1302 
       
  1303 text {*
       
  1304   If you want to construct a function type with more than one argument
       
  1305   type, then you can use @{ML [index] "--->"}.
       
  1306 *}
       
  1307 
       
  1308 ML{*fun make_fun_types tys ty = tys ---> ty *}
       
  1309 
       
  1310 text {*
       
  1311   A handy function for manipulating terms is @{ML [index] map_types}: it takes a 
       
  1312   function and applies it to every type in a term. You can, for example,
       
  1313   change every @{typ nat} in a term into an @{typ int} using the function:
       
  1314 *}
       
  1315 
       
  1316 ML{*fun nat_to_int ty =
       
  1317   (case ty of
       
  1318      @{typ nat} => @{typ int}
       
  1319    | Type (s, tys) => Type (s, map nat_to_int tys)
       
  1320    | _ => ty)*}
       
  1321 
       
  1322 text {*
       
  1323   Here is an example:
       
  1324 
       
  1325 @{ML_response_fake [display,gray] 
       
  1326 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
       
  1327 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
       
  1328            $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"}
       
  1329 
       
  1330   If you want to obtain the list of free type-variables of a term, you
       
  1331   can use the function @{ML [index] add_tfrees in Term} 
       
  1332   (similarly @{ML [index] add_tvars in Term} for the schematic type-variables). 
       
  1333   One would expect that such functions
       
  1334   take a term as input and return a list of types. But their type is actually 
       
  1335 
       
  1336   @{text[display] "Term.term -> (string * Term.sort) list -> (string * Term.sort) list"}
       
  1337 
       
  1338   that is they take, besides a term, also a list of type-variables as input. 
       
  1339   So in order to obtain the list of type-variables of a term you have to 
       
  1340   call them as follows
       
  1341 
       
  1342   @{ML_response [gray,display]
       
  1343   "Term.add_tfrees @{term \"(a, b)\"} []"
       
  1344   "[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"}
       
  1345 
       
  1346   The reason for this definition is that @{ML add_tfrees in Term} can
       
  1347   be easily folded over a list of terms. Similarly for all functions
       
  1348   named @{text "add_*"} in @{ML_file "Pure/term.ML"}.
  1285 
  1349 
  1286   \begin{exercise}\label{fun:revsum}
  1350   \begin{exercise}\label{fun:revsum}
  1287   Write a function @{text "rev_sum : term -> term"} that takes a
  1351   Write a function @{text "rev_sum : term -> term"} that takes a
  1288   term of the form @{text "t\<^isub>1 + t\<^isub>2 + \<dots> + t\<^isub>n"} (whereby @{text "n"} might be one)
  1352   term of the form @{text "t\<^isub>1 + t\<^isub>2 + \<dots> + t\<^isub>n"} (whereby @{text "n"} might be one)
  1289   and returns the reversed sum @{text "t\<^isub>n + \<dots> + t\<^isub>2 + t\<^isub>1"}. Assume
  1353   and returns the reversed sum @{text "t\<^isub>n + \<dots> + t\<^isub>2 + t\<^isub>1"}. Assume
  1295   Write a function which takes two terms representing natural numbers
  1359   Write a function which takes two terms representing natural numbers
  1296   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
  1360   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
  1297   number representing their sum.
  1361   number representing their sum.
  1298   \end{exercise}
  1362   \end{exercise}
  1299 
  1363 
  1300   The antiquotation for properly referencing type constants is @{text "@{type_name \<dots>}"}.
  1364   \begin{exercise}\footnote{Personal communication of
  1301   For example
  1365   de Bruijn to Dyckhoff.}\label{ex:debruijn}
  1302 
  1366   Implement the function, which we below name deBruijn, that depends on a natural
  1303   @{ML_response [display,gray]
  1367   number n$>$0 and constructs terms of the form:
  1304   "@{type_name \"list\"}" "\"List.list\""}
  1368   
  1305 
  1369   \begin{center}
  1306   (FIXME: Explain the following better.)
  1370   \begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l}
  1307 
  1371   {\it rhs n} & $\dn$ & {\large$\bigwedge$}{\it i=1\ldots n.  P\,i}\\
  1308   Occasionally you have to calculate what the ``base'' name of a given
  1372   {\it lhs n} & $\dn$ & {\large$\bigwedge$}{\it i=1\ldots n. P\,i = P (i + 1 mod n)}
  1309   constant is. For this you can use the function @{ML [index] "Sign.extern_const"} or
  1373                         $\longrightarrow$ {\it rhs n}\\
  1310   @{ML [index] Long_Name.base_name}. For example:
  1374   {\it deBruijn n} & $\dn$ & {\it lhs n} $\longrightarrow$ {\it rhs n}\\
  1311 
  1375   \end{tabular}
  1312   @{ML_response [display,gray] "Sign.extern_const @{theory} \"List.list.Nil\"" "\"Nil\""}
  1376   \end{center}
  1313 
  1377 
  1314   The difference between both functions is that @{ML extern_const in Sign} returns
  1378   For n=3 this function returns the term
  1315   the smallest name that is still unique, whereas @{ML base_name in Long_Name} always
  1379 
  1316   strips off all qualifiers.
  1380   \begin{center}
  1317 
  1381   \begin{tabular}{l}
  1318   \begin{readmore}
  1382   (P 1 = P 2 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\
  1319   Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};
  1383   (P 2 = P 3 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\ 
  1320   functions about signatures in @{ML_file "Pure/sign.ML"}.
  1384   (P 3 = P 1 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3
  1321   \end{readmore}
  1385   \end{tabular}
  1322 
  1386   \end{center}
  1323   Although types of terms can often be inferred, there are many
  1387 
  1324   situations where you need to construct types manually, especially  
  1388   Make sure you use the functions defined in @{ML_file "HOL/Tools/hologic.ML"}
  1325   when defining constants. For example the function returning a function 
  1389   for constructing the terms for the logical connectives. 
  1326   type is as follows:
  1390   \end{exercise}
  1327 
       
  1328 *} 
       
  1329 
       
  1330 ML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
       
  1331 
       
  1332 text {* This can be equally written with the combinator @{ML [index] "-->"} as: *}
       
  1333 
       
  1334 ML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
       
  1335 
       
  1336 text {*
       
  1337   If you want to construct a function type with more than one argument
       
  1338   type, then you can use @{ML [index] "--->"}.
       
  1339 *}
       
  1340 
       
  1341 ML{*fun make_fun_types tys ty = tys ---> ty *}
       
  1342 
       
  1343 text {*
       
  1344   A handy function for manipulating terms is @{ML [index] map_types}: it takes a 
       
  1345   function and applies it to every type in a term. You can, for example,
       
  1346   change every @{typ nat} in a term into an @{typ int} using the function:
       
  1347 *}
       
  1348 
       
  1349 ML{*fun nat_to_int ty =
       
  1350   (case ty of
       
  1351      @{typ nat} => @{typ int}
       
  1352    | Type (s, tys) => Type (s, map nat_to_int tys)
       
  1353    | _ => ty)*}
       
  1354 
       
  1355 text {*
       
  1356   Here is an example:
       
  1357 
       
  1358 @{ML_response_fake [display,gray] 
       
  1359 "map_types nat_to_int @{term \"a = (1::nat)\"}" 
       
  1360 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\")
       
  1361            $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"}
       
  1362 
       
  1363   If you want to obtain the list of free type-variables of a term, you
       
  1364   can use the function @{ML [index] add_tfrees in Term} 
       
  1365   (similarly @{ML [index] add_tvars in Term} for the schematic type-variables). 
       
  1366   One would expect that such functions
       
  1367   take a term as input and return a list of types. But their type is actually 
       
  1368 
       
  1369   @{text[display] "Term.term -> (string * Term.sort) list -> (string * Term.sort) list"}
       
  1370 
       
  1371   that is they take, besides a term, also a list of type-variables as input. 
       
  1372   So in order to obtain the list of type-variables of a term you have to 
       
  1373   call them as follows
       
  1374 
       
  1375   @{ML_response [gray,display]
       
  1376   "Term.add_tfrees @{term \"(a, b)\"} []"
       
  1377   "[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"}
       
  1378 
       
  1379   The reason for this definition is that @{ML add_tfrees in Term} can
       
  1380   be easily folded over a list of terms. Similarly for all functions
       
  1381   named @{text "add_*"} in @{ML_file "Pure/term.ML"}.
       
  1382 
       
  1383 *}
  1391 *}
  1384 
  1392 
  1385 
  1393 
  1386 section {* Type-Checking\label{sec:typechecking} *}
  1394 section {* Type-Checking\label{sec:typechecking} *}
  1387 
  1395