# HG changeset patch # User kuncar # Date 1362745318 -3600 # Node ID 6dd83e007f56fc3fffa74433d72a62a22cc8fa1e # Parent 502f6a53519b9a41b0ea7147393ffb8eaf36e52d convert mappings to parametric lifting diff -r 502f6a53519b -r 6dd83e007f56 src/HOL/Library/Mapping.thy --- a/src/HOL/Library/Mapping.thy Fri Mar 08 13:21:55 2013 +0100 +++ b/src/HOL/Library/Mapping.thy Fri Mar 08 13:21:58 2013 +0100 @@ -8,6 +8,70 @@ imports Main Quotient_Option Quotient_List begin +subsection {* Parametricity transfer rules *} + +lemma empty_transfer: "(A ===> option_rel B) Map.empty Map.empty" by transfer_prover + +lemma lookup_transfer: "((A ===> B) ===> A ===> B) (\m k. m k) (\m k. m k)" by transfer_prover + +lemma update_transfer: + assumes [transfer_rule]: "bi_unique A" + shows "(A ===> B ===> (A ===> option_rel B) ===> A ===> option_rel B) + (\k v m. m(k \ v)) (\k v m. m(k \ v))" +by transfer_prover + +lemma delete_transfer: + assumes [transfer_rule]: "bi_unique A" + shows "(A ===> (A ===> option_rel B) ===> A ===> option_rel B) + (\k m. m(k := None)) (\k m. m(k := None))" +by transfer_prover + +definition equal_None :: "'a option \ bool" where "equal_None x \ x = None" + +lemma [transfer_rule]: "(option_rel A ===> op=) equal_None equal_None" +unfolding fun_rel_def option_rel_unfold equal_None_def by (auto split: option.split) + +lemma dom_transfer: + assumes [transfer_rule]: "bi_total A" + shows "((A ===> option_rel B) ===> set_rel A) dom dom" +unfolding dom_def[abs_def] equal_None_def[symmetric] +by transfer_prover + +lemma map_of_transfer [transfer_rule]: + assumes [transfer_rule]: "bi_unique R1" + shows "(list_all2 (prod_rel R1 R2) ===> R1 ===> option_rel R2) map_of map_of" +unfolding map_of_def by transfer_prover + +lemma tabulate_transfer: + assumes [transfer_rule]: "bi_unique A" + shows "(list_all2 A ===> (A ===> B) ===> A ===> option_rel B) + (\ks f. (map_of (List.map (\k. (k, f k)) ks))) (\ks f. (map_of (List.map (\k. (k, f k)) ks)))" +by transfer_prover + +lemma bulkload_transfer: + "(list_all2 A ===> op= ===> option_rel A) + (\xs k. if k < length xs then Some (xs ! k) else None) (\xs k. if k < length xs then Some (xs ! k) else None)" +unfolding fun_rel_def +apply clarsimp +apply (erule list_all2_induct) + apply simp +apply (case_tac xa) + apply simp +by (auto dest: list_all2_lengthD list_all2_nthD) + +lemma map_transfer: + "((A ===> B) ===> (C ===> D) ===> (B ===> option_rel C) ===> A ===> option_rel D) + (\f g m. (Option.map g \ m \ f)) (\f g m. (Option.map g \ m \ f))" +by transfer_prover + +lemma map_entry_transfer: + assumes [transfer_rule]: "bi_unique A" + shows "(A ===> (B ===> B) ===> (A ===> option_rel B) ===> A ===> option_rel B) + (\k f m. (case m k of None \ m + | Some v \ m (k \ (f v)))) (\k f m. (case m k of None \ m + | Some v \ m (k \ (f v))))" +by transfer_prover + subsection {* Type definition and primitive operations *} typedef ('a, 'b) mapping = "UNIV :: ('a \ 'b) set" @@ -15,24 +79,27 @@ setup_lifting(no_code) type_definition_mapping -lift_definition empty :: "('a, 'b) mapping" is "(\_. None)" . +lift_definition empty :: "('a, 'b) mapping" is Map.empty parametric empty_transfer . -lift_definition lookup :: "('a, 'b) mapping \ 'a \ 'b option" is "\m k. m k" . +lift_definition lookup :: "('a, 'b) mapping \ 'a \ 'b option" is "\m k. m k" + parametric lookup_transfer . -lift_definition update :: "'a \ 'b \ ('a, 'b) mapping \ ('a, 'b) mapping" is "\k v m. m(k \ v)" . +lift_definition update :: "'a \ 'b \ ('a, 'b) mapping \ ('a, 'b) mapping" is "\k v m. m(k \ v)" + parametric update_transfer . -lift_definition delete :: "'a \ ('a, 'b) mapping \ ('a, 'b) mapping" is "\k m. m(k := None)" . +lift_definition delete :: "'a \ ('a, 'b) mapping \ ('a, 'b) mapping" is "\k m. m(k := None)" + parametric delete_transfer . -lift_definition keys :: "('a, 'b) mapping \ 'a set" is dom . +lift_definition keys :: "('a, 'b) mapping \ 'a set" is dom parametric dom_transfer . lift_definition tabulate :: "'a list \ ('a \ 'b) \ ('a, 'b) mapping" is - "\ks f. (map_of (List.map (\k. (k, f k)) ks))" . + "\ks f. (map_of (List.map (\k. (k, f k)) ks))" parametric tabulate_transfer . lift_definition bulkload :: "'a list \ (nat, 'a) mapping" is - "\xs k. if k < length xs then Some (xs ! k) else None" . + "\xs k. if k < length xs then Some (xs ! k) else None" parametric bulkload_transfer . lift_definition map :: "('c \ 'a) \ ('b \ 'd) \ ('a, 'b) mapping \ ('c, 'd) mapping" is - "\f g m. (Option.map g \ m \ f)" . + "\f g m. (Option.map g \ m \ f)" parametric map_transfer . subsection {* Functorial structure *} @@ -60,7 +127,7 @@ 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)))" . + | Some v \ m (k \ (f v)))" parametric map_entry_transfer . lemma map_entry_code [code]: "map_entry k f m = (case lookup m k of None \ m | Some v \ update k (f v) m)" @@ -69,6 +136,13 @@ 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)" +lift_definition assoc_list_to_mapping :: "('k \ 'v) list \ ('k, 'v) mapping" +is map_of parametric map_of_transfer . + +lemma assoc_list_to_mapping_code [code]: + "assoc_list_to_mapping xs = foldr (\(k, v) m. update k v m) xs empty" +by transfer(simp add: map_add_map_of_foldr[symmetric]) + instantiation mapping :: (type, type) equal begin @@ -81,8 +155,10 @@ end lemma [transfer_rule]: - "fun_rel (pcr_mapping op= op=) (fun_rel (pcr_mapping op= op=) HOL.iff) HOL.eq HOL.equal" - by (unfold equal) transfer_prover + assumes [transfer_rule]: "bi_total A" + assumes [transfer_rule]: "bi_unique B" + shows "fun_rel (pcr_mapping A B) (fun_rel (pcr_mapping A B) HOL.iff) HOL.eq HOL.equal" +by (unfold equal) transfer_prover subsection {* Properties *} @@ -281,3 +357,4 @@ end + diff -r 502f6a53519b -r 6dd83e007f56 src/HOL/Library/RBT_Mapping.thy --- a/src/HOL/Library/RBT_Mapping.thy Fri Mar 08 13:21:55 2013 +0100 +++ b/src/HOL/Library/RBT_Mapping.thy Fri Mar 08 13:21:58 2013 +0100 @@ -39,7 +39,7 @@ lemma map_entry_Mapping [code]: "Mapping.map_entry k f (Mapping t) = Mapping (map_entry k f t)" - apply (transfer fixing: t) by (case_tac "lookup t k") auto +by (transfer fixing: t, case_tac "lookup t k") auto lemma keys_Mapping [code]: "Mapping.keys (Mapping t) = set (keys t)"