404 The function @{ML rep_ss in MetaSimplifier} returns a record containing all |
404 The function @{ML rep_ss in MetaSimplifier} returns a record containing all |
405 information about the simpset. The rules of a simpset are stored in a |
405 information about the simpset. The rules of a simpset are stored in a |
406 \emph{discrimination net} (a data structure for fast indexing). From this |
406 \emph{discrimination net} (a data structure for fast indexing). From this |
407 net you can extract the entries using the function @{ML Net.entries}. |
407 net you can extract the entries using the function @{ML Net.entries}. |
408 You can now use @{ML get_thm_names_from_ss} to obtain all names of theorems stored |
408 You can now use @{ML get_thm_names_from_ss} to obtain all names of theorems stored |
409 in the current simpset---this simpset can be referred to using the antiquotation |
409 in the current simpset. This simpset can be referred to using the antiquotation |
410 @{text "@{simpset}"}. |
410 @{text "@{simpset}"}. |
411 |
411 |
412 @{ML_response_fake [display,gray] |
412 @{ML_response_fake [display,gray] |
413 "get_thm_names_from_ss @{simpset}" |
413 "get_thm_names_from_ss @{simpset}" |
414 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
414 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
|
415 |
|
416 Again, this way or referencing simpsets makes you independent from additions |
|
417 of lemmas to the simpset by the user that potentially cause loops. |
415 |
418 |
416 \begin{readmore} |
419 \begin{readmore} |
417 The infrastructure for simpsets is implemented in @{ML_file "Pure/meta_simplifier.ML"} |
420 The infrastructure for simpsets is implemented in @{ML_file "Pure/meta_simplifier.ML"} |
418 and @{ML_file "Pure/simplifier.ML"}. Discrimination nets are implemented |
421 and @{ML_file "Pure/simplifier.ML"}. Discrimination nets are implemented |
419 in @{ML_file "Pure/net.ML"}. |
422 in @{ML_file "Pure/net.ML"}. |
425 |
428 |
426 ML{*val allI = thm "allI" *} |
429 ML{*val allI = thm "allI" *} |
427 |
430 |
428 text {* |
431 text {* |
429 These bindings are difficult to maintain and also can be accidentally |
432 These bindings are difficult to maintain and also can be accidentally |
430 overwritten by the user. This often breakes Isabelle |
433 overwritten by the user. This often broke Isabelle |
431 packages. Antiquotations solve this problem, since they are ``linked'' |
434 packages. Antiquotations solve this problem, since they are ``linked'' |
432 statically at compile-time. However, this static linkage also limits their |
435 statically at compile-time. However, this static linkage also limits their |
433 usefulness in cases where data needs to be build up dynamically. In the |
436 usefulness in cases where data needs to be build up dynamically. In the |
434 course of this chapter you will learn more about these antiquotations: |
437 course of this chapter you will learn more about these antiquotations: |
435 they can simplify Isabelle programming since one can directly access all |
438 they can simplify Isabelle programming since one can directly access all |
511 in @{ML_file "Pure/type.ML"}. |
514 in @{ML_file "Pure/type.ML"}. |
512 \end{readmore} |
515 \end{readmore} |
513 *} |
516 *} |
514 |
517 |
515 |
518 |
516 section {* Constructing Terms and Types Manually *} |
519 section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *} |
517 |
520 |
518 text {* |
521 text {* |
519 While antiquotations are very convenient for constructing terms, they can |
522 While antiquotations are very convenient for constructing terms, they can |
520 only construct fixed terms (remember they are ``linked'' at compile-time). |
523 only construct fixed terms (remember they are ``linked'' at compile-time). |
521 However, you often need to construct terms dynamically. For example, a |
524 However, you often need to construct terms dynamically. For example, a |
566 |
569 |
567 *} |
570 *} |
568 |
571 |
569 ML{*fun make_fun_type tau1 tau2 = Type ("fun",[tau1,tau2]) *} |
572 ML{*fun make_fun_type tau1 tau2 = Type ("fun",[tau1,tau2]) *} |
570 |
573 |
571 text {* This can be equally written as: *} |
574 text {* This can be equally written with the combinator @{ML "-->"} as: *} |
572 |
575 |
573 ML{*fun make_fun_type tau1 tau2 = tau1 --> tau2 *} |
576 ML{*fun make_fun_type tau1 tau2 = tau1 --> tau2 *} |
574 |
577 |
575 text {* |
578 text {* |
576 A handy function for manipulating terms is @{ML map_types}: it takes a |
579 A handy function for manipulating terms is @{ML map_types}: it takes a |
577 function and applies it to every type in the term. You can, for example, |
580 function and applies it to every type in a term. You can, for example, |
578 change every @{typ nat} in a term into an @{typ int} using the function: |
581 change every @{typ nat} in a term into an @{typ int} using the function: |
579 *} |
582 *} |
580 |
583 |
581 ML{*fun nat_to_int t = |
584 ML{*fun nat_to_int t = |
582 (case t of |
585 (case t of |
916 text {* |
919 text {* |
917 where the function @{ML "Thm.rule_attribute"} expects a function taking a |
920 where the function @{ML "Thm.rule_attribute"} expects a function taking a |
918 context (which we ignore in the code above) and a theorem (@{text thm}), and |
921 context (which we ignore in the code above) and a theorem (@{text thm}), and |
919 returns another theorem (namely @{text thm} resolved with the lemma |
922 returns another theorem (namely @{text thm} resolved with the lemma |
920 @{thm [source] sym}: @{thm sym[no_vars]}). The function @{ML "Thm.rule_attribute"} then returns |
923 @{thm [source] sym}: @{thm sym[no_vars]}). The function @{ML "Thm.rule_attribute"} then returns |
921 an attribute (of type @{ML_type "attribute"}). |
924 an attribute. |
922 |
925 |
923 Before we can use the attribute, we need to set it up. This can be done |
926 Before we can use the attribute, we need to set it up. This can be done |
924 using the function @{ML Attrib.add_attributes} as follows. |
927 using the function @{ML Attrib.add_attributes} as follows. |
925 *} |
928 *} |
926 |
929 |
972 fun my_thms_del thm ctxt = |
975 fun my_thms_del thm ctxt = |
973 (my_thms := Thm.del_thm thm (!my_thms); ctxt)*} |
976 (my_thms := Thm.del_thm thm (!my_thms); ctxt)*} |
974 |
977 |
975 text {* |
978 text {* |
976 These functions take a theorem and a context and, for what we are explaining |
979 These functions take a theorem and a context and, for what we are explaining |
977 here it is sufficient to just return the context unchanged. They change |
980 here it is sufficient that they just return the context unchanged. They change |
978 however the reference @{ML my_thms}, whereby the function @{ML Thm.add_thm} |
981 however the reference @{ML my_thms}, whereby the function @{ML Thm.add_thm} |
979 adds a theorem if it is not already included in the list, and @{ML |
982 adds a theorem if it is not already included in the list, and @{ML |
980 Thm.del_thm} deletes one. Both functions use the predicate @{ML |
983 Thm.del_thm} deletes one. Both functions use the predicate @{ML |
981 Thm.eq_thm_prop} which compares theorems according to their proved |
984 Thm.eq_thm_prop} which compares theorems according to their proved |
982 propositions (modulo alpha-equivalence). |
985 propositions (modulo alpha-equivalence). |
983 |
986 |
984 |
987 |
985 We can turn both functions into attributes using |
988 You can turn both functions into attributes using |
986 *} |
989 *} |
987 |
990 |
988 ML{*val my_add = Thm.declaration_attribute my_thms_add |
991 ML{*val my_add = Thm.declaration_attribute my_thms_add |
989 val my_del = Thm.declaration_attribute my_thms_del *} |
992 val my_del = Thm.declaration_attribute my_thms_del *} |
990 |
993 |
1007 then you can see the lemma is added to the initially empty list. |
1010 then you can see the lemma is added to the initially empty list. |
1008 |
1011 |
1009 @{ML_response_fake [display,gray] |
1012 @{ML_response_fake [display,gray] |
1010 "!my_thms" "[\"True\"]"} |
1013 "!my_thms" "[\"True\"]"} |
1011 |
1014 |
1012 We can also add theorems using the command \isacommand{declare} |
1015 You can also add theorems using the command \isacommand{declare} |
1013 *} |
1016 *} |
1014 |
1017 |
1015 declare test[my_thms] trueI_2[my_thms add] |
1018 declare test[my_thms] trueI_2[my_thms add] |
1016 |
1019 |
1017 text {* |
1020 text {* |
1028 the list. Deletion from the list works as follows: |
1031 the list. Deletion from the list works as follows: |
1029 *} |
1032 *} |
1030 |
1033 |
1031 declare test[my_thms del] |
1034 declare test[my_thms del] |
1032 |
1035 |
1033 text {* After this, the theorem list is: |
1036 text {* After this, the theorem list is again: |
1034 |
1037 |
1035 @{ML_response_fake [display,gray] |
1038 @{ML_response_fake [display,gray] |
1036 "!my_thms" |
1039 "!my_thms" |
1037 "[\"True\"]"} |
1040 "[\"True\"]"} |
1038 |
1041 |
1039 We used in this example two functions declared as @{ML Thm.declaration_attribute}, |
1042 We used in this example two functions declared as @{ML Thm.declaration_attribute}, |
1040 but there can be any number of them. We just have to change the parser for reading |
1043 but there can be any number of them. We just have to change the parser for reading |
1041 the arguments accordingly. |
1044 the arguments accordingly. |
1042 |
1045 |
1043 However, as said at the beginning using references for storing theorems is |
1046 However, as said at the beginning of this example, using references for storing theorems is |
1044 \emph{not} the received way of doing such things. The received way is to |
1047 \emph{not} the received way of doing such things. The received way is to |
1045 start a ``data slot'' in a context by using the functor @{text GenericDataFun}: |
1048 start a ``data slot'' in a context by using the functor @{text GenericDataFun}: |
1046 *} |
1049 *} |
1047 |
1050 |
1048 ML {*structure Data = GenericDataFun |
1051 ML {*structure Data = GenericDataFun |
1050 val empty = [] |
1053 val empty = [] |
1051 val extend = I |
1054 val extend = I |
1052 fun merge _ = Thm.merge_thms) *} |
1055 fun merge _ = Thm.merge_thms) *} |
1053 |
1056 |
1054 text {* |
1057 text {* |
1055 To use this data slot, we only have to change the functions @{ML my_thms_add} and |
1058 To use this data slot, you only have to change @{ML my_thms_add} and |
1056 @{ML my_thms_del} to: |
1059 @{ML my_thms_del} to: |
1057 *} |
1060 *} |
1058 |
1061 |
1059 ML{*val thm_add = Data.map o Thm.add_thm |
1062 ML{*val thm_add = Data.map o Thm.add_thm |
1060 val thm_del = Data.map o Thm.del_thm*} |
1063 val thm_del = Data.map o Thm.del_thm*} |
1081 an attribute @{text foo} (with the @{text add} and @{text del} options |
1084 an attribute @{text foo} (with the @{text add} and @{text del} options |
1082 for adding and deleting theorems) and an internal ML interface to retrieve and |
1085 for adding and deleting theorems) and an internal ML interface to retrieve and |
1083 modify the theorems. |
1086 modify the theorems. |
1084 |
1087 |
1085 Furthermore, the facts are made available on the user level under the dynamic |
1088 Furthermore, the facts are made available on the user level under the dynamic |
1086 fact name @{text foo}. For example we can declare three lemmas to be of the kind |
1089 fact name @{text foo}. For example you can declare three lemmas to be of the kind |
1087 @{text foo} by: |
1090 @{text foo} by: |
1088 *} |
1091 *} |
1089 |
1092 |
1090 lemma rule1[foo]: "A" sorry |
1093 lemma rule1[foo]: "A" sorry |
1091 lemma rule2[foo]: "B" sorry |
1094 lemma rule2[foo]: "B" sorry |
1101 \isacommand{thm}~@{text "foo"}\\ |
1104 \isacommand{thm}~@{text "foo"}\\ |
1102 @{text "> ?C"}\\ |
1105 @{text "> ?C"}\\ |
1103 @{text "> ?B"} |
1106 @{text "> ?B"} |
1104 \end{isabelle} |
1107 \end{isabelle} |
1105 |
1108 |
1106 On the ML-level the rules marked with @{text "foo"} an be retrieved |
1109 On the ML-level the rules marked with @{text "foo"} can be retrieved |
1107 using the function @{ML FooRules.get}: |
1110 using the function @{ML FooRules.get}: |
1108 |
1111 |
1109 @{ML_response_fake [display,gray] "FooRules.get @{context}" "[\"?C\",\"?B\"]"} |
1112 @{ML_response_fake [display,gray] "FooRules.get @{context}" "[\"?C\",\"?B\"]"} |
1110 |
1113 |
1111 \begin{readmore} |
1114 \begin{readmore} |
1112 For more information see @{ML_file "Pure/Tools/named_thms.ML"} and also |
1115 For more information see @{ML_file "Pure/Tools/named_thms.ML"} and also |
1113 the recipe in Section~\ref{recipe:storingdata} about storing arbitrary |
1116 the recipe in Section~\ref{recipe:storingdata} about storing arbitrary |
1114 data. |
1117 data. |
1115 \end{readmore} |
1118 \end{readmore} |
1116 |
1119 |
1117 (FIXME What are: |
1120 (FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?) |
1118 |
|
1119 @{text "theory_attributes"} |
|
1120 @{text "proof_attributes"}) |
|
1121 |
1121 |
1122 |
1122 |
1123 \begin{readmore} |
1123 \begin{readmore} |
1124 FIXME: @{ML_file "Pure/more_thm.ML"} @{ML_file "Pure/Isar/attrib.ML"} |
1124 FIXME: @{ML_file "Pure/more_thm.ML"} @{ML_file "Pure/Isar/attrib.ML"} |
1125 \end{readmore} |
1125 \end{readmore} |