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 |