266 |
266 |
267 @{ML_response_fake [display, gray] |
267 @{ML_response_fake [display, gray] |
268 "tracing (string_of_term @{context} @{term \"(1::nat, x)\"})" |
268 "tracing (string_of_term @{context} @{term \"(1::nat, x)\"})" |
269 "(1::nat, x::'a)"} |
269 "(1::nat, x::'a)"} |
270 |
270 |
271 where @{text 1} and @{text x} are displayed with their type. |
271 where @{text 1} and @{text x} are displayed with their inferred type. |
272 Even more type information can be printed by setting |
272 Even more type information can be printed by setting |
273 @{ML_ind show_all_types in Syntax} to @{ML true}. We obtain |
273 @{ML_ind show_all_types in Syntax} to @{ML true}. We obtain then |
274 *} |
274 *} |
275 (*<*)ML %linenos {*show_all_types := true*} |
275 (*<*)ML %linenos {*show_all_types := true*} |
276 (*>*) |
276 (*>*) |
277 text {* |
277 text {* |
278 @{ML_response_fake [display, gray] |
278 @{ML_response_fake [display, gray] |
505 variant_frees in Variable} generates for each @{text "z"} a unique name |
505 variant_frees in Variable} generates for each @{text "z"} a unique name |
506 avoiding the given @{text f}; the list of name-type pairs is turned into a |
506 avoiding the given @{text f}; the list of name-type pairs is turned into a |
507 list of variable terms in Line 6, which in the last line is applied by the |
507 list of variable terms in Line 6, which in the last line is applied by the |
508 function @{ML_ind list_comb in Term} to the term. In this last step we have |
508 function @{ML_ind list_comb in Term} to the term. In this last step we have |
509 to use the function @{ML_ind curry in Library}, because @{ML list_comb} |
509 to use the function @{ML_ind curry in Library}, because @{ML list_comb} |
510 expects the function and the variables list as a pair. This kind of |
510 expects the function and the variables list as a pair. |
511 functions is often needed when constructing terms with fresh variables. The |
511 Functions like @{ML apply_fresh_args} are often needed when constructing |
|
512 terms with fresh variables. The |
512 infrastructure helps tremendously to avoid any name clashes. Consider for |
513 infrastructure helps tremendously to avoid any name clashes. Consider for |
513 example: |
514 example: |
514 |
515 |
515 @{ML_response_fake [display,gray] |
516 @{ML_response_fake [display,gray] |
516 "let |
517 "let |
710 end" |
711 end" |
711 "m + n, m * n, m - n"} |
712 "m + n, m * n, m - n"} |
712 *} |
713 *} |
713 |
714 |
714 text {* |
715 text {* |
715 In this example we obtain three terms (using @{ML_ind parse_term in Syntax}) whose |
716 In this example we obtain three terms (using the function |
716 variables @{text m} and @{text n} are of type @{typ "nat"}. If you have only |
717 @{ML_ind parse_term in Syntax}) whose variables @{text m} and @{text n} |
717 a single term, then @{ML |
718 are of type @{typ "nat"}. If you have only a single term, then @{ML |
718 check_terms in Syntax} needs plumbing. This can be done with the function |
719 check_terms in Syntax} needs plumbing. This can be done with the function |
719 @{ML singleton}.\footnote{There is already a function @{ML check_term in |
720 @{ML_ind singleton in Library}.\footnote{There is already a function @{ML check_term in |
720 Syntax} in the Isabelle sources that is defined in terms of @{ML singleton} |
721 Syntax} in the file @{ML_file "Pure/Syntax/syntax.ML"} that is implemented |
721 and @{ML check_terms in Syntax}.} For example |
722 in terms of @{ML singleton} and @{ML check_terms in Syntax}.} For example |
722 |
723 |
723 @{ML_response_fake [display, gray] |
724 @{ML_response_fake [display, gray, linenos] |
724 "let |
725 "let |
725 val ctxt = @{context} |
726 val ctxt = @{context} |
726 in |
727 in |
727 Syntax.parse_term ctxt \"m - (n::nat)\" |
728 Syntax.parse_term ctxt \"m - (n::nat)\" |
728 |> singleton (Syntax.check_terms ctxt) |
729 |> singleton (Syntax.check_terms ctxt) |
729 |> string_of_term ctxt |
730 |> string_of_term ctxt |
730 |> tracing |
731 |> tracing |
731 end" |
732 end" |
732 "m - n"} |
733 "m - n"} |
733 |
734 |
|
735 where in Line 5, the function operating over lists fits with the |
|
736 single term generated in Line 4. |
|
737 |
734 \begin{readmore} |
738 \begin{readmore} |
735 The most frequently used combinators are defined in the files @{ML_file |
739 The most frequently used combinators are defined in the files @{ML_file |
736 "Pure/library.ML"} |
740 "Pure/library.ML"} |
737 and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} |
741 and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} |
738 contains further information about combinators. |
742 contains further information about combinators. |
744 |
748 |
745 |
749 |
746 section {* ML-Antiquotations *} |
750 section {* ML-Antiquotations *} |
747 |
751 |
748 text {* |
752 text {* |
749 Recall that code in Isabelle is always embedded in a theory. The main |
753 Recall from Section \ref{sec:include} that code in Isabelle is always |
750 advantage of this is that the code can contain references to entities |
754 embedded in a theory. The main advantage of this is that the code can |
751 defined on the logical level of Isabelle. By this we mean definitions, |
755 contain references to entities defined on the logical level of Isabelle. By |
752 theorems, terms and so on. This kind of reference is realised in Isabelle |
756 this we mean references to definitions, theorems, terms and so on. These |
753 with ML-antiquotations, often just called antiquotations.\footnote{There are |
757 reference are realised in Isabelle with ML-antiquotations, often just called |
754 two kinds of antiquotations in Isabelle, which have very different purposes |
758 antiquotations.\footnote{Note that there are two kinds of antiquotations in |
755 and infrastructures. The first kind, described in this section, are |
759 Isabelle, which have very different purposes and infrastructures. The first |
756 \emph{\index*{ML-antiquotation}}. They are used to refer to entities (like terms, |
760 kind, described in this section, are \emph{\index*{ML-antiquotation}}. They |
757 types etc) from Isabelle's logic layer inside ML-code. The other kind of |
761 are used to refer to entities (like terms, types etc) from Isabelle's logic |
758 antiquotations are \emph{document}\index{document antiquotation} antiquotations. |
762 layer inside ML-code. The other kind of antiquotations are |
759 They are used only in the |
763 \emph{document}\index{document antiquotation} antiquotations. They are used |
760 text parts of Isabelle and their purpose is to print logical entities inside |
764 only in the text parts of Isabelle and their purpose is to print logical |
761 \LaTeX-documents. Document antiquotations are part of the user level and |
765 entities inside \LaTeX-documents. Document antiquotations are part of the |
762 therefore we are not interested in them in this Tutorial, except in Appendix |
766 user level and therefore we are not interested in them in this Tutorial, |
763 \ref{rec:docantiquotations} where we show how to implement your own document |
767 except in Appendix \ref{rec:docantiquotations} where we show how to |
764 antiquotations.} For example, one can print out the name of the current |
768 implement your own document antiquotations.} Syntactically antiquotations |
765 theory with the code |
769 are indicated by the @{ML_text @}-sign followed by text wrapped in @{text |
|
770 "{\<dots>}"}. For example, one can print out the name of the current theory with |
|
771 the code |
766 |
772 |
767 @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""} |
773 @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""} |
768 |
774 |
769 where @{text "@{theory}"} is an antiquotation that is substituted with the |
775 where @{text "@{theory}"} is an antiquotation that is substituted with the |
770 current theory (remember that we assumed we are inside the theory |
776 current theory (remember that we assumed we are inside the theory |
868 \footnote{\bf FIXME: There should probably a separate section on binding, long-names |
874 \footnote{\bf FIXME: There should probably a separate section on binding, long-names |
869 and sign.} |
875 and sign.} |
870 |
876 |
871 It is also possible to define your own antiquotations. But you should |
877 It is also possible to define your own antiquotations. But you should |
872 exercise care when introducing new ones, as they can also make your code |
878 exercise care when introducing new ones, as they can also make your code |
873 also difficult to read. In the next chapter we describe how the (build in) |
879 also difficult to read. In the next chapter we describe how to construct |
874 antiquotation @{text "@{term \<dots>}"} for constructing terms. A |
880 terms with the (build in) antiquotation @{text "@{term \<dots>}"}. A restriction |
875 restriction of this antiquotation is that it does not allow you to use |
881 of this antiquotation is that it does not allow you to use schematic |
876 schematic variables in terms. If you want to have an antiquotation that does not have |
882 variables in terms. If you want to have an antiquotation that does not have |
877 this restriction, you can implement your own using the function @{ML_ind |
883 this restriction, you can implement your own using the function @{ML_ind |
878 inline in ML_Antiquote} in the structure @{ML_struct ML_Antiquote}. The code |
884 inline in ML_Antiquote} from the structure @{ML_struct ML_Antiquote}. The code |
879 for the antiquotation @{text "term_pat"} is as follows. |
885 for the antiquotation @{text "term_pat"} is as follows. |
880 *} |
886 *} |
881 |
887 |
882 ML %linenosgray{*let |
888 ML %linenosgray{*let |
883 val parser = Args.context -- Scan.lift Args.name_source |
889 val parser = Args.context -- Scan.lift Args.name_source |
892 |
898 |
893 text {* |
899 text {* |
894 The parser in Line 2 provides us with a context and a string; this string is |
900 The parser in Line 2 provides us with a context and a string; this string is |
895 transformed into a term using the function @{ML_ind read_term_pattern in |
901 transformed into a term using the function @{ML_ind read_term_pattern in |
896 ProofContext} (Line 5); the next two lines transform the term into a string |
902 ProofContext} (Line 5); the next two lines transform the term into a string |
897 so that the ML-system can understand it. An example for this antiquotation is: |
903 so that the ML-system can understand it. (All these functions will be explained |
|
904 in more detail in later sections.) An example for this antiquotation is: |
898 |
905 |
899 @{ML_response_fake [display,gray] |
906 @{ML_response_fake [display,gray] |
900 "@{term_pat \"Suc (?x::nat)\"}" |
907 "@{term_pat \"Suc (?x::nat)\"}" |
901 "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"} |
908 "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"} |
902 |
909 |
919 @{ML_type "'a"}. Despite this wisdom, however, it is possible to implement a |
926 @{ML_type "'a"}. Despite this wisdom, however, it is possible to implement a |
920 universal type in ML, although by some arguably accidental features of ML. |
927 universal type in ML, although by some arguably accidental features of ML. |
921 This universal type can be used to store data of different type into a single list. |
928 This universal type can be used to store data of different type into a single list. |
922 In fact, it allows one to inject and to project data of \emph{arbitrary} type. This is |
929 In fact, it allows one to inject and to project data of \emph{arbitrary} type. This is |
923 in contrast to datatypes, which only allow injection and projection of data for |
930 in contrast to datatypes, which only allow injection and projection of data for |
924 some fixed collection of types. In light of the conventional wisdom cited |
931 some \emph{fixed} collection of types. In light of the conventional wisdom cited |
925 above it is important to keep in mind that the universal type does not |
932 above it is important to keep in mind that the universal type does not |
926 destroy type-safety of ML: storing and accessing the data can only be done |
933 destroy type-safety of ML: storing and accessing the data can only be done |
927 in a type-safe manner. |
934 in a type-safe manner. |
928 |
935 |
929 \begin{readmore} |
936 \begin{readmore} |
960 in |
967 in |
961 [thirteen, truth_val] |
968 [thirteen, truth_val] |
962 end*} |
969 end*} |
963 |
970 |
964 text {* |
971 text {* |
965 The data can be retrieved using the projection functions. |
972 The data can be retrieved with the projection functions defined above. |
966 |
973 |
967 @{ML_response [display, gray] |
974 @{ML_response_fake [display, gray] |
968 "(project_int (nth foo_list 0), project_bool (nth foo_list 1))" |
975 "project_int (nth foo_list 0); |
969 "(13, true)"} |
976 project_bool (nth foo_list 1)" |
|
977 "13 |
|
978 true"} |
970 |
979 |
971 Notice that we access the integer as an integer and the boolean as |
980 Notice that we access the integer as an integer and the boolean as |
972 a boolean. If we attempt to access the integer as a boolean, then we get |
981 a boolean. If we attempt to access the integer as a boolean, then we get |
973 a runtime error. |
982 a runtime error. |
974 |
983 |
980 containing a universal type. |
989 containing a universal type. |
981 |
990 |
982 Now, Isabelle heavily uses this mechanism for storing all sorts of |
991 Now, Isabelle heavily uses this mechanism for storing all sorts of |
983 data: theorem lists, simpsets, facts etc. Roughly speaking, there are two |
992 data: theorem lists, simpsets, facts etc. Roughly speaking, there are two |
984 places where data can be stored in Isabelle: in \emph{theories} and in \emph{proof |
993 places where data can be stored in Isabelle: in \emph{theories} and in \emph{proof |
985 contexts}. Data such as simpsets need to be stored |
994 contexts}. Data such as simpsets are ``global'' and therefore need to be stored |
986 in a theory, since they need to be maintained across proofs and even across |
995 in a theory (simpsets need to be maintained across proofs and even across |
987 theories. On the other hand, data such as facts change inside a proof and |
996 theories). On the other hand, data such as facts change inside a proof and |
988 are only relevant to the proof at hand. Therefore such data needs to be |
997 are only relevant to the proof at hand. Therefore such data needs to be |
989 maintained inside a proof context. |
998 maintained inside a proof context, which represents ``local'' data. |
990 |
999 |
991 For theories and proof contexts there are, respectively, the functors |
1000 For theories and proof contexts there are, respectively, the functors |
992 @{ML_funct_ind TheoryDataFun} and @{ML_funct_ind ProofDataFun} that help |
1001 @{ML_funct_ind TheoryDataFun} and @{ML_funct_ind ProofDataFun} that help |
993 with the data storage. Below we show how to implement a table in which we |
1002 with the data storage. Below we show how to implement a table in which you |
994 can store theorems and look them up according to a string key. The |
1003 can store theorems and look them up according to a string key. The |
995 intention in this example is to be able to look up introduction rules for logical |
1004 intention in this example is to be able to look up introduction rules for logical |
996 connectives. Such a table might be useful in an automatic proof procedure |
1005 connectives. Such a table might be useful in an automatic proof procedure |
997 and therefore it makes sense to store this data inside a theory. |
1006 and therefore it makes sense to store this data inside a theory. |
998 Therefore we use the functor @{ML_funct TheoryDataFun}. |
1007 Consequently we use the functor @{ML_funct TheoryDataFun}. |
999 The code for the table is: |
1008 The code for the table is: |
1000 *} |
1009 *} |
1001 |
1010 |
1002 ML %linenosgray{*structure Data = TheoryDataFun |
1011 ML %linenosgray{*structure Data = TheoryDataFun |
1003 (type T = thm Symtab.table |
1012 (type T = thm Symtab.table |
1013 producing an associated @{ML_type thm}. We also have to specify four |
1022 producing an associated @{ML_type thm}. We also have to specify four |
1014 functions to use this functor: namely how to initialise the data storage |
1023 functions to use this functor: namely how to initialise the data storage |
1015 (Line 3), how to copy it (Line 4), how to extend it (Line 5) and how two |
1024 (Line 3), how to copy it (Line 4), how to extend it (Line 5) and how two |
1016 tables should be merged (Line 6). These functions correspond roughly to the |
1025 tables should be merged (Line 6). These functions correspond roughly to the |
1017 operations performed on theories and we just give some sensible |
1026 operations performed on theories and we just give some sensible |
1018 defaults\footnote{\bf FIXME: Say more about the |
1027 defaults.\footnote{\bf FIXME: Say more about the |
1019 assumptions of these operations.} The result structure @{ML_text Data} |
1028 assumptions of these operations.} The result structure @{ML_text Data} |
1020 contains functions for accessing the table (@{ML Data.get}) and for updating |
1029 contains functions for accessing the table (@{ML Data.get}) and for updating |
1021 it (@{ML Data.map}). There are also two more functions (@{ML Data.init} and |
1030 it (@{ML Data.map}). There are also two more functions (@{ML Data.init} and |
1022 @{ML Data.put}), which however are not relevant here. Below we define two |
1031 @{ML Data.put}), which however are not relevant here. Below we define two |
1023 auxiliary functions, which help us with accessing the table. |
1032 auxiliary functions, which help us with accessing the table. |
1140 fun init _ = [])*} |
1149 fun init _ = [])*} |
1141 |
1150 |
1142 text {* |
1151 text {* |
1143 The function we have to specify has to produce a list once a context |
1152 The function we have to specify has to produce a list once a context |
1144 is initialised (possibly taking the theory into account from which the |
1153 is initialised (possibly taking the theory into account from which the |
1145 context is derived). We choose to just return the empty list. Next |
1154 context is derived). We choose here to just return the empty list. Next |
1146 we define two auxiliary functions for updating the list with a given |
1155 we define two auxiliary functions for updating the list with a given |
1147 term and printing the list. |
1156 term and printing the list. |
1148 *} |
1157 *} |
1149 |
1158 |
1150 ML{*fun update trm = Data.map (fn trms => trm::trms) |
1159 ML{*fun update trm = Data.map (fn trms => trm::trms) |