# HG changeset patch # User haftmann # Date 1274448157 -7200 # Node ID 80dd92673fcad86eb1fa0a4c3da8bf39b1917e41 # Parent d3ad914e3e029ba5a5cbaecd564ababb14a5f9b5 more lemmas about mappings, in particular keys diff -r d3ad914e3e02 -r 80dd92673fca src/HOL/Library/Mapping.thy --- a/src/HOL/Library/Mapping.thy Fri May 21 15:22:36 2010 +0200 +++ b/src/HOL/Library/Mapping.thy Fri May 21 15:22:37 2010 +0200 @@ -6,6 +6,30 @@ imports Main begin +lemma remove1_idem: (*FIXME move to List.thy*) + assumes "x \ set xs" + shows "remove1 x xs = xs" + using assms by (induct xs) simp_all + +lemma remove1_insort [simp]: + "remove1 x (insort x xs) = xs" + by (induct xs) simp_all + +lemma sorted_list_of_set_remove: + assumes "finite A" + shows "sorted_list_of_set (A - {x}) = remove1 x (sorted_list_of_set A)" +proof (cases "x \ A") + case False with assms have "x \ set (sorted_list_of_set A)" by simp + with False show ?thesis by (simp add: remove1_idem) +next + case True then obtain B where A: "A = insert x B" by (rule Set.set_insert) + with assms show ?thesis by simp +qed + +lemma sorted_list_of_set_range [simp]: + "sorted_list_of_set {m.. 'b" @@ -29,19 +53,19 @@ "keys m = dom (lookup m)" definition ordered_keys :: "('a\linorder, 'b) mapping \ 'a list" where - "ordered_keys m = sorted_list_of_set (keys m)" + "ordered_keys m = (if finite (keys m) then sorted_list_of_set (keys m) else [])" definition is_empty :: "('a, 'b) mapping \ bool" where - "is_empty m \ dom (lookup m) = {}" + "is_empty m \ keys m = {}" definition size :: "('a, 'b) mapping \ nat" where - "size m = (if finite (dom (lookup m)) then card (dom (lookup m)) else 0)" + "size m = (if finite (keys m) then card (keys m) else 0)" definition replace :: "'a \ 'b \ ('a, 'b) mapping \ ('a, 'b) mapping" where - "replace k v m = (if lookup m k = None then m else update k v m)" + "replace k v m = (if k \ keys m then update k v m else m)" definition default :: "'a \ 'b \ ('a, 'b) mapping \ ('a, 'b) mapping" where - "default k v m = (if lookup m k = None then update k v m else m)" + "default k v m = (if k \ keys m then m else update k v m)" definition map_entry :: "'a \ ('b \ 'b) \ ('a, 'b) mapping \ ('a, 'b) mapping" where "map_entry k f m = (case lookup m k of None \ m @@ -68,6 +92,10 @@ shows "m = n" using assms by simp +lemma keys_is_none_lookup [code_inline]: + "k \ keys m \ \ (Option.is_none (lookup m k))" + by (auto simp add: keys_def is_none_def) + lemma lookup_empty [simp]: "lookup empty = Map.empty" by (simp add: empty_def) @@ -111,42 +139,157 @@ by (rule mapping_eqI) simp lemma replace_update: - "k \ dom (lookup m) \ replace k v m = m" - "k \ dom (lookup m) \ replace k v m = update k v m" - by (rule mapping_eqI, auto simp add: replace_def fun_upd_twist)+ + "k \ keys m \ replace k v m = m" + "k \ keys m \ replace k v m = update k v m" + by (rule mapping_eqI) (auto simp add: replace_def fun_upd_twist)+ lemma size_empty [simp]: "size empty = 0" - by (simp add: size_def) + by (simp add: size_def keys_def) lemma size_update: - "finite (dom (lookup m)) \ size (update k v m) = - (if k \ dom (lookup m) then size m else Suc (size m))" - by (auto simp add: size_def insert_dom) + "finite (keys m) \ size (update k v m) = + (if k \ keys m then size m else Suc (size m))" + by (auto simp add: size_def insert_dom keys_def) lemma size_delete: - "size (delete k m) = (if k \ dom (lookup m) then size m - 1 else size m)" - by (simp add: size_def) + "size (delete k m) = (if k \ keys m then size m - 1 else size m)" + by (simp add: size_def keys_def) -lemma size_tabulate: +lemma size_tabulate [simp]: "size (tabulate ks f) = length (remdups ks)" - by (simp add: size_def distinct_card [of "remdups ks", symmetric] comp_def) + by (simp add: size_def distinct_card [of "remdups ks", symmetric] comp_def keys_def) lemma bulkload_tabulate: "bulkload xs = tabulate [0.. m = Mapping Map.empty" + by (cases m) (simp add: is_empty_def keys_def) + +lemma is_empty_empty' [simp]: + "is_empty empty" + by (simp add: is_empty_empty empty_def) + +lemma is_empty_update [simp]: + "\ is_empty (update k v m)" + by (cases m) (simp add: is_empty_empty) + +lemma is_empty_delete: + "is_empty (delete k m) \ is_empty m \ keys m = {k}" + by (cases m) (auto simp add: is_empty_empty keys_def dom_eq_empty_conv [symmetric] simp del: dom_eq_empty_conv) + +lemma is_empty_replace [simp]: + "is_empty (replace k v m) \ is_empty m" + by (auto simp add: replace_def) (simp add: is_empty_def) + +lemma is_empty_default [simp]: + "\ is_empty (default k v m)" + by (auto simp add: default_def) (simp add: is_empty_def) + +lemma is_empty_map_entry [simp]: + "is_empty (map_entry k f m) \ is_empty m" + by (cases "lookup m k") + (auto simp add: map_entry_def, simp add: is_empty_empty) + +lemma is_empty_map_default [simp]: + "\ is_empty (map_default k v f m)" + by (simp add: map_default_def) + +lemma keys_empty [simp]: + "keys empty = {}" + by (simp add: keys_def) + +lemma keys_update [simp]: + "keys (update k v m) = insert k (keys m)" + by (simp add: keys_def) + +lemma keys_delete [simp]: + "keys (delete k m) = keys m - {k}" + by (simp add: keys_def) + +lemma keys_replace [simp]: + "keys (replace k v m) = keys m" + by (auto simp add: keys_def replace_def) + +lemma keys_default [simp]: + "keys (default k v m) = insert k (keys m)" + by (auto simp add: keys_def default_def) + +lemma keys_map_entry [simp]: + "keys (map_entry k f m) = keys m" + by (auto simp add: keys_def) + +lemma keys_map_default [simp]: + "keys (map_default k v f m) = insert k (keys m)" + by (simp add: map_default_def) + +lemma keys_tabulate [simp]: "keys (tabulate ks f) = set ks" by (simp add: tabulate_def keys_def map_of_map_restrict o_def) -lemma keys_bulkload: +lemma keys_bulkload [simp]: "keys (bulkload xs) = {0.. m = Mapping Map.empty" - by (cases m) (simp add: is_empty_def) +lemma distinct_ordered_keys [simp]: + "distinct (ordered_keys m)" + by (simp add: ordered_keys_def) + +lemma ordered_keys_infinite [simp]: + "\ finite (keys m) \ ordered_keys m = []" + by (simp add: ordered_keys_def) + +lemma ordered_keys_empty [simp]: + "ordered_keys empty = []" + by (simp add: ordered_keys_def) + +lemma ordered_keys_update [simp]: + "k \ keys m \ ordered_keys (update k v m) = ordered_keys m" + "finite (keys m) \ k \ keys m \ ordered_keys (update k v m) = insort k (ordered_keys m)" + by (simp_all add: ordered_keys_def) (auto simp only: sorted_list_of_set_insert [symmetric] insert_absorb) + +lemma ordered_keys_delete [simp]: + "ordered_keys (delete k m) = remove1 k (ordered_keys m)" +proof (cases "finite (keys m)") + case False then show ?thesis by simp +next + case True note fin = True + show ?thesis + proof (cases "k \ keys m") + case False with fin have "k \ set (sorted_list_of_set (keys m))" by simp + with False show ?thesis by (simp add: ordered_keys_def remove1_idem) + next + case True with fin show ?thesis by (simp add: ordered_keys_def sorted_list_of_set_remove) + qed +qed + +lemma ordered_keys_replace [simp]: + "ordered_keys (replace k v m) = ordered_keys m" + by (simp add: replace_def) + +lemma ordered_keys_default [simp]: + "k \ keys m \ ordered_keys (default k v m) = ordered_keys m" + "finite (keys m) \ k \ keys m \ ordered_keys (default k v m) = insort k (ordered_keys m)" + by (simp_all add: default_def) + +lemma ordered_keys_map_entry [simp]: + "ordered_keys (map_entry k f m) = ordered_keys m" + by (simp add: ordered_keys_def) + +lemma ordered_keys_map_default [simp]: + "k \ keys m \ ordered_keys (map_default k v f m) = ordered_keys m" + "finite (keys m) \ k \ keys m \ ordered_keys (map_default k v f m) = insort k (ordered_keys m)" + by (simp_all add: map_default_def) + +lemma ordered_keys_tabulate [simp]: + "ordered_keys (tabulate ks f) = sort (remdups ks)" + by (simp add: ordered_keys_def sorted_list_of_set_sort_remdups) + +lemma ordered_keys_bulkload [simp]: + "ordered_keys (bulkload ks) = [0..