ProgTutorial/FirstSteps.thy
changeset 385 78c91a629602
parent 378 8d160d79b48c
child 394 0019ebf76e10
equal deleted inserted replaced
384:0b24a016f6dd 385:78c91a629602
  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))*}
  1131   defeat its undo-mechanism. To see the latter, consider the 
  1130   defeat its undo-mechanism. To see the latter, consider the 
  1132   following data container where we maintain a reference to a list of 
  1131   following data container where we maintain a reference to a list of 
  1133   integers.
  1132   integers.
  1134 *}
  1133 *}
  1135 
  1134 
  1136 ML{*structure WrongRefData = TheoryDataFun
  1135 ML{*structure WrongRefData = Theory_Data
  1137   (type T = (int list) Unsynchronized.ref
  1136   (type T = (int list) Unsynchronized.ref
  1138    val empty = Unsynchronized.ref []
  1137    val empty = Unsynchronized.ref []
  1139    val copy = I
       
  1140    val extend = I
  1138    val extend = I
  1141    fun merge _ = fst)*}
  1139    val merge = fst)*}
  1142 
  1140 
  1143 text {*
  1141 text {*
  1144   We initialise the reference with the empty list. Consequently a first 
  1142   We initialise the reference with the empty list. Consequently a first 
  1145   lookup produces @{ML "ref []" in Unsynchronized}.
  1143   lookup produces @{ML "ref []" in Unsynchronized}.
  1146 
  1144 
  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