# HG changeset patch # User haftmann # Date 1202283272 -3600 # Node ID c2e15e65165f2a446110f927e539869f50096884 # Parent 08d52e2dba07ad44046bf562de827688c66f0943 locales ACf, ACIf, ACIfSL and ACIfSLlin have been abandoned in favour of the existing algebraic classes ab_semigroup_mult, ab_semigroup_idem_mult, lower_semilattice (resp. uper_semilattice) and linorder diff -r 08d52e2dba07 -r c2e15e65165f NEWS --- a/NEWS Mon Feb 04 17:00:01 2008 +0100 +++ b/NEWS Wed Feb 06 08:34:32 2008 +0100 @@ -35,6 +35,11 @@ *** HOL *** +* Theory Finite_Set: locales ACf, ACIf, ACIfSL and ACIfSLlin (whose purpose +mainly if for various fold_set functionals) have been abandoned in favour of +the existing algebraic classes ab_semigroup_mult, ab_semigroup_idem_mult, +lower_semilattice (resp. uper_semilattice) and linorder. INCOMPATIBILITY. + * Theorem Inductive.lfp_ordinal_induct generalized to complete lattices. The form set-specific version is available as Inductive.lfp_ordinal_induct_set. diff -r 08d52e2dba07 -r c2e15e65165f src/HOL/Finite_Set.thy --- a/src/HOL/Finite_Set.thy Mon Feb 04 17:00:01 2008 +0100 +++ b/src/HOL/Finite_Set.thy Wed Feb 06 08:34:32 2008 +0100 @@ -420,6 +420,157 @@ done +subsection {* Class @{text finite} and code generation *} + +lemma finite_code [code func]: + "finite {} \ True" + "finite (insert a A) \ finite A" + by auto + +setup {* Sign.add_path "finite" *} -- {*FIXME: name tweaking*} +class finite (attach UNIV) = type + + fixes itself :: "'a itself" + assumes finite_UNIV: "finite (UNIV \ 'a set)" +setup {* Sign.parent_path *} +hide const finite + +lemma finite [simp]: "finite (A \ 'a\finite set)" + by (rule finite_subset [OF subset_UNIV finite_UNIV]) + +lemma univ_unit [noatp]: + "UNIV = {()}" by auto + +instantiation unit :: finite +begin + +definition + "itself = TYPE(unit)" + +instance proof + have "finite {()}" by simp + also note univ_unit [symmetric] + finally show "finite (UNIV :: unit set)" . +qed + +end + +lemmas [code func] = univ_unit + +lemma univ_bool [noatp]: + "UNIV = {False, True}" by auto + +instantiation bool :: finite +begin + +definition + "itself = TYPE(bool)" + +instance proof + have "finite {False, True}" by simp + also note univ_bool [symmetric] + finally show "finite (UNIV :: bool set)" . +qed + +end + +lemmas [code func] = univ_bool + +instantiation * :: (finite, finite) finite +begin + +definition + "itself = TYPE('a \ 'b)" + +instance proof + show "finite (UNIV :: ('a \ 'b) set)" + proof (rule finite_Prod_UNIV) + show "finite (UNIV :: 'a set)" by (rule finite) + show "finite (UNIV :: 'b set)" by (rule finite) + qed +qed + +end + +lemma univ_prod [noatp, code func]: + "UNIV = (UNIV \ 'a\finite set) \ (UNIV \ 'b\finite set)" + unfolding UNIV_Times_UNIV .. + +instantiation "+" :: (finite, finite) finite +begin + +definition + "itself = TYPE('a + 'b)" + +instance proof + have a: "finite (UNIV :: 'a set)" by (rule finite) + have b: "finite (UNIV :: 'b set)" by (rule finite) + from a b have "finite ((UNIV :: 'a set) <+> (UNIV :: 'b set))" + by (rule finite_Plus) + thus "finite (UNIV :: ('a + 'b) set)" by simp +qed + +end + +lemma univ_sum [noatp, code func]: + "UNIV = (UNIV \ 'a\finite set) <+> (UNIV \ 'b\finite set)" + unfolding UNIV_Plus_UNIV .. + +instantiation set :: (finite) finite +begin + +definition + "itself = TYPE('a set)" + +instance proof + have "finite (UNIV :: 'a set)" by (rule finite) + hence "finite (Pow (UNIV :: 'a set))" + by (rule finite_Pow_iff [THEN iffD2]) + thus "finite (UNIV :: 'a set set)" by simp +qed + +end + +lemma univ_set [noatp, code func]: + "UNIV = Pow (UNIV \ 'a\finite set)" unfolding Pow_UNIV .. + +lemma inj_graph: "inj (%f. {(x, y). y = f x})" + by (rule inj_onI, auto simp add: expand_set_eq expand_fun_eq) + +instantiation "fun" :: (finite, finite) finite +begin + +definition + "itself \ TYPE('a \ 'b)" + +instance 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 + +hide (open) const itself + +subsection {* Equality and order on functions *} + +instance "fun" :: (finite, eq) eq .. + +lemma eq_fun [code func]: + fixes f g :: "'a\finite \ 'b\eq" + shows "f = g \ (\x\UNIV. f x = g x)" + unfolding expand_fun_eq by auto + +lemma order_fun [code func]: + fixes f g :: "'a\finite \ 'b\order" + shows "f \ g \ (\x\UNIV. f x \ g x)" + and "f < g \ f \ g \ (\x\UNIV. f x \ g x)" + by (auto simp add: expand_fun_eq le_fun_def less_fun_def order_less_le) + + subsection {* A fold functional for finite sets *} text {* The intended behaviour is @@ -463,56 +614,6 @@ by (induct set: finite) auto -subsubsection {* Commutative monoids *} - -(*FIXME integrate with Orderings.thy/OrderedGroup.thy*) -locale ACf = - fixes f :: "'a => 'a => 'a" (infixl "\" 70) - assumes commute: "x \ y = y \ x" - and assoc: "(x \ y) \ z = x \ (y \ z)" -begin - -lemma left_commute: "x \ (y \ z) = y \ (x \ z)" -proof - - have "x \ (y \ z) = (y \ z) \ x" by (simp only: commute) - also have "... = y \ (z \ x)" by (simp only: assoc) - also have "z \ x = x \ z" by (simp only: commute) - finally show ?thesis . -qed - -lemmas AC = assoc commute left_commute - -end - -locale ACe = ACf + - fixes e :: 'a - assumes ident [simp]: "x \ e = x" -begin - -lemma left_ident [simp]: "e \ x = x" -proof - - have "x \ e = x" by (rule ident) - thus ?thesis by (subst commute) -qed - -end - -locale ACIf = ACf + - assumes idem: "x \ x = x" -begin - -lemma idem2: "x \ (x \ y) = x \ y" -proof - - have "x \ (x \ y) = (x \ x) \ y" by(simp add:assoc) - also have "\ = x \ y" by(simp add:idem) - finally show ?thesis . -qed - -lemmas ACI = AC idem idem2 - -end - - subsubsection{*From @{term foldSet} to @{term fold}*} lemma image_less_Suc: "h ` {i. i < Suc m} = insert (h m) (h ` {i. i < m})" @@ -557,16 +658,19 @@ qed qed -lemma (in ACf) foldSet_determ_aux: +context ab_semigroup_mult +begin + +lemma foldSet_determ_aux: "!!A x x' h. \ A = h`{i::nat. i + foldSet times g z A x; foldSet times g z A x' \ \ x' = x" proof (induct n rule: less_induct) case (less n) have IH: "!!m h A x x'. \m \ x' = x" by fact - have Afoldx: "foldSet f g z A x" and Afoldx': "foldSet f g z A x'" + foldSet times g z A x; foldSet times g z A x'\ \ x' = x" by fact + have Afoldx: "foldSet times g z A x" and Afoldx': "foldSet times g z A x'" and A: "A = h`{i. i u" - and notinB: "b \ B" and Bu: "foldSet f g z B u" + assume AbB: "A = insert b B" and x: "x = g b * u" + and notinB: "b \ B" and Bu: "foldSet times g z B u" show "x'=x" proof (rule foldSet.cases [OF Afoldx']) assume "A = {}" and "x' = z" with AbB show "x' = x" by blast next fix C c v - assume AcC: "A = insert c C" and x': "x' = g c \ v" - and notinC: "c \ C" and Cv: "foldSet f g z C v" + assume AcC: "A = insert c C" and x': "x' = g c * v" + and notinC: "c \ C" and Cv: "foldSet times g z C v" from A AbB have Beq: "insert b B = h`{i. i B" using B by auto - ultimately have "foldSet f g z B (g c \ d)" + ultimately have "foldSet times g z B (g c * d)" by(rule Diff1_foldSet) - hence "g c \ d = u" by (rule IH [OF lessB Beq inj_onB Bu]) - moreover have "g b \ d = v" - proof (rule IH[OF lessC Ceq inj_onC Cv]) - show "foldSet f g z C (g b \ d)" using C notinB Dfoldd + then have "g c * d = u" by (rule IH [OF lessB Beq inj_onB Bu]) + then have "u = g c * d" .. + moreover have "v = g b * d" + proof (rule sym, rule IH [OF lessC Ceq inj_onC Cv]) + show "foldSet times g z C (g b * d)" using C notinB Dfoldd by fastsimp qed - ultimately show ?thesis using x x' by (auto simp: AC) + ultimately show ?thesis using x x' + by (simp add: mult_left_commute) qed qed qed qed - -lemma (in ACf) foldSet_determ: - "foldSet f g z A x ==> foldSet f g z A y ==> y = x" +lemma foldSet_determ: + "foldSet times g z A x ==> foldSet times g z A y ==> y = x" apply (frule foldSet_imp_finite [THEN finite_imp_nat_seg_image_inj_on]) apply (blast intro: foldSet_determ_aux [rule_format]) done -lemma (in ACf) fold_equality: "foldSet f g z A y ==> fold f g z A = y" +lemma fold_equality: "foldSet times g z A y ==> fold times g z A = y" by (unfold fold_def) (blast intro: foldSet_determ) text{* The base case for @{text fold}: *} -lemma fold_empty [simp]: "fold f g z {} = z" +lemma (in -) fold_empty [simp]: "fold f g z {} = z" by (unfold fold_def) blast -lemma (in ACf) fold_insert_aux: "x \ A ==> - (foldSet f g z (insert x A) v) = - (EX y. foldSet f g z A y & v = f (g x) y)" +lemma fold_insert_aux: "x \ A ==> + (foldSet times g z (insert x A) v) = + (EX y. foldSet times g z A y & v = g x * y)" apply auto - apply (rule_tac A1 = A and f1 = f in finite_imp_foldSet [THEN exE]) + apply (rule_tac A1 = A and f1 = times in finite_imp_foldSet [THEN exE]) apply (fastsimp dest: foldSet_imp_finite) apply (blast intro: foldSet_determ) done text{* The recursion equation for @{text fold}: *} -lemma (in ACf) fold_insert[simp]: - "finite A ==> x \ A ==> fold f g z (insert x A) = f (g x) (fold f g z A)" +lemma fold_insert [simp]: + "finite A ==> x \ A ==> fold times g z (insert x A) = g x * fold times g z A" apply (unfold fold_def) apply (simp add: fold_insert_aux) apply (rule the_equality) @@ -659,23 +764,27 @@ cong add: conj_cong simp add: fold_def [symmetric] fold_equality) done -lemma (in ACf) fold_rec: +lemma fold_rec: assumes fin: "finite A" and a: "a:A" -shows "fold f g z A = f (g a) (fold f g z (A - {a}))" +shows "fold times g z A = g a * fold times g z (A - {a})" proof- have A: "A = insert a (A - {a})" using a by blast - hence "fold f g z A = fold f g z (insert a (A - {a}))" by simp - also have "\ = f (g a) (fold f g z (A - {a}))" + hence "fold times g z A = fold times g z (insert a (A - {a}))" by simp + also have "\ = g a * fold times g z (A - {a})" by(rule fold_insert) (simp add:fin)+ finally show ?thesis . qed +end text{* A simplified version for idempotent functions: *} -lemma (in ACIf) fold_insert_idem: +context ab_semigroup_idem_mult +begin + +lemma fold_insert_idem: assumes finA: "finite A" -shows "fold f g z (insert a A) = g a \ fold f g z A" +shows "fold times g z (insert a A) = g a * fold times g z A" proof cases assume "a \ A" then obtain B where A: "A = insert a B" and disj: "a \ B" @@ -683,11 +792,12 @@ show ?thesis proof - from finA A have finB: "finite B" by(blast intro: finite_subset) - have "fold f g z (insert a A) = fold f g z (insert a B)" using A by simp - also have "\ = (g a) \ (fold f g z B)" + have "fold times g z (insert a A) = fold times g z (insert a B)" using A by simp + also have "\ = g a * fold times g z B" using finB disj by simp - also have "\ = g a \ fold f g z A" - using A finB disj by(simp add:idem assoc[symmetric]) + also have "\ = g a * fold times g z A" + using A finB disj + by (simp add: mult_idem mult_assoc [symmetric]) finally show ?thesis . qed next @@ -695,81 +805,61 @@ with finA show ?thesis by simp qed -lemma (in ACIf) foldI_conv_id: - "finite A \ fold f g z A = fold f id z (g ` A)" +lemma foldI_conv_id: + "finite A \ fold times g z A = fold times id z (g ` A)" by(erule finite_induct)(simp_all add: fold_insert_idem del: fold_insert) +end + subsubsection{*Lemmas about @{text fold}*} -lemma (in ACf) fold_commute: - "finite A ==> (!!z. f x (fold f g z A) = fold f g (f x z) A)" +context ab_semigroup_mult +begin + +lemma fold_commute: + "finite A ==> (!!z. x * (fold times g z A) = fold times g (x * z) A)" apply (induct set: finite) apply simp - apply (simp add: left_commute [of x]) + apply (simp add: mult_left_commute [of x]) done -lemma (in ACf) fold_nest_Un_Int: +lemma fold_nest_Un_Int: "finite A ==> finite B - ==> fold f g (fold f g z B) A = fold f g (fold f g z (A Int B)) (A Un B)" + ==> fold times g (fold times g z B) A = fold times g (fold times g z (A Int B)) (A Un B)" apply (induct set: finite) apply simp apply (simp add: fold_commute Int_insert_left insert_absorb) done -lemma (in ACf) fold_nest_Un_disjoint: +lemma fold_nest_Un_disjoint: "finite A ==> finite B ==> A Int B = {} - ==> fold f g z (A Un B) = fold f g (fold f g z B) A" + ==> fold times g z (A Un B) = fold times g (fold times g z B) A" by (simp add: fold_nest_Un_Int) -lemma (in ACf) fold_reindex: +lemma fold_reindex: assumes fin: "finite A" -shows "inj_on h A \ fold f g z (h ` A) = fold f (g \ h) z A" +shows "inj_on h A \ fold times g z (h ` A) = fold times (g \ h) z A" using fin apply induct apply simp apply simp done -lemma (in ACe) fold_Un_Int: - "finite A ==> finite B ==> - fold f g e A \ fold f g e B = - fold f g e (A Un B) \ fold f g e (A Int B)" - apply (induct set: finite, simp) - apply (simp add: AC insert_absorb Int_insert_left) - done - -corollary (in ACe) fold_Un_disjoint: - "finite A ==> finite B ==> A Int B = {} ==> - fold f g e (A Un B) = fold f g e A \ fold f g e B" - by (simp add: fold_Un_Int) - -lemma (in ACe) fold_UN_disjoint: - "\ finite I; ALL i:I. finite (A i); - ALL i:I. ALL j:I. i \ j --> A i Int A j = {} \ - \ fold f g e (UNION I A) = - fold f (%i. fold f g e (A i)) e I" - apply (induct set: finite, simp, atomize) - apply (subgoal_tac "ALL i:F. x \ i") - prefer 2 apply blast - apply (subgoal_tac "A x Int UNION F A = {}") - prefer 2 apply blast - apply (simp add: fold_Un_disjoint) - done - -text{*Fusion theorem, as described in -Graham Hutton's paper, -A Tutorial on the Universality and Expressiveness of Fold, -JFP 9:4 (355-372), 1999.*} -lemma (in ACf) fold_fusion: - includes ACf g - shows - "finite A ==> - (!!x y. h (g x y) = f x (h y)) ==> - h (fold g j w A) = fold f j (h w) A" - by (induct set: finite) simp_all - -lemma (in ACf) fold_cong: - "finite A \ (!!x. x:A ==> g x = h x) ==> fold f g z A = fold f h z A" - apply (subgoal_tac "ALL C. C <= A --> (ALL x:C. g x = h x) --> fold f g z C = fold f h z C") +text{* + Fusion theorem, as described in Graham Hutton's paper, + A Tutorial on the Universality and Expressiveness of Fold, + JFP 9:4 (355-372), 1999. +*} + +lemma fold_fusion: + includes ab_semigroup_mult g + assumes fin: "finite A" + and hyp: "\x y. h (g x y) = times x (h y)" + shows "h (fold g j w A) = fold times j (h w) A" + using fin hyp by (induct set: finite) simp_all + +lemma fold_cong: + "finite A \ (!!x. x:A ==> g x = h x) ==> fold times g z A = fold times h z A" + apply (subgoal_tac "ALL C. C <= A --> (ALL x:C. g x = h x) --> fold times g z C = fold times h z C") apply simp apply (erule finite_induct, simp) apply (simp add: subset_insert_iff, clarify) @@ -783,9 +873,39 @@ apply (simp add: Ball_def del: insert_Diff_single) done -lemma (in ACe) fold_Sigma: "finite A ==> ALL x:A. finite (B x) ==> - fold f (%x. fold f (g x) e (B x)) e A = - fold f (split g) e (SIGMA x:A. B x)" +end + +context comm_monoid_mult +begin + +lemma fold_Un_Int: + "finite A ==> finite B ==> + fold times g 1 A * fold times g 1 B = + fold times g 1 (A Un B) * fold times g 1 (A Int B)" + by (induct set: finite) + (auto simp add: mult_ac insert_absorb Int_insert_left) + +corollary fold_Un_disjoint: + "finite A ==> finite B ==> A Int B = {} ==> + fold times g 1 (A Un B) = fold times g 1 A * fold times g 1 B" + by (simp add: fold_Un_Int) + +lemma fold_UN_disjoint: + "\ finite I; ALL i:I. finite (A i); + ALL i:I. ALL j:I. i \ j --> A i Int A j = {} \ + \ fold times g 1 (UNION I A) = + fold times (%i. fold times g 1 (A i)) 1 I" + apply (induct set: finite, simp, atomize) + apply (subgoal_tac "ALL i:F. x \ i") + prefer 2 apply blast + apply (subgoal_tac "A x Int UNION F A = {}") + prefer 2 apply blast + apply (simp add: fold_Un_disjoint) + done + +lemma fold_Sigma: "finite A ==> ALL x:A. finite (B x) ==> + fold times (%x. fold times (g x) 1 (B x)) 1 A = + fold times (split g) 1 (SIGMA x:A. B x)" apply (subst Sigma_def) apply (subst fold_UN_disjoint, assumption, simp) apply blast @@ -795,24 +915,18 @@ apply simp done -lemma (in ACe) fold_distrib: "finite A \ - fold f (%x. f (g x) (h x)) e A = f (fold f g e A) (fold f h e A)" -apply (erule finite_induct, simp) -apply (simp add:AC) -done - - -text{* Interpretation of locales -- see OrderedGroup.thy *} - -interpretation AC_add: ACe ["op +" "0::'a::comm_monoid_add"] - by unfold_locales (auto intro: add_assoc add_commute) - -interpretation AC_mult: ACe ["op *" "1::'a::comm_monoid_mult"] - by unfold_locales (auto intro: mult_assoc mult_commute) +lemma fold_distrib: "finite A \ + fold times (%x. g x * h x) 1 A = fold times g 1 A * fold times h 1 A" + by (erule finite_induct) (simp_all add: mult_ac) + +end subsection {* Generalized summation over a set *} +interpretation comm_monoid_add: comm_monoid_mult ["0::'a::comm_monoid_add" "op +"] + by unfold_locales (auto intro: add_assoc add_commute) + constdefs setsum :: "('a => 'b) => 'a set => 'b::comm_monoid_add" "setsum f A == if finite A then fold (op +) f 0 A else 0" @@ -873,7 +987,7 @@ lemma setsum_reindex: "inj_on f B ==> setsum h (f ` B) = setsum (h \ f) B" -by(auto simp add: setsum_def AC_add.fold_reindex dest!:finite_imageD) +by(auto simp add: setsum_def comm_monoid_add.fold_reindex dest!:finite_imageD) lemma setsum_reindex_id: "inj_on f B ==> setsum f B = setsum id (f ` B)" @@ -881,12 +995,12 @@ lemma setsum_cong: "A = B ==> (!!x. x:B ==> f x = g x) ==> setsum f A = setsum g B" -by(fastsimp simp: setsum_def intro: AC_add.fold_cong) +by(fastsimp simp: setsum_def intro: comm_monoid_add.fold_cong) lemma strong_setsum_cong[cong]: "A = B ==> (!!x. x:B =simp=> f x = g x) ==> setsum (%x. f x) A = setsum (%x. g x) B" -by(fastsimp simp: simp_implies_def setsum_def intro: AC_add.fold_cong) +by(fastsimp simp: simp_implies_def setsum_def intro: comm_monoid_add.fold_cong) lemma setsum_cong2: "\\x. x \ A \ f x = g x\ \ setsum f A = setsum g A"; by (rule setsum_cong[OF refl], auto); @@ -907,7 +1021,7 @@ lemma setsum_Un_Int: "finite A ==> finite B ==> setsum g (A Un B) + setsum g (A Int B) = setsum g A + setsum g B" -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *} -by(simp add: setsum_def AC_add.fold_Un_Int [symmetric]) +by(simp add: setsum_def comm_monoid_add.fold_Un_Int [symmetric]) lemma setsum_Un_disjoint: "finite A ==> finite B ==> A Int B = {} ==> setsum g (A Un B) = setsum g A + setsum g B" @@ -919,7 +1033,7 @@ "finite I ==> (ALL i:I. finite (A i)) ==> (ALL i:I. ALL j:I. i \ j --> A i Int A j = {}) ==> setsum f (UNION I A) = (\i\I. setsum f (A i))" -by(simp add: setsum_def AC_add.fold_UN_disjoint cong: setsum_cong) +by(simp add: setsum_def comm_monoid_add.fold_UN_disjoint cong: setsum_cong) text{*No need to assume that @{term C} is finite. If infinite, the rhs is directly 0, and @{term "Union C"} is also infinite, hence the lhs is also 0.*} @@ -937,7 +1051,7 @@ the rhs need not be, since SIGMA A B could still be finite.*) lemma setsum_Sigma: "finite A ==> ALL x:A. finite (B x) ==> (\x\A. (\y\B x. f x y)) = (\(x,y)\(SIGMA x:A. B x). f x y)" -by(simp add:setsum_def AC_add.fold_Sigma split_def cong:setsum_cong) +by(simp add:setsum_def comm_monoid_add.fold_Sigma split_def cong:setsum_cong) text{*Here we can eliminate the finiteness assumptions, by cases.*} lemma setsum_cartesian_product: @@ -952,7 +1066,7 @@ done lemma setsum_addf: "setsum (%x. f x + g x) A = (setsum f A + setsum g A)" -by(simp add:setsum_def AC_add.fold_distrib) +by(simp add:setsum_def comm_monoid_add.fold_distrib) subsubsection {* Properties in more restricted classes of structures *} @@ -1331,18 +1445,18 @@ lemma setprod_reindex: "inj_on f B ==> setprod h (f ` B) = setprod (h \ f) B" -by(auto simp: setprod_def AC_mult.fold_reindex dest!:finite_imageD) +by(auto simp: setprod_def fold_reindex dest!:finite_imageD) lemma setprod_reindex_id: "inj_on f B ==> setprod f B = setprod id (f ` B)" by (auto simp add: setprod_reindex) lemma setprod_cong: "A = B ==> (!!x. x:B ==> f x = g x) ==> setprod f A = setprod g B" -by(fastsimp simp: setprod_def intro: AC_mult.fold_cong) +by(fastsimp simp: setprod_def intro: fold_cong) lemma strong_setprod_cong: "A = B ==> (!!x. x:B =simp=> f x = g x) ==> setprod f A = setprod g B" -by(fastsimp simp: simp_implies_def setprod_def intro: AC_mult.fold_cong) +by(fastsimp simp: simp_implies_def setprod_def intro: fold_cong) lemma setprod_reindex_cong: "inj_on f A ==> B = f ` A ==> g = h \ f ==> setprod h B = setprod g A" @@ -1362,7 +1476,7 @@ lemma setprod_Un_Int: "finite A ==> finite B ==> setprod g (A Un B) * setprod g (A Int B) = setprod g A * setprod g B" -by(simp add: setprod_def AC_mult.fold_Un_Int[symmetric]) +by(simp add: setprod_def fold_Un_Int[symmetric]) lemma setprod_Un_disjoint: "finite A ==> finite B ==> A Int B = {} ==> setprod g (A Un B) = setprod g A * setprod g B" @@ -1372,7 +1486,7 @@ "finite I ==> (ALL i:I. finite (A i)) ==> (ALL i:I. ALL j:I. i \ j --> A i Int A j = {}) ==> setprod f (UNION I A) = setprod (%i. setprod f (A i)) I" -by(simp add: setprod_def AC_mult.fold_UN_disjoint cong: setprod_cong) +by(simp add: setprod_def fold_UN_disjoint cong: setprod_cong) lemma setprod_Union_disjoint: "[| (ALL A:C. finite A); @@ -1387,7 +1501,7 @@ lemma setprod_Sigma: "finite A ==> ALL x:A. finite (B x) ==> (\x\A. (\y\ B x. f x y)) = (\(x,y)\(SIGMA x:A. B x). f x y)" -by(simp add:setprod_def AC_mult.fold_Sigma split_def cong:setprod_cong) +by(simp add:setprod_def fold_Sigma split_def cong:setprod_cong) text{*Here we can eliminate the finiteness assumptions, by cases.*} lemma setprod_cartesian_product: @@ -1403,7 +1517,7 @@ lemma setprod_timesf: "setprod (%x. f x * g x) A = (setprod f A * setprod g A)" -by(simp add:setprod_def AC_mult.fold_distrib) +by(simp add:setprod_def fold_distrib) subsubsection {* Properties in more restricted classes of structures *} @@ -1555,6 +1669,12 @@ lemma card_insert: "finite A ==> card (insert x A) = Suc (card (A - {x}))" by (simp add: card_insert_if card_Suc_Diff1 del:card_Diff_insert) +lemma card_code [code func]: + "card {} = 0" + "card (insert a A) = + (if finite A then Suc (card (A - {a})) else card (insert a A))" + by (auto simp add: card_insert) + lemma card_insert_le: "finite A ==> card A <= card (insert x A)" by (simp add: card_insert_if) @@ -1701,10 +1821,14 @@ text{*The image of a finite set can be expressed using @{term fold}.*} lemma image_eq_fold: "finite A ==> f ` A = fold (op Un) (%x. {f x}) {} A" - apply (erule finite_induct, simp) - apply (subst ACf.fold_insert) - apply (auto simp add: ACf_def) - done +proof (induct rule: finite_induct) + case empty then show ?case by simp +next + invoke ab_semigroup_mult ["op Un"] + by unfold_locales auto + case insert + then show ?case by simp +qed lemma card_image_le: "finite A ==> card (f ` A) <= card A" apply (induct set: finite) @@ -1861,22 +1985,25 @@ text{*First, some lemmas about @{term foldSet}.*} -lemma (in ACf) foldSet_insert_swap: -assumes fold: "foldSet f id b A y" -shows "b \ A \ foldSet f id z (insert b A) (z \ y)" +context ab_semigroup_mult +begin + +lemma foldSet_insert_swap: +assumes fold: "foldSet times id b A y" +shows "b \ A \ foldSet times id z (insert b A) (z * y)" using fold proof (induct rule: foldSet.induct) - case emptyI thus ?case by (force simp add: fold_insert_aux commute) + case emptyI thus ?case by (force simp add: fold_insert_aux mult_commute) next case (insertI x A y) - have "foldSet f (\u. u) z (insert x (insert b A)) (x \ (z \ y))" + have "foldSet times (\u. u) z (insert x (insert b A)) (x * (z * y))" using insertI by force --{*how does @{term id} get unfolded?*} - thus ?case by (simp add: insert_commute AC) + thus ?case by (simp add: insert_commute mult_ac) qed -lemma (in ACf) foldSet_permute_diff: -assumes fold: "foldSet f id b A x" -shows "!!a. \a \ A; b \ A\ \ foldSet f id a (insert b (A-{a})) x" +lemma foldSet_permute_diff: +assumes fold: "foldSet times id b A x" +shows "!!a. \a \ A; b \ A\ \ foldSet times id a (insert b (A-{a})) x" using fold proof (induct rule: foldSet.induct) case emptyI thus ?case by simp @@ -1890,7 +2017,7 @@ by (simp add: id_def [symmetric], blast intro: foldSet_insert_swap) next assume ainA: "a \ A" - hence "foldSet f id a (insert x (insert b (A - {a}))) (x \ y)" + hence "foldSet times id a (insert x (insert b (A - {a}))) (x * y)" using insertI by (force simp: id_def) moreover have "insert x (insert b (A - {a})) = insert b (insert x A - {a})" @@ -1899,15 +2026,15 @@ qed qed -lemma (in ACf) fold1_eq_fold: - "[|finite A; a \ A|] ==> fold1 f (insert a A) = fold f id a A" +lemma fold1_eq_fold: + "[|finite A; a \ A|] ==> fold1 times (insert a A) = fold times id a A" apply (simp add: fold1_def fold_def) apply (rule the_equality) -apply (best intro: foldSet_determ theI dest: finite_imp_foldSet [of _ f id]) +apply (best intro: foldSet_determ theI dest: finite_imp_foldSet [of _ times id]) apply (rule sym, clarify) apply (case_tac "Aa=A") apply (best intro: the_equality foldSet_determ) -apply (subgoal_tac "foldSet f id a A x") +apply (subgoal_tac "foldSet times id a A x") apply (best intro: the_equality foldSet_determ) apply (subgoal_tac "insert aa (Aa - {a}) = A") prefer 2 apply (blast elim: equalityE) @@ -1921,9 +2048,9 @@ apply (drule_tac x="A-{x}" in spec, auto) done -lemma (in ACf) fold1_insert: +lemma fold1_insert: assumes nonempty: "A \ {}" and A: "finite A" "x \ A" - shows "fold1 f (insert x A) = f x (fold1 f A)" + shows "fold1 times (insert x A) = x * fold1 times A" proof - from nonempty obtain a A' where "A = insert a A' & a ~: A'" by (auto simp add: nonempty_iff) @@ -1931,9 +2058,14 @@ by (simp add: insert_commute [of x] fold1_eq_fold eq_commute) qed -lemma (in ACIf) fold1_insert_idem [simp]: +end + +context ab_semigroup_idem_mult +begin + +lemma fold1_insert_idem [simp]: assumes nonempty: "A \ {}" and A: "finite A" - shows "fold1 f (insert x A) = f x (fold1 f A)" + shows "fold1 times (insert x A) = x * fold1 times A" proof - from nonempty obtain a A' where A': "A = insert a A' & a ~: A'" by (auto simp add: nonempty_iff) @@ -1943,11 +2075,11 @@ thus ?thesis proof cases assume "A' = {}" - with prems show ?thesis by (simp add: idem) + with prems show ?thesis by (simp add: mult_idem) next assume "A' \ {}" with prems show ?thesis - by (simp add: fold1_insert assoc [symmetric] idem) + by (simp add: fold1_insert mult_assoc [symmetric] mult_idem) qed next assume "a \ x" @@ -1956,53 +2088,58 @@ qed qed -lemma (in ACIf) hom_fold1_commute: -assumes hom: "!!x y. h(f x y) = f (h x) (h y)" -and N: "finite N" "N \ {}" shows "h(fold1 f N) = fold1 f (h ` N)" +lemma hom_fold1_commute: +assumes hom: "!!x y. h (x * y) = h x * h y" +and N: "finite N" "N \ {}" shows "h (fold1 times N) = fold1 times (h ` N)" using N proof (induct rule: finite_ne_induct) case singleton thus ?case by simp next case (insert n N) - then have "h(fold1 f (insert n N)) = h(f n (fold1 f N))" by simp - also have "\ = f (h n) (h(fold1 f N))" by(rule hom) - also have "h(fold1 f N) = fold1 f (h ` N)" by(rule insert) - also have "f (h n) \ = fold1 f (insert (h n) (h ` N))" + then have "h (fold1 times (insert n N)) = h (n * fold1 times N)" by simp + also have "\ = h n * h (fold1 times N)" by(rule hom) + also have "h (fold1 times N) = fold1 times (h ` N)" by(rule insert) + also have "times (h n) \ = fold1 times (insert (h n) (h ` N))" using insert by(simp) also have "insert (h n) (h ` N) = h ` insert n N" by simp finally show ?case . qed +end + text{* Now the recursion rules for definitions: *} lemma fold1_singleton_def: "g = fold1 f \ g {a} = a" by(simp add:fold1_singleton) -lemma (in ACf) fold1_insert_def: - "\ g = fold1 f; finite A; x \ A; A \ {} \ \ g (insert x A) = x \ (g A)" -by(simp add:fold1_insert) - -lemma (in ACIf) fold1_insert_idem_def: - "\ g = fold1 f; finite A; A \ {} \ \ g (insert x A) = x \ (g A)" -by(simp add:fold1_insert_idem) +lemma (in ab_semigroup_mult) fold1_insert_def: + "\ g = fold1 times; finite A; x \ A; A \ {} \ \ g (insert x A) = x * g A" +by (simp add:fold1_insert) + +lemma (in ab_semigroup_idem_mult) fold1_insert_idem_def: + "\ g = fold1 times; finite A; A \ {} \ \ g (insert x A) = x * g A" +by simp subsubsection{* Determinacy for @{term fold1Set} *} text{*Not actually used!!*} -lemma (in ACf) foldSet_permute: - "[|foldSet f id b (insert a A) x; a \ A; b \ A|] - ==> foldSet f id a (insert b A) x" -apply (case_tac "a=b") +context ab_semigroup_mult +begin + +lemma foldSet_permute: + "[|foldSet times id b (insert a A) x; a \ A; b \ A|] + ==> foldSet times id a (insert b A) x" +apply (cases "a=b") apply (auto dest: foldSet_permute_diff) done -lemma (in ACf) fold1Set_determ: - "fold1Set f A x ==> fold1Set f A y ==> y = x" +lemma fold1Set_determ: + "fold1Set times A x ==> fold1Set times A y ==> y = x" proof (clarify elim!: fold1Set.cases) fix A x B y a b - assume Ax: "foldSet f id a A x" - assume By: "foldSet f id b B y" + assume Ax: "foldSet times id a A x" + assume By: "foldSet times id b B y" assume anotA: "a \ A" assume bnotB: "b \ B" assume eq: "insert a A = insert b B" @@ -2018,171 +2155,40 @@ and aB: "a \ B" and bA: "b \ A" using eq anotA bnotB diff by (blast elim!:equalityE)+ with aB bnotB By - have "foldSet f id a (insert b ?D) y" + have "foldSet times id a (insert b ?D) y" by (auto intro: foldSet_permute simp add: insert_absorb) moreover - have "foldSet f id a (insert b ?D) x" + have "foldSet times id a (insert b ?D) x" by (simp add: A [symmetric] Ax) ultimately show ?thesis by (blast intro: foldSet_determ) qed qed -lemma (in ACf) fold1Set_equality: "fold1Set f A y ==> fold1 f A = y" +lemma fold1Set_equality: "fold1Set times A y ==> fold1 times A = y" by (unfold fold1_def) (blast intro: fold1Set_determ) +end + declare empty_foldSetE [rule del] foldSet.intros [rule del] empty_fold1SetE [rule del] insert_fold1SetE [rule del] -- {* No more proofs involve these relations. *} - -subsubsection{* Semi-Lattices *} - -locale ACIfSL = ord + ACIf + - assumes below_def: "less_eq x y \ x \ y = x" - and strict_below_def: "less x y \ less_eq x y \ x \ y" +subsubsection {* Lemmas about @{text fold1} *} + +context ab_semigroup_mult begin -notation - less ("(_/ \ _)" [51, 51] 50) - -notation (xsymbols) - less_eq ("(_/ \ _)" [51, 51] 50) - -notation (HTML output) - less_eq ("(_/ \ _)" [51, 51] 50) - -lemma below_refl [simp]: "x \ x" - by (simp add: below_def idem) - -lemma below_antisym: - assumes xy: "x \ y" and yx: "y \ x" - shows "x = y" - using xy [unfolded below_def, symmetric] - yx [unfolded below_def commute] - by (rule trans) - -lemma below_trans: - assumes xy: "x \ y" and yz: "y \ z" - shows "x \ z" -proof - - from xy have x_xy: "x \ y = x" by (simp add: below_def) - from yz have y_yz: "y \ z = y" by (simp add: below_def) - from y_yz have "x \ y \ z = x \ y" by (simp add: assoc) - with x_xy have "x \ y \ z = x" by simp - moreover from x_xy have "x \ z = x \ y \ z" by simp - ultimately have "x \ z = x" by simp - then show ?thesis by (simp add: below_def) -qed - -lemma below_f_conv [simp,noatp]: "x \ y \ z = (x \ y \ x \ z)" -proof - assume "x \ y \ z" - hence xyzx: "x \ (y \ z) = x" by(simp add: below_def) - have "x \ y = x" - proof - - have "x \ y = (x \ (y \ z)) \ y" by(rule subst[OF xyzx], rule refl) - also have "\ = x \ (y \ z)" by(simp add:ACI) - also have "\ = x" by(rule xyzx) - finally show ?thesis . - qed - moreover have "x \ z = x" - proof - - have "x \ z = (x \ (y \ z)) \ z" by(rule subst[OF xyzx], rule refl) - also have "\ = x \ (y \ z)" by(simp add:ACI) - also have "\ = x" by(rule xyzx) - finally show ?thesis . - qed - ultimately show "x \ y \ x \ z" by(simp add: below_def) -next - assume a: "x \ y \ x \ z" - hence y: "x \ y = x" and z: "x \ z = x" by(simp_all add: below_def) - have "x \ (y \ z) = (x \ y) \ z" by(simp add:assoc) - also have "x \ y = x" using a by(simp_all add: below_def) - also have "x \ z = x" using a by(simp_all add: below_def) - finally show "x \ y \ z" by(simp_all add: below_def) -qed - -end - -interpretation ACIfSL < order -by unfold_locales - (simp add: strict_below_def, auto intro: below_refl below_trans below_antisym) - -locale ACIfSLlin = ACIfSL + - assumes lin: "x\y \ {x,y}" -begin - -lemma above_f_conv: - "x \ y \ z = (x \ z \ y \ z)" -proof - assume a: "x \ y \ z" - have "x \ y = x \ x \ y = y" using lin[of x y] by simp - thus "x \ z \ y \ z" - proof - assume "x \ y = x" hence "x \ z" by(rule subst)(rule a) thus ?thesis .. - next - assume "x \ y = y" hence "y \ z" by(rule subst)(rule a) thus ?thesis .. - qed -next - assume "x \ z \ y \ z" - thus "x \ y \ z" - proof - assume a: "x \ z" - have "(x \ y) \ z = (x \ z) \ y" by(simp add:ACI) - also have "x \ z = x" using a by(simp add:below_def) - finally show "x \ y \ z" by(simp add:below_def) - next - assume a: "y \ z" - have "(x \ y) \ z = x \ (y \ z)" by(simp add:ACI) - also have "y \ z = y" using a by(simp add:below_def) - finally show "x \ y \ z" by(simp add:below_def) - qed -qed - -lemma strict_below_f_conv[simp,noatp]: "x \ y \ z = (x \ y \ x \ z)" -apply(simp add: strict_below_def) -using lin[of y z] by (auto simp:below_def ACI) - -lemma strict_above_f_conv: - "x \ y \ z = (x \ z \ y \ z)" -apply(simp add: strict_below_def above_f_conv) -using lin[of y z] lin[of x z] by (auto simp:below_def ACI) - -end - -interpretation ACIfSLlin < linorder - by unfold_locales - (insert lin [simplified insert_iff], simp add: below_def commute) - - -subsubsection{* Lemmas about @{text fold1} *} - -lemma (in ACf) fold1_Un: +lemma fold1_Un: assumes A: "finite A" "A \ {}" shows "finite B \ B \ {} \ A Int B = {} \ - fold1 f (A Un B) = f (fold1 f A) (fold1 f B)" -using A -proof(induct rule:finite_ne_induct) - case singleton thus ?case by(simp add:fold1_insert) -next - case insert thus ?case by (simp add:fold1_insert assoc) -qed - -lemma (in ACIf) fold1_Un2: -assumes A: "finite A" "A \ {}" -shows "finite B \ B \ {} \ - fold1 f (A Un B) = f (fold1 f A) (fold1 f B)" -using A -proof(induct rule:finite_ne_induct) - case singleton thus ?case by(simp add:fold1_insert_idem) -next - case insert thus ?case by (simp add:fold1_insert_idem assoc) -qed - -lemma (in ACf) fold1_in: - assumes A: "finite (A)" "A \ {}" and elem: "\x y. x\y \ {x,y}" - shows "fold1 f A \ A" + fold1 times (A Un B) = fold1 times A * fold1 times B" +using A by (induct rule: finite_ne_induct) + (simp_all add: fold1_insert mult_assoc) + +lemma fold1_in: + assumes A: "finite (A)" "A \ {}" and elem: "\x y. x * y \ {x,y}" + shows "fold1 times A \ A" using A proof (induct rule:finite_ne_induct) case singleton thus ?case by simp @@ -2190,73 +2196,17 @@ case insert thus ?case using elem by (force simp add:fold1_insert) qed -lemma (in ACIfSL) below_fold1_iff: +end + +lemma (in ab_semigroup_idem_mult) fold1_Un2: assumes A: "finite A" "A \ {}" -shows "x \ fold1 f A = (\a\A. x \ a)" +shows "finite B \ B \ {} \ + fold1 times (A Un B) = fold1 times A * fold1 times B" using A -by(induct rule:finite_ne_induct) simp_all - -lemma (in ACIfSLlin) strict_below_fold1_iff: - "finite A \ A \ {} \ x \ fold1 f A = (\a\A. x \ a)" -by(induct rule:finite_ne_induct) simp_all - - -lemma (in ACIfSL) fold1_belowI: -assumes A: "finite A" "A \ {}" -shows "a \ A \ fold1 f A \ a" -using A -proof (induct rule:finite_ne_induct) +proof(induct rule:finite_ne_induct) case singleton thus ?case by simp next - case (insert x F) - from insert(5) have "a = x \ a \ F" by simp - thus ?case - proof - assume "a = x" thus ?thesis using insert by(simp add:below_def ACI) - next - assume "a \ F" - hence bel: "fold1 f F \ a" by(rule insert) - have "fold1 f (insert x F) \ a = x \ (fold1 f F \ a)" - using insert by(simp add:below_def ACI) - also have "fold1 f F \ a = fold1 f F" - using bel by(simp add:below_def ACI) - also have "x \ \ = fold1 f (insert x F)" - using insert by(simp add:below_def ACI) - finally show ?thesis by(simp add:below_def) - qed -qed - -lemma (in ACIfSLlin) fold1_below_iff: -assumes A: "finite A" "A \ {}" -shows "fold1 f A \ x = (\a\A. a \ x)" -using A -by(induct rule:finite_ne_induct)(simp_all add:above_f_conv) - -lemma (in ACIfSLlin) fold1_strict_below_iff: -assumes A: "finite A" "A \ {}" -shows "fold1 f A \ x = (\a\A. a \ x)" -using A -by(induct rule:finite_ne_induct)(simp_all add:strict_above_f_conv) - -lemma (in ACIfSLlin) fold1_antimono: -assumes "A \ {}" and "A \ B" and "finite B" -shows "fold1 f B \ fold1 f A" -proof(cases) - assume "A = B" thus ?thesis by simp -next - assume "A \ B" - have B: "B = A \ (B-A)" using `A \ B` by blast - have "fold1 f B = fold1 f (A \ (B-A))" by(subst B)(rule refl) - also have "\ = f (fold1 f A) (fold1 f (B-A))" - proof - - have "finite A" by(rule finite_subset[OF `A \ B` `finite B`]) - moreover have "finite(B-A)" by(rule finite_Diff[OF `finite B`]) (* by(blast intro:finite_Diff prems) fails *) - moreover have "(B-A) \ {}" using prems by blast - moreover have "A Int (B-A) = {}" using prems by blast - ultimately show ?thesis using `A \ {}` by(rule_tac fold1_Un) - qed - also have "\ \ fold1 f A" by(simp add: above_f_conv) - finally show ?thesis . + case insert thus ?case by (simp add: mult_assoc) qed @@ -2268,51 +2218,62 @@ over (non-empty) sets by means of @{text fold1}. *} -lemma (in lower_semilattice) ACf_inf: "ACf inf" - by (blast intro: ACf.intro inf_commute inf_assoc) - -lemma (in upper_semilattice) ACf_sup: "ACf sup" - by (blast intro: ACf.intro sup_commute sup_assoc) - -lemma (in lower_semilattice) ACIf_inf: "ACIf inf" -apply(rule ACIf.intro) -apply(rule ACf_inf) -apply(rule ACIf_axioms.intro) -apply(rule inf_idem) -done - -lemma (in upper_semilattice) ACIf_sup: "ACIf sup" -apply(rule ACIf.intro) -apply(rule ACf_sup) -apply(rule ACIf_axioms.intro) -apply(rule sup_idem) -done - -lemma (in lower_semilattice) ACIfSL_inf: "ACIfSL (op \) (op <) inf" -apply(rule ACIfSL.intro) -apply(rule ACIf.intro) -apply(rule ACf_inf) -apply(rule ACIf.axioms[OF ACIf_inf]) -apply(rule ACIfSL_axioms.intro) -apply(rule iffI) - apply(blast intro: antisym inf_le1 inf_le2 inf_greatest refl) -apply(erule subst) -apply(rule inf_le2) -apply(rule less_le) -done - -lemma (in upper_semilattice) ACIfSL_sup: "ACIfSL (%x y. y \ x) (%x y. y < x) sup" -apply(rule ACIfSL.intro) -apply(rule ACIf.intro) -apply(rule ACf_sup) -apply(rule ACIf.axioms[OF ACIf_sup]) -apply(rule ACIfSL_axioms.intro) -apply(rule iffI) - apply(blast intro: antisym sup_ge1 sup_ge2 sup_least refl) -apply(erule subst) -apply(rule sup_ge2) -apply(simp add: neq_commute less_le) -done +context lower_semilattice +begin + +lemma ab_semigroup_idem_mult_inf: + "ab_semigroup_idem_mult inf" + apply unfold_locales + apply (rule inf_assoc) + apply (rule inf_commute) + apply (rule inf_idem) + done + +lemma below_fold1_iff: + assumes "finite A" "A \ {}" + shows "x \ fold1 inf A \ (\a\A. x \ a)" +proof - + invoke ab_semigroup_idem_mult [inf] + by (rule ab_semigroup_idem_mult_inf) + show ?thesis using assms by (induct rule: finite_ne_induct) simp_all +qed + +lemma fold1_belowI: + assumes "finite A" "A \ {}" + and "a \ A" + shows "fold1 inf A \ a" +using assms proof (induct rule: finite_ne_induct) + case singleton thus ?case by simp +next + invoke ab_semigroup_idem_mult [inf] + by (rule ab_semigroup_idem_mult_inf) + case (insert x F) + from insert(5) have "a = x \ a \ F" by simp + thus ?case + proof + assume "a = x" thus ?thesis using insert + by (simp add: mult_ac_idem) + next + assume "a \ F" + hence bel: "fold1 inf F \ a" by (rule insert) + have "inf (fold1 inf (insert x F)) a = inf x (inf (fold1 inf F) a)" + using insert by (simp add: mult_ac_idem) + also have "inf (fold1 inf F) a = fold1 inf F" + using bel by (auto intro: antisym) + also have "inf x \ = fold1 inf (insert x F)" + using insert by (simp add: mult_ac_idem) + finally have aux: "inf (fold1 inf (insert x F)) a = fold1 inf (insert x F)" . + moreover have "inf (fold1 inf (insert x F)) a \ a" by simp + ultimately show ?thesis by simp + qed +qed + +end + +lemma (in upper_semilattice) ab_semigroup_idem_mult_sup: + "ab_semigroup_idem_mult sup" + by (rule lower_semilattice.ab_semigroup_idem_mult_inf) + (rule dual_lattice) context lattice begin @@ -2333,19 +2294,20 @@ prefer 2 apply blast apply(erule exE) apply(rule order_trans) -apply(erule (2) ACIfSL.fold1_belowI[OF ACIfSL_inf]) -apply(erule (2) ACIfSL.fold1_belowI[OF ACIfSL_sup]) +apply(erule (2) fold1_belowI) +apply(erule (2) lower_semilattice.fold1_belowI [OF dual_lattice]) done lemma sup_Inf_absorb [simp]: "\ finite A; A \ {}; a \ A \ \ (sup a (\\<^bsub>fin\<^esub>A)) = a" apply(subst sup_commute) -apply(simp add: Inf_fin_def sup_absorb2 ACIfSL.fold1_belowI [OF ACIfSL_inf]) +apply(simp add: Inf_fin_def sup_absorb2 fold1_belowI) done lemma inf_Sup_absorb [simp]: "\ finite A; A \ {}; a \ A \ \ (inf a (\\<^bsub>fin\<^esub>A)) = a" -by(simp add: Sup_fin_def inf_absorb1 ACIfSL.fold1_belowI [OF ACIfSL_sup]) +by (simp add: Sup_fin_def inf_absorb1 + lower_semilattice.fold1_belowI [OF dual_lattice]) end @@ -2353,11 +2315,17 @@ begin lemma sup_Inf1_distrib: - "finite A \ A \ {} \ sup x (\\<^bsub>fin\<^esub>A) = \\<^bsub>fin\<^esub>{sup x a|a. a \ A}" -apply(simp add: Inf_fin_def image_def - ACIf.hom_fold1_commute[OF ACIf_inf, where h="sup x", OF sup_inf_distrib1]) -apply(rule arg_cong, blast) -done + assumes "finite A" + and "A \ {}" + shows "sup x (\\<^bsub>fin\<^esub>A) = \\<^bsub>fin\<^esub>{sup x a|a. a \ A}" +proof - + invoke ab_semigroup_idem_mult [inf] + by (rule ab_semigroup_idem_mult_inf) + from assms show ?thesis + by (simp add: Inf_fin_def image_def + hom_fold1_commute [where h="sup x", OF sup_inf_distrib1]) + (rule arg_cong, blast) +qed lemma sup_Inf2_distrib: assumes A: "finite A" "A \ {}" and B: "finite B" "B \ {}" @@ -2366,6 +2334,8 @@ case singleton thus ?case by (simp add: sup_Inf1_distrib [OF B] fold1_singleton_def [OF Inf_fin_def]) next + invoke ab_semigroup_idem_mult [inf] + by (rule ab_semigroup_idem_mult_inf) case (insert x A) have finB: "finite {sup x b |b. b \ B}" by(rule finite_surj[where f = "sup x", OF B(1)], auto) @@ -2377,26 +2347,29 @@ qed have ne: "{sup a b |a b. a \ A \ b \ B} \ {}" using insert B by blast have "sup (\\<^bsub>fin\<^esub>(insert x A)) (\\<^bsub>fin\<^esub>B) = sup (inf x (\\<^bsub>fin\<^esub>A)) (\\<^bsub>fin\<^esub>B)" - using insert - by(simp add:ACIf.fold1_insert_idem_def[OF ACIf_inf Inf_fin_def]) + using insert by (simp add: fold1_insert_idem_def [OF Inf_fin_def]) also have "\ = inf (sup x (\\<^bsub>fin\<^esub>B)) (sup (\\<^bsub>fin\<^esub>A) (\\<^bsub>fin\<^esub>B))" by(rule sup_inf_distrib2) also have "\ = inf (\\<^bsub>fin\<^esub>{sup x b|b. b \ B}) (\\<^bsub>fin\<^esub>{sup a b|a b. a \ A \ b \ B})" using insert by(simp add:sup_Inf1_distrib[OF B]) also have "\ = \\<^bsub>fin\<^esub>({sup x b |b. b \ B} \ {sup a b |a b. a \ A \ b \ B})" (is "_ = \\<^bsub>fin\<^esub>?M") using B insert - by (simp add: Inf_fin_def ACIf.fold1_Un2[OF ACIf_inf finB _ finAB ne]) + by (simp add: Inf_fin_def fold1_Un2 [OF finB _ finAB ne]) also have "?M = {sup a b |a b. a \ insert x A \ b \ B}" by blast finally show ?case . qed lemma inf_Sup1_distrib: - "finite A \ A \ {} \ inf x (\\<^bsub>fin\<^esub>A) = \\<^bsub>fin\<^esub>{inf x a|a. a \ A}" -apply (simp add: Sup_fin_def image_def - ACIf.hom_fold1_commute[OF ACIf_sup, where h="inf x", OF inf_sup_distrib1]) -apply (rule arg_cong, blast) -done + assumes "finite A" and "A \ {}" + shows "inf x (\\<^bsub>fin\<^esub>A) = \\<^bsub>fin\<^esub>{inf x a|a. a \ A}" +proof - + invoke ab_semigroup_idem_mult [sup] + by (rule ab_semigroup_idem_mult_sup) + from assms show ?thesis + by (simp add: Sup_fin_def image_def hom_fold1_commute [where h="inf x", OF inf_sup_distrib1]) + (rule arg_cong, blast) +qed lemma inf_Sup2_distrib: assumes A: "finite A" "A \ {}" and B: "finite B" "B \ {}" @@ -2415,15 +2388,17 @@ thus ?thesis by(simp add: insert(1) B(1)) qed have ne: "{inf a b |a b. a \ A \ b \ B} \ {}" using insert B by blast + invoke ab_semigroup_idem_mult [sup] + by (rule ab_semigroup_idem_mult_sup) have "inf (\\<^bsub>fin\<^esub>(insert x A)) (\\<^bsub>fin\<^esub>B) = inf (sup x (\\<^bsub>fin\<^esub>A)) (\\<^bsub>fin\<^esub>B)" - using insert by (simp add: ACIf.fold1_insert_idem_def [OF ACIf_sup Sup_fin_def]) + using insert by (simp add: fold1_insert_idem_def [OF Sup_fin_def]) also have "\ = sup (inf x (\\<^bsub>fin\<^esub>B)) (inf (\\<^bsub>fin\<^esub>A) (\\<^bsub>fin\<^esub>B))" by(rule inf_sup_distrib2) also have "\ = sup (\\<^bsub>fin\<^esub>{inf x b|b. b \ B}) (\\<^bsub>fin\<^esub>{inf a b|a b. a \ A \ b \ B})" using insert by(simp add:inf_Sup1_distrib[OF B]) also have "\ = \\<^bsub>fin\<^esub>({inf x b |b. b \ B} \ {inf a b |a b. a \ A \ b \ B})" (is "_ = \\<^bsub>fin\<^esub>?M") using B insert - by (simp add: Sup_fin_def ACIf.fold1_Un2[OF ACIf_sup finB _ finAB ne]) + by (simp add: Sup_fin_def fold1_Un2 [OF finB _ finAB ne]) also have "?M = {inf a b |a b. a \ insert x A \ b \ B}" by blast finally show ?case . @@ -2439,14 +2414,26 @@ *} lemma Inf_fin_Inf: - "finite A \ A \ {} \ \\<^bsub>fin\<^esub>A = Inf A" -unfolding Inf_fin_def by (induct A set: finite) - (simp_all add: Inf_insert_simp ACIf.fold1_insert_idem [OF ACIf_inf]) + assumes "finite A" and "A \ {}" + shows "\\<^bsub>fin\<^esub>A = Inf A" +proof - + invoke ab_semigroup_idem_mult [inf] + by (rule ab_semigroup_idem_mult_inf) + from assms show ?thesis + unfolding Inf_fin_def by (induct A set: finite) + (simp_all add: Inf_insert_simp) +qed lemma Sup_fin_Sup: - "finite A \ A \ {} \ \\<^bsub>fin\<^esub>A = Sup A" -unfolding Sup_fin_def by (induct A set: finite) - (simp_all add: Sup_insert_simp ACIf.fold1_insert_idem [OF ACIf_sup]) + assumes "finite A" and "A \ {}" + shows "\\<^bsub>fin\<^esub>A = Sup A" +proof - + invoke ab_semigroup_idem_mult [sup] + by (rule ab_semigroup_idem_mult_sup) + from assms show ?thesis + unfolding Sup_fin_def by (induct A set: finite) + (simp_all add: Sup_insert_simp) +qed end @@ -2462,6 +2449,86 @@ context linorder begin +lemma ab_semigroup_idem_mult_min: + "ab_semigroup_idem_mult min" + by unfold_locales (auto simp add: min_def) + +lemma ab_semigroup_idem_mult_max: + "ab_semigroup_idem_mult max" + by unfold_locales (auto simp add: max_def) + +lemma min_lattice: + "lower_semilattice (op \) (op <) min" + by unfold_locales (auto simp add: min_def) + +lemma max_lattice: + "lower_semilattice (op \) (op >) max" + by unfold_locales (auto simp add: max_def) + +lemma dual_max: + "ord.max (op \) = min" + by (auto simp add: ord.max_def_raw min_def_raw expand_fun_eq) + +lemma dual_min: + "ord.min (op \) = max" + by (auto simp add: ord.min_def_raw max_def_raw expand_fun_eq) + +lemma strict_below_fold1_iff: + assumes "finite A" and "A \ {}" + shows "x < fold1 min A \ (\a\A. x < a)" +proof - + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + from assms show ?thesis + by (induct rule: finite_ne_induct) + (simp_all add: fold1_insert) +qed + +lemma fold1_below_iff: + assumes "finite A" and "A \ {}" + shows "fold1 min A \ x \ (\a\A. a \ x)" +proof - + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + from assms show ?thesis + by (induct rule: finite_ne_induct) + (simp_all add: fold1_insert min_le_iff_disj) +qed + +lemma fold1_strict_below_iff: + assumes "finite A" and "A \ {}" + shows "fold1 min A < x \ (\a\A. a < x)" +proof - + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + from assms show ?thesis + by (induct rule: finite_ne_induct) + (simp_all add: fold1_insert min_less_iff_disj) +qed + +lemma fold1_antimono: + assumes "A \ {}" and "A \ B" and "finite B" + shows "fold1 min B \ fold1 min A" +proof cases + assume "A = B" thus ?thesis by simp +next + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + assume "A \ B" + have B: "B = A \ (B-A)" using `A \ B` by blast + have "fold1 min B = fold1 min (A \ (B-A))" by(subst B)(rule refl) + also have "\ = min (fold1 min A) (fold1 min (B-A))" + proof - + have "finite A" by(rule finite_subset[OF `A \ B` `finite B`]) + moreover have "finite(B-A)" by(rule finite_Diff[OF `finite B`]) (* by(blast intro:finite_Diff prems) fails *) + moreover have "(B-A) \ {}" using prems by blast + moreover have "A Int (B-A) = {}" using prems by blast + ultimately show ?thesis using `A \ {}` by (rule_tac fold1_Un) + qed + also have "\ \ fold1 min A" by (simp add: min_le_iff_disj) + finally show ?thesis . +qed + definition Min :: "'a set \ 'a" where @@ -2472,138 +2539,204 @@ where "Max = fold1 max" -end context linorder begin - -text {* recall: @{term min} and @{term max} behave like @{const inf} and @{const sup} *} - -lemma ACIf_min: "ACIf min" - by (rule lower_semilattice.ACIf_inf, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - -lemma ACf_min: "ACf min" - by (rule lower_semilattice.ACf_inf, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - -lemma ACIfSL_min: "ACIfSL (op \) (op <) min" - by (rule lower_semilattice.ACIfSL_inf, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - -lemma ACIfSLlin_min: "ACIfSLlin (op \) (op <) min" - by (rule ACIfSLlin.intro, - rule lower_semilattice.ACIfSL_inf, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - (unfold_locales, simp add: min_def) - -lemma ACIf_max: "ACIf max" - by (rule upper_semilattice.ACIf_sup, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - -lemma ACf_max: "ACf max" - by (rule upper_semilattice.ACf_sup, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - -lemma ACIfSL_max: "ACIfSL (\x y. y \ x) (\x y. y < x) max" - by (rule upper_semilattice.ACIfSL_sup, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - -lemma ACIfSLlin_max: "ACIfSLlin (\x y. y \ x) (\x y. y < x) max" - by (rule ACIfSLlin.intro, - rule upper_semilattice.ACIfSL_sup, - rule lattice.axioms, - rule distrib_lattice.axioms, - rule distrib_lattice_min_max) - (unfold_locales, simp add: max_def) - lemmas Min_singleton [simp] = fold1_singleton_def [OF Min_def] lemmas Max_singleton [simp] = fold1_singleton_def [OF Max_def] -lemmas Min_insert [simp] = ACIf.fold1_insert_idem_def [OF ACIf_min Min_def] -lemmas Max_insert [simp] = ACIf.fold1_insert_idem_def [OF ACIf_max Max_def] + +lemma Min_insert [simp]: + assumes "finite A" and "A \ {}" + shows "Min (insert x A) = min x (Min A)" +proof - + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + from assms show ?thesis by (rule fold1_insert_idem_def [OF Min_def]) +qed + +lemma Max_insert [simp]: + assumes "finite A" and "A \ {}" + shows "Max (insert x A) = max x (Max A)" +proof - + invoke ab_semigroup_idem_mult [max] + by (rule ab_semigroup_idem_mult_max) + from assms show ?thesis by (rule fold1_insert_idem_def [OF Max_def]) +qed lemma Min_in [simp]: - shows "finite A \ A \ {} \ Min A \ A" - using ACf.fold1_in [OF ACf_min] - by (fastsimp simp: Min_def min_def) + assumes "finite A" and "A \ {}" + shows "Min A \ A" +proof - + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + from assms fold1_in show ?thesis by (fastsimp simp: Min_def min_def) +qed lemma Max_in [simp]: - shows "finite A \ A \ {} \ Max A \ A" - using ACf.fold1_in [OF ACf_max] - by (fastsimp simp: Max_def max_def) - -lemma Min_antimono: "\ M \ N; M \ {}; finite N \ \ Min N \ Min M" - by (simp add: Min_def ACIfSLlin.fold1_antimono [OF ACIfSLlin_min]) - -lemma Max_mono: "\ M \ N; M \ {}; finite N \ \ Max M \ Max N" - by (simp add: Max_def ACIfSLlin.fold1_antimono [OF ACIfSLlin_max]) - -lemma Min_le [simp]: "\ finite A; A \ {}; x \ A \ \ Min A \ x" - by (simp add: Min_def ACIfSL.fold1_belowI [OF ACIfSL_min]) - -lemma Max_ge [simp]: "\ finite A; A \ {}; x \ A \ \ x \ Max A" - by (simp add: Max_def ACIfSL.fold1_belowI [OF ACIfSL_max]) - -lemma Min_ge_iff [simp,noatp]: - "\ finite A; A \ {} \ \ x \ Min A \ (\a\A. x \ a)" - by (simp add: Min_def ACIfSL.below_fold1_iff [OF ACIfSL_min]) - -lemma Max_le_iff [simp,noatp]: - "\ finite A; A \ {} \ \ Max A \ x \ (\a\A. a \ x)" - by (simp add: Max_def ACIfSL.below_fold1_iff [OF ACIfSL_max]) - -lemma Min_gr_iff [simp,noatp]: - "\ finite A; A \ {} \ \ x < Min A \ (\a\A. x < a)" - by (simp add: Min_def ACIfSLlin.strict_below_fold1_iff [OF ACIfSLlin_min]) - -lemma Max_less_iff [simp,noatp]: - "\ finite A; A \ {} \ \ Max A < x \ (\a\A. a < x)" - by (simp add: Max_def ACIfSLlin.strict_below_fold1_iff [OF ACIfSLlin_max]) + assumes "finite A" and "A \ {}" + shows "Max A \ A" +proof - + invoke ab_semigroup_idem_mult [max] + by (rule ab_semigroup_idem_mult_max) + from assms fold1_in [of A] show ?thesis by (fastsimp simp: Max_def max_def) +qed + +lemma Min_Un: + assumes "finite A" and "A \ {}" and "finite B" and "B \ {}" + shows "Min (A \ B) = min (Min A) (Min B)" +proof - + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + from assms show ?thesis + by (simp add: Min_def fold1_Un2) +qed + +lemma Max_Un: + assumes "finite A" and "A \ {}" and "finite B" and "B \ {}" + shows "Max (A \ B) = max (Max A) (Max B)" +proof - + invoke ab_semigroup_idem_mult [max] + by (rule ab_semigroup_idem_mult_max) + from assms show ?thesis + by (simp add: Max_def fold1_Un2) +qed + +lemma hom_Min_commute: + assumes "\x y. h (min x y) = min (h x) (h y)" + and "finite N" and "N \ {}" + shows "h (Min N) = Min (h ` N)" +proof - + invoke ab_semigroup_idem_mult [min] + by (rule ab_semigroup_idem_mult_min) + from assms show ?thesis + by (simp add: Min_def hom_fold1_commute) +qed + +lemma hom_Max_commute: + assumes "\x y. h (max x y) = max (h x) (h y)" + and "finite N" and "N \ {}" + shows "h (Max N) = Max (h ` N)" +proof - + invoke ab_semigroup_idem_mult [max] + by (rule ab_semigroup_idem_mult_max) + from assms show ?thesis + by (simp add: Max_def hom_fold1_commute [of h]) +qed + +lemma Min_le [simp]: + assumes "finite A" and "A \ {}" and "x \ A" + shows "Min A \ x" +proof - + invoke lower_semilattice [_ _ min] + by (rule min_lattice) + from assms show ?thesis by (simp add: Min_def fold1_belowI) +qed + +lemma Max_ge [simp]: + assumes "finite A" and "A \ {}" and "x \ A" + shows "x \ Max A" +proof - + invoke lower_semilattice [_ _ max] + by (rule max_lattice) + from assms show ?thesis by (simp add: Max_def fold1_belowI) +qed + +lemma Min_ge_iff [simp, noatp]: + assumes "finite A" and "A \ {}" + shows "x \ Min A \ (\a\A. x \ a)" +proof - + invoke lower_semilattice [_ _ min] + by (rule min_lattice) + from assms show ?thesis by (simp add: Min_def below_fold1_iff) +qed + +lemma Max_le_iff [simp, noatp]: + assumes "finite A" and "A \ {}" + shows "Max A \ x \ (\a\A. a \ x)" +proof - + invoke lower_semilattice [_ _ max] + by (rule max_lattice) + from assms show ?thesis by (simp add: Max_def below_fold1_iff) +qed + +lemma Min_gr_iff [simp, noatp]: + assumes "finite A" and "A \ {}" + shows "x < Min A \ (\a\A. x < a)" +proof - + invoke lower_semilattice [_ _ min] + by (rule min_lattice) + from assms show ?thesis by (simp add: Min_def strict_below_fold1_iff) +qed + +lemma Max_less_iff [simp, noatp]: + assumes "finite A" and "A \ {}" + shows "Max A < x \ (\a\A. a < x)" +proof - + note Max = Max_def + invoke linorder ["op \" "op >"] + by (rule dual_linorder) + from assms show ?thesis + by (simp add: Max strict_below_fold1_iff [folded dual_max]) +qed lemma Min_le_iff [noatp]: - "\ finite A; A \ {} \ \ Min A \ x \ (\a\A. a \ x)" - by (simp add: Min_def ACIfSLlin.fold1_below_iff [OF ACIfSLlin_min]) + assumes "finite A" and "A \ {}" + shows "Min A \ x \ (\a\A. a \ x)" +proof - + invoke lower_semilattice [_ _ min] + by (rule min_lattice) + from assms show ?thesis + by (simp add: Min_def fold1_below_iff) +qed lemma Max_ge_iff [noatp]: - "\ finite A; A \ {} \ \ x \ Max A \ (\a\A. x \ a)" - by (simp add: Max_def ACIfSLlin.fold1_below_iff [OF ACIfSLlin_max]) + assumes "finite A" and "A \ {}" + shows "x \ Max A \ (\a\A. x \ a)" +proof - + note Max = Max_def + invoke linorder ["op \" "op >"] + by (rule dual_linorder) + from assms show ?thesis + by (simp add: Max fold1_below_iff [folded dual_max]) +qed lemma Min_less_iff [noatp]: - "\ finite A; A \ {} \ \ Min A < x \ (\a\A. a < x)" - by (simp add: Min_def ACIfSLlin.fold1_strict_below_iff [OF ACIfSLlin_min]) + assumes "finite A" and "A \ {}" + shows "Min A < x \ (\a\A. a < x)" +proof - + invoke lower_semilattice [_ _ min] + by (rule min_lattice) + from assms show ?thesis + by (simp add: Min_def fold1_strict_below_iff) +qed lemma Max_gr_iff [noatp]: - "\ finite A; A \ {} \ \ x < Max A \ (\a\A. x < a)" - by (simp add: Max_def ACIfSLlin.fold1_strict_below_iff [OF ACIfSLlin_max]) - -lemma Min_Un: "\finite A; A \ {}; finite B; B \ {}\ - \ Min (A \ B) = min (Min A) (Min B)" - by (simp add: Min_def ACIf.fold1_Un2 [OF ACIf_min]) - -lemma Max_Un: "\finite A; A \ {}; finite B; B \ {}\ - \ Max (A \ B) = max (Max A) (Max B)" - by (simp add: Max_def ACIf.fold1_Un2 [OF ACIf_max]) - -lemma hom_Min_commute: - "(\x y. h (min x y) = min (h x) (h y)) - \ finite N \ N \ {} \ h (Min N) = Min (h ` N)" - by (simp add: Min_def ACIf.hom_fold1_commute [OF ACIf_min]) - -lemma hom_Max_commute: - "(\x y. h (max x y) = max (h x) (h y)) - \ finite N \ N \ {} \ h (Max N) = Max (h ` N)" - by (simp add: Max_def ACIf.hom_fold1_commute [OF ACIf_max]) + assumes "finite A" and "A \ {}" + shows "x < Max A \ (\a\A. x < a)" +proof - + note Max = Max_def + invoke linorder ["op \" "op >"] + by (rule dual_linorder) + from assms show ?thesis + by (simp add: Max fold1_strict_below_iff [folded dual_max]) +qed + +lemma Min_antimono: + assumes "M \ N" and "M \ {}" and "finite N" + shows "Min N \ Min M" +proof - + invoke distrib_lattice ["op \" "op <" min max] + by (rule distrib_lattice_min_max) + from assms show ?thesis by (simp add: Min_def fold1_antimono) +qed + +lemma Max_mono: + assumes "M \ N" and "M \ {}" and "finite N" + shows "Max M \ Max N" +proof - + note Max = Max_def + invoke linorder ["op \" "op >"] + by (rule dual_linorder) + from assms show ?thesis + by (simp add: Max fold1_antimono [folded dual_max]) +qed end @@ -2638,161 +2771,4 @@ end - -subsection {* Class @{text finite} and code generation *} - -lemma finite_code [code func]: - "finite {} \ True" - "finite (insert a A) \ finite A" - by auto - -lemma card_code [code func]: - "card {} = 0" - "card (insert a A) = - (if finite A then Suc (card (A - {a})) else card (insert a A))" - by (auto simp add: card_insert) - -setup {* Sign.add_path "finite" *} -- {*FIXME: name tweaking*} -class finite (attach UNIV) = type + - fixes itself :: "'a itself" - assumes finite_UNIV: "finite (UNIV \ 'a set)" -setup {* Sign.parent_path *} -hide const finite - -lemma finite [simp]: "finite (A \ 'a\finite set)" - by (rule finite_subset [OF subset_UNIV finite_UNIV]) - -lemma univ_unit [noatp]: - "UNIV = {()}" by auto - -instantiation unit :: finite -begin - -definition - "itself = TYPE(unit)" - -instance proof - have "finite {()}" by simp - also note univ_unit [symmetric] - finally show "finite (UNIV :: unit set)" . -qed - end - -lemmas [code func] = univ_unit - -lemma univ_bool [noatp]: - "UNIV = {False, True}" by auto - -instantiation bool :: finite -begin - -definition - "itself = TYPE(bool)" - -instance proof - have "finite {False, True}" by simp - also note univ_bool [symmetric] - finally show "finite (UNIV :: bool set)" . -qed - -end - -lemmas [code func] = univ_bool - -instantiation * :: (finite, finite) finite -begin - -definition - "itself = TYPE('a \ 'b)" - -instance proof - show "finite (UNIV :: ('a \ 'b) set)" - proof (rule finite_Prod_UNIV) - show "finite (UNIV :: 'a set)" by (rule finite) - show "finite (UNIV :: 'b set)" by (rule finite) - qed -qed - -end - -lemma univ_prod [noatp, code func]: - "UNIV = (UNIV \ 'a\finite set) \ (UNIV \ 'b\finite set)" - unfolding UNIV_Times_UNIV .. - -instantiation "+" :: (finite, finite) finite -begin - -definition - "itself = TYPE('a + 'b)" - -instance proof - have a: "finite (UNIV :: 'a set)" by (rule finite) - have b: "finite (UNIV :: 'b set)" by (rule finite) - from a b have "finite ((UNIV :: 'a set) <+> (UNIV :: 'b set))" - by (rule finite_Plus) - thus "finite (UNIV :: ('a + 'b) set)" by simp -qed - -end - -lemma univ_sum [noatp, code func]: - "UNIV = (UNIV \ 'a\finite set) <+> (UNIV \ 'b\finite set)" - unfolding UNIV_Plus_UNIV .. - -instantiation set :: (finite) finite -begin - -definition - "itself = TYPE('a set)" - -instance proof - have "finite (UNIV :: 'a set)" by (rule finite) - hence "finite (Pow (UNIV :: 'a set))" - by (rule finite_Pow_iff [THEN iffD2]) - thus "finite (UNIV :: 'a set set)" by simp -qed - -end - -lemma univ_set [noatp, code func]: - "UNIV = Pow (UNIV \ 'a\finite set)" unfolding Pow_UNIV .. - -lemma inj_graph: "inj (%f. {(x, y). y = f x})" - by (rule inj_onI, auto simp add: expand_set_eq expand_fun_eq) - -instantiation "fun" :: (finite, finite) finite -begin - -definition - "itself \ TYPE('a \ 'b)" - -instance 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 - -hide (open) const itself - -subsection {* Equality and order on functions *} - -instance "fun" :: (finite, eq) eq .. - -lemma eq_fun [code func]: - fixes f g :: "'a\finite \ 'b\eq" - shows "f = g \ (\x\UNIV. f x = g x)" - unfolding expand_fun_eq by auto - -lemma order_fun [code func]: - fixes f g :: "'a\finite \ 'b\order" - shows "f \ g \ (\x\UNIV. f x \ g x)" - and "f < g \ f \ g \ (\x\UNIV. f x \ g x)" - by (auto simp add: expand_fun_eq le_fun_def less_fun_def order_less_le) - -end diff -r 08d52e2dba07 -r c2e15e65165f src/HOL/MetisExamples/BigO.thy --- a/src/HOL/MetisExamples/BigO.thy Mon Feb 04 17:00:01 2008 +0100 +++ b/src/HOL/MetisExamples/BigO.thy Wed Feb 06 08:34:32 2008 +0100 @@ -389,11 +389,11 @@ have 4: "\X1 X3\'b\ordered_idom. X3 \ X1 \ X1 \ \X3\" by (metis linorder_linear abs_le_D1) have 5: "\X3::'b. \X3\ * \X3\ = X3 * X3" - by (metis abs_mult_self AC_mult.f.commute) + by (metis abs_mult_self) have 6: "\X3. \ X3 * X3 < (0\'b\ordered_idom)" - by (metis not_square_less_zero AC_mult.f.commute) + by (metis not_square_less_zero) have 7: "\X1 X3::'b. \X1\ * \X3\ = \X3 * X1\" - by (metis abs_mult AC_mult.f.commute) + by (metis abs_mult mult_commute) have 8: "\X3::'b. X3 * X3 = \X3 * X3\" by (metis abs_mult 5) have 9: "\X3. X3 * g (x \X3\) \ f (x \X3\)" @@ -403,7 +403,7 @@ have 11: "\X3::'b. \X3\ * \\X3\\ = \X3\ * \X3\" by (metis abs_idempotent abs_mult 8) have 12: "\X3::'b. \X3 * \X3\\ = \X3\ * \X3\" - by (metis AC_mult.f.commute 7 11) + by (metis mult_commute 7 11) have 13: "\X3::'b. \X3 * \X3\\ = X3 * X3" by (metis 8 7 12) have 14: "\X3. X3 \ \X3\ \ X3 < (0\'b)" @@ -597,8 +597,10 @@ (c * abs(f x)) * (ca * abs(g x))") ML{*ResAtp.problem_name := "BigO__bigo_mult_simpler"*} prefer 2 -apply (metis Finite_Set.AC_mult.f.assoc Finite_Set.AC_mult.f.left_commute OrderedGroup.abs_of_pos OrderedGroup.mult_left_commute Ring_and_Field.abs_mult Ring_and_Field.mult_pos_pos) - apply(erule ssubst) +apply (metis mult_assoc mult_left_commute + OrderedGroup.abs_of_pos OrderedGroup.mult_left_commute + Ring_and_Field.abs_mult Ring_and_Field.mult_pos_pos) + apply (erule ssubst) apply (subst abs_mult) (*not qute BigO__bigo_mult_simpler_1 (a hard problem!) as abs_mult has just been done*) @@ -627,7 +629,7 @@ have 9: "\X1\'b\ordered_idom. (0\'b\ordered_idom) \ (c\'b\ordered_idom) * \X1\" by (metis OrderedGroup.abs_ge_zero 5) have 10: "\X1\'b\ordered_idom. X1 * (1\'b\ordered_idom) = X1" - by (metis Ring_and_Field.mult_cancel_right2 Finite_Set.AC_mult.f.commute) + by (metis Ring_and_Field.mult_cancel_right2 mult_commute) have 11: "\X1\'b\ordered_idom. \\X1\\ = \X1\ * \1\'b\ordered_idom\" by (metis Ring_and_Field.abs_mult OrderedGroup.abs_idempotent 10) have 12: "\X1\'b\ordered_idom. \\X1\\ = \X1\" @@ -901,10 +903,10 @@ apply safe apply (rule_tac [2] ext) prefer 2 - apply (metis AC_mult.f_e.left_ident mult_assoc right_inverse) + apply simp apply (simp add: mult_assoc [symmetric] abs_mult) (*couldn't get this proof without the step above; SLOW*) - apply (metis AC_mult.f.assoc abs_ge_zero mult_left_mono) + apply (metis mult_assoc abs_ge_zero mult_left_mono) done diff -r 08d52e2dba07 -r c2e15e65165f src/HOLCF/CompactBasis.thy --- a/src/HOLCF/CompactBasis.thy Mon Feb 04 17:00:01 2008 +0100 +++ b/src/HOLCF/CompactBasis.thy Wed Feb 06 08:34:32 2008 +0100 @@ -610,12 +610,12 @@ "('a compact_basis \ 'b::type) \ ('b \ 'b \ 'b) \ 'a pd_basis \ 'b" where "fold_pd g f t = fold1 f (g ` Rep_pd_basis t)" -lemma (in ACIf) fold_pd_PDUnit: - "fold_pd g f (PDUnit x) = g x" +lemma (in ab_semigroup_idem_mult) fold_pd_PDUnit: + "fold_pd g (op *) (PDUnit x) = g x" unfolding fold_pd_def Rep_PDUnit by simp -lemma (in ACIf) fold_pd_PDPlus: - "fold_pd g f (PDPlus t u) = f (fold_pd g f t) (fold_pd g f u)" +lemma (in ab_semigroup_idem_mult) fold_pd_PDPlus: + "fold_pd g (op *) (PDPlus t u) = fold_pd g (op *) t * fold_pd g (op *) u" unfolding fold_pd_def Rep_PDPlus by (simp add: image_Un fold1_Un2) text {* approx-pd *} diff -r 08d52e2dba07 -r c2e15e65165f src/HOLCF/ConvexPD.thy --- a/src/HOLCF/ConvexPD.thy Mon Feb 04 17:00:01 2008 +0100 +++ b/src/HOLCF/ConvexPD.thy Wed Feb 06 08:34:32 2008 +0100 @@ -443,10 +443,10 @@ (\a. \ f. f\(Rep_compact_basis a)) (\x y. \ f. convex_plus\(x\f)\(y\f))" -lemma ACI_convex_bind: "ACIf (\x y. \ f. convex_plus\(x\f)\(y\f))" +lemma ACI_convex_bind: "ab_semigroup_idem_mult (\x y. \ f. convex_plus\(x\f)\(y\f))" apply unfold_locales +apply (simp add: convex_plus_assoc) apply (simp add: convex_plus_commute) -apply (simp add: convex_plus_assoc) apply (simp add: convex_plus_absorb eta_cfun) done @@ -457,8 +457,8 @@ (\ f. convex_plus\(convex_bind_basis t\f)\(convex_bind_basis u\f))" unfolding convex_bind_basis_def apply - -apply (rule ACIf.fold_pd_PDUnit [OF ACI_convex_bind]) -apply (rule ACIf.fold_pd_PDPlus [OF ACI_convex_bind]) +apply (rule ab_semigroup_idem_mult.fold_pd_PDUnit [OF ACI_convex_bind]) +apply (rule ab_semigroup_idem_mult.fold_pd_PDPlus [OF ACI_convex_bind]) done lemma monofun_LAM: diff -r 08d52e2dba07 -r c2e15e65165f src/HOLCF/LowerPD.thy --- a/src/HOLCF/LowerPD.thy Mon Feb 04 17:00:01 2008 +0100 +++ b/src/HOLCF/LowerPD.thy Wed Feb 06 08:34:32 2008 +0100 @@ -433,10 +433,10 @@ (\a. \ f. f\(Rep_compact_basis a)) (\x y. \ f. lower_plus\(x\f)\(y\f))" -lemma ACI_lower_bind: "ACIf (\x y. \ f. lower_plus\(x\f)\(y\f))" +lemma ACI_lower_bind: "ab_semigroup_idem_mult (\x y. \ f. lower_plus\(x\f)\(y\f))" apply unfold_locales +apply (simp add: lower_plus_assoc) apply (simp add: lower_plus_commute) -apply (simp add: lower_plus_assoc) apply (simp add: lower_plus_absorb eta_cfun) done @@ -447,8 +447,8 @@ (\ f. lower_plus\(lower_bind_basis t\f)\(lower_bind_basis u\f))" unfolding lower_bind_basis_def apply - -apply (rule ACIf.fold_pd_PDUnit [OF ACI_lower_bind]) -apply (rule ACIf.fold_pd_PDPlus [OF ACI_lower_bind]) +apply (rule ab_semigroup_idem_mult.fold_pd_PDUnit [OF ACI_lower_bind]) +apply (rule ab_semigroup_idem_mult.fold_pd_PDPlus [OF ACI_lower_bind]) done lemma lower_bind_basis_mono: diff -r 08d52e2dba07 -r c2e15e65165f src/HOLCF/UpperPD.thy --- a/src/HOLCF/UpperPD.thy Mon Feb 04 17:00:01 2008 +0100 +++ b/src/HOLCF/UpperPD.thy Wed Feb 06 08:34:32 2008 +0100 @@ -403,10 +403,10 @@ (\a. \ f. f\(Rep_compact_basis a)) (\x y. \ f. upper_plus\(x\f)\(y\f))" -lemma ACI_upper_bind: "ACIf (\x y. \ f. upper_plus\(x\f)\(y\f))" +lemma ACI_upper_bind: "ab_semigroup_idem_mult (\x y. \ f. upper_plus\(x\f)\(y\f))" apply unfold_locales +apply (simp add: upper_plus_assoc) apply (simp add: upper_plus_commute) -apply (simp add: upper_plus_assoc) apply (simp add: upper_plus_absorb eta_cfun) done @@ -417,8 +417,8 @@ (\ f. upper_plus\(upper_bind_basis t\f)\(upper_bind_basis u\f))" unfolding upper_bind_basis_def apply - -apply (rule ACIf.fold_pd_PDUnit [OF ACI_upper_bind]) -apply (rule ACIf.fold_pd_PDPlus [OF ACI_upper_bind]) +apply (rule ab_semigroup_idem_mult.fold_pd_PDUnit [OF ACI_upper_bind]) +apply (rule ab_semigroup_idem_mult.fold_pd_PDPlus [OF ACI_upper_bind]) done lemma upper_bind_basis_mono: