20 24~Nov.~2009 |
20 24~Nov.~2009 |
21 \end{flushright} |
21 \end{flushright} |
22 |
22 |
23 \medskip |
23 \medskip |
24 Isabelle is build around a few central ideas. One central idea is the |
24 Isabelle is build around a few central ideas. One central idea is the |
25 LCF-approach to theorem proving where there is a small trusted core and |
25 LCF-approach to theorem proving \cite{GordonMilnerWadsworth79} where there |
26 everything else is built on top of this trusted core |
26 is a small trusted core and everything else is built on top of this trusted |
27 \cite{GordonMilnerWadsworth79}. The fundamental data |
27 core. The fundamental data structures involved in this core are certified |
28 structures involved in this core are certified terms and certified types, |
28 terms and certified types, as well as theorems. |
29 as well as theorems. |
|
30 *} |
29 *} |
31 |
30 |
32 |
31 |
33 section {* Terms and Types *} |
32 section {* Terms and Types *} |
34 |
33 |
111 @{ML_response_fake_both [display,gray] |
110 @{ML_response_fake_both [display,gray] |
112 "@{term \"x x\"}" |
111 "@{term \"x x\"}" |
113 "Type unification failed: Occurs check!"} |
112 "Type unification failed: Occurs check!"} |
114 |
113 |
115 raises a typing error, while it perfectly ok to construct the term |
114 raises a typing error, while it perfectly ok to construct the term |
|
115 with the raw ML-constructors: |
116 |
116 |
117 @{ML_response_fake [display,gray] |
117 @{ML_response_fake [display,gray] |
118 "let |
118 "let |
119 val omega = Free (\"x\", @{typ \"nat \<Rightarrow> nat\"}) $ Free (\"x\", @{typ nat}) |
119 val omega = Free (\"x\", @{typ \"nat \<Rightarrow> nat\"}) $ Free (\"x\", @{typ nat}) |
120 in |
120 in |
121 tracing (string_of_term @{context} omega) |
121 tracing (string_of_term @{context} omega) |
122 end" |
122 end" |
123 "x x"} |
123 "x x"} |
124 |
|
125 with the raw ML-constructors. |
|
126 |
124 |
127 Sometimes the internal representation of terms can be surprisingly different |
125 Sometimes the internal representation of terms can be surprisingly different |
128 from what you see at the user-level, because the layers of |
126 from what you see at the user-level, because the layers of |
129 parsing/type-checking/pretty printing can be quite elaborate. |
127 parsing/type-checking/pretty printing can be quite elaborate. |
130 |
128 |
190 |
188 |
191 @{ML_response [display, gray] |
189 @{ML_response [display, gray] |
192 "@{typ \"bool\"}" |
190 "@{typ \"bool\"}" |
193 "bool"} |
191 "bool"} |
194 |
192 |
195 that is the pretty printed version of @{text "bool"}. However, in PolyML |
193 which is the pretty printed version of @{text "bool"}. However, in PolyML |
196 (version 5.3) it is easy to install your own pretty printer. With the |
194 (version @{text "\<ge>"}5.3) it is easy to install your own pretty printer. With the |
197 function below we mimic the behaviour of the usual pretty printer for |
195 function below we mimic the behaviour of the usual pretty printer for |
198 datatypes (it uses pretty-printing functions which will be explained in more |
196 datatypes (it uses pretty-printing functions which will be explained in more |
199 detail in Section~\ref{sec:pretty}). |
197 detail in Section~\ref{sec:pretty}). |
200 *} |
198 *} |
201 |
199 |
323 term list applied to the term. For example |
321 term list applied to the term. For example |
324 |
322 |
325 |
323 |
326 @{ML_response_fake [display,gray] |
324 @{ML_response_fake [display,gray] |
327 "let |
325 "let |
328 val trm = @{term \"P::nat\"} |
326 val trm = @{term \"P::bool \<Rightarrow> bool \<Rightarrow> bool\"} |
329 val args = [@{term \"True\"}, @{term \"False\"}] |
327 val args = [@{term \"True\"}, @{term \"False\"}] |
330 in |
328 in |
331 list_comb (trm, args) |
329 list_comb (trm, args) |
332 end" |
330 end" |
333 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"} |
331 "Free (\"P\", \"bool \<Rightarrow> bool \<Rightarrow> bool\") |
|
332 $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"} |
334 |
333 |
335 Another handy function is @{ML_ind lambda in Term}, which abstracts a variable |
334 Another handy function is @{ML_ind lambda in Term}, which abstracts a variable |
336 in a term. For example |
335 in a term. For example |
337 |
336 |
338 @{ML_response_fake [display,gray] |
337 @{ML_response_fake [display,gray] |
448 Term.dest_abs (\"x\", @{typ \"nat \<Rightarrow> bool\"}, body) |
447 Term.dest_abs (\"x\", @{typ \"nat \<Rightarrow> bool\"}, body) |
449 end" |
448 end" |
450 "(\"xa\", Free (\"xa\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"} |
449 "(\"xa\", Free (\"xa\", \"nat \<Rightarrow> bool\") $ Free (\"x\", \"nat\"))"} |
451 |
450 |
452 There are also many convenient functions that construct specific HOL-terms |
451 There are also many convenient functions that construct specific HOL-terms |
453 in the structure @{ML_struct HOLogic}. For |
452 in the structure @{ML_struct HOLogic}. For example @{ML_ind mk_eq in |
454 example @{ML_ind mk_eq in HOLogic} constructs an equality out of two terms. |
453 HOLogic} constructs an equality out of two terms. The types needed in this |
455 The types needed in this equality are calculated from the type of the |
454 equality are calculated from the type of the arguments. For example |
456 arguments. For example |
|
457 |
455 |
458 @{ML_response_fake [gray,display] |
456 @{ML_response_fake [gray,display] |
459 "let |
457 "let |
460 val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"}) |
458 val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"}) |
461 in |
459 in |
462 string_of_term @{context} eq |
460 string_of_term @{context} eq |
463 |> tracing |
461 |> tracing |
464 end" |
462 end" |
465 "True = False"} |
463 "True = False"} |
466 *} |
464 |
467 |
|
468 text {* |
|
469 \begin{readmore} |
465 \begin{readmore} |
470 There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file |
466 There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file |
471 "Pure/logic.ML"} and @{ML_file "HOL/Tools/hologic.ML"} that make manual |
467 "Pure/logic.ML"} and @{ML_file "HOL/Tools/hologic.ML"} that make manual |
472 constructions of terms and types easier. |
468 constructions of terms and types easier. |
473 \end{readmore} |
469 \end{readmore} |
559 The antiquotation for properly referencing type constants is @{text "@{type_name \<dots>}"}. |
555 The antiquotation for properly referencing type constants is @{text "@{type_name \<dots>}"}. |
560 For example |
556 For example |
561 |
557 |
562 @{ML_response [display,gray] |
558 @{ML_response [display,gray] |
563 "@{type_name \"list\"}" "\"List.list\""} |
559 "@{type_name \"list\"}" "\"List.list\""} |
564 |
|
565 \footnote{\bf FIXME: Explain the following better; maybe put in a separate |
|
566 section and link with the comment in the antiquotation section.} |
|
567 |
|
568 Occasionally you have to calculate what the ``base'' name of a given |
|
569 constant is. For this you can use the function @{ML_ind "Sign.extern_const"} or |
|
570 @{ML_ind Long_Name.base_name}. For example: |
|
571 |
|
572 @{ML_response [display,gray] "Sign.extern_const @{theory} \"List.list.Nil\"" "\"Nil\""} |
|
573 |
|
574 The difference between both functions is that @{ML extern_const in Sign} returns |
|
575 the smallest name that is still unique, whereas @{ML base_name in Long_Name} always |
|
576 strips off all qualifiers. |
|
577 |
|
578 \begin{readmore} |
|
579 Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"}; |
|
580 functions about signatures in @{ML_file "Pure/sign.ML"}. |
|
581 \end{readmore} |
|
582 |
560 |
583 Although types of terms can often be inferred, there are many |
561 Although types of terms can often be inferred, there are many |
584 situations where you need to construct types manually, especially |
562 situations where you need to construct types manually, especially |
585 when defining constants. For example the function returning a function |
563 when defining constants. For example the function returning a function |
586 type is as follows: |
564 type is as follows: |
716 |
694 |
717 text {* |
695 text {* |
718 The environment @{ML_ind "Vartab.empty"} in line 5 stands for the empty type |
696 The environment @{ML_ind "Vartab.empty"} in line 5 stands for the empty type |
719 environment, which is needed for starting the unification without any |
697 environment, which is needed for starting the unification without any |
720 (pre)instantiations. The @{text 0} is an integer index that will be explained |
698 (pre)instantiations. The @{text 0} is an integer index that will be explained |
721 below. In case of failure @{ML typ_unify in Sign} will throw the exception |
699 below. In case of failure, @{ML typ_unify in Sign} will throw the exception |
722 @{text TUNIFY}. We can print out the resulting type environment bound to |
700 @{text TUNIFY}. We can print out the resulting type environment bound to |
723 @{ML tyenv_unif} with the built-in function @{ML_ind dest in Vartab} from the |
701 @{ML tyenv_unif} with the built-in function @{ML_ind dest in Vartab} from the |
724 structure @{ML_struct Vartab}. |
702 structure @{ML_struct Vartab}. |
725 |
703 |
726 @{ML_response_fake [display,gray] |
704 @{ML_response_fake [display,gray] |
985 end" |
963 end" |
986 "[?X := P]"} |
964 "[?X := P]"} |
987 *} |
965 *} |
988 |
966 |
989 text {* |
967 text {* |
990 Unification of abstractions is more thoroughly studied in the context |
968 Unification of abstractions is more thoroughly studied in the context of |
991 of higher-order pattern unification and higher-order pattern matching. A |
969 higher-order pattern unification and higher-order pattern matching. A |
992 \emph{\index*{pattern}} is an abstraction term whose ``head symbol'' (that is the |
970 \emph{\index*{pattern}} is an abstraction term whose ``head symbol'' (that |
993 first symbol under an abstraction) is either a constant, a schematic or a free |
971 is the first symbol under an abstraction) is either a constant, a schematic |
994 variable. If it is a schematic variable then it can only have distinct bound |
972 variable or a free variable. If it is a schematic variable then it can only |
995 variables as arguments. This excludes terms where a schematic variable is an |
973 have distinct bound variables as arguments. This excludes terms where a |
996 argument of another one and where a schematic variable is applied |
974 schematic variable is an argument of another one and where a schematic |
997 twice with the same bound variable. The function @{ML_ind pattern in Pattern} |
975 variable is applied twice with the same bound variable. The function |
998 in the structure @{ML_struct Pattern} tests whether a term satisfies these |
976 @{ML_ind pattern in Pattern} in the structure @{ML_struct Pattern} tests |
999 restrictions. |
977 whether a term satisfies these restrictions. |
1000 |
978 |
1001 @{ML_response [display, gray] |
979 @{ML_response [display, gray] |
1002 "let |
980 "let |
1003 val trm_list = |
981 val trm_list = |
1004 [@{term_pat \"?X\"}, @{term_pat \"a\"}, |
982 [@{term_pat \"?X\"}, @{term_pat \"a\"}, |
1012 |
990 |
1013 The point of the restriction to patterns is that unification and matching |
991 The point of the restriction to patterns is that unification and matching |
1014 are decidable and produce most general unifiers, respectively matchers. |
992 are decidable and produce most general unifiers, respectively matchers. |
1015 In this way, matching and unification can be implemented as functions that |
993 In this way, matching and unification can be implemented as functions that |
1016 produce a type and term environment (unification actually returns a |
994 produce a type and term environment (unification actually returns a |
1017 record of type @{ML_type Envir.env} containing a maxind, a type environment |
995 record of type @{ML_type Envir.env} containing a max-index, a type environment |
1018 and a term environment). The corresponding functions are @{ML_ind match in Pattern}, |
996 and a term environment). The corresponding functions are @{ML_ind match in Pattern} |
1019 and @{ML_ind unify in Pattern} both implemented in the structure |
997 and @{ML_ind unify in Pattern}, both implemented in the structure |
1020 @{ML_struct Pattern}. An example for higher-order pattern unification is |
998 @{ML_struct Pattern}. An example for higher-order pattern unification is |
1021 |
999 |
1022 @{ML_response_fake [display, gray] |
1000 @{ML_response_fake [display, gray] |
1023 "let |
1001 "let |
1024 val trm1 = @{term_pat \"\<lambda>x y. g (?X y x) (f (?Y x))\"} |
1002 val trm1 = @{term_pat \"\<lambda>x y. g (?X y x) (f (?Y x))\"} |
1032 |
1010 |
1033 The function @{ML_ind "Envir.empty"} generates a record with a specified |
1011 The function @{ML_ind "Envir.empty"} generates a record with a specified |
1034 max-index for the schematic variables (in the example the index is @{text |
1012 max-index for the schematic variables (in the example the index is @{text |
1035 0}) and empty type and term environments. The function @{ML_ind |
1013 0}) and empty type and term environments. The function @{ML_ind |
1036 "Envir.term_env"} pulls out the term environment from the result record. The |
1014 "Envir.term_env"} pulls out the term environment from the result record. The |
1037 function for type environment is @{ML_ind "Envir.type_env"}. An assumption of |
1015 corresponding function for type environment is @{ML_ind |
1038 this function is that the terms to be unified have already the same type. In |
1016 "Envir.type_env"}. An assumption of this function is that the terms to be |
1039 case of failure, the exceptions that are raised are either @{text Pattern}, |
1017 unified have already the same type. In case of failure, the exceptions that |
1040 @{text MATCH} or @{text Unif}. |
1018 are raised are either @{text Pattern}, @{text MATCH} or @{text Unif}. |
1041 |
1019 |
1042 As mentioned before, unrestricted higher-order unification, respectively |
1020 As mentioned before, unrestricted higher-order unification, respectively |
1043 higher-order matching, is in general undecidable and might also not posses a |
1021 unrestricted higher-order matching, is in general undecidable and might also |
1044 single most general solution. Therefore Isabelle implements the unification |
1022 not posses a single most general solution. Therefore Isabelle implements the |
1045 function @{ML_ind unifiers in Unify} so that it returns a lazy list of |
1023 unification function @{ML_ind unifiers in Unify} so that it returns a lazy |
1046 potentially infinite unifiers. An example is as follows |
1024 list of potentially infinite unifiers. An example is as follows |
1047 *} |
1025 *} |
1048 |
1026 |
1049 ML{*val uni_seq = |
1027 ML{*val uni_seq = |
1050 let |
1028 let |
1051 val trm1 = @{term_pat "?X ?Y"} |
1029 val trm1 = @{term_pat "?X ?Y"} |
1116 Unify}, this function does not raise an exception in case of failure, but |
1094 Unify}, this function does not raise an exception in case of failure, but |
1117 returns an empty sequence. It also first tries out whether the matching |
1095 returns an empty sequence. It also first tries out whether the matching |
1118 problem can be solved by first-order matching. |
1096 problem can be solved by first-order matching. |
1119 |
1097 |
1120 Higher-order matching might be necessary for instantiating a theorem |
1098 Higher-order matching might be necessary for instantiating a theorem |
1121 appropriately (theorems and their instantiation will be described in more |
1099 appropriately. More on this will be given in Sections~\ref{sec:theorems}. |
1122 detail in Sections~\ref{sec:theorems}). This is for example the |
1100 Here we only have a look at a simple case, namely the theorem |
1123 case when applying the rule @{thm [source] spec}: |
1101 @{thm [source] spec}: |
1124 |
1102 |
1125 \begin{isabelle} |
1103 \begin{isabelle} |
1126 \isacommand{thm}~@{thm [source] spec}\\ |
1104 \isacommand{thm}~@{thm [source] spec}\\ |
1127 @{text "> "}~@{thm spec} |
1105 @{text "> "}~@{thm spec} |
1128 \end{isabelle} |
1106 \end{isabelle} |
1129 |
1107 |
1130 as an introduction rule. One way is to instantiate this rule. The |
1108 as an introduction rule. Applying it directly can lead to unexpected |
1131 instantiation function for theorems is @{ML_ind instantiate in Drule} from |
1109 behaviour since the unification has more than one solution. One way round |
1132 the structure @{ML_struct Drule}. One problem, however, is that this |
1110 this problem is to instantiate the schematic variables @{text "?P"} and |
1133 function expects the instantiations as lists of @{ML_type ctyp} and |
1111 @{text "?x"}. instantiation function for theorems is @{ML_ind instantiate |
1134 @{ML_type cterm} pairs: |
1112 in Drule} from the structure @{ML_struct Drule}. One problem, however, is |
|
1113 that this function expects the instantiations as lists of @{ML_type ctyp} |
|
1114 and @{ML_type cterm} pairs: |
1135 |
1115 |
1136 \begin{isabelle} |
1116 \begin{isabelle} |
1137 @{ML instantiate in Drule}@{text ":"} |
1117 @{ML instantiate in Drule}@{text ":"} |
1138 @{ML_type "(ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm"} |
1118 @{ML_type "(ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm"} |
1139 \end{isabelle} |
1119 \end{isabelle} |