772 fold (Sign.typ_unify @{theory}) [tys1, tys2] (Vartab.empty, 0) |
772 fold (Sign.typ_unify @{theory}) [tys1, tys2] (Vartab.empty, 0) |
773 end*} |
773 end*} |
774 |
774 |
775 text {* |
775 text {* |
776 The index @{text 0} in Line 5 is the maximal index of the schematic type |
776 The index @{text 0} in Line 5 is the maximal index of the schematic type |
777 variables occurring in @{text ty1} and @{text ty2}. This index will be |
777 variables occurring in @{text tys1} and @{text tys2}. This index will be |
778 increased whenever a new schematic type variable is introduced during |
778 increased whenever a new schematic type variable is introduced during |
779 unification. This is for example the case when two schematic type variables |
779 unification. This is for example the case when two schematic type variables |
780 have different, incomparable sorts. Then a new schematic type variable is |
780 have different, incomparable sorts. Then a new schematic type variable is |
781 introduced with the combined sorts. To show this let us assume two sorts, |
781 introduced with the combined sorts. To show this let us assume two sorts, |
782 say @{text "s1"} and @{text "s2"}, which we attach to the schematic type |
782 say @{text "s1"} and @{text "s2"}, which we attach to the schematic type |
796 of sort information by setting @{ML_ind show_sorts in Syntax} to |
796 of sort information by setting @{ML_ind show_sorts in Syntax} to |
797 true. This allows us to inspect the typing environment. |
797 true. This allows us to inspect the typing environment. |
798 |
798 |
799 @{ML_response_fake [display,gray] |
799 @{ML_response_fake [display,gray] |
800 "pretty_tyenv @{context} tyenv" |
800 "pretty_tyenv @{context} tyenv" |
801 "[?'a::s1 := ?'a1::{s1,s2}, ?'b::s2 := ?'a1::{s1,s2}]"} |
801 "[?'a::s1 := ?'a1::{s1, s2}, ?'b::s2 := ?'a1::{s1, s2}]"} |
802 |
802 |
803 As can be seen, the type variables @{text "?'a"} and @{text "?'b"} are instantiated |
803 As can be seen, the type variables @{text "?'a"} and @{text "?'b"} are instantiated |
804 with a new type variable @{text "?'a1"} with sort @{text "{s1,s2}"}. Since a new |
804 with a new type variable @{text "?'a1"} with sort @{text "{s1, s2}"}. Since a new |
805 type variable has been introduced the @{ML index}, originally being @{text 0}, |
805 type variable has been introduced the @{ML index}, originally being @{text 0}, |
806 has been increased by @{text 1}. |
806 has been increased to @{text 1}. |
807 |
807 |
808 @{ML_response [display,gray] |
808 @{ML_response [display,gray] |
809 "index" |
809 "index" |
810 "1"} |
810 "1"} |
811 |
811 |
924 @{text "?X ?Y"}. |
924 @{text "?X ?Y"}. |
925 *} |
925 *} |
926 |
926 |
927 ML{*val (_, fo_env) = let |
927 ML{*val (_, fo_env) = let |
928 val fo_pat = @{term_pat "(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y"} |
928 val fo_pat = @{term_pat "(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y"} |
929 val trm = @{term "P::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool"} |
929 val trm_a = @{term "P::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool"} |
930 $ @{term "\<lambda>a b. (Q::nat\<Rightarrow>nat\<Rightarrow>nat) b a"} |
930 val trm_b = @{term "\<lambda>a b. (Q::nat\<Rightarrow>nat\<Rightarrow>nat) b a"} |
931 val init = (Vartab.empty, Vartab.empty) |
931 val init = (Vartab.empty, Vartab.empty) |
932 in |
932 in |
933 Pattern.first_order_match @{theory} (fo_pat, trm) init |
933 Pattern.first_order_match @{theory} (fo_pat, trm_a $ trm_b) init |
934 end *} |
934 end *} |
935 |
935 |
936 text {* |
936 text {* |
937 In this example we annotated explicitly types because then |
937 In this example we annotated explicitly types because then |
938 the type environment is empty and can be ignored. The |
938 the type environment is empty and can be ignored. The |
961 First-order matching is useful for matching against applications and |
961 First-order matching is useful for matching against applications and |
962 variables. It can deal also with abstractions and a limited form of |
962 variables. It can deal also with abstractions and a limited form of |
963 alpha-equivalence, but this kind of matching should be used with care, since |
963 alpha-equivalence, but this kind of matching should be used with care, since |
964 it is not clear whether the result is meaningful. A meaningful example is |
964 it is not clear whether the result is meaningful. A meaningful example is |
965 matching @{text "\<lambda>x. P x"} against the pattern @{text "\<lambda>y. ?X y"}. In this |
965 matching @{text "\<lambda>x. P x"} against the pattern @{text "\<lambda>y. ?X y"}. In this |
966 case first-order matching produces @{text "[?X := P]"}. |
966 case, first-order matching produces @{text "[?X := P]"}. |
967 |
967 |
968 @{ML_response_fake [display, gray] |
968 @{ML_response_fake [display, gray] |
969 "let |
969 "let |
970 val fo_pat = @{term_pat \"\<lambda>y. (?X::nat\<Rightarrow>bool) y\"} |
970 val fo_pat = @{term_pat \"\<lambda>y. (?X::nat\<Rightarrow>bool) y\"} |
971 val trm = @{term \"\<lambda>x. (P::nat\<Rightarrow>bool) x\"} |
971 val trm = @{term \"\<lambda>x. (P::nat\<Rightarrow>bool) x\"} |
979 *} |
979 *} |
980 |
980 |
981 text {* |
981 text {* |
982 Unification of abstractions is more thoroughly studied in the context |
982 Unification of abstractions is more thoroughly studied in the context |
983 of higher-order pattern unification and higher-order pattern matching. A |
983 of higher-order pattern unification and higher-order pattern matching. A |
984 \emph{\index*{pattern}} is a lambda term whose ``head symbol'' (that is the |
984 \emph{\index*{pattern}} is an abstraction term whose ``head symbol'' (that is the |
985 first symbol under an abstraction) is either a constant, a schematic or a free |
985 first symbol under an abstraction) is either a constant, a schematic or a free |
986 variable. If it is a schematic variable then it can be only applied with |
986 variable. If it is a schematic variable then it can be only applied with |
987 distinct bound variables. This excludes that a schematic variable is an |
987 distinct bound variables. This excludes terms where a schematic variable is an |
988 argument of another one and that a schematic variable is applied |
988 argument of another one and where a schematic variable is applied |
989 twice with the same bound variable. The function @{ML_ind pattern in Pattern} |
989 twice with the same bound variable. The function @{ML_ind pattern in Pattern} |
990 in the structure @{ML_struct Pattern} tests whether a term satisfies these |
990 in the structure @{ML_struct Pattern} tests whether a term satisfies these |
991 restrictions. |
991 restrictions. |
992 |
992 |
993 @{ML_response [display, gray] |
993 @{ML_response [display, gray] |
1020 in |
1020 in |
1021 pretty_env @{context} (Envir.term_env env) |
1021 pretty_env @{context} (Envir.term_env env) |
1022 end" |
1022 end" |
1023 "[?X := \<lambda>y x. x, ?Y := \<lambda>x. x]"} |
1023 "[?X := \<lambda>y x. x, ?Y := \<lambda>x. x]"} |
1024 |
1024 |
1025 |
1025 The function @{ML_ind "Envir.empty"} generates a record with a specified |
1026 An assumption of this function is that the terms to be unified have |
1026 max-index for the schematic variables (in the example the index is @{text |
1027 already the same type. In case of failure, the exceptions that are raised |
1027 0}) and empty type and term environments. The function @{ML_ind |
1028 are either @{text Pattern}, @{text MATCH} or @{text Unif}. |
1028 "Envir.term_env"} pulls out the term environment from the result record. The |
1029 |
1029 function for type environment is @{ML_ind "Envir.type_env"}. An assumption of |
1030 As mentioned before, ``full'' higher-order unification, respectively |
1030 this function is that the terms to be unified have already the same type. In |
1031 higher-order matching problems, are in general undecidable and might also not posses a |
1031 case of failure, the exceptions that are raised are either @{text Pattern}, |
|
1032 @{text MATCH} or @{text Unif}. |
|
1033 |
|
1034 As mentioned before, unrestricted higher-order unification, respectively |
|
1035 higher-order matching, is in general undecidable and might also not posses a |
1032 single most general solution. Therefore Isabelle implements the unification |
1036 single most general solution. Therefore Isabelle implements the unification |
1033 function @{ML_ind unifiers in Unify} so that it returns a lazy list of |
1037 function @{ML_ind unifiers in Unify} so that it returns a lazy list of |
1034 potentially infinite unifiers. An example is as follows |
1038 potentially infinite unifiers. An example is as follows |
1035 |
1039 *} |
1036 \ldots |
1040 |
1037 |
1041 ML{*val uni_seq = |
1038 In case of failure this function does not raise an exception, rather returns |
1042 let |
1039 the empty sequence. In order to find a reasonable solution for a unification |
1043 val trm1 = @{term_pat "?X ?Y"} |
1040 problem, Isabelle also tries first to solve the problem by higher-order |
1044 val trm2 = @{term "f a"} |
1041 pattern unification. For higher-order matching the function is called |
1045 val init = Envir.empty 0 |
1042 @{ML_ind matchers in Unify}. Also this function might potentially return |
1046 in |
1043 sequences with more than one matcher. |
1047 Unify.unifiers (@{theory}, init, [(trm1, trm2)]) |
1044 |
1048 end *} |
1045 \ldots |
1049 |
1046 |
1050 text {* |
|
1051 The unifiers can be extracted from the lazy sequence using the |
|
1052 function @{ML_ind "Seq.pull"}. In the example we obtain three |
|
1053 unifiers @{text "un1\<dots>un3"}. |
|
1054 *} |
|
1055 |
|
1056 ML{*val SOME ((un1, _), next1) = Seq.pull uni_seq; |
|
1057 val SOME ((un2, _), next2) = Seq.pull next1; |
|
1058 val SOME ((un3, _), next3) = Seq.pull next2; |
|
1059 val NONE = Seq.pull next3 *} |
|
1060 |
|
1061 text {* |
|
1062 \footnote{\bf FIXME: what is the list of term pairs in the unifier: flex-flex pairs?} |
|
1063 |
|
1064 We can print them out as follows. |
|
1065 |
|
1066 @{ML_response_fake [display, gray] |
|
1067 "pretty_env @{context} (Envir.term_env un1); |
|
1068 pretty_env @{context} (Envir.term_env un2); |
|
1069 pretty_env @{context} (Envir.term_env un3)" |
|
1070 "[?X := \<lambda>a. a, ?Y := f a] |
|
1071 [?X := f, ?Y := a] |
|
1072 [?X := \<lambda>b. f a]"} |
|
1073 |
|
1074 |
|
1075 In case of failure the function @{ML_ind unifiers in Unify} does not raise |
|
1076 an exception, rather returns the empty sequence. For example |
|
1077 |
|
1078 @{ML_response [display, gray] |
|
1079 "let |
|
1080 val trm1 = @{term \"a\"} |
|
1081 val trm2 = @{term \"b\"} |
|
1082 val init = Envir.empty 0 |
|
1083 in |
|
1084 Unify.unifiers (@{theory}, init, [(trm1, trm2)]) |
|
1085 |> Seq.pull |
|
1086 end" |
|
1087 "NONE"} |
|
1088 |
|
1089 In order to find a |
|
1090 reasonable solution for a unification problem, Isabelle also tries first to |
|
1091 solve the problem by higher-order pattern unification. |
|
1092 |
|
1093 For higher-order |
|
1094 matching the function is called @{ML_ind matchers in Unify} implemented |
|
1095 in the structure @{ML_struct Unify}. Also this |
|
1096 function returns sequences with possibly more than one matcher. |
1047 Like @{ML unifiers in Unify}, this function does not raise an exception |
1097 Like @{ML unifiers in Unify}, this function does not raise an exception |
1048 in case of failure. It also first tries out whether the matching problem |
1098 in case of failure, but returns an empty sequence. It also first tries |
1049 can be solved by first-order matching. |
1099 out whether the matching problem can be solved by first-order matching. |
1050 |
1100 |
1051 \begin{readmore} |
1101 \begin{readmore} |
1052 Unification and matching of higher-order patterns is implemented in |
1102 Unification and matching of higher-order patterns is implemented in |
1053 @{ML_file "Pure/pattern.ML"}. This file also contains a first-order matcher |
1103 @{ML_file "Pure/pattern.ML"}. This file also contains a first-order matcher |
1054 for terms. Full higher-order unification is implemented |
1104 for terms. Full higher-order unification is implemented |