81 |
81 |
82 subsection {* The finfun type *} |
82 subsection {* The finfun type *} |
83 |
83 |
84 definition "finfun = {f::'a\<Rightarrow>'b. \<exists>b. finite {a. f a \<noteq> b}}" |
84 definition "finfun = {f::'a\<Rightarrow>'b. \<exists>b. finite {a. f a \<noteq> b}}" |
85 |
85 |
86 typedef (open) ('a,'b) finfun ("(_ \<Rightarrow>\<^isub>f /_)" [22, 21] 21) = "finfun :: ('a => 'b) set" |
86 typedef (open) ('a,'b) finfun ("(_ =>f /_)" [22, 21] 21) = "finfun :: ('a => 'b) set" |
87 morphisms finfun_apply Abs_finfun |
87 morphisms finfun_apply Abs_finfun |
88 proof - |
88 proof - |
89 have "\<exists>f. finite {x. f x \<noteq> undefined}" |
89 have "\<exists>f. finite {x. f x \<noteq> undefined}" |
90 proof |
90 proof |
91 show "finite {x. (\<lambda>y. undefined) x \<noteq> undefined}" by auto |
91 show "finite {x. (\<lambda>y. undefined) x \<noteq> undefined}" by auto |
92 qed |
92 qed |
93 then show ?thesis unfolding finfun_def by auto |
93 then show ?thesis unfolding finfun_def by auto |
94 qed |
94 qed |
|
95 |
|
96 type_notation finfun ("(_ \<Rightarrow>f /_)" [22, 21] 21) |
95 |
97 |
96 setup_lifting type_definition_finfun |
98 setup_lifting type_definition_finfun |
97 |
99 |
98 lemma fun_upd_finfun: "y(a := b) \<in> finfun \<longleftrightarrow> y \<in> finfun" |
100 lemma fun_upd_finfun: "y(a := b) \<in> finfun \<longleftrightarrow> y \<in> finfun" |
99 proof - |
101 proof - |
218 using finite_UNIV |
220 using finite_UNIV |
219 by(simp add: Abs_finfun_inject_finite) |
221 by(simp add: Abs_finfun_inject_finite) |
220 |
222 |
221 lemma Abs_finfun_inj_finite: |
223 lemma Abs_finfun_inj_finite: |
222 assumes fin: "finite (UNIV :: 'a set)" |
224 assumes fin: "finite (UNIV :: 'a set)" |
223 shows "inj (Abs_finfun :: ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'b)" |
225 shows "inj (Abs_finfun :: ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow>f 'b)" |
224 proof(rule inj_onI) |
226 proof(rule inj_onI) |
225 fix x y :: "'a \<Rightarrow> 'b" |
227 fix x y :: "'a \<Rightarrow> 'b" |
226 assume "Abs_finfun x = Abs_finfun y" |
228 assume "Abs_finfun x = Abs_finfun y" |
227 moreover have "x \<in> finfun" "y \<in> finfun" unfolding finfun_def |
229 moreover have "x \<in> finfun" "y \<in> finfun" unfolding finfun_def |
228 by(auto intro: finite_subset[OF _ fin]) |
230 by(auto intro: finite_subset[OF _ fin]) |
272 moreover have "b \<notin> ran ?g" by(auto simp add: ran_def) |
274 moreover have "b \<notin> ran ?g" by(auto simp add: ran_def) |
273 ultimately show ?thesis by(rule that) |
275 ultimately show ?thesis by(rule that) |
274 qed |
276 qed |
275 |
277 |
276 |
278 |
277 subsection {* Kernel functions for type @{typ "'a \<Rightarrow>\<^isub>f 'b"} *} |
279 subsection {* Kernel functions for type @{typ "'a \<Rightarrow>f 'b"} *} |
278 |
280 |
279 lift_definition finfun_const :: "'b \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'b" ("\<lambda>\<^isup>f/ _" [0] 1) |
281 lift_definition finfun_const :: "'b \<Rightarrow> 'a \<Rightarrow>f 'b" ("\<lambda>\<^isup>f/ _" [0] 1) |
280 is "\<lambda> b x. b" by (rule const_finfun) |
282 is "\<lambda> b x. b" by (rule const_finfun) |
281 |
283 |
282 lift_definition finfun_update :: "'a \<Rightarrow>\<^isub>f 'b \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'b" ("_'(\<^sup>f/ _ := _')" [1000,0,0] 1000) is "fun_upd" by (simp add: fun_upd_finfun) |
284 lift_definition finfun_update :: "'a \<Rightarrow>f 'b \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow>f 'b" ("_'(\<^sup>f/ _ := _')" [1000,0,0] 1000) is "fun_upd" |
|
285 by (simp add: fun_upd_finfun) |
283 |
286 |
284 lemma finfun_update_twist: "a \<noteq> a' \<Longrightarrow> f(\<^sup>f a := b)(\<^sup>f a' := b') = f(\<^sup>f a' := b')(\<^sup>f a := b)" |
287 lemma finfun_update_twist: "a \<noteq> a' \<Longrightarrow> f(\<^sup>f a := b)(\<^sup>f a' := b') = f(\<^sup>f a' := b')(\<^sup>f a := b)" |
285 by transfer (simp add: fun_upd_twist) |
288 by transfer (simp add: fun_upd_twist) |
286 |
289 |
287 lemma finfun_update_twice [simp]: |
290 lemma finfun_update_twice [simp]: |
291 lemma finfun_update_const_same: "(\<lambda>\<^isup>f b)(\<^sup>f a := b) = (\<lambda>\<^isup>f b)" |
294 lemma finfun_update_const_same: "(\<lambda>\<^isup>f b)(\<^sup>f a := b) = (\<lambda>\<^isup>f b)" |
292 by transfer (simp add: fun_eq_iff) |
295 by transfer (simp add: fun_eq_iff) |
293 |
296 |
294 subsection {* Code generator setup *} |
297 subsection {* Code generator setup *} |
295 |
298 |
296 definition finfun_update_code :: "'a \<Rightarrow>\<^isub>f 'b \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'b" ("_'(\<^sup>fc/ _ := _')" [1000,0,0] 1000) |
299 definition finfun_update_code :: "'a \<Rightarrow>f 'b \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow>f 'b" ("_'(\<^sup>fc/ _ := _')" [1000,0,0] 1000) |
297 where [simp, code del]: "finfun_update_code = finfun_update" |
300 where [simp, code del]: "finfun_update_code = finfun_update" |
298 |
301 |
299 code_datatype finfun_const finfun_update_code |
302 code_datatype finfun_const finfun_update_code |
300 |
303 |
301 lemma finfun_update_const_code [code]: |
304 lemma finfun_update_const_code [code]: |
307 by(simp add: finfun_update_twist) |
310 by(simp add: finfun_update_twist) |
308 |
311 |
309 |
312 |
310 subsection {* Setup for quickcheck *} |
313 subsection {* Setup for quickcheck *} |
311 |
314 |
312 quickcheck_generator finfun constructors: finfun_update_code, "finfun_const :: 'b => 'a \<Rightarrow>\<^isub>f 'b" |
315 quickcheck_generator finfun constructors: finfun_update_code, "finfun_const :: 'b \<Rightarrow> 'a \<Rightarrow>f 'b" |
313 |
316 |
314 subsection {* @{text "finfun_update"} as instance of @{text "comp_fun_commute"} *} |
317 subsection {* @{text "finfun_update"} as instance of @{text "comp_fun_commute"} *} |
315 |
318 |
316 interpretation finfun_update: comp_fun_commute "\<lambda>a f. f(\<^sup>f a :: 'a := b')" |
319 interpretation finfun_update: comp_fun_commute "\<lambda>a f. f(\<^sup>f a :: 'a := b')" |
317 including finfun |
320 including finfun |
412 with False b' show ?thesis by(auto simp del: fun_upd_apply simp add: finfun_default_aux_infinite) |
415 with False b' show ?thesis by(auto simp del: fun_upd_apply simp add: finfun_default_aux_infinite) |
413 next |
416 next |
414 case True thus ?thesis by(simp add: finfun_default_aux_def) |
417 case True thus ?thesis by(simp add: finfun_default_aux_def) |
415 qed |
418 qed |
416 |
419 |
417 lift_definition finfun_default :: "'a \<Rightarrow>\<^isub>f 'b \<Rightarrow> 'b" |
420 lift_definition finfun_default :: "'a \<Rightarrow>f 'b \<Rightarrow> 'b" |
418 is "finfun_default_aux" .. |
421 is "finfun_default_aux" .. |
419 |
422 |
420 lemma finfun_apply_transfer [transfer_rule]: |
423 lemma finfun_apply_transfer [transfer_rule]: |
421 "(fun_rel cr_finfun (fun_rel op = op =)) (\<lambda>f. f) finfun_apply" |
424 "(fun_rel cr_finfun (fun_rel op = op =)) (\<lambda>f. f) finfun_apply" |
422 unfolding Rel_def fun_rel_def cr_finfun_def by simp |
425 unfolding Rel_def fun_rel_def cr_finfun_def by simp |
423 |
426 |
424 lemma finite_finfun_default: "finite {a. finfun_apply f a \<noteq> finfun_default f}" |
427 lemma finite_finfun_default: "finite {a. finfun_apply f a \<noteq> finfun_default f}" |
425 by transfer (erule finite_finfun_default_aux) |
428 by transfer (erule finite_finfun_default_aux) |
426 |
429 |
427 lemma finfun_default_const: "finfun_default ((\<lambda>\<^isup>f b) :: 'a \<Rightarrow>\<^isub>f 'b) = (if finite (UNIV :: 'a set) then undefined else b)" |
430 lemma finfun_default_const: "finfun_default ((\<lambda>\<^isup>f b) :: 'a \<Rightarrow>f 'b) = (if finite (UNIV :: 'a set) then undefined else b)" |
428 by(transfer)(auto simp add: finfun_default_aux_infinite finfun_default_aux_def) |
431 by(transfer)(auto simp add: finfun_default_aux_infinite finfun_default_aux_def) |
429 |
432 |
430 lemma finfun_default_update_const: |
433 lemma finfun_default_update_const: |
431 "finfun_default (f(\<^sup>f a := b)) = finfun_default f" |
434 "finfun_default (f(\<^sup>f a := b)) = finfun_default f" |
432 by transfer (simp add: finfun_default_aux_update_const) |
435 by transfer (simp add: finfun_default_aux_update_const) |
433 |
436 |
434 lemma finfun_default_const_code [code]: |
437 lemma finfun_default_const_code [code]: |
435 "finfun_default ((\<lambda>\<^isup>f c) :: ('a :: card_UNIV) \<Rightarrow>\<^isub>f 'b) = (if card_UNIV (TYPE('a)) = 0 then c else undefined)" |
438 "finfun_default ((\<lambda>\<^isup>f c) :: ('a :: card_UNIV) \<Rightarrow>f 'b) = (if card_UNIV (TYPE('a)) = 0 then c else undefined)" |
436 by(simp add: finfun_default_const card_UNIV_eq_0_infinite_UNIV) |
439 by(simp add: finfun_default_const card_UNIV_eq_0_infinite_UNIV) |
437 |
440 |
438 lemma finfun_default_update_code [code]: |
441 lemma finfun_default_update_code [code]: |
439 "finfun_default (finfun_update_code f a b) = finfun_default f" |
442 "finfun_default (finfun_update_code f a b) = finfun_default f" |
440 by(simp add: finfun_default_update_const) |
443 by(simp add: finfun_default_update_const) |
441 |
444 |
442 subsection {* Recursion combinator and well-formedness conditions *} |
445 subsection {* Recursion combinator and well-formedness conditions *} |
443 |
446 |
444 definition finfun_rec :: "('b \<Rightarrow> 'c) \<Rightarrow> ('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a \<Rightarrow>\<^isub>f 'b) \<Rightarrow> 'c" |
447 definition finfun_rec :: "('b \<Rightarrow> 'c) \<Rightarrow> ('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a \<Rightarrow>f 'b) \<Rightarrow> 'c" |
445 where [code del]: |
448 where [code del]: |
446 "finfun_rec cnst upd f \<equiv> |
449 "finfun_rec cnst upd f \<equiv> |
447 let b = finfun_default f; |
450 let b = finfun_default f; |
448 g = THE g. f = Abs_finfun (map_default b g) \<and> finite (dom g) \<and> b \<notin> ran g |
451 g = THE g. f = Abs_finfun (map_default b g) \<and> finite (dom g) \<and> b \<notin> ran g |
449 in Finite_Set.fold (\<lambda>a. upd a (map_default b g a)) (cnst b) (dom g)" |
452 in Finite_Set.fold (\<lambda>a. upd a (map_default b g a)) (cnst b) (dom g)" |
738 |
741 |
739 lemma finfun_rec_const [simp]: includes finfun shows |
742 lemma finfun_rec_const [simp]: includes finfun shows |
740 "finfun_rec cnst upd (\<lambda>\<^isup>f c) = cnst c" |
743 "finfun_rec cnst upd (\<lambda>\<^isup>f c) = cnst c" |
741 proof(cases "finite (UNIV :: 'a set)") |
744 proof(cases "finite (UNIV :: 'a set)") |
742 case False |
745 case False |
743 hence "finfun_default ((\<lambda>\<^isup>f c) :: 'a \<Rightarrow>\<^isub>f 'b) = c" by(simp add: finfun_default_const) |
746 hence "finfun_default ((\<lambda>\<^isup>f c) :: 'a \<Rightarrow>f 'b) = c" by(simp add: finfun_default_const) |
744 moreover have "(THE g :: 'a \<rightharpoonup> 'b. (\<lambda>\<^isup>f c) = Abs_finfun (map_default c g) \<and> finite (dom g) \<and> c \<notin> ran g) = empty" |
747 moreover have "(THE g :: 'a \<rightharpoonup> 'b. (\<lambda>\<^isup>f c) = Abs_finfun (map_default c g) \<and> finite (dom g) \<and> c \<notin> ran g) = empty" |
745 proof (rule the_equality) |
748 proof (rule the_equality) |
746 show "(\<lambda>\<^isup>f c) = Abs_finfun (map_default c empty) \<and> finite (dom empty) \<and> c \<notin> ran empty" |
749 show "(\<lambda>\<^isup>f c) = Abs_finfun (map_default c empty) \<and> finite (dom empty) \<and> c \<notin> ran empty" |
747 by(auto simp add: finfun_const_def) |
750 by(auto simp add: finfun_const_def) |
748 next |
751 next |
755 ultimately show "g = empty" by-(rule map_default_inject[OF disjI2[OF refl] fin ran], auto) |
758 ultimately show "g = empty" by-(rule map_default_inject[OF disjI2[OF refl] fin ran], auto) |
756 qed |
759 qed |
757 ultimately show ?thesis by(simp add: finfun_rec_def) |
760 ultimately show ?thesis by(simp add: finfun_rec_def) |
758 next |
761 next |
759 case True |
762 case True |
760 hence default: "finfun_default ((\<lambda>\<^isup>f c) :: 'a \<Rightarrow>\<^isub>f 'b) = undefined" by(simp add: finfun_default_const) |
763 hence default: "finfun_default ((\<lambda>\<^isup>f c) :: 'a \<Rightarrow>f 'b) = undefined" by(simp add: finfun_default_const) |
761 let ?the = "\<lambda>g :: 'a \<rightharpoonup> 'b. (\<lambda>\<^isup>f c) = Abs_finfun (map_default undefined g) \<and> finite (dom g) \<and> undefined \<notin> ran g" |
764 let ?the = "\<lambda>g :: 'a \<rightharpoonup> 'b. (\<lambda>\<^isup>f c) = Abs_finfun (map_default undefined g) \<and> finite (dom g) \<and> undefined \<notin> ran g" |
762 show ?thesis |
765 show ?thesis |
763 proof(cases "c = undefined") |
766 proof(cases "c = undefined") |
764 case True |
767 case True |
765 have the: "The ?the = empty" |
768 have the: "The ?the = empty" |
838 obtains b where "x = (\<lambda>\<^isup>f b)" |
841 obtains b where "x = (\<lambda>\<^isup>f b)" |
839 | f a b where "x = f(\<^sup>f a := b)" |
842 | f a b where "x = f(\<^sup>f a := b)" |
840 by(atomize_elim)(rule finfun_exhaust_disj) |
843 by(atomize_elim)(rule finfun_exhaust_disj) |
841 |
844 |
842 lemma finfun_rec_unique: |
845 lemma finfun_rec_unique: |
843 fixes f :: "'a \<Rightarrow>\<^isub>f 'b \<Rightarrow> 'c" |
846 fixes f :: "'a \<Rightarrow>f 'b \<Rightarrow> 'c" |
844 assumes c: "\<And>c. f (\<lambda>\<^isup>f c) = cnst c" |
847 assumes c: "\<And>c. f (\<lambda>\<^isup>f c) = cnst c" |
845 and u: "\<And>g a b. f (g(\<^sup>f a := b)) = upd g a b (f g)" |
848 and u: "\<And>g a b. f (g(\<^sup>f a := b)) = upd g a b (f g)" |
846 and c': "\<And>c. f' (\<lambda>\<^isup>f c) = cnst c" |
849 and c': "\<And>c. f' (\<lambda>\<^isup>f c) = cnst c" |
847 and u': "\<And>g a b. f' (g(\<^sup>f a := b)) = upd g a b (f' g)" |
850 and u': "\<And>g a b. f' (g(\<^sup>f a := b)) = upd g a b (f' g)" |
848 shows "f = f'" |
851 shows "f = f'" |
849 proof |
852 proof |
850 fix g :: "'a \<Rightarrow>\<^isub>f 'b" |
853 fix g :: "'a \<Rightarrow>f 'b" |
851 show "f g = f' g" |
854 show "f g = f' g" |
852 by(induct g rule: finfun_weak_induct)(auto simp add: c u c' u') |
855 by(induct g rule: finfun_weak_induct)(auto simp add: c u c' u') |
853 qed |
856 qed |
854 |
857 |
855 |
858 |
908 "((\<lambda>\<^isup>f b) = f(\<^sup>f a := b')) = (b = b' \<and> (\<forall>a'. a \<noteq> a' \<longrightarrow> f\<^sub>f a' = b))" |
911 "((\<lambda>\<^isup>f b) = f(\<^sup>f a := b')) = (b = b' \<and> (\<forall>a'. a \<noteq> a' \<longrightarrow> f\<^sub>f a' = b))" |
909 by(auto simp add: expand_finfun_eq fun_eq_iff finfun_upd_apply) |
912 by(auto simp add: expand_finfun_eq fun_eq_iff finfun_upd_apply) |
910 |
913 |
911 subsection {* Function composition *} |
914 subsection {* Function composition *} |
912 |
915 |
913 definition finfun_comp :: "('a \<Rightarrow> 'b) \<Rightarrow> 'c \<Rightarrow>\<^isub>f 'a \<Rightarrow> 'c \<Rightarrow>\<^isub>f 'b" (infixr "\<circ>\<^isub>f" 55) |
916 definition finfun_comp :: "('a \<Rightarrow> 'b) \<Rightarrow> 'c \<Rightarrow>f 'a \<Rightarrow> 'c \<Rightarrow>f 'b" (infixr "\<circ>\<^isub>f" 55) |
914 where [code del]: "g \<circ>\<^isub>f f = finfun_rec (\<lambda>b. (\<lambda>\<^isup>f g b)) (\<lambda>a b c. c(\<^sup>f a := g b)) f" |
917 where [code del]: "g \<circ>\<^isub>f f = finfun_rec (\<lambda>b. (\<lambda>\<^isup>f g b)) (\<lambda>a b c. c(\<^sup>f a := g b)) f" |
915 |
918 |
916 interpretation finfun_comp_aux: finfun_rec_wf_aux "(\<lambda>b. (\<lambda>\<^isup>f g b))" "(\<lambda>a b c. c(\<^sup>f a := g b))" |
919 interpretation finfun_comp_aux: finfun_rec_wf_aux "(\<lambda>b. (\<lambda>\<^isup>f g b))" "(\<lambda>a b c. c(\<^sup>f a := g b))" |
917 by(unfold_locales)(auto simp add: finfun_upd_apply intro: finfun_ext) |
920 by(unfold_locales)(auto simp add: finfun_upd_apply intro: finfun_ext) |
918 |
921 |
966 qed } |
969 qed } |
967 qed auto |
970 qed auto |
968 thus ?thesis by(auto simp add: fun_eq_iff) |
971 thus ?thesis by(auto simp add: fun_eq_iff) |
969 qed |
972 qed |
970 |
973 |
971 definition finfun_comp2 :: "'b \<Rightarrow>\<^isub>f 'c \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'c" (infixr "\<^sub>f\<circ>" 55) |
974 definition finfun_comp2 :: "'b \<Rightarrow>f 'c \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow>f 'c" (infixr "\<^sub>f\<circ>" 55) |
972 where [code del]: "finfun_comp2 g f = Abs_finfun (finfun_apply g \<circ> f)" |
975 where [code del]: "finfun_comp2 g f = Abs_finfun (finfun_apply g \<circ> f)" |
973 |
976 |
974 lemma finfun_comp2_const [code, simp]: "finfun_comp2 (\<lambda>\<^isup>f c) f = (\<lambda>\<^isup>f c)" |
977 lemma finfun_comp2_const [code, simp]: "finfun_comp2 (\<lambda>\<^isup>f c) f = (\<lambda>\<^isup>f c)" |
975 including finfun |
978 including finfun |
976 by(simp add: finfun_comp2_def finfun_const_def comp_def) |
979 by(simp add: finfun_comp2_def finfun_const_def comp_def) |
989 with False show ?thesis by(auto simp add: finfun_comp2_def finfun_update_def) |
992 with False show ?thesis by(auto simp add: finfun_comp2_def finfun_update_def) |
990 qed |
993 qed |
991 |
994 |
992 subsection {* Universal quantification *} |
995 subsection {* Universal quantification *} |
993 |
996 |
994 definition finfun_All_except :: "'a list \<Rightarrow> 'a \<Rightarrow>\<^isub>f bool \<Rightarrow> bool" |
997 definition finfun_All_except :: "'a list \<Rightarrow> 'a \<Rightarrow>f bool \<Rightarrow> bool" |
995 where [code del]: "finfun_All_except A P \<equiv> \<forall>a. a \<in> set A \<or> P\<^sub>f a" |
998 where [code del]: "finfun_All_except A P \<equiv> \<forall>a. a \<in> set A \<or> P\<^sub>f a" |
996 |
999 |
997 lemma finfun_All_except_const: "finfun_All_except A (\<lambda>\<^isup>f b) \<longleftrightarrow> b \<or> set A = UNIV" |
1000 lemma finfun_All_except_const: "finfun_All_except A (\<lambda>\<^isup>f b) \<longleftrightarrow> b \<or> set A = UNIV" |
998 by(auto simp add: finfun_All_except_def) |
1001 by(auto simp add: finfun_All_except_def) |
999 |
1002 |
1008 lemma finfun_All_except_update_code [code]: |
1011 lemma finfun_All_except_update_code [code]: |
1009 fixes a :: "'a :: card_UNIV" |
1012 fixes a :: "'a :: card_UNIV" |
1010 shows "finfun_All_except A (finfun_update_code f a b) = ((a \<in> set A \<or> b) \<and> finfun_All_except (a # A) f)" |
1013 shows "finfun_All_except A (finfun_update_code f a b) = ((a \<in> set A \<or> b) \<and> finfun_All_except (a # A) f)" |
1011 by(simp add: finfun_All_except_update) |
1014 by(simp add: finfun_All_except_update) |
1012 |
1015 |
1013 definition finfun_All :: "'a \<Rightarrow>\<^isub>f bool \<Rightarrow> bool" |
1016 definition finfun_All :: "'a \<Rightarrow>f bool \<Rightarrow> bool" |
1014 where "finfun_All = finfun_All_except []" |
1017 where "finfun_All = finfun_All_except []" |
1015 |
1018 |
1016 lemma finfun_All_const [simp]: "finfun_All (\<lambda>\<^isup>f b) = b" |
1019 lemma finfun_All_const [simp]: "finfun_All (\<lambda>\<^isup>f b) = b" |
1017 by(simp add: finfun_All_def finfun_All_except_def) |
1020 by(simp add: finfun_All_def finfun_All_except_def) |
1018 |
1021 |
1021 |
1024 |
1022 lemma finfun_All_All: "finfun_All P = All P\<^sub>f" |
1025 lemma finfun_All_All: "finfun_All P = All P\<^sub>f" |
1023 by(simp add: finfun_All_def finfun_All_except_def) |
1026 by(simp add: finfun_All_def finfun_All_except_def) |
1024 |
1027 |
1025 |
1028 |
1026 definition finfun_Ex :: "'a \<Rightarrow>\<^isub>f bool \<Rightarrow> bool" |
1029 definition finfun_Ex :: "'a \<Rightarrow>f bool \<Rightarrow> bool" |
1027 where "finfun_Ex P = Not (finfun_All (Not \<circ>\<^isub>f P))" |
1030 where "finfun_Ex P = Not (finfun_All (Not \<circ>\<^isub>f P))" |
1028 |
1031 |
1029 lemma finfun_Ex_Ex: "finfun_Ex P = Ex P\<^sub>f" |
1032 lemma finfun_Ex_Ex: "finfun_Ex P = Ex P\<^sub>f" |
1030 unfolding finfun_Ex_def finfun_All_All by simp |
1033 unfolding finfun_Ex_def finfun_All_All by simp |
1031 |
1034 |
1033 by(simp add: finfun_Ex_def) |
1036 by(simp add: finfun_Ex_def) |
1034 |
1037 |
1035 |
1038 |
1036 subsection {* A diagonal operator for FinFuns *} |
1039 subsection {* A diagonal operator for FinFuns *} |
1037 |
1040 |
1038 definition finfun_Diag :: "'a \<Rightarrow>\<^isub>f 'b \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'c \<Rightarrow> 'a \<Rightarrow>\<^isub>f ('b \<times> 'c)" ("(1'(_,/ _')\<^sup>f)" [0, 0] 1000) |
1041 definition finfun_Diag :: "'a \<Rightarrow>f 'b \<Rightarrow> 'a \<Rightarrow>f 'c \<Rightarrow> 'a \<Rightarrow>f ('b \<times> 'c)" ("(1'(_,/ _')\<^sup>f)" [0, 0] 1000) |
1039 where [code del]: "finfun_Diag f g = finfun_rec (\<lambda>b. Pair b \<circ>\<^isub>f g) (\<lambda>a b c. c(\<^sup>f a := (b, g\<^sub>f a))) f" |
1042 where [code del]: "finfun_Diag f g = finfun_rec (\<lambda>b. Pair b \<circ>\<^isub>f g) (\<lambda>a b c. c(\<^sup>f a := (b, g\<^sub>f a))) f" |
1040 |
1043 |
1041 interpretation finfun_Diag_aux: finfun_rec_wf_aux "\<lambda>b. Pair b \<circ>\<^isub>f g" "\<lambda>a b c. c(\<^sup>f a := (b, g\<^sub>f a))" |
1044 interpretation finfun_Diag_aux: finfun_rec_wf_aux "\<lambda>b. Pair b \<circ>\<^isub>f g" "\<lambda>a b c. c(\<^sup>f a := (b, g\<^sub>f a))" |
1042 by(unfold_locales)(simp_all add: expand_finfun_eq fun_eq_iff finfun_upd_apply) |
1045 by(unfold_locales)(simp_all add: expand_finfun_eq fun_eq_iff finfun_upd_apply) |
1043 |
1046 |
1098 |
1101 |
1099 lemma finfun_Diag_conv_Abs_finfun: |
1102 lemma finfun_Diag_conv_Abs_finfun: |
1100 "(f, g)\<^sup>f = Abs_finfun ((\<lambda>x. (finfun_apply f x, finfun_apply g x)))" |
1103 "(f, g)\<^sup>f = Abs_finfun ((\<lambda>x. (finfun_apply f x, finfun_apply g x)))" |
1101 including finfun |
1104 including finfun |
1102 proof - |
1105 proof - |
1103 have "(\<lambda>f :: 'a \<Rightarrow>\<^isub>f 'b. (f, g)\<^sup>f) = (\<lambda>f. Abs_finfun ((\<lambda>x. (finfun_apply f x, finfun_apply g x))))" |
1106 have "(\<lambda>f :: 'a \<Rightarrow>f 'b. (f, g)\<^sup>f) = (\<lambda>f. Abs_finfun ((\<lambda>x. (finfun_apply f x, finfun_apply g x))))" |
1104 proof(rule finfun_rec_unique) |
1107 proof(rule finfun_rec_unique) |
1105 { fix c show "Abs_finfun (\<lambda>x. (finfun_apply (\<lambda>\<^isup>f c) x, finfun_apply g x)) = Pair c \<circ>\<^isub>f g" |
1108 { fix c show "Abs_finfun (\<lambda>x. (finfun_apply (\<lambda>\<^isup>f c) x, finfun_apply g x)) = Pair c \<circ>\<^isub>f g" |
1106 by(simp add: finfun_comp_conv_comp o_def finfun_const_def) } |
1109 by(simp add: finfun_comp_conv_comp o_def finfun_const_def) } |
1107 { fix g' a b |
1110 { fix g' a b |
1108 show "Abs_finfun (\<lambda>x. (finfun_apply g'(\<^sup>f a := b) x, finfun_apply g x)) = |
1111 show "Abs_finfun (\<lambda>x. (finfun_apply g'(\<^sup>f a := b) x, finfun_apply g x)) = |
1113 qed |
1116 qed |
1114 |
1117 |
1115 lemma finfun_Diag_eq: "(f, g)\<^sup>f = (f', g')\<^sup>f \<longleftrightarrow> f = f' \<and> g = g'" |
1118 lemma finfun_Diag_eq: "(f, g)\<^sup>f = (f', g')\<^sup>f \<longleftrightarrow> f = f' \<and> g = g'" |
1116 by(auto simp add: expand_finfun_eq fun_eq_iff) |
1119 by(auto simp add: expand_finfun_eq fun_eq_iff) |
1117 |
1120 |
1118 definition finfun_fst :: "'a \<Rightarrow>\<^isub>f ('b \<times> 'c) \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'b" |
1121 definition finfun_fst :: "'a \<Rightarrow>f ('b \<times> 'c) \<Rightarrow> 'a \<Rightarrow>f 'b" |
1119 where [code]: "finfun_fst f = fst \<circ>\<^isub>f f" |
1122 where [code]: "finfun_fst f = fst \<circ>\<^isub>f f" |
1120 |
1123 |
1121 lemma finfun_fst_const: "finfun_fst (\<lambda>\<^isup>f bc) = (\<lambda>\<^isup>f fst bc)" |
1124 lemma finfun_fst_const: "finfun_fst (\<lambda>\<^isup>f bc) = (\<lambda>\<^isup>f fst bc)" |
1122 by(simp add: finfun_fst_def) |
1125 by(simp add: finfun_fst_def) |
1123 |
1126 |
1133 |
1136 |
1134 lemma finfun_fst_conv_Abs_finfun: "finfun_fst = (\<lambda>f. Abs_finfun (fst o finfun_apply f))" |
1137 lemma finfun_fst_conv_Abs_finfun: "finfun_fst = (\<lambda>f. Abs_finfun (fst o finfun_apply f))" |
1135 by(simp add: finfun_fst_def [abs_def] finfun_comp_conv_comp) |
1138 by(simp add: finfun_fst_def [abs_def] finfun_comp_conv_comp) |
1136 |
1139 |
1137 |
1140 |
1138 definition finfun_snd :: "'a \<Rightarrow>\<^isub>f ('b \<times> 'c) \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'c" |
1141 definition finfun_snd :: "'a \<Rightarrow>f ('b \<times> 'c) \<Rightarrow> 'a \<Rightarrow>f 'c" |
1139 where [code]: "finfun_snd f = snd \<circ>\<^isub>f f" |
1142 where [code]: "finfun_snd f = snd \<circ>\<^isub>f f" |
1140 |
1143 |
1141 lemma finfun_snd_const: "finfun_snd (\<lambda>\<^isup>f bc) = (\<lambda>\<^isup>f snd bc)" |
1144 lemma finfun_snd_const: "finfun_snd (\<lambda>\<^isup>f bc) = (\<lambda>\<^isup>f snd bc)" |
1142 by(simp add: finfun_snd_def) |
1145 by(simp add: finfun_snd_def) |
1143 |
1146 |
1159 lemma finfun_Diag_collapse [simp]: "(finfun_fst f, finfun_snd f)\<^sup>f = f" |
1162 lemma finfun_Diag_collapse [simp]: "(finfun_fst f, finfun_snd f)\<^sup>f = f" |
1160 by(induct f rule: finfun_weak_induct)(simp_all add: finfun_fst_const finfun_snd_const finfun_fst_update finfun_snd_update finfun_Diag_update_update) |
1163 by(induct f rule: finfun_weak_induct)(simp_all add: finfun_fst_const finfun_snd_const finfun_fst_update finfun_snd_update finfun_Diag_update_update) |
1161 |
1164 |
1162 subsection {* Currying for FinFuns *} |
1165 subsection {* Currying for FinFuns *} |
1163 |
1166 |
1164 definition finfun_curry :: "('a \<times> 'b) \<Rightarrow>\<^isub>f 'c \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'b \<Rightarrow>\<^isub>f 'c" |
1167 definition finfun_curry :: "('a \<times> 'b) \<Rightarrow>f 'c \<Rightarrow> 'a \<Rightarrow>f 'b \<Rightarrow>f 'c" |
1165 where [code del]: "finfun_curry = finfun_rec (finfun_const \<circ> finfun_const) (\<lambda>(a, b) c f. f(\<^sup>f a := (f\<^sub>f a)(\<^sup>f b := c)))" |
1168 where [code del]: "finfun_curry = finfun_rec (finfun_const \<circ> finfun_const) (\<lambda>(a, b) c f. f(\<^sup>f a := (f\<^sub>f a)(\<^sup>f b := c)))" |
1166 |
1169 |
1167 interpretation finfun_curry_aux: finfun_rec_wf_aux "finfun_const \<circ> finfun_const" "\<lambda>(a, b) c f. f(\<^sup>f a := (f\<^sub>f a)(\<^sup>f b := c))" |
1170 interpretation finfun_curry_aux: finfun_rec_wf_aux "finfun_const \<circ> finfun_const" "\<lambda>(a, b) c f. f(\<^sup>f a := (f\<^sub>f a)(\<^sup>f b := c))" |
1168 apply(unfold_locales) |
1171 apply(unfold_locales) |
1169 apply(auto simp add: split_def finfun_update_twist finfun_upd_apply split_paired_all finfun_update_const_same) |
1172 apply(auto simp add: split_def finfun_update_twist finfun_upd_apply split_paired_all finfun_update_const_same) |
1209 by(simp add: finfun_const_def finfun_curry) |
1212 by(simp add: finfun_const_def finfun_curry) |
1210 thus ?thesis unfolding finfun_def by auto |
1213 thus ?thesis unfolding finfun_def by auto |
1211 qed |
1214 qed |
1212 |
1215 |
1213 lemma finfun_curry_conv_curry: |
1216 lemma finfun_curry_conv_curry: |
1214 fixes f :: "('a \<times> 'b) \<Rightarrow>\<^isub>f 'c" |
1217 fixes f :: "('a \<times> 'b) \<Rightarrow>f 'c" |
1215 shows "finfun_curry f = Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply f) a))" |
1218 shows "finfun_curry f = Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply f) a))" |
1216 including finfun |
1219 including finfun |
1217 proof - |
1220 proof - |
1218 have "finfun_curry = (\<lambda>f :: ('a \<times> 'b) \<Rightarrow>\<^isub>f 'c. Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply f) a)))" |
1221 have "finfun_curry = (\<lambda>f :: ('a \<times> 'b) \<Rightarrow>f 'c. Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply f) a)))" |
1219 proof(rule finfun_rec_unique) |
1222 proof(rule finfun_rec_unique) |
1220 { fix c show "finfun_curry (\<lambda>\<^isup>f c) = (\<lambda>\<^isup>f \<lambda>\<^isup>f c)" by simp } |
1223 fix c show "finfun_curry (\<lambda>\<^isup>f c) = (\<lambda>\<^isup>f \<lambda>\<^isup>f c)" by simp |
1221 { fix f a c show "finfun_curry (f(\<^sup>f a := c)) = (finfun_curry f)(\<^sup>f fst a := ((finfun_curry f)\<^sub>f (fst a))(\<^sup>f snd a := c))" |
1224 fix f a |
1222 by(cases a) simp } |
1225 show "finfun_curry (f(\<^sup>f a := c)) = (finfun_curry f)(\<^sup>f fst a := ((finfun_curry f)\<^sub>f (fst a))(\<^sup>f snd a := c))" |
1223 { fix c show "Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply (\<lambda>\<^isup>f c)) a)) = (\<lambda>\<^isup>f \<lambda>\<^isup>f c)" |
1226 by(cases a) simp |
1224 by(simp add: finfun_curry_def finfun_const_def curry_def) } |
1227 show "Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply (\<lambda>\<^isup>f c)) a)) = (\<lambda>\<^isup>f \<lambda>\<^isup>f c)" |
1225 { fix g a b |
1228 by(simp add: finfun_curry_def finfun_const_def curry_def) |
1226 show "Abs_finfun (\<lambda>aa. Abs_finfun (curry (finfun_apply g(\<^sup>f a := b)) aa)) = |
1229 fix g b |
1227 (Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply g) a)))(\<^sup>f |
1230 show "Abs_finfun (\<lambda>aa. Abs_finfun (curry (finfun_apply g(\<^sup>f a := b)) aa)) = |
1228 fst a := ((Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply g) a)))\<^sub>f (fst a))(\<^sup>f snd a := b))" |
1231 (Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply g) a)))(\<^sup>f |
1229 by(cases a)(auto intro!: ext arg_cong[where f=Abs_finfun] simp add: finfun_curry_def finfun_update_def finfun_curry finfun_Abs_finfun_curry) } |
1232 fst a := ((Abs_finfun (\<lambda>a. Abs_finfun (curry (finfun_apply g) a)))\<^sub>f (fst a))(\<^sup>f snd a := b))" |
|
1233 by(cases a)(auto intro!: ext arg_cong[where f=Abs_finfun] simp add: finfun_curry_def finfun_update_def finfun_curry finfun_Abs_finfun_curry) |
1230 qed |
1234 qed |
1231 thus ?thesis by(auto simp add: fun_eq_iff) |
1235 thus ?thesis by(auto simp add: fun_eq_iff) |
1232 qed |
1236 qed |
1233 |
1237 |
1234 subsection {* Executable equality for FinFuns *} |
1238 subsection {* Executable equality for FinFuns *} |
1240 definition eq_finfun_def [code]: "HOL.equal f g \<longleftrightarrow> finfun_All ((\<lambda>(x, y). x = y) \<circ>\<^isub>f (f, g)\<^sup>f)" |
1244 definition eq_finfun_def [code]: "HOL.equal f g \<longleftrightarrow> finfun_All ((\<lambda>(x, y). x = y) \<circ>\<^isub>f (f, g)\<^sup>f)" |
1241 instance by(intro_classes)(simp add: eq_finfun_All_ext eq_finfun_def) |
1245 instance by(intro_classes)(simp add: eq_finfun_All_ext eq_finfun_def) |
1242 end |
1246 end |
1243 |
1247 |
1244 lemma [code nbe]: |
1248 lemma [code nbe]: |
1245 "HOL.equal (f :: _ \<Rightarrow>\<^isub>f _) f \<longleftrightarrow> True" |
1249 "HOL.equal (f :: _ \<Rightarrow>f _) f \<longleftrightarrow> True" |
1246 by (fact equal_refl) |
1250 by (fact equal_refl) |
1247 |
1251 |
1248 subsection {* An operator that explicitly removes all redundant updates in the generated representations *} |
1252 subsection {* An operator that explicitly removes all redundant updates in the generated representations *} |
1249 |
1253 |
1250 definition finfun_clearjunk :: "'a \<Rightarrow>\<^isub>f 'b \<Rightarrow> 'a \<Rightarrow>\<^isub>f 'b" |
1254 definition finfun_clearjunk :: "'a \<Rightarrow>f 'b \<Rightarrow> 'a \<Rightarrow>f 'b" |
1251 where [simp, code del]: "finfun_clearjunk = id" |
1255 where [simp, code del]: "finfun_clearjunk = id" |
1252 |
1256 |
1253 lemma finfun_clearjunk_const [code]: "finfun_clearjunk (\<lambda>\<^isup>f b) = (\<lambda>\<^isup>f b)" |
1257 lemma finfun_clearjunk_const [code]: "finfun_clearjunk (\<lambda>\<^isup>f b) = (\<lambda>\<^isup>f b)" |
1254 by simp |
1258 by simp |
1255 |
1259 |
1256 lemma finfun_clearjunk_update [code]: "finfun_clearjunk (finfun_update_code f a b) = f(\<^sup>f a := b)" |
1260 lemma finfun_clearjunk_update [code]: "finfun_clearjunk (finfun_update_code f a b) = f(\<^sup>f a := b)" |
1257 by simp |
1261 by simp |
1258 |
1262 |
1259 subsection {* The domain of a FinFun as a FinFun *} |
1263 subsection {* The domain of a FinFun as a FinFun *} |
1260 |
1264 |
1261 definition finfun_dom :: "('a \<Rightarrow>\<^isub>f 'b) \<Rightarrow> ('a \<Rightarrow>\<^isub>f bool)" |
1265 definition finfun_dom :: "('a \<Rightarrow>f 'b) \<Rightarrow> ('a \<Rightarrow>f bool)" |
1262 where [code del]: "finfun_dom f = Abs_finfun (\<lambda>a. f\<^sub>f a \<noteq> finfun_default f)" |
1266 where [code del]: "finfun_dom f = Abs_finfun (\<lambda>a. f\<^sub>f a \<noteq> finfun_default f)" |
1263 |
1267 |
1264 lemma finfun_dom_const: |
1268 lemma finfun_dom_const: |
1265 "finfun_dom ((\<lambda>\<^isup>f c) :: 'a \<Rightarrow>\<^isub>f 'b) = (\<lambda>\<^isup>f finite (UNIV :: 'a set) \<and> c \<noteq> undefined)" |
1269 "finfun_dom ((\<lambda>\<^isup>f c) :: 'a \<Rightarrow>f 'b) = (\<lambda>\<^isup>f finite (UNIV :: 'a set) \<and> c \<noteq> undefined)" |
1266 unfolding finfun_dom_def finfun_default_const |
1270 unfolding finfun_dom_def finfun_default_const |
1267 by(auto)(simp_all add: finfun_const_def) |
1271 by(auto)(simp_all add: finfun_const_def) |
1268 |
1272 |
1269 text {* |
1273 text {* |
1270 @{term "finfun_dom" } raises an exception when called on a FinFun whose domain is a finite type. |
1274 @{term "finfun_dom" } raises an exception when called on a FinFun whose domain is a finite type. |
1271 For such FinFuns, the default value (and as such the domain) is undefined. |
1275 For such FinFuns, the default value (and as such the domain) is undefined. |
1272 *} |
1276 *} |
1273 |
1277 |
1274 lemma finfun_dom_const_code [code]: |
1278 lemma finfun_dom_const_code [code]: |
1275 "finfun_dom ((\<lambda>\<^isup>f c) :: ('a :: card_UNIV) \<Rightarrow>\<^isub>f 'b) = |
1279 "finfun_dom ((\<lambda>\<^isup>f c) :: ('a :: card_UNIV) \<Rightarrow>f 'b) = |
1276 (if card_UNIV (TYPE('a)) = 0 then (\<lambda>\<^isup>f False) else FinFun.code_abort (\<lambda>_. finfun_dom (\<lambda>\<^isup>f c)))" |
1280 (if card_UNIV (TYPE('a)) = 0 then (\<lambda>\<^isup>f False) else FinFun.code_abort (\<lambda>_. finfun_dom (\<lambda>\<^isup>f c)))" |
1277 unfolding card_UNIV_eq_0_infinite_UNIV |
1281 unfolding card_UNIV_eq_0_infinite_UNIV |
1278 by(simp add: finfun_dom_const) |
1282 by(simp add: finfun_dom_const) |
1279 |
1283 |
1280 lemma finfun_dom_finfunI: "(\<lambda>a. f\<^sub>f a \<noteq> finfun_default f) \<in> finfun" |
1284 lemma finfun_dom_finfunI: "(\<lambda>a. f\<^sub>f a \<noteq> finfun_default f) \<in> finfun" |
1329 |
1333 |
1330 lemma finfun_const_True_conv_top: "(\<lambda>\<^isup>f True)\<^sub>f = top" |
1334 lemma finfun_const_True_conv_top: "(\<lambda>\<^isup>f True)\<^sub>f = top" |
1331 by auto |
1335 by auto |
1332 |
1336 |
1333 lemma finfun_to_list_const: |
1337 lemma finfun_to_list_const: |
1334 "finfun_to_list ((\<lambda>\<^isup>f c) :: ('a :: {linorder} \<Rightarrow>\<^isub>f 'b)) = |
1338 "finfun_to_list ((\<lambda>\<^isup>f c) :: ('a :: {linorder} \<Rightarrow>f 'b)) = |
1335 (if \<not> finite (UNIV :: 'a set) \<or> c = undefined then [] else THE xs. set xs = UNIV \<and> sorted xs \<and> distinct xs)" |
1339 (if \<not> finite (UNIV :: 'a set) \<or> c = undefined then [] else THE xs. set xs = UNIV \<and> sorted xs \<and> distinct xs)" |
1336 by(auto simp add: finfun_to_list_def finfun_const_False_conv_bot finfun_const_True_conv_top finfun_dom_const) |
1340 by(auto simp add: finfun_to_list_def finfun_const_False_conv_bot finfun_const_True_conv_top finfun_dom_const) |
1337 |
1341 |
1338 lemma finfun_to_list_const_code [code]: |
1342 lemma finfun_to_list_const_code [code]: |
1339 "finfun_to_list ((\<lambda>\<^isup>f c) :: ('a :: {linorder, card_UNIV} \<Rightarrow>\<^isub>f 'b)) = |
1343 "finfun_to_list ((\<lambda>\<^isup>f c) :: ('a :: {linorder, card_UNIV} \<Rightarrow>f 'b)) = |
1340 (if card_UNIV (TYPE('a)) = 0 then [] else FinFun.code_abort (\<lambda>_. finfun_to_list ((\<lambda>\<^isup>f c) :: ('a \<Rightarrow>\<^isub>f 'b))))" |
1344 (if card_UNIV (TYPE('a)) = 0 then [] else FinFun.code_abort (\<lambda>_. finfun_to_list ((\<lambda>\<^isup>f c) :: ('a \<Rightarrow>f 'b))))" |
1341 unfolding card_UNIV_eq_0_infinite_UNIV |
1345 unfolding card_UNIV_eq_0_infinite_UNIV |
1342 by(auto simp add: finfun_to_list_const) |
1346 by(auto simp add: finfun_to_list_const) |
1343 |
1347 |
1344 lemma remove1_insort_insert_same: |
1348 lemma remove1_insort_insert_same: |
1345 "x \<notin> set xs \<Longrightarrow> remove1 x (insort_insert x xs) = xs" |
1349 "x \<notin> set xs \<Longrightarrow> remove1 x (insort_insert x xs) = xs" |