Theory PiE_Rel_Extras
section‹Extensional function extras›
text‹Counting lemmas (i.e. reasoning on cardinality) of sets on the extensional function relation ›
theory PiE_Rel_Extras imports Card_Partitions.Card_Partitions
begin
subsection ‹Relations and Extensional Function sets ›
text ‹A number of lemmas to convert between relations and functions for counting purposes.
Note, ultimately not needed in this formalisation, but may be of use in the future ›
lemma : "Range r = {y. ∃x. (x, y) ∈ r}"
by blast
:: " 'a set ⇒ 'b set ⇒ ('a ⇒ 'b) ⇒('a × 'b) set" where
"fun_to_rel A B f ≡ {(a, b) | a b . a ∈ A ∧ b ∈ B ∧ f a = b}"
:: "('a × 'b) set ⇒ ('a ⇒ 'b)" where
"rel_to_fun R ≡ λ a . (if a ∈ Domain R then (THE b . (a, b) ∈ R) else undefined)"
lemma : "a ∈ A ⟹ b ∈ B ⟹ f a = b ⟹ (a, b) ∈ fun_to_rel A B f"
unfolding fun_to_rel_def by auto
lemma : "fun_to_rel A B f ≡ {(a, f a) | a b . a ∈ A ∧ f a ∈ B}"
unfolding fun_to_rel_def by simp
lemma : "a ∈ A ⟹ f a ∈ B ⟹ (a, f a) ∈ fun_to_rel A B f"
using fun_to_rel_alt by fast
lemma [simp]: "a ∈ Domain R ⟹ (rel_to_fun R) a = (THE b . (a, b) ∈ R)"
unfolding rel_to_fun_def by simp
lemma [simp]: "a ∉ Domain R ⟹ (rel_to_fun R) a = undefined"
unfolding rel_to_fun_def by simp
lemma : "single_valued R ⟷ (∀ x ∈ Domain R. ∃! y . (x, y) ∈ R)"
using single_valued_def by fastforce
lemma :
assumes "single_valued R"
assumes "a ∈ Domain R"
shows "(THE b . (a, b) ∈ R) ∈ Range R"
using single_valued_unique_Dom_iff
by (metis Range_iff assms(1) assms(2) theI')
lemma : "single_valued R ⟹ rel_to_fun R ∈ (Domain R →⇩E Range R)"
by (intro PiE_I) (simp_all add: rel_to_fun_range)
lemma : "single_valued (fun_to_rel A B f)"
unfolding single_valued_def fun_to_rel_def
by simp
lemma fun_to_rel_domain:
assumes "f ∈ A →⇩E B"
shows "Domain (fun_to_rel A B f) = A"
unfolding fun_to_rel_def using assms by (auto simp add: subset_antisym subsetI Domain_unfold)
lemma :
assumes "f ∈ A →⇩E B"
shows "Range (fun_to_rel A B f) ⊆ B"
unfolding fun_to_rel_def using assms by (auto simp add: subsetI Range_unfold)
lemma :
assumes "f ∈ A →⇩E B"
shows "rel_to_fun (fun_to_rel A B f) = f"
proof (intro ext allI)
fix x
show "rel_to_fun (fun_to_rel A B f) x = f x"
proof (cases "x ∈ A")
case True
then have ind: "x ∈ Domain (fun_to_rel A B f)" using fun_to_rel_domain assms
by blast
have "(x, f x) ∈ fun_to_rel A B f" using fun_to_rel_alt True single_value_fun_to_rel
using assms by fastforce
moreover have "rel_to_fun (fun_to_rel A B f) x = (THE b. (x, b) ∈ (fun_to_rel A B f))" by (simp add: ind)
ultimately show ?thesis using single_value_fun_to_rel single_valuedD the_equality
by (metis (no_types, lifting))
next
case False
then have "x ∉ Domain (fun_to_rel A B f)" unfolding fun_to_rel_def
by blast
then show ?thesis
using False assms by auto
qed
qed
lemma :
assumes "single_valued R"
shows "fun_to_rel (Domain R) (Range R) (rel_to_fun R) = R"
proof (intro subset_antisym subsetI)
fix x assume "x ∈ fun_to_rel (Domain R) (Range R) (rel_to_fun R)"
then obtain a b where "x = (a, b)" and "a ∈ Domain R" and "b ∈ Range R" and "(rel_to_fun R a) = b"
using fun_to_rel_def by (smt (verit) mem_Collect_eq)
then have "b = (THE b'. (a, b') ∈ R)" using rel_to_fun_in
by simp
then show "x ∈ R"
by (metis (no_types, lifting) ‹a ∈ Domain R› ‹x = (a, b)› assms single_valued_unique_Dom_iff the1_equality)
next
fix x assume "x ∈ R"
then obtain a b where "x = (a, b)" and "(a, b) ∈ R" and "∀ c . (a, c) ∈ R ⟶ b = c"
using assms
by (metis prod.collapse single_valued_def)
then have "a ∈ Domain R" "b ∈ Range R" by blast+
then have "b = (THE b' . (a, b') ∈ R)"
by (metis ‹∀c. (a, c) ∈ R ⟶ b = c› ‹x = (a, b)› ‹x ∈ R› the_equality)
then have "(a, b) ∈ fun_to_rel (Domain R) (Range R) (rel_to_fun R)"
using ‹a ∈ Domain R› ‹b ∈ Range R› by (intro fun_to_relI) (simp_all)
then show "x ∈ fun_to_rel (Domain R) (Range R) (rel_to_fun R)" using ‹x = (a, b)› by simp
qed
lemma :
assumes "f ∈ A →⇩E B"
shows "bij_betw (λ a . (a, f a)) A (fun_to_rel A B f)"
proof (intro bij_betw_imageI inj_onI)
show "⋀x y. x ∈ A ⟹ y ∈ A ⟹ (x, f x) = (y, f y) ⟹ x = y" by simp
next
show "(λa. (a, f a)) ` A = fun_to_rel A B f"
proof (intro subset_antisym subsetI)
fix x assume "x ∈ (λa. (a, f a)) ` A"
then obtain a where "a ∈ A" and "x = (a, f a)" by blast
then show "x ∈ fun_to_rel A B f" using fun_to_rel_alt assms
by fastforce
next
fix x assume "x ∈ fun_to_rel A B f"
then show "x ∈ (λa. (a, f a)) ` A" using fun_to_rel_alt
using image_iff by fastforce
qed
qed
lemma :
assumes "f ∈ A →⇩E B"
shows "card (fun_to_rel A B f) = card A"
using bij_betw_fun_to_rel assms bij_betw_same_card[of "(λ a . (a, f a))" A "(fun_to_rel A B f)"]
by (metis)
lemma :
assumes "C ⊆ A →⇩E B"
shows "inj_on (fun_to_rel A B) C"
proof (intro inj_onI ext allI)
fix f g x assume fin: "f ∈ C" and gin: "g ∈ C" and eq: "fun_to_rel A B f = fun_to_rel A B g"
then show "f x = g x"
proof (cases "x ∈ A")
case True
then have "(x, f x) ∈ fun_to_rel A B f" using fun_to_rel_alt
by (smt (verit) PiE_mem assms fin fun_to_rel_def mem_Collect_eq subset_eq)
moreover have "(x, g x) ∈ fun_to_rel A B g" using fun_to_rel_alt True
by (smt (verit) PiE_mem assms fun_to_rel_def gin mem_Collect_eq subset_eq)
ultimately show ?thesis using eq single_value_fun_to_rel single_valued_def
by metis
next
case False
then have "f x = undefined" "g x = undefined" using fin gin assms by auto
then show ?thesis by simp
qed
qed
lemma : "fun_to_rel A B f ⊆ A × B"
unfolding fun_to_rel_def by auto
lemma : "C ⊆ A →⇩E B ⟹ card C = card ((λ f . fun_to_rel A B f ) ` C)"
using card_image fun_to_rel_inj by metis
subsection ‹Cardinality Lemmas ›
text ‹Lemmas to count variations of filtered sets over the extensional function set relation ›
lemma :
assumes "⋀ a. a ∈ A' ⟹ X a ∈ C"
assumes "A' ⊆ A"
assumes "finite A"
shows "card {f ∈ A →⇩E C . ∀ a ∈ A' . f a = X a} = (card C)^(card A - card A')"
proof -
have finA: "finite A'" using assms(3) finite_subset assms(2) by auto
have c1: "card (A - A') = card A - card A'" using assms(2)
using card_Diff_subset finA by blast
define g :: "('a ⇒ 'b) ⇒ ('a ⇒ 'b)" where "g ≡ λ f. (λ a' . if a' ∈ A' then undefined else f a')"
have "bij_betw g {f ∈ A →⇩E C . ∀ a ∈ A' . f a = X a} ((A - A') →⇩E C)"
proof (intro bij_betw_imageI inj_onI)
fix h h' assume h1in: "h ∈ {f ∈ A →⇩E C. ∀ a ∈ A' . f a = X a}" and h2in: "h' ∈ {f ∈ A →⇩E C. ∀ a ∈ A' . f a = X a}" "g h = g h'"
then have eq: "(λ a' . if a' ∈ A' then undefined else h a') = (λ a' . if a' ∈ A' then undefined else h' a')"
using g_def by simp
show "h = h'"
proof (intro ext allI)
fix x
show "h x = h' x" using h1in h2in eq by (cases "x ∈ A'", simp, meson)
qed
next
show "g ` {f ∈ A →⇩E C. ∀ a ∈ A' . f a = X a} = A - A' →⇩E C"
proof (intro subset_antisym subsetI)
fix g' assume "g' ∈ g ` {f ∈ A →⇩E C. ∀ a ∈ A' . f a = X a}"
then obtain f' where geq: "g' = g f'" and fin: "f' ∈ A →⇩E C" and "∀ a ∈ A' . f' a = X a"
by blast
show "g' ∈ A - A' →⇩E C"
using g_def fin geq by (intro PiE_I)(auto)
next
fix g' assume gin: "g' ∈ A - A' →⇩E C"
define f' where "f' = (λ a' . (if a' ∈ A' then X a' else g' a'))"
then have eqc: "∀ a' ∈ A' . f' a' = X a'" by auto
have fin: "f' ∈ A →⇩E C"
proof (intro PiE_I)
fix x assume "x ∈ A"
have "x ∉ A' ⟹ f' x = g' x" using f'_def by auto
moreover have "x ∈ A' ⟹ f' x = X x" using f'_def by (simp add: ‹x ∈ A›)
ultimately show "f' x ∈ C"
using gin PiE_E ‹x ∈ A› assms(1)[of x] by (metis Diff_iff)
next
fix x assume "x ∉ A"
then show "f' x = undefined"
using f'_def gin assms(2) by auto
qed
have "g' = g f'" unfolding f'_def g_def
by (auto simp add: fun_eq_iff) (metis DiffE PiE_arb gin)
then show "g' ∈ g ` {f ∈ A →⇩E C. ∀ a ∈ A' . f a = X a}" using fin eqc by blast
qed
qed
then have "card {f ∈ A →⇩E C . ∀ a ∈ A' . f a = X a} = card ((A - A') →⇩E C)"
using bij_betw_same_card by blast
also have "... = (card C)^card (A - A')"
using card_funcsetE assms(3) by (metis finite_Diff)
finally show ?thesis using c1 by auto
qed
lemma : "X a' ∈ C ⟹ a' ∈ A ⟹ finite A ⟹
card {f ∈ A →⇩E C . f a' = X a'} = (card C)^(card A - 1)"
using card_PiE_filter_range_set[of "{a'}" X C A ] by auto
lemma : "c ∈ C ⟹ A' ⊆ A ⟹ finite A ⟹
card {f ∈ A →⇩E C . ∀ a ∈ A' . f a = c} = (card C)^(card A - card A')"
using card_PiE_filter_range_set[of A' "λ a . c"] by auto
lemma : "c ∈ {0..<n} ⟹ A' ⊆ A ⟹ finite A ⟹
card {f ∈ A →⇩E {0..<n} . ∀ a ∈ A' . f a = c} = n^(card A - card A')"
using card_PiE_filter_range_set_const[of c "{0..<n}" A' A] by auto
end