# HG changeset patch # User haftmann # Date 1206641078 -3600 # Node ID 6a5faa5bcf1926950c3310293bc3dc594b0ff3e1 # Parent cae9fa1865416007e5743a0eaee138786aefb20d instance for functions, explicit characters diff -r cae9fa186541 -r 6a5faa5bcf19 src/HOL/Library/Enum.thy --- a/src/HOL/Library/Enum.thy Thu Mar 27 19:04:37 2008 +0100 +++ b/src/HOL/Library/Enum.thy Thu Mar 27 19:04:38 2008 +0100 @@ -11,11 +11,17 @@ subsection {* Class @{text enum} *} -class enum = finite + -- FIXME +class enum = itself + fixes enum :: "'a list" - assumes enum_all: "set enum = UNIV" + assumes UNIV_enum [code func]: "UNIV = set enum" + and enum_distinct: "distinct enum" begin +lemma finite_enum: "finite (UNIV \ 'a set)" + unfolding UNIV_enum .. + +lemma enum_all: "set enum = UNIV" unfolding UNIV_enum .. + lemma in_enum [intro]: "x \ set enum" unfolding enum_all by auto @@ -32,8 +38,6 @@ subsection {* Equality and order on functions *} -declare eq_fun [code func del] order_fun [code func del] - instance "fun" :: (enum, eq) eq .. lemma eq_fun [code func]: @@ -50,6 +54,120 @@ subsection {* Default instances *} +primrec n_lists :: "nat \ 'a list \ 'a list list" where + "n_lists 0 xs = [[]]" + | "n_lists (Suc n) xs = concat (map (\ys. map (\y. y # ys) xs) (n_lists n xs))" + +lemma n_lists_Nil [simp]: "n_lists n [] = (if n = 0 then [[]] else [])" + by (induct n) simp_all + +lemma length_n_lists: "length (n_lists n xs) = length xs ^ n" + by (induct n) (auto simp add: length_concat map_compose [symmetric] o_def listsum_triv) + +lemma length_n_lists_elem: "ys \ set (n_lists n xs) \ length ys = n" + by (induct n arbitrary: ys) auto + +lemma set_n_lists: "set (n_lists n xs) = {ys. length ys = n \ set ys \ set xs}" +proof (rule set_ext) + fix ys :: "'a list" + show "ys \ set (n_lists n xs) \ ys \ {ys. length ys = n \ set ys \ set xs}" + proof - + have "ys \ set (n_lists n xs) \ length ys = n" + by (induct n arbitrary: ys) auto + moreover have "\x. ys \ set (n_lists n xs) \ x \ set ys \ x \ set xs" + by (induct n arbitrary: ys) auto + moreover have "set ys \ set xs \ ys \ set (n_lists (length ys) xs)" + by (induct ys) auto + ultimately show ?thesis by auto + qed +qed + +lemma distinct_n_lists: + assumes "distinct xs" + shows "distinct (n_lists n xs)" +proof (rule card_distinct) + from assms have card_length: "card (set xs) = length xs" by (rule distinct_card) + have "card (set (n_lists n xs)) = card (set xs) ^ n" + proof (induct n) + case 0 then show ?case by simp + next + case (Suc n) + moreover have "card (\ys\set (n_lists n xs). (\y. y # ys) ` set xs) + = (\ys\set (n_lists n xs). card ((\y. y # ys) ` set xs))" + by (rule card_UN_disjoint) auto + moreover have "\ys. card ((\y. y # ys) ` set xs) = card (set xs)" + by (rule card_image) (simp add: inj_on_def) + ultimately show ?case by auto + qed + also have "\ = length xs ^ n" by (simp add: card_length) + finally show "card (set (n_lists n xs)) = length (n_lists n xs)" + by (simp add: length_n_lists) +qed + +lemma map_of_zip_map: + fixes f :: "'a\enum \ 'b\enum" + shows "map_of (zip xs (map f xs)) = (\x. if x \ set xs then Some (f x) else None)" + by (induct xs) (simp_all add: expand_fun_eq) + +lemma map_of_zip_enum_is_Some: + assumes "length ys = length (enum \ 'a\enum list)" + shows "\y. map_of (zip (enum \ 'a\enum list) ys) x = Some y" +proof - + from assms have "x \ set (enum \ 'a\enum list) \ + (\y. map_of (zip (enum \ 'a\enum list) ys) x = Some y)" + by (auto intro!: map_of_zip_is_Some) + then show ?thesis using enum_all by auto +qed + +lemma map_of_zip_enum_inject: + fixes xs ys :: "'b\enum list" + assumes length: "length xs = length (enum \ 'a\enum list)" + "length ys = length (enum \ 'a\enum list)" + and map_of: "the \ map_of (zip (enum \ 'a\enum list) xs) = the \ map_of (zip (enum \ 'a\enum list) ys)" + shows "xs = ys" +proof - + have "map_of (zip (enum \ 'a list) xs) = map_of (zip (enum \ 'a list) ys)" + proof + fix x :: 'a + from length map_of_zip_enum_is_Some obtain y1 y2 + where "map_of (zip (enum \ 'a list) xs) x = Some y1" + and "map_of (zip (enum \ 'a list) ys) x = Some y2" by blast + moreover from map_of have "the (map_of (zip (enum \ 'a\enum list) xs) x) = the (map_of (zip (enum \ 'a\enum list) ys) x)" + by (auto dest: fun_cong) + ultimately show "map_of (zip (enum \ 'a\enum list) xs) x = map_of (zip (enum \ 'a\enum list) ys) x" + by simp + qed + with length enum_distinct show "xs = ys" by (rule map_of_zip_inject) +qed + +instantiation "fun" :: (enum, enum) enum +begin + +definition + [code func del]: "enum = map (\ys. the o map_of (zip (enum\'a list) ys)) (n_lists (length (enum\'a\enum list)) enum)" + +instance proof + show "UNIV = set (enum \ ('a \ 'b) list)" + proof (rule UNIV_eq_I) + fix f :: "'a \ 'b" + have "f = the \ map_of (zip (enum \ 'a\enum list) (map f enum))" + by (auto simp add: map_of_zip_map expand_fun_eq) + then show "f \ set enum" + by (auto simp add: enum_fun_def set_n_lists) + qed +next + from map_of_zip_enum_inject + show "distinct (enum \ ('a \ 'b) list)" + by (auto intro!: inj_onI simp add: enum_fun_def + distinct_map distinct_n_lists enum_distinct set_n_lists enum_all) +qed + +end + +lemma [code func]: + "enum = map (\ys. the o map_of (zip (enum\('a\{enum, eq}) list) ys)) (n_lists (length (enum\'a\{enum, eq} list)) enum)" + unfolding enum_fun_def .. + instantiation unit :: enum begin @@ -57,7 +175,7 @@ "enum = [()]" instance by default - (simp add: enum_unit_def UNIV_unit) + (simp_all add: enum_unit_def UNIV_unit) end @@ -68,7 +186,7 @@ "enum = [False, True]" instance by default - (simp add: enum_bool_def UNIV_bool) + (simp_all add: enum_bool_def UNIV_bool) end @@ -80,6 +198,12 @@ "set (product xs ys) = set xs \ set ys" by (induct xs) auto +lemma distinct_product: + assumes "distinct xs" and "distinct ys" + shows "distinct (product xs ys)" + using assms by (induct xs) + (auto intro: inj_onI simp add: product_list_set distinct_map) + instantiation * :: (enum, enum) enum begin @@ -87,7 +211,7 @@ "enum = product enum enum" instance by default - (simp add: enum_prod_def product_list_set enum_all) + (simp_all add: enum_prod_def product_list_set distinct_product enum_all enum_distinct) end @@ -98,7 +222,7 @@ "enum = map Inl enum @ map Inr enum" instance by default - (auto simp add: enum_all enum_sum_def, case_tac x, auto) + (auto simp add: enum_all enum_sum_def, case_tac x, auto intro: inj_onI simp add: distinct_map enum_distinct) end @@ -106,14 +230,31 @@ "sublists [] = [[]]" | "sublists (x#xs) = (let xss = sublists xs in map (Cons x) xss @ xss)" +lemma length_sublists: + "length (sublists xs) = Suc (Suc (0\nat)) ^ length xs" + by (induct xs) (simp_all add: Let_def) + lemma sublists_powset: - "set (map set (sublists xs)) = Pow (set xs)" + "set ` set (sublists xs) = Pow (set xs)" proof - have aux: "\x A. set ` Cons x ` A = insert x ` set ` A" by (auto simp add: image_def) - show ?thesis + have "set (map set (sublists xs)) = Pow (set xs)" by (induct xs) - (simp_all add: aux Let_def Pow_insert Un_commute) + (simp_all add: aux Let_def Pow_insert Un_commute) + then show ?thesis by simp +qed + +lemma distinct_set_sublists: + assumes "distinct xs" + shows "distinct (map set (sublists xs))" +proof (rule card_distinct) + have "finite (set xs)" by rule + then have "card (Pow (set xs)) = Suc (Suc 0) ^ card (set xs)" by (rule card_Pow) + with assms distinct_card [of xs] + have "card (Pow (set xs)) = Suc (Suc 0) ^ length xs" by simp + then show "card (set (map set (sublists xs))) = length (map set (sublists xs))" + by (simp add: sublists_powset length_sublists) qed instantiation set :: (enum) enum @@ -123,7 +264,7 @@ "enum = map set (sublists enum)" instance by default - (simp add: enum_set_def sublists_powset enum_all del: set_map) + (simp_all add: enum_set_def enum_all sublists_powset distinct_set_sublists enum_distinct) end @@ -135,7 +276,7 @@ Nibble8, Nibble9, NibbleA, NibbleB, NibbleC, NibbleD, NibbleE, NibbleF]" instance by default - (simp add: enum_nibble_def UNIV_nibble) + (simp_all add: enum_nibble_def UNIV_nibble) end @@ -143,31 +284,83 @@ begin definition - "enum = map (split Char) (product enum enum)" + [code func del]: "enum = map (split Char) (product enum enum)" + +lemma enum_char [code func]: + "enum = [Char Nibble0 Nibble0, Char Nibble0 Nibble1, Char Nibble0 Nibble2, + Char Nibble0 Nibble3, Char Nibble0 Nibble4, Char Nibble0 Nibble5, + Char Nibble0 Nibble6, Char Nibble0 Nibble7, Char Nibble0 Nibble8, + Char Nibble0 Nibble9, Char Nibble0 NibbleA, Char Nibble0 NibbleB, + Char Nibble0 NibbleC, Char Nibble0 NibbleD, Char Nibble0 NibbleE, + Char Nibble0 NibbleF, Char Nibble1 Nibble0, Char Nibble1 Nibble1, + Char Nibble1 Nibble2, Char Nibble1 Nibble3, Char Nibble1 Nibble4, + Char Nibble1 Nibble5, Char Nibble1 Nibble6, Char Nibble1 Nibble7, + Char Nibble1 Nibble8, Char Nibble1 Nibble9, Char Nibble1 NibbleA, + Char Nibble1 NibbleB, Char Nibble1 NibbleC, Char Nibble1 NibbleD, + Char Nibble1 NibbleE, Char Nibble1 NibbleF, CHR '' '', CHR ''!'', + Char Nibble2 Nibble2, CHR ''#'', CHR ''$'', CHR ''%'', CHR ''&'', + Char Nibble2 Nibble7, CHR ''('', CHR '')'', CHR ''*'', CHR ''+'', CHR '','', + CHR ''-'', CHR ''.'', CHR ''/'', CHR ''0'', CHR ''1'', CHR ''2'', CHR ''3'', + CHR ''4'', CHR ''5'', CHR ''6'', CHR ''7'', CHR ''8'', CHR ''9'', CHR '':'', + CHR '';'', CHR ''<'', CHR ''='', CHR ''>'', CHR ''?'', CHR ''@'', CHR ''A'', + CHR ''B'', CHR ''C'', CHR ''D'', CHR ''E'', CHR ''F'', CHR ''G'', CHR ''H'', + CHR ''I'', CHR ''J'', CHR ''K'', CHR ''L'', CHR ''M'', CHR ''N'', CHR ''O'', + CHR ''P'', CHR ''Q'', CHR ''R'', CHR ''S'', CHR ''T'', CHR ''U'', CHR ''V'', + CHR ''W'', CHR ''X'', CHR ''Y'', CHR ''Z'', CHR ''['', Char Nibble5 NibbleC, + CHR '']'', CHR ''^'', CHR ''_'', Char Nibble6 Nibble0, CHR ''a'', CHR ''b'', + CHR ''c'', CHR ''d'', CHR ''e'', CHR ''f'', CHR ''g'', CHR ''h'', CHR ''i'', + CHR ''j'', CHR ''k'', CHR ''l'', CHR ''m'', CHR ''n'', CHR ''o'', CHR ''p'', + CHR ''q'', CHR ''r'', CHR ''s'', CHR ''t'', CHR ''u'', CHR ''v'', CHR ''w'', + CHR ''x'', CHR ''y'', CHR ''z'', CHR ''{'', CHR ''|'', CHR ''}'', CHR ''~'', + Char Nibble7 NibbleF, Char Nibble8 Nibble0, Char Nibble8 Nibble1, + Char Nibble8 Nibble2, Char Nibble8 Nibble3, Char Nibble8 Nibble4, + Char Nibble8 Nibble5, Char Nibble8 Nibble6, Char Nibble8 Nibble7, + Char Nibble8 Nibble8, Char Nibble8 Nibble9, Char Nibble8 NibbleA, + Char Nibble8 NibbleB, Char Nibble8 NibbleC, Char Nibble8 NibbleD, + Char Nibble8 NibbleE, Char Nibble8 NibbleF, Char Nibble9 Nibble0, + Char Nibble9 Nibble1, Char Nibble9 Nibble2, Char Nibble9 Nibble3, + Char Nibble9 Nibble4, Char Nibble9 Nibble5, Char Nibble9 Nibble6, + Char Nibble9 Nibble7, Char Nibble9 Nibble8, Char Nibble9 Nibble9, + Char Nibble9 NibbleA, Char Nibble9 NibbleB, Char Nibble9 NibbleC, + Char Nibble9 NibbleD, Char Nibble9 NibbleE, Char Nibble9 NibbleF, + Char NibbleA Nibble0, Char NibbleA Nibble1, Char NibbleA Nibble2, + Char NibbleA Nibble3, Char NibbleA Nibble4, Char NibbleA Nibble5, + Char NibbleA Nibble6, Char NibbleA Nibble7, Char NibbleA Nibble8, + Char NibbleA Nibble9, Char NibbleA NibbleA, Char NibbleA NibbleB, + Char NibbleA NibbleC, Char NibbleA NibbleD, Char NibbleA NibbleE, + Char NibbleA NibbleF, Char NibbleB Nibble0, Char NibbleB Nibble1, + Char NibbleB Nibble2, Char NibbleB Nibble3, Char NibbleB Nibble4, + Char NibbleB Nibble5, Char NibbleB Nibble6, Char NibbleB Nibble7, + Char NibbleB Nibble8, Char NibbleB Nibble9, Char NibbleB NibbleA, + Char NibbleB NibbleB, Char NibbleB NibbleC, Char NibbleB NibbleD, + Char NibbleB NibbleE, Char NibbleB NibbleF, Char NibbleC Nibble0, + Char NibbleC Nibble1, Char NibbleC Nibble2, Char NibbleC Nibble3, + Char NibbleC Nibble4, Char NibbleC Nibble5, Char NibbleC Nibble6, + Char NibbleC Nibble7, Char NibbleC Nibble8, Char NibbleC Nibble9, + Char NibbleC NibbleA, Char NibbleC NibbleB, Char NibbleC NibbleC, + Char NibbleC NibbleD, Char NibbleC NibbleE, Char NibbleC NibbleF, + Char NibbleD Nibble0, Char NibbleD Nibble1, Char NibbleD Nibble2, + Char NibbleD Nibble3, Char NibbleD Nibble4, Char NibbleD Nibble5, + Char NibbleD Nibble6, Char NibbleD Nibble7, Char NibbleD Nibble8, + Char NibbleD Nibble9, Char NibbleD NibbleA, Char NibbleD NibbleB, + Char NibbleD NibbleC, Char NibbleD NibbleD, Char NibbleD NibbleE, + Char NibbleD NibbleF, Char NibbleE Nibble0, Char NibbleE Nibble1, + Char NibbleE Nibble2, Char NibbleE Nibble3, Char NibbleE Nibble4, + Char NibbleE Nibble5, Char NibbleE Nibble6, Char NibbleE Nibble7, + Char NibbleE Nibble8, Char NibbleE Nibble9, Char NibbleE NibbleA, + Char NibbleE NibbleB, Char NibbleE NibbleC, Char NibbleE NibbleD, + Char NibbleE NibbleE, Char NibbleE NibbleF, Char NibbleF Nibble0, + Char NibbleF Nibble1, Char NibbleF Nibble2, Char NibbleF Nibble3, + Char NibbleF Nibble4, Char NibbleF Nibble5, Char NibbleF Nibble6, + Char NibbleF Nibble7, Char NibbleF Nibble8, Char NibbleF Nibble9, + Char NibbleF NibbleA, Char NibbleF NibbleB, Char NibbleF NibbleC, + Char NibbleF NibbleD, Char NibbleF NibbleE, Char NibbleF NibbleF]" + unfolding enum_char_def enum_nibble_def by simp instance by default - (auto intro: char.exhaust simp add: enum_char_def product_list_set enum_all full_SetCompr_eq [symmetric]) + (auto intro: char.exhaust injI simp add: enum_char_def product_list_set enum_all full_SetCompr_eq [symmetric] + distinct_map distinct_product enum_distinct) end -(*instantiation "fun" :: (enum, enum) enum -begin - - -definition - "enum - -lemma inj_graph: "inj (%f. {(x, y). y = f x})" - by (rule inj_onI, auto simp add: expand_set_eq expand_fun_eq) - -instance "fun" :: (finite, finite) finite -proof - show "finite (UNIV :: ('a => 'b) set)" - proof (rule finite_imageD) - let ?graph = "%f::'a => 'b. {(x, y). y = f x}" - show "finite (range ?graph)" by (rule finite) - show "inj ?graph" by (rule inj_graph) - qed -qed*) - end \ No newline at end of file