# HG changeset patch # User nipkow # Date 1107533682 -3600 # Node ID 53bca254719adc8fcd32451c9e84af2cfb148fa2 # Parent 3263daa9616705c9470e8d81ac831f432c0e5596 Added semi-lattice locales and reorganized fold1 lemmas diff -r 3263daa96167 -r 53bca254719a src/HOL/Finite_Set.thy --- a/src/HOL/Finite_Set.thy Thu Feb 03 16:45:59 2005 +0100 +++ b/src/HOL/Finite_Set.thy Fri Feb 04 17:14:42 2005 +0100 @@ -487,6 +487,15 @@ thus ?thesis by (subst commute) qed +lemma (in ACIf) 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 (in ACIf) ACI = AC idem idem2 + text{* Instantiation of locales: *} lemma ACf_add: "ACf (op + :: 'a::comm_monoid_add \ 'a \ 'a)" @@ -1913,6 +1922,74 @@ by(simp add:fold1_insert2) +subsubsection{* Semi-Lattices *} + +locale ACIfSL = ACIf + + fixes below :: "'a \ 'a \ bool" (infixl "\" 50) + assumes below_def: "x \ y = (x\y = x)" + +locale ACIfSLlin = ACIfSL + + assumes lin: "x\y \ {x,y}" + +lemma (in ACIfSL) below_refl[simp]: "x \ x" +by(simp add: below_def idem) + +lemma (in ACIfSL) below_f_conv[simp]: "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 + +lemma (in ACIfSLlin) 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 + + subsubsection{* Lemmas about {@text fold1} *} lemma (in ACf) fold1_Un: @@ -1947,38 +2024,59 @@ case insert thus ?case using elem by (force simp add:fold1_insert) qed -lemma fold1_le: - assumes ACf: "ACf(f::'a::linorder \ 'a \ 'a)" - and A: "finite (A)" "A \ {}" and le: "\x y. f x y \ x" - shows "a \ A \ fold1 f A \ a" +lemma (in ACIfSL) below_fold1_iff: +assumes A: "finite A" "A \ {}" +shows "x \ fold1 f A = (\a\A. x \ a)" +using 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) - case singleton thus ?case by(simp) + case singleton thus ?case by simp next - from le have le2: "\x y. f x y \ y" by (fastsimp simp:ACf.commute[OF ACf]) - case (insert x F) thus ?case using le le2 - by (simp add:ACf.fold1_insert[OF ACf]) (blast intro: le order_trans) + case (insert x F) + from insert(4) 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 op \ F \ a" by(rule insert) + have "fold1 op \ (insert x F) \ a = x \ (fold1 op \ F \ a)" + using insert by(simp add:below_def ACI) + also have "fold1 op \ F \ a = fold1 op \ F" + using bel by(simp add:below_def ACI) + also have "x \ \ = fold1 op \ (insert x F)" + using insert by(simp add:below_def ACI) + finally show ?thesis by(simp add:below_def) + qed qed -lemma fold1_ge: - assumes ACf: "ACf(f::'a::linorder \ 'a \ 'a)" - and A: "finite (A)" "A \ {}" and ge: "\x y. x \ f x y" - shows "a \ A \ a \ fold1 f A" +lemma (in ACIfSLlin) fold1_below_iff: +assumes A: "finite A" "A \ {}" +shows "fold1 f A \ x = (\a\A. a \ x)" using A -proof (induct rule:finite_ne_induct) - case singleton thus ?case by(simp) -next - from ge have ge2: "\x y. y \ f x y" by (fastsimp simp:ACf.commute[OF ACf]) - case (insert x F) thus ?case using ge ge2 - by (simp add:ACf.fold1_insert[OF ACf]) (blast intro: ge order_trans) -qed +by(induct rule:finite_ne_induct)(simp_all add:above_f_conv) subsection{*Min and Max*} text{* As an application of @{text fold1} we define the minimal and -maximal element of a (non-empty) set over a linear order. First we -show that @{text min} and @{text max} are ACI: *} +maximal element of a (non-empty) set over a linear order. *} + +constdefs + Min :: "('a::linorder)set => 'a" + "Min == fold1 min" + + Max :: "('a::linorder)set => 'a" + "Max == fold1 max" + + +text{* Before we can do anything, we need to show that @{text min} and +@{text max} are ACI and the ordering is linear: *} lemma ACf_min: "ACf(min :: 'a::linorder \ 'a \ 'a)" apply(rule ACf.intro) @@ -2002,14 +2100,39 @@ apply(auto simp:max_def) done -text{* Now we make the definitions: *} +lemma ACIfSL_min: "ACIfSL(min :: 'a::linorder \ 'a \ 'a) (op \)" +apply(rule ACIfSL.intro) +apply(rule ACf_min) +apply(rule ACIf.axioms[OF ACIf_min]) +apply(rule ACIfSL_axioms.intro) +apply(auto simp:min_def) +done + +lemma ACIfSLlin_min: "ACIfSLlin(min :: 'a::linorder \ 'a \ 'a) (op \)" +apply(rule ACIfSLlin.intro) +apply(rule ACf_min) +apply(rule ACIf.axioms[OF ACIf_min]) +apply(rule ACIfSL.axioms[OF ACIfSL_min]) +apply(rule ACIfSLlin_axioms.intro) +apply(auto simp:min_def) +done -constdefs - Min :: "('a::linorder)set => 'a" - "Min == fold1 min" +lemma ACIfSL_max: "ACIfSL(max :: 'a::linorder \ 'a \ 'a) (%x y. y\x)" +apply(rule ACIfSL.intro) +apply(rule ACf_max) +apply(rule ACIf.axioms[OF ACIf_max]) +apply(rule ACIfSL_axioms.intro) +apply(auto simp:max_def) +done - Max :: "('a::linorder)set => 'a" - "Max == fold1 max" +lemma ACIfSLlin_max: "ACIfSLlin(max :: 'a::linorder \ 'a \ 'a) (%x y. y\x)" +apply(rule ACIfSLlin.intro) +apply(rule ACf_max) +apply(rule ACIf.axioms[OF ACIf_max]) +apply(rule ACIfSL.axioms[OF ACIfSL_max]) +apply(rule ACIfSLlin_axioms.intro) +apply(auto simp:max_def) +done text{* Now we instantiate the recursion equations and declare them simplification rules: *} @@ -2033,9 +2156,25 @@ by(fastsimp simp: Max_def max_def) lemma Min_le [simp]: "\ finite A; A \ {}; x \ A \ \ Min A \ x" -by(simp add: Min_def fold1_le[OF ACf_min] min_le_iff_disj) +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 fold1_ge[OF ACf_max] le_max_iff_disj) +by(simp add: Max_def ACIfSL.fold1_belowI[OF ACIfSL_max]) + +lemma Min_ge_iff[simp]: + "\ 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]: + "\ finite A; A \ {} \ \ (Max A \ x) = (\a\A. a \ x)" +by(simp add: Max_def ACIfSL.below_fold1_iff[OF ACIfSL_max]) + +lemma Min_le_iff: + "\ finite A; A \ {} \ \ (Min A \ x) = (\a\A. a \ x)" +by(simp add: Min_def ACIfSLlin.fold1_below_iff[OF ACIfSLlin_min]) + +lemma Max_ge_iff: + "\ finite A; A \ {} \ \ (x \ Max A) = (\a\A. x \ a)" +by(simp add: Max_def ACIfSLlin.fold1_below_iff[OF ACIfSLlin_max]) end