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> |