src/HOL/Library/Finite_Map.thy
changeset 68810 db97c1ed115e
parent 68757 e7e3776385ba
child 68909 34e777447ed5
equal deleted inserted replaced
68802:3974935e0252 68810:db97c1ed115e
   132   hence "x k = y k" for k
   132   hence "x k = y k" for k
   133     by (metis not_None_eq)
   133     by (metis not_None_eq)
   134   thus "x = y" ..
   134   thus "x = y" ..
   135 qed
   135 qed
   136 
   136 
       
   137 lemma dom_comp: "dom (m \<circ>\<^sub>m n) \<subseteq> dom n"
       
   138 unfolding map_comp_def dom_def
       
   139 by (auto split: option.splits)
       
   140 
       
   141 lemma dom_comp_finite: "finite (dom n) \<Longrightarrow> finite (dom (map_comp m n))"
       
   142 by (metis finite_subset dom_comp)
       
   143 
       
   144 parametric_constant map_comp_transfer[transfer_rule]: map_comp_def
       
   145 
   137 end
   146 end
   138 
   147 
   139 
   148 
   140 subsection \<open>Abstract characterisation\<close>
   149 subsection \<open>Abstract characterisation\<close>
   141 
   150 
   648   assumes "fmrel_on_fset S P m n" "P v\<^sub>1 v\<^sub>2"
   657   assumes "fmrel_on_fset S P m n" "P v\<^sub>1 v\<^sub>2"
   649   shows "fmrel_on_fset (finsert k S) P (fmupd k v\<^sub>1 m) (fmupd k v\<^sub>2 n)"
   658   shows "fmrel_on_fset (finsert k S) P (fmupd k v\<^sub>1 m) (fmupd k v\<^sub>2 n)"
   650 using assms
   659 using assms
   651 unfolding fmrel_on_fset_alt_def
   660 unfolding fmrel_on_fset_alt_def
   652 by auto
   661 by auto
       
   662 
       
   663 lift_definition fmimage :: "('a, 'b) fmap \<Rightarrow> 'a fset \<Rightarrow> 'b fset" is "\<lambda>m S. {b|a b. m a = Some b \<and> a \<in> S}"
       
   664 subgoal for m S
       
   665   apply (rule finite_subset[where B = "ran m"])
       
   666   apply (auto simp: ran_def)[]
       
   667   by (rule finite_ran)
       
   668 done
       
   669 
       
   670 lemma fmimage_alt_def: "fmimage m S = fmran (fmrestrict_fset S m)"
       
   671 by transfer' (auto simp: ran_def map_restrict_set_def map_filter_def)
       
   672 
       
   673 lemma fmimage_empty[simp]: "fmimage m fempty = fempty"
       
   674 by transfer' auto
       
   675 
       
   676 lemma fmimage_subset_ran[simp]: "fmimage m S |\<subseteq>| fmran m"
       
   677 by transfer' (auto simp: ran_def)
       
   678 
       
   679 lemma fmimage_dom[simp]: "fmimage m (fmdom m) = fmran m"
       
   680 by transfer' (auto simp: ran_def)
       
   681 
       
   682 lemma fmimage_inter: "fmimage m (A |\<inter>| B) |\<subseteq>| fmimage m A |\<inter>| fmimage m B"
       
   683 by transfer' auto
       
   684 
       
   685 lemma fimage_inter_dom[simp]:
       
   686   "fmimage m (fmdom m |\<inter>| A) = fmimage m A"
       
   687   "fmimage m (A |\<inter>| fmdom m) = fmimage m A"
       
   688 by (transfer'; auto)+
       
   689 
       
   690 lemma fmimage_union[simp]: "fmimage m (A |\<union>| B) = fmimage m A |\<union>| fmimage m B"
       
   691 by transfer' auto
       
   692 
       
   693 lemma fmimage_Union[simp]: "fmimage m (ffUnion A) = ffUnion (fmimage m |`| A)"
       
   694 by transfer' auto
       
   695 
       
   696 lemma fmimage_filter[simp]: "fmimage (fmfilter P m) A = fmimage m (ffilter P A)"
       
   697 by transfer' (auto simp: map_filter_def)
       
   698 
       
   699 lemma fmimage_drop[simp]: "fmimage (fmdrop a m) A = fmimage m (A - {|a|})"
       
   700 by transfer' (auto simp: map_filter_def map_drop_def)
       
   701 
       
   702 lemma fmimage_drop_fset[simp]: "fmimage (fmdrop_fset B m) A = fmimage m (A - B)"
       
   703 by transfer' (auto simp: map_filter_def map_drop_set_def)
       
   704 
       
   705 lemma fmimage_restrict_fset[simp]: "fmimage (fmrestrict_fset B m) A = fmimage m (A |\<inter>| B)"
       
   706 by transfer' (auto simp: map_filter_def map_restrict_set_def)
       
   707 
       
   708 lemma fmfilter_ran[simp]: "fmran (fmfilter P m) = fmimage m (ffilter P (fmdom m))"
       
   709 by transfer' (auto simp: ran_def map_filter_def)
       
   710 
       
   711 lemma fmran_drop[simp]: "fmran (fmdrop a m) = fmimage m (fmdom m - {|a|})"
       
   712 by transfer' (auto simp: ran_def map_drop_def map_filter_def)
       
   713 
       
   714 lemma fmran_drop_fset[simp]: "fmran (fmdrop_fset A m) = fmimage m (fmdom m - A)"
       
   715 by transfer' (auto simp: ran_def map_drop_set_def map_filter_def)
       
   716 
       
   717 lemma fmran_restrict_fset: "fmran (fmrestrict_fset A m) = fmimage m (fmdom m |\<inter>| A)"
       
   718 by transfer' (auto simp: ran_def map_restrict_set_def map_filter_def)
       
   719 
       
   720 lemma fmlookup_image_iff: "y |\<in>| fmimage m A \<longleftrightarrow> (\<exists>x. fmlookup m x = Some y \<and> x |\<in>| A)"
       
   721 by transfer' (auto simp: ran_def)
       
   722 
       
   723 lemma fmimageI: "fmlookup m x = Some y \<Longrightarrow> x |\<in>| A \<Longrightarrow> y |\<in>| fmimage m A"
       
   724 by (auto simp: fmlookup_image_iff)
       
   725 
       
   726 lemma fmimageE[elim]:
       
   727   assumes "y |\<in>| fmimage m A"
       
   728   obtains x where "fmlookup m x = Some y" "x |\<in>| A"
       
   729 using assms by (auto simp: fmlookup_image_iff)
       
   730 
       
   731 lift_definition fmcomp :: "('b, 'c) fmap \<Rightarrow> ('a, 'b) fmap \<Rightarrow> ('a, 'c) fmap" (infixl "\<circ>\<^sub>f" 55)
       
   732   is map_comp
       
   733   parametric map_comp_transfer
       
   734 by (rule dom_comp_finite)
       
   735 
       
   736 lemma fmlookup_comp[simp]: "fmlookup (m \<circ>\<^sub>f n) x = Option.bind (fmlookup n x) (fmlookup m)"
       
   737 by transfer' (auto simp: map_comp_def split: option.splits)
   653 
   738 
   654 end
   739 end
   655 
   740 
   656 
   741 
   657 subsection \<open>BNF setup\<close>
   742 subsection \<open>BNF setup\<close>
   961 "sorted_list_of_fmap m = map (\<lambda>k. (k, the (fmlookup m k))) (sorted_list_of_fset (fmdom m))"
  1046 "sorted_list_of_fmap m = map (\<lambda>k. (k, the (fmlookup m k))) (sorted_list_of_fset (fmdom m))"
   962 
  1047 
   963 lemma list_all_sorted_list[simp]: "list_all P (sorted_list_of_fmap m) = fmpred (curry P) m"
  1048 lemma list_all_sorted_list[simp]: "list_all P (sorted_list_of_fmap m) = fmpred (curry P) m"
   964 unfolding sorted_list_of_fmap_def curry_def list.pred_map
  1049 unfolding sorted_list_of_fmap_def curry_def list.pred_map
   965 apply (auto simp: list_all_iff)
  1050 apply (auto simp: list_all_iff)
   966 including fmap.lifting fset.lifting
  1051 including fset.lifting
   967 by (transfer; auto simp: dom_def map_pred_def split: option.splits)+
  1052 by (transfer; auto simp: dom_def map_pred_def split: option.splits)+
   968 
  1053 
   969 lemma map_of_sorted_list[simp]: "map_of (sorted_list_of_fmap m) = fmlookup m"
  1054 lemma map_of_sorted_list[simp]: "map_of (sorted_list_of_fmap m) = fmlookup m"
   970 unfolding sorted_list_of_fmap_def
  1055 unfolding sorted_list_of_fmap_def
   971 including fmap.lifting fset.lifting
  1056 including fset.lifting
   972 by transfer (simp add: map_of_map_keys)
  1057 by transfer (simp add: map_of_map_keys)
   973 
  1058 
   974 
  1059 
   975 subsection \<open>Lifting/transfer setup\<close>
  1060 subsection \<open>Lifting/transfer setup\<close>
   976 
  1061 
   997   "fmupd k v m \<noteq> fmempty"
  1082   "fmupd k v m \<noteq> fmempty"
   998 by (transfer'; auto simp: map_upd_def fun_eq_iff)+
  1083 by (transfer'; auto simp: map_upd_def fun_eq_iff)+
   999 
  1084 
  1000 lifting_update fmap.lifting
  1085 lifting_update fmap.lifting
  1001 
  1086 
  1002 lemma fmap_exhaust[case_names fmempty fmupd, cases type: fmap]:
  1087 lemma fmap_exhaust[cases type: fmap]:
  1003   assumes fmempty: "m = fmempty \<Longrightarrow> P"
  1088   obtains (fmempty) "m = fmempty"
  1004   assumes fmupd: "\<And>x y m'. m = fmupd x y m' \<Longrightarrow> x |\<notin>| fmdom m' \<Longrightarrow> P"
  1089         | (fmupd) x y m' where "m = fmupd x y m'" "x |\<notin>| fmdom m'"
  1005   shows "P"
  1090 using that including fmap.lifting fset.lifting
  1006 using assms including fmap.lifting fset.lifting
       
  1007 proof transfer
  1091 proof transfer
  1008   fix m P
  1092   fix m P
  1009   assume "finite (dom m)"
  1093   assume "finite (dom m)"
  1010   assume empty: P if "m = Map.empty"
  1094   assume empty: P if "m = Map.empty"
  1011   assume map_upd: P if "finite (dom m')" "m = map_upd x y m'" "x \<notin> dom m'" for x y m'
  1095   assume map_upd: P if "finite (dom m')" "m = map_upd x y m'" "x \<notin> dom m'" for x y m'
  1137 apply transfer
  1221 apply transfer
  1138 apply (subst map_of_map[symmetric])
  1222 apply (subst map_of_map[symmetric])
  1139 apply (auto simp: apsnd_def map_prod_def)
  1223 apply (auto simp: apsnd_def map_prod_def)
  1140 done
  1224 done
  1141 
  1225 
  1142 lemma fmmap_keys_of_list[code]: "fmmap_keys f (fmap_of_list m) = fmap_of_list (map (\<lambda>(a, b). (a, f a b)) m)"
  1226 lemma fmmap_keys_of_list[code]:
       
  1227   "fmmap_keys f (fmap_of_list m) = fmap_of_list (map (\<lambda>(a, b). (a, f a b)) m)"
  1143 apply transfer
  1228 apply transfer
  1144 subgoal for f m by (induction m) (auto simp: apsnd_def map_prod_def fun_eq_iff)
  1229 subgoal for f m by (induction m) (auto simp: apsnd_def map_prod_def fun_eq_iff)
  1145 done
  1230 done
       
  1231 
       
  1232 lemma fmimage_of_list[code]:
       
  1233   "fmimage (fmap_of_list m) A = fset_of_list (map snd (filter (\<lambda>(k, _). k |\<in>| A) (AList.clearjunk m)))"
       
  1234 apply (subst fmimage_alt_def)
       
  1235 apply (subst fmfilter_alt_defs)
       
  1236 apply (subst fmfilter_of_list)
       
  1237 apply (subst fmran_of_list)
       
  1238 apply transfer'
       
  1239 apply (subst AList.restrict_eq[symmetric])
       
  1240 apply (subst clearjunk_restrict)
       
  1241 apply (subst AList.restrict_eq)
       
  1242 by auto
       
  1243 
       
  1244 lemma fmcomp_list[code]:
       
  1245   "fmap_of_list m \<circ>\<^sub>f fmap_of_list n = fmap_of_list (AList.compose n m)"
       
  1246 by (rule fmap_ext) (simp add: fmlookup_of_list compose_conv map_comp_def split: option.splits)
  1146 
  1247 
  1147 end
  1248 end
  1148 
  1249 
  1149 
  1250 
  1150 subsection \<open>Instances\<close>
  1251 subsection \<open>Instances\<close>