# HG changeset patch # User Andreas Lochbihler # Date 1360861093 -3600 # Node ID 8fd094d5b7b7003ad41030d3f115dc513b7d46bd # Parent 47af65ef228e92489948679bec1586b0a7f9bb8c instantiate finite_UNIV and card_UNIV for finfun type diff -r 47af65ef228e -r 8fd094d5b7b7 src/HOL/Library/FinFun.thy --- a/src/HOL/Library/FinFun.thy Thu Feb 14 16:01:59 2013 +0100 +++ b/src/HOL/Library/FinFun.thy Thu Feb 14 17:58:13 2013 +0100 @@ -1444,6 +1444,99 @@ (if b = finfun_default f then List.remove1 a (finfun_to_list f) else List.insort_insert a (finfun_to_list f))" by(simp add: finfun_to_list_update) +text {* More type class instantiations *} + +lemma card_eq_1_iff: "card A = 1 \ A \ {} \ (\x\A. \y\A. x = y)" + (is "?lhs \ ?rhs") +proof + assume ?lhs + moreover { + fix x y + assume A: "x \ A" "y \ A" and neq: "x \ y" + have "finite A" using `?lhs` by(simp add: card_ge_0_finite) + from neq have "2 = card {x, y}" by simp + also have "\ \ card A" using A `finite A` + by(auto intro: card_mono) + finally have False using `?lhs` by simp } + ultimately show ?rhs by auto +next + assume ?rhs + hence "A = {THE x. x \ A}" + by safe (auto intro: theI the_equality[symmetric]) + also have "card \ = 1" by simp + finally show ?lhs . +qed + +lemma card_UNIV_finfun: + defines "F == finfun :: ('a \ 'b) set" + shows "CARD('a \f 'b) = (if CARD('a) \ 0 \ CARD('b) \ 0 \ CARD('b) = 1 then CARD('b) ^ CARD('a) else 0)" +proof(cases "0 < CARD('a) \ 0 < CARD('b) \ CARD('b) = 1") + case True + from True have "F = UNIV" + proof + assume b: "CARD('b) = 1" + hence "\x :: 'b. x = undefined" + by(auto simp add: card_eq_1_iff simp del: One_nat_def) + thus ?thesis by(auto simp add: finfun_def F_def intro: exI[where x=undefined]) + qed(auto simp add: finfun_def card_gt_0_iff F_def intro: finite_subset[where B=UNIV]) + moreover have "CARD('a \f 'b) = card F" + unfolding type_definition.Abs_image[OF type_definition_finfun, symmetric] + by(auto intro!: card_image inj_onI simp add: Abs_finfun_inject F_def) + ultimately show ?thesis by(simp add: card_fun) +next + case False + hence infinite: "\ (finite (UNIV :: 'a set) \ finite (UNIV :: 'b set))" + and b: "CARD('b) \ 1" by(simp_all add: card_eq_0_iff) + from b obtain b1 b2 :: 'b where "b1 \ b2" + by(auto simp add: card_eq_1_iff simp del: One_nat_def) + let ?f = "\a a' :: 'a. if a = a' then b1 else b2" + from infinite have "\ finite (UNIV :: ('a \f 'b) set)" + proof(rule contrapos_nn[OF _ conjI]) + assume finite: "finite (UNIV :: ('a \f 'b) set)" + hence "finite F" + unfolding type_definition.Abs_image[OF type_definition_finfun, symmetric] F_def + by(rule finite_imageD)(auto intro: inj_onI simp add: Abs_finfun_inject) + hence "finite (range ?f)" + by(rule finite_subset[rotated 1])(auto simp add: F_def finfun_def `b1 \ b2` intro!: exI[where x=b2]) + thus "finite (UNIV :: 'a set)" + by(rule finite_imageD)(auto intro: inj_onI simp add: fun_eq_iff `b1 \ b2` split: split_if_asm) + + from finite have "finite (range (\b. ((K$ b) :: 'a \f 'b)))" + by(rule finite_subset[rotated 1]) simp + thus "finite (UNIV :: 'b set)" + by(rule finite_imageD)(auto intro!: inj_onI) + qed + with False show ?thesis by simp +qed + +lemma finite_UNIV_finfun: + "finite (UNIV :: ('a \f 'b) set) \ + (finite (UNIV :: 'a set) \ finite (UNIV :: 'b set) \ CARD('b) = 1)" + (is "?lhs \ ?rhs") +proof - + have "?lhs \ CARD('a \f 'b) > 0" by(simp add: card_gt_0_iff) + also have "\ \ CARD('a) > 0 \ CARD('b) > 0 \ CARD('b) = 1" + by(simp add: card_UNIV_finfun) + also have "\ = ?rhs" by(simp add: card_gt_0_iff) + finally show ?thesis . +qed + +instantiation finfun :: (finite_UNIV, card_UNIV) finite_UNIV begin +definition "finite_UNIV = Phantom('a \f 'b) + (let cb = of_phantom (card_UNIV :: 'b card_UNIV) + in cb = 1 \ of_phantom (finite_UNIV :: 'a finite_UNIV) \ cb \ 0)" +instance + by intro_classes (auto simp add: finite_UNIV_finfun_def Let_def card_UNIV finite_UNIV finite_UNIV_finfun card_gt_0_iff) +end + +instantiation finfun :: (card_UNIV, card_UNIV) card_UNIV begin +definition "card_UNIV = Phantom('a \f 'b) + (let ca = of_phantom (card_UNIV :: 'a card_UNIV); + cb = of_phantom (card_UNIV :: 'b card_UNIV) + in if ca \ 0 \ cb \ 0 \ cb = 1 then cb ^ ca else 0)" +instance by intro_classes (simp add: card_UNIV_finfun_def card_UNIV Let_def card_UNIV_finfun) +end + text {* Deactivate syntax again. Import theory @{text FinFun_Syntax} to reactivate it again *} no_type_notation