1052 theories). On the other hand, data such as facts change inside a proof and |
1052 theories). On the other hand, data such as facts change inside a proof and |
1053 are only relevant to the proof at hand. Therefore such data needs to be |
1053 are only relevant to the proof at hand. Therefore such data needs to be |
1054 maintained inside a proof context, which represents ``local'' data. |
1054 maintained inside a proof context, which represents ``local'' data. |
1055 |
1055 |
1056 For theories and proof contexts there are, respectively, the functors |
1056 For theories and proof contexts there are, respectively, the functors |
1057 @{ML_funct_ind TheoryDataFun} and @{ML_funct_ind ProofDataFun} that help |
1057 @{ML_funct_ind Theory_Data} and @{ML_funct_ind Proof_Data} that help |
1058 with the data storage. Below we show how to implement a table in which you |
1058 with the data storage. Below we show how to implement a table in which you |
1059 can store theorems and look them up according to a string key. The |
1059 can store theorems and look them up according to a string key. The |
1060 intention in this example is to be able to look up introduction rules for logical |
1060 intention in this example is to be able to look up introduction rules for logical |
1061 connectives. Such a table might be useful in an automatic proof procedure |
1061 connectives. Such a table might be useful in an automatic proof procedure |
1062 and therefore it makes sense to store this data inside a theory. |
1062 and therefore it makes sense to store this data inside a theory. |
1063 Consequently we use the functor @{ML_funct TheoryDataFun}. |
1063 Consequently we use the functor @{ML_funct Theory_Data}. |
1064 The code for the table is: |
1064 The code for the table is: |
1065 *} |
1065 *} |
1066 |
1066 |
1067 ML %linenosgray{*structure Data = TheoryDataFun |
1067 ML %linenosgray{*structure Data = Theory_Data |
1068 (type T = thm Symtab.table |
1068 (type T = thm Symtab.table |
1069 val empty = Symtab.empty |
1069 val empty = Symtab.empty |
1070 val copy = I |
|
1071 val extend = I |
1070 val extend = I |
1072 fun merge _ = Symtab.merge (K true))*} |
1071 val merge = Symtab.merge (K true))*} |
1073 |
1072 |
1074 text {* |
1073 text {* |
1075 In order to store data in a theory, we have to specify the type of the data |
1074 In order to store data in a theory, we have to specify the type of the data |
1076 (Line 2). In this case we specify the type @{ML_type "thm Symtab.table"}, |
1075 (Line 2). In this case we specify the type @{ML_type "thm Symtab.table"}, |
1077 which stands for a table in which @{ML_type string}s can be looked up |
1076 which stands for a table in which @{ML_type string}s can be looked up |
1078 producing an associated @{ML_type thm}. We also have to specify four |
1077 producing an associated @{ML_type thm}. We also have to specify four |
1079 functions to use this functor: namely how to initialise the data storage |
1078 functions to use this functor: namely how to initialise the data storage |
1080 (Line 3), how to copy it (Line 4), how to extend it (Line 5) and how two |
1079 (Line 3), how to extend it (Line 4) and how two |
1081 tables should be merged (Line 6). These functions correspond roughly to the |
1080 tables should be merged (Line 5). These functions correspond roughly to the |
1082 operations performed on theories and we just give some sensible |
1081 operations performed on theories and we just give some sensible |
1083 defaults.\footnote{\bf FIXME: Say more about the |
1082 defaults.\footnote{\bf FIXME: Say more about the |
1084 assumptions of these operations.} The result structure @{ML_text Data} |
1083 assumptions of these operations.} The result structure @{ML_text Data} |
1085 contains functions for accessing the table (@{ML Data.get}) and for updating |
1084 contains functions for accessing the table (@{ML Data.get}) and for updating |
1086 it (@{ML Data.map}). There are also two more functions (@{ML Data.init} and |
1085 it (@{ML Data.map}). There is also the functions @{ML Data.put}, which however is |
1087 @{ML Data.put}), which however are not relevant here. Below we define two |
1086 not relevant here. Below we define two |
1088 auxiliary functions, which help us with accessing the table. |
1087 auxiliary functions, which help us with accessing the table. |
1089 *} |
1088 *} |
1090 |
1089 |
1091 ML{*val lookup = Symtab.lookup o Data.get |
1090 ML{*val lookup = Symtab.lookup o Data.get |
1092 fun update k v = Data.map (Symtab.update (k, v))*} |
1091 fun update k v = Data.map (Symtab.update (k, v))*} |
1194 directed graphs in @{ML_file "Pure/General/graph.ML"}, and |
1192 directed graphs in @{ML_file "Pure/General/graph.ML"}, and |
1195 tables and symtables in @{ML_file "Pure/General/table.ML"}. |
1193 tables and symtables in @{ML_file "Pure/General/table.ML"}. |
1196 \end{readmore} |
1194 \end{readmore} |
1197 |
1195 |
1198 Storing data in a proof context is done in a similar fashion. As mentioned |
1196 Storing data in a proof context is done in a similar fashion. As mentioned |
1199 before, the corresponding functor is @{ML_funct_ind ProofDataFun}. With the |
1197 before, the corresponding functor is @{ML_funct_ind Proof_Data}. With the |
1200 following code we can store a list of terms in a proof context. |
1198 following code we can store a list of terms in a proof context. |
1201 *} |
1199 *} |
1202 |
1200 |
1203 ML{*structure Data = ProofDataFun |
1201 ML{*structure Data = Proof_Data |
1204 (type T = term list |
1202 (type T = term list |
1205 fun init _ = [])*} |
1203 fun init _ = [])*} |
1206 |
1204 |
1207 text {* |
1205 text {* |
1208 The function we have to specify has to produce a list once a context |
1206 The function we have to specify has to produce a list once a context |