# HG changeset patch # User kuncar # Date 1350568353 -7200 # Node ID 70300f1b6835c4c2757c623ebdebbc5c35c0b9f0 # Parent e3f0a92de280ce0054be249d791b0a06954b4aca update RBT_Mapping, AList_Mapping and Mapping to use lifting/transfer diff -r e3f0a92de280 -r 70300f1b6835 src/HOL/Library/AList_Mapping.thy --- a/src/HOL/Library/AList_Mapping.thy Thu Oct 18 15:52:32 2012 +0200 +++ b/src/HOL/Library/AList_Mapping.thy Thu Oct 18 15:52:33 2012 +0200 @@ -8,34 +8,33 @@ imports AList Mapping begin -definition Mapping :: "('a \ 'b) list \ ('a, 'b) mapping" where - "Mapping xs = Mapping.Mapping (map_of xs)" +lift_definition Mapping :: "('a \ 'b) list \ ('a, 'b) mapping" is map_of . code_datatype Mapping lemma lookup_Mapping [simp, code]: "Mapping.lookup (Mapping xs) = map_of xs" - by (simp add: Mapping_def) + by transfer rule lemma keys_Mapping [simp, code]: - "Mapping.keys (Mapping xs) = set (map fst xs)" - by (simp add: keys_def dom_map_of_conv_image_fst) + "Mapping.keys (Mapping xs) = set (map fst xs)" + by transfer (simp add: dom_map_of_conv_image_fst) lemma empty_Mapping [code]: "Mapping.empty = Mapping []" - by (rule mapping_eqI) simp + by transfer simp lemma is_empty_Mapping [code]: "Mapping.is_empty (Mapping xs) \ List.null xs" - by (cases xs) (simp_all add: is_empty_def null_def) + by (case_tac xs) (simp_all add: is_empty_def null_def) lemma update_Mapping [code]: "Mapping.update k v (Mapping xs) = Mapping (AList.update k v xs)" - by (rule mapping_eqI) (simp add: update_conv') + by transfer (simp add: update_conv') lemma delete_Mapping [code]: "Mapping.delete k (Mapping xs) = Mapping (AList.delete k xs)" - by (rule mapping_eqI) (simp add: delete_conv') + by transfer (simp add: delete_conv') lemma ordered_keys_Mapping [code]: "Mapping.ordered_keys (Mapping xs) = sort (remdups (map fst xs))" @@ -47,11 +46,11 @@ lemma tabulate_Mapping [code]: "Mapping.tabulate ks f = Mapping (map (\k. (k, f k)) ks)" - by (rule mapping_eqI) (simp add: map_of_map_restrict) + by transfer (simp add: map_of_map_restrict) lemma bulkload_Mapping [code]: "Mapping.bulkload vs = Mapping (map (\n. (n, vs ! n)) [0.. @@ -60,9 +59,8 @@ proof - have aux: "\a b xs. (a, b) \ set xs \ a \ fst ` set xs" by (auto simp add: image_def intro!: bexI) - show ?thesis - by (auto intro!: map_of_eqI simp add: Let_def equal Mapping_def) - (auto dest!: map_of_eq_dom intro: aux) + show ?thesis apply transfer + by (auto intro!: map_of_eqI) (auto dest!: map_of_eq_dom intro: aux) qed lemma [code nbe]: diff -r e3f0a92de280 -r 70300f1b6835 src/HOL/Library/Mapping.thy --- a/src/HOL/Library/Mapping.thy Thu Oct 18 15:52:32 2012 +0200 +++ b/src/HOL/Library/Mapping.thy Thu Oct 18 15:52:33 2012 +0200 @@ -1,64 +1,46 @@ -(* Author: Florian Haftmann, TU Muenchen *) +(* Title: HOL/Library/Mapping.thy + Author: Florian Haftmann and Ondrej Kuncar +*) header {* An abstract view on maps for code generation. *} theory Mapping -imports Main +imports Main "~~/src/HOL/Library/Quotient_Option" begin subsection {* Type definition and primitive operations *} typedef ('a, 'b) mapping = "UNIV :: ('a \ 'b) set" - morphisms lookup Mapping .. + morphisms rep Mapping .. -lemma lookup_Mapping [simp]: - "lookup (Mapping f) = f" - by (rule Mapping_inverse) rule +setup_lifting(no_code) type_definition_mapping -lemma Mapping_lookup [simp]: - "Mapping (lookup m) = m" - by (fact lookup_inverse) +lift_definition empty :: "('a, 'b) mapping" is "(\_. None)" . -lemma Mapping_inject [simp]: - "Mapping f = Mapping g \ f = g" - by (simp add: Mapping_inject) +lift_definition lookup :: "('a, 'b) mapping \ 'a \ 'b option" is "\m k. m k" . + +lift_definition update :: "'a \ 'b \ ('a, 'b) mapping \ ('a, 'b) mapping" is "\k v m. m(k \ v)" . -lemma mapping_eq_iff: - "m = n \ lookup m = lookup n" - by (simp add: lookup_inject) +lift_definition delete :: "'a \ ('a, 'b) mapping \ ('a, 'b) mapping" is "\k m. m(k := None)" . -lemma mapping_eqI: - "lookup m = lookup n \ m = n" - by (simp add: mapping_eq_iff) +lift_definition keys :: "('a, 'b) mapping \ 'a set" is dom . -definition empty :: "('a, 'b) mapping" where - "empty = Mapping (\_. None)" +lift_definition tabulate :: "'a list \ ('a \ 'b) \ ('a, 'b) mapping" is + "\ks f. (map_of (List.map (\k. (k, f k)) ks))" . -definition update :: "'a \ 'b \ ('a, 'b) mapping \ ('a, 'b) mapping" where - "update k v m = Mapping ((lookup m)(k \ v))" +lift_definition bulkload :: "'a list \ (nat, 'a) mapping" is + "\xs k. if k < length xs then Some (xs ! k) else None" . -definition delete :: "'a \ ('a, 'b) mapping \ ('a, 'b) mapping" where - "delete k m = Mapping ((lookup m)(k := None))" - +lift_definition map :: "('c \ 'a) \ ('b \ 'd) \ ('a, 'b) mapping \ ('c, 'd) mapping" is + "\f g m. (Option.map g \ m \ f)" . subsection {* Functorial structure *} -definition map :: "('c \ 'a) \ ('b \ 'd) \ ('a, 'b) mapping \ ('c, 'd) mapping" where - "map f g m = Mapping (Option.map g \ lookup m \ f)" - -lemma lookup_map [simp]: - "lookup (map f g m) = Option.map g \ lookup m \ f" - by (simp add: map_def) - enriched_type map: map - by (simp_all add: mapping_eq_iff fun_eq_iff Option.map.compositionality Option.map.id) - + by (transfer, auto simp add: fun_eq_iff Option.map.compositionality Option.map.id)+ subsection {* Derived operations *} -definition keys :: "('a, 'b) mapping \ 'a set" where - "keys m = dom (lookup m)" - definition ordered_keys :: "('a\linorder, 'b) mapping \ 'a list" where "ordered_keys m = (if finite (keys m) then sorted_list_of_set (keys m) else [])" @@ -74,122 +56,94 @@ definition default :: "'a \ 'b \ ('a, 'b) mapping \ ('a, 'b) mapping" where "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 - | Some v \ update k (f v) m)" +lift_definition map_entry :: "'a \ ('b \ 'b) \ ('a, 'b) mapping \ ('a, 'b) mapping" is + "\k f m. (case m k of None \ m + | Some v \ m (k \ (f v)))" . + +lemma map_entry_code [code]: "map_entry k f m = (case lookup m k of None \ m + | Some v \ update k (f v) m)" by transfer rule definition map_default :: "'a \ 'b \ ('b \ 'b) \ ('a, 'b) mapping \ ('a, 'b) mapping" where "map_default k v f m = map_entry k f (default k v m)" -definition tabulate :: "'a list \ ('a \ 'b) \ ('a, 'b) mapping" where - "tabulate ks f = Mapping (map_of (List.map (\k. (k, f k)) ks))" - -definition bulkload :: "'a list \ (nat, 'a) mapping" where - "bulkload xs = Mapping (\k. if k < length xs then Some (xs ! k) else None)" - - subsection {* Properties *} -lemma keys_is_none_lookup [code_unfold]: +lemma keys_is_none_rep [code_unfold]: "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) - -lemma lookup_update [simp]: - "lookup (update k v m) = (lookup m) (k \ v)" - by (simp add: update_def) + by transfer (auto simp add: is_none_def) -lemma lookup_delete [simp]: - "lookup (delete k m) = (lookup m) (k := None)" - by (simp add: delete_def) - -lemma lookup_map_entry [simp]: - "lookup (map_entry k f m) = (lookup m) (k := Option.map f (lookup m k))" - by (cases "lookup m k") (simp_all add: map_entry_def fun_eq_iff) - -lemma lookup_tabulate [simp]: - "lookup (tabulate ks f) = (Some o f) |` set ks" - by (induct ks) (auto simp add: tabulate_def restrict_map_def fun_eq_iff) - -lemma lookup_bulkload [simp]: - "lookup (bulkload xs) = (\k. if k < length xs then Some (xs ! k) else None)" - by (simp add: bulkload_def) +lemma tabulate_alt_def: + "map_of (List.map (\k. (k, f k)) ks) = (Some o f) |` set ks" + by (induct ks) (auto simp add: tabulate_def restrict_map_def) lemma update_update: "update k v (update k w m) = update k v m" "k \ l \ update k v (update l w m) = update l w (update k v m)" - by (rule mapping_eqI, simp add: fun_upd_twist)+ + by (transfer, simp add: fun_upd_twist)+ lemma update_delete [simp]: "update k v (delete k m) = update k v m" - by (rule mapping_eqI) simp + by transfer simp lemma delete_update: "delete k (update k v m) = delete k m" "k \ l \ delete k (update l v m) = update l v (delete k m)" - by (rule mapping_eqI, simp add: fun_upd_twist)+ + by (transfer, simp add: fun_upd_twist)+ lemma delete_empty [simp]: "delete k empty = empty" - by (rule mapping_eqI) simp + by transfer simp lemma replace_update: "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)+ + by (transfer, auto simp add: replace_def fun_upd_twist)+ lemma size_empty [simp]: "size empty = 0" - by (simp add: size_def keys_def) + unfolding size_def by transfer simp lemma size_update: "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) + unfolding size_def by transfer (auto simp add: insert_dom) lemma size_delete: "size (delete k m) = (if k \ keys m then size m - 1 else size m)" - by (simp add: size_def keys_def) + unfolding size_def by transfer simp lemma size_tabulate [simp]: "size (tabulate ks f) = length (remdups ks)" - by (simp add: size_def distinct_card [of "remdups ks", symmetric] comp_def keys_def) + unfolding size_def by transfer (auto simp add: tabulate_alt_def card_set comp_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]: +lemma is_empty_empty [simp]: "is_empty empty" - by (simp add: is_empty_empty empty_def) + unfolding is_empty_def by transfer simp lemma is_empty_update [simp]: "\ is_empty (update k v m)" - by (simp add: is_empty_empty update_def) + unfolding is_empty_def by transfer simp lemma is_empty_delete: "is_empty (delete k m) \ is_empty m \ keys m = {k}" - by (auto simp add: delete_def is_empty_def keys_def simp del: dom_eq_empty_conv) + unfolding is_empty_def by transfer (auto 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) + unfolding is_empty_def replace_def by transfer auto lemma is_empty_default [simp]: "\ is_empty (default k v m)" - by (auto simp add: default_def) (simp add: is_empty_def) + unfolding is_empty_def default_def by transfer auto 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) + unfolding is_empty_def + apply transfer by (case_tac "m k") auto lemma is_empty_map_default [simp]: "\ is_empty (map_default k v f m)" @@ -197,27 +151,27 @@ lemma keys_empty [simp]: "keys empty = {}" - by (simp add: keys_def) + by transfer simp lemma keys_update [simp]: "keys (update k v m) = insert k (keys m)" - by (simp add: keys_def) + by transfer simp lemma keys_delete [simp]: "keys (delete k m) = keys m - {k}" - by (simp add: keys_def) + by transfer simp lemma keys_replace [simp]: "keys (replace k v m) = keys m" - by (auto simp add: keys_def replace_def) + unfolding replace_def by transfer (simp add: insert_absorb) lemma keys_default [simp]: "keys (default k v m) = insert k (keys m)" - by (auto simp add: keys_def default_def) + unfolding default_def by transfer (simp add: insert_absorb) lemma keys_map_entry [simp]: "keys (map_entry k f m) = keys m" - by (auto simp add: keys_def) + apply transfer by (case_tac "m k") auto lemma keys_map_default [simp]: "keys (map_default k v f m) = insert k (keys m)" @@ -225,7 +179,7 @@ lemma keys_tabulate [simp]: "keys (tabulate ks f) = set ks" - by (simp add: tabulate_def keys_def map_of_map_restrict o_def) + by transfer (simp add: map_of_map_restrict o_def) lemma keys_bulkload [simp]: "keys (bulkload xs) = {0.. lookup m = lookup n" +lift_definition equal_mapping :: "('a, 'b) mapping \ ('a, 'b) mapping \ bool" is "op=" . instance proof -qed (simp add: equal_mapping_def mapping_eq_iff) +qed(transfer, rule) end -hide_const (open) empty is_empty lookup update delete ordered_keys keys size +hide_const (open) empty is_empty rep lookup update delete ordered_keys keys size replace default map_entry map_default tabulate bulkload map end \ No newline at end of file diff -r e3f0a92de280 -r 70300f1b6835 src/HOL/Library/RBT_Mapping.thy --- a/src/HOL/Library/RBT_Mapping.thy Thu Oct 18 15:52:32 2012 +0200 +++ b/src/HOL/Library/RBT_Mapping.thy Thu Oct 18 15:52:33 2012 +0200 @@ -1,4 +1,6 @@ -(* Author: Florian Haftmann, TU Muenchen *) +(* Title: HOL/Library/RBT_Mapping.thy + Author: Florian Haftmann and Ondrej Kuncar +*) header {* Implementation of mappings with Red-Black Trees *} @@ -9,62 +11,69 @@ subsection {* Implementation of mappings *} -definition Mapping :: "('a\linorder, 'b) rbt \ ('a, 'b) mapping" where - "Mapping t = Mapping.Mapping (lookup t)" +lift_definition Mapping :: "('a\linorder, 'b) rbt \ ('a, 'b) mapping" is lookup . code_datatype Mapping lemma lookup_Mapping [simp, code]: "Mapping.lookup (Mapping t) = lookup t" - by (simp add: Mapping_def) + by (transfer fixing: t) rule -lemma empty_Mapping [code]: - "Mapping.empty = Mapping empty" - by (rule mapping_eqI) simp +lemma empty_Mapping [code]: "Mapping.empty = Mapping empty" +proof - + note RBT.empty.transfer[transfer_rule del] + show ?thesis by transfer simp +qed lemma is_empty_Mapping [code]: "Mapping.is_empty (Mapping t) \ is_empty t" - by (simp add: rbt_eq_iff Mapping.is_empty_empty Mapping_def) + unfolding is_empty_def by (transfer fixing: t) simp lemma insert_Mapping [code]: "Mapping.update k v (Mapping t) = Mapping (insert k v t)" - by (rule mapping_eqI) simp + by (transfer fixing: t) simp lemma delete_Mapping [code]: "Mapping.delete k (Mapping t) = Mapping (delete k t)" - by (rule mapping_eqI) simp + by (transfer fixing: t) simp lemma map_entry_Mapping [code]: "Mapping.map_entry k f (Mapping t) = Mapping (map_entry k f t)" - by (rule mapping_eqI) simp + apply (transfer fixing: t) by (case_tac "lookup t k") auto lemma keys_Mapping [code]: "Mapping.keys (Mapping t) = set (keys t)" - by (simp add: RBT.keys_def Mapping_def Mapping.keys_def lookup_def rbt_lookup_keys) +by (transfer fixing: t) (simp add: lookup_keys) lemma ordered_keys_Mapping [code]: "Mapping.ordered_keys (Mapping t) = keys t" - by (rule sorted_distinct_set_unique) (simp_all add: ordered_keys_def keys_Mapping) +unfolding ordered_keys_def +by (transfer fixing: t) (auto simp add: lookup_keys intro: sorted_distinct_set_unique) lemma Mapping_size_card_keys: (*FIXME*) "Mapping.size m = card (Mapping.keys m)" - by (simp add: Mapping.size_def Mapping.keys_def) +unfolding size_def by transfer simp lemma size_Mapping [code]: "Mapping.size (Mapping t) = length (keys t)" - by (simp add: Mapping_size_card_keys keys_Mapping distinct_card) +unfolding size_def +by (transfer fixing: t) (simp add: lookup_keys distinct_card) -lemma tabulate_Mapping [code]: - "Mapping.tabulate ks f = Mapping (bulkload (List.map (\k. (k, f k)) ks))" - by (rule mapping_eqI) (simp add: map_of_map_restrict) - -lemma bulkload_Mapping [code]: - "Mapping.bulkload vs = Mapping (bulkload (List.map (\n. (n, vs ! n)) [0..k. (k, f k)) ks))" + by transfer (simp add: map_of_map_restrict) + + lemma bulkload_Mapping [code]: + "Mapping.bulkload vs = Mapping (bulkload (List.map (\n. (n, vs ! n)) [0.. entries t1 = entries t2" - by (simp add: equal Mapping_def entries_lookup) +by (transfer fixing: t1 t2) (simp add: entries_lookup) lemma [code nbe]: "HOL.equal (x :: (_, _) mapping) x \ True" diff -r e3f0a92de280 -r 70300f1b6835 src/HOL/ex/Execute_Choice.thy --- a/src/HOL/ex/Execute_Choice.thy Thu Oct 18 15:52:32 2012 +0200 +++ b/src/HOL/ex/Execute_Choice.thy Thu Oct 18 15:52:33 2012 +0200 @@ -26,7 +26,7 @@ case True then show ?thesis by (simp add: is_empty_def keys_def valuesum_def) next case False - then have l: "\l. l \ dom (Mapping.lookup m)" by (auto simp add: is_empty_def keys_def) + then have l: "\l. l \ dom (Mapping.lookup m)" unfolding is_empty_def by transfer auto then have "(let l = SOME l. l \ dom (Mapping.lookup m) in the (Mapping.lookup m l) + (\k \ dom (Mapping.lookup m) - {l}. the (Mapping.lookup m k))) = (\k \ dom (Mapping.lookup m). the (Mapping.lookup m k))" @@ -41,7 +41,7 @@ (\k \ dom (Mapping.lookup m). the (Mapping.lookup m k))" by simp qed - then show ?thesis by (simp add: keys_def valuesum_def is_empty_def) + then show ?thesis unfolding is_empty_def valuesum_def by transfer simp qed text {* @@ -54,7 +54,7 @@ "finite (Mapping.keys M) \ x \ Mapping.keys M \ y \ Mapping.keys M \ the (Mapping.lookup M x) + valuesum (Mapping.delete x M) = the (Mapping.lookup M y) + valuesum (Mapping.delete y M)" - by (simp add: valuesum_def keys_def setsum_diff) + unfolding valuesum_def by transfer (simp add: setsum_diff) text {* Given @{text valuesum_rec} as initial description, we stepwise refine it to something executable;