src/HOL/Library/Table.thy
changeset 36111 5844017e31f8
parent 35617 a6528fb99641
equal deleted inserted replaced
36110:4ab91a42666a 36111:5844017e31f8
     1 (* Author: Florian Haftmann, TU Muenchen *)
     1 (* Author: Florian Haftmann, TU Muenchen *)
     2 
     2 
     3 header {* Tables: finite mappings implemented by red-black trees *}
     3 header {* Tables: finite mappings implemented by red-black trees *}
     4 
     4 
     5 theory Table
     5 theory Table
     6 imports Main RBT
     6 imports Main RBT Mapping
     7 begin
     7 begin
     8 
     8 
     9 subsection {* Type definition *}
     9 subsection {* Type definition *}
    10 
    10 
    11 typedef (open) ('a, 'b) table = "{t :: ('a\<Colon>linorder, 'b) rbt. is_rbt t}"
    11 typedef (open) ('a, 'b) table = "{t :: ('a\<Colon>linorder, 'b) rbt. is_rbt t}"
    21 
    21 
    22 lemma table_eq:
    22 lemma table_eq:
    23   "t1 = t2 \<longleftrightarrow> tree_of t1 = tree_of t2"
    23   "t1 = t2 \<longleftrightarrow> tree_of t1 = tree_of t2"
    24   by (simp add: tree_of_inject)
    24   by (simp add: tree_of_inject)
    25 
    25 
    26 code_abstype Table tree_of
    26 lemma [code abstype]:
       
    27   "Table (tree_of t) = t"
    27   by (simp add: tree_of_inverse)
    28   by (simp add: tree_of_inverse)
    28 
    29 
    29 
    30 
    30 subsection {* Primitive operations *}
    31 subsection {* Primitive operations *}
    31 
    32 
    54   by (simp add: delete_def Table_inverse)
    55   by (simp add: delete_def Table_inverse)
    55 
    56 
    56 definition entries :: "('a\<Colon>linorder, 'b) table \<Rightarrow> ('a \<times> 'b) list" where
    57 definition entries :: "('a\<Colon>linorder, 'b) table \<Rightarrow> ('a \<times> 'b) list" where
    57   [code]: "entries t = RBT.entries (tree_of t)"
    58   [code]: "entries t = RBT.entries (tree_of t)"
    58 
    59 
       
    60 definition keys :: "('a\<Colon>linorder, 'b) table \<Rightarrow> 'a list" where
       
    61   [code]: "keys t = RBT.keys (tree_of t)"
       
    62 
    59 definition bulkload :: "('a\<Colon>linorder \<times> 'b) list \<Rightarrow> ('a, 'b) table" where
    63 definition bulkload :: "('a\<Colon>linorder \<times> 'b) list \<Rightarrow> ('a, 'b) table" where
    60   "bulkload xs = Table (RBT.bulkload xs)"
    64   "bulkload xs = Table (RBT.bulkload xs)"
    61 
    65 
    62 lemma tree_of_bulkload [code abstract]:
    66 lemma tree_of_bulkload [code abstract]:
    63   "tree_of (bulkload xs) = RBT.bulkload xs"
    67   "tree_of (bulkload xs) = RBT.bulkload xs"
    99 
   103 
   100 lemma entries_tree_of:
   104 lemma entries_tree_of:
   101   "RBT.entries (tree_of t) = entries t"
   105   "RBT.entries (tree_of t) = entries t"
   102   by (simp add: entries_def)
   106   by (simp add: entries_def)
   103 
   107 
       
   108 lemma keys_tree_of:
       
   109   "RBT.keys (tree_of t) = keys t"
       
   110   by (simp add: keys_def)
       
   111 
   104 lemma lookup_empty [simp]:
   112 lemma lookup_empty [simp]:
   105   "lookup empty = Map.empty"
   113   "lookup empty = Map.empty"
   106   by (simp add: empty_def lookup_Table expand_fun_eq)
   114   by (simp add: empty_def lookup_Table expand_fun_eq)
   107 
   115 
   108 lemma lookup_update [simp]:
   116 lemma lookup_update [simp]:
   109   "lookup (update k v t) = (lookup t)(k \<mapsto> v)"
   117   "lookup (update k v t) = (lookup t)(k \<mapsto> v)"
   110   by (simp add: update_def lookup_Table lookup_insert lookup_tree_of)
   118   by (simp add: update_def lookup_Table lookup_insert lookup_tree_of)
   111 
   119 
   112 lemma lookup_delete [simp]:
   120 lemma lookup_delete [simp]:
   113   "lookup (delete k t) = (lookup t)(k := None)"
   121   "lookup (delete k t) = (lookup t)(k := None)"
   114   by (simp add: delete_def lookup_Table lookup_delete lookup_tree_of restrict_complement_singleton_eq)
   122   by (simp add: delete_def lookup_Table RBT.lookup_delete lookup_tree_of restrict_complement_singleton_eq)
   115 
   123 
   116 lemma map_of_entries [simp]:
   124 lemma map_of_entries [simp]:
   117   "map_of (entries t) = lookup t"
   125   "map_of (entries t) = lookup t"
   118   by (simp add: entries_def map_of_entries lookup_tree_of)
   126   by (simp add: entries_def map_of_entries lookup_tree_of)
   119 
   127 
       
   128 lemma entries_lookup:
       
   129   "entries t1 = entries t2 \<longleftrightarrow> lookup t1 = lookup t2"
       
   130   by (simp add: entries_def lookup_def entries_lookup)
       
   131 
   120 lemma lookup_bulkload [simp]:
   132 lemma lookup_bulkload [simp]:
   121   "lookup (bulkload xs) = map_of xs"
   133   "lookup (bulkload xs) = map_of xs"
   122   by (simp add: bulkload_def lookup_Table lookup_bulkload)
   134   by (simp add: bulkload_def lookup_Table RBT.lookup_bulkload)
   123 
   135 
   124 lemma lookup_map_entry [simp]:
   136 lemma lookup_map_entry [simp]:
   125   "lookup (map_entry k f t) = (lookup t)(k := Option.map f (lookup t k))"
   137   "lookup (map_entry k f t) = (lookup t)(k := Option.map f (lookup t k))"
   126   by (simp add: map_entry_def lookup_Table lookup_map_entry lookup_tree_of)
   138   by (simp add: map_entry_def lookup_Table lookup_map_entry lookup_tree_of)
   127 
   139 
   131 
   143 
   132 lemma fold_fold:
   144 lemma fold_fold:
   133   "fold f t = (\<lambda>s. foldl (\<lambda>s (k, v). f k v s) s (entries t))"
   145   "fold f t = (\<lambda>s. foldl (\<lambda>s (k, v). f k v s) s (entries t))"
   134   by (simp add: fold_def expand_fun_eq RBT.fold_def entries_tree_of)
   146   by (simp add: fold_def expand_fun_eq RBT.fold_def entries_tree_of)
   135 
   147 
       
   148 lemma is_empty_empty [simp]:
       
   149   "is_empty t \<longleftrightarrow> t = empty"
       
   150   by (simp add: table_eq is_empty_def tree_of_empty split: rbt.split)
       
   151 
       
   152 lemma RBT_lookup_empty [simp]: (*FIXME*)
       
   153   "RBT.lookup t = Map.empty \<longleftrightarrow> t = RBT.Empty"
       
   154   by (cases t) (auto simp add: expand_fun_eq)
       
   155 
       
   156 lemma lookup_empty_empty [simp]:
       
   157   "lookup t = Map.empty \<longleftrightarrow> t = empty"
       
   158   by (cases t) (simp add: empty_def lookup_def Table_inject Table_inverse)
       
   159 
       
   160 lemma sorted_keys [iff]:
       
   161   "sorted (keys t)"
       
   162   by (simp add: keys_def RBT.keys_def sorted_entries)
       
   163 
       
   164 lemma distinct_keys [iff]:
       
   165   "distinct (keys t)"
       
   166   by (simp add: keys_def RBT.keys_def distinct_entries)
       
   167 
       
   168 
       
   169 subsection {* Implementation of mappings *}
       
   170 
       
   171 definition Mapping :: "('a\<Colon>linorder, 'b) table \<Rightarrow> ('a, 'b) mapping" where
       
   172   "Mapping t = Mapping.Mapping (lookup t)"
       
   173 
       
   174 code_datatype Mapping
       
   175 
       
   176 lemma lookup_Mapping [simp, code]:
       
   177   "Mapping.lookup (Mapping t) = lookup t"
       
   178   by (simp add: Mapping_def)
       
   179 
       
   180 lemma empty_Mapping [code]:
       
   181   "Mapping.empty = Mapping empty"
       
   182   by (rule mapping_eqI) simp
       
   183 
       
   184 lemma is_empty_Mapping [code]:
       
   185   "Mapping.is_empty (Mapping t) \<longleftrightarrow> is_empty t"
       
   186   by (simp add: table_eq Mapping.is_empty_empty Mapping_def)
       
   187 
       
   188 lemma update_Mapping [code]:
       
   189   "Mapping.update k v (Mapping t) = Mapping (update k v t)"
       
   190   by (rule mapping_eqI) simp
       
   191 
       
   192 lemma delete_Mapping [code]:
       
   193   "Mapping.delete k (Mapping xs) = Mapping (delete k xs)"
       
   194   by (rule mapping_eqI) simp
       
   195 
       
   196 lemma keys_Mapping [code]:
       
   197   "Mapping.keys (Mapping t) = set (keys t)"
       
   198   by (simp add: keys_def Mapping_def Mapping.keys_def lookup_def lookup_keys)
       
   199 
       
   200 lemma ordered_keys_Mapping [code]:
       
   201   "Mapping.ordered_keys (Mapping t) = keys t"
       
   202   by (rule sorted_distinct_set_unique) (simp_all add: ordered_keys_def keys_Mapping)
       
   203 
       
   204 lemma Mapping_size_card_keys: (*FIXME*)
       
   205   "Mapping.size m = card (Mapping.keys m)"
       
   206   by (simp add: Mapping.size_def Mapping.keys_def)
       
   207 
       
   208 lemma size_Mapping [code]:
       
   209   "Mapping.size (Mapping t) = length (keys t)"
       
   210   by (simp add: Mapping_size_card_keys keys_Mapping distinct_card)
       
   211 
       
   212 lemma tabulate_Mapping [code]:
       
   213   "Mapping.tabulate ks f = Mapping (bulkload (List.map (\<lambda>k. (k, f k)) ks))"
       
   214   by (rule mapping_eqI) (simp add: map_of_map_restrict)
       
   215 
       
   216 lemma bulkload_Mapping [code]:
       
   217   "Mapping.bulkload vs = Mapping (bulkload (List.map (\<lambda>n. (n, vs ! n)) [0..<length vs]))"
       
   218   by (rule mapping_eqI) (simp add: map_of_map_restrict expand_fun_eq)
       
   219 
       
   220 lemma [code, code del]: "HOL.eq (x :: (_, _) mapping) y \<longleftrightarrow> x = y" by (fact eq_equals) (*FIXME*)
       
   221 
       
   222 lemma eq_Mapping [code]:
       
   223   "HOL.eq (Mapping t1) (Mapping t2) \<longleftrightarrow> entries t1 = entries t2"
       
   224   by (simp add: eq Mapping_def entries_lookup)
       
   225 
   136 hide (open) const tree_of lookup empty update delete
   226 hide (open) const tree_of lookup empty update delete
   137   entries bulkload map_entry map fold
   227   entries keys bulkload map_entry map fold
   138 
   228 
   139 end
   229 end