# HG changeset patch # User avigad # Date 1122310489 -7200 # Node ID d374530bfaaab5a6f5220543b092614c9f8ce550 # Parent 2187e3f947614071d4211dbadf35bbf5009dd7d6 Added two new theories to HOL/Library: SetsAndFunctions.thy and BigO.thy diff -r 2187e3f94761 -r d374530bfaaa NEWS --- a/NEWS Mon Jul 25 15:51:30 2005 +0200 +++ b/NEWS Mon Jul 25 18:54:49 2005 +0200 @@ -389,6 +389,12 @@ * Theory RComplete: expanded support for floor and ceiling functions. +*** HOL-Library *** + +* Theories SetsAndFunctions and BigO support asymptotic "big O" calculations. +See the notes in BigO.thy. + + *** HOLCF *** * HOLCF: discontinued special version of 'constdefs' (which used to diff -r 2187e3f94761 -r d374530bfaaa src/HOL/IsaMakefile --- a/src/HOL/IsaMakefile Mon Jul 25 15:51:30 2005 +0200 +++ b/src/HOL/IsaMakefile Mon Jul 25 18:54:49 2005 +0200 @@ -176,6 +176,7 @@ HOL-Library: HOL $(LOG)/HOL-Library.gz $(LOG)/HOL-Library.gz: $(OUT)/HOL Library/Accessible_Part.thy \ + Library/SetsAndFunctions.thy Library/BigO.thy \ Library/EfficientNat.thy Library/FuncSet.thy Library/Library.thy \ Library/List_Prefix.thy Library/Multiset.thy Library/NatPair.thy \ Library/Permutation.thy Library/Primes.thy Library/Quotient.thy \ diff -r 2187e3f94761 -r d374530bfaaa src/HOL/Library/BigO.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Library/BigO.thy Mon Jul 25 18:54:49 2005 +0200 @@ -0,0 +1,916 @@ +(* Title: BigO.thy + Authors: Jeremy Avigad and Kevin Donnelly +*) + +header {* Big O notation *} + +theory BigO +imports SetsAndFunctions +begin + +text {* +This library is designed to support asymptotic ``big O'' calculations, +i.e.~reasoning with expressions of the form $f = O(g)$ and $f = g + O(h)$. +An earlier version of this library is described in detail in +\begin{quote} +Avigad, Jeremy, and Kevin Donnelly, \emph{Formalizing O notation in +Isabelle/HOL}, in David Basin and Micha\"el Rusiowitch, editors, +\emph{Automated Reasoning: second international conference, IJCAR 2004}, +Springer, 357--371, 2004. +\end{quote} +The main changes in this version are as follows: +\begin{itemize} +\item We have eliminated the $O$ operator on sets. (Most uses of this seem + to be inessential.) +\item We no longer use $+$ as output syntax for $+o$. +\item Lemmas involving ``sumr-pos'' have been replaced by more + general lemmas involving ``setsum''. +\item The library has been expanded, with e.g.~support for expressions of + the form $f < g + O(h)$. +\end{itemize} +Note that two lemmas at the end of this file are commented out, as they +require the HOL-Complex library. + +Note also since the Big O library includes rules that demonstrate set +inclusion, to use the automated reasoners effectively with the library one +should redeclare the theorem ``subsetI'' as an intro rule, rather than as +an intro! rule, for example, using ``declare subsetI [del, intro]''. +*} + +subsection {* Definitions *} + +constdefs + + bigo :: "('a => 'b::ordered_idom) => ('a => 'b) set" ("(1O'(_'))") + "O(f::('a => 'b)) == + {h. EX c. ALL x. abs (h x) <= c * abs (f x)}" + +lemma bigo_pos_const: "(EX (c::'a::ordered_idom). + ALL x. (abs (h x)) <= (c * (abs (f x)))) + = (EX c. 0 < c & (ALL x. (abs(h x)) <= (c * (abs (f x)))))" + apply auto + apply (case_tac "c = 0") + apply simp + apply (rule_tac x = "1" in exI) + apply simp + apply (rule_tac x = "abs c" in exI) + apply auto + apply (subgoal_tac "c * abs(f x) <= abs c * abs (f x)") + apply (erule_tac x = x in allE) + apply force + apply (rule mult_right_mono) + apply (rule abs_ge_self) + apply (rule abs_ge_zero) +done + +lemma bigo_alt_def: "O(f) = + {h. EX c. (0 < c & (ALL x. abs (h x) <= c * abs (f x)))}" +by (auto simp add: bigo_def bigo_pos_const) + +lemma bigo_elt_subset [intro]: "f : O(g) ==> O(f) <= O(g)" + apply (auto simp add: bigo_alt_def) + apply (rule_tac x = "ca * c" in exI) + apply (rule conjI) + apply (rule mult_pos_pos) + apply (assumption)+ + apply (rule allI) + apply (drule_tac x = "xa" in spec)+ + apply (subgoal_tac "ca * abs(f xa) <= ca * (c * abs(g xa))") + apply (erule order_trans) + apply (simp add: mult_ac) + apply (rule mult_left_mono, assumption) + apply (rule order_less_imp_le, assumption) +done + +lemma bigo_refl [intro]: "f : O(f)" + apply(auto simp add: bigo_def) + apply(rule_tac x = 1 in exI) + apply simp +done + +lemma bigo_zero: "0 : O(g)" + apply (auto simp add: bigo_def func_zero) + apply (rule_tac x = 0 in exI) + apply auto +done + +lemma bigo_zero2: "O(%x.0) = {%x.0}" + apply (auto simp add: bigo_def) + apply (rule ext) + apply auto +done + +lemma bigo_plus_self_subset [intro]: + "O(f) + O(f) <= O(f)" + apply (auto simp add: bigo_alt_def set_plus) + apply (rule_tac x = "c + ca" in exI) + apply auto + apply (simp add: ring_distrib func_plus) + apply (rule order_trans) + apply (rule abs_triangle_ineq) + apply (rule add_mono) + apply force + apply force +done + +lemma bigo_plus_idemp [simp]: "O(f) + O(f) = O(f)" + apply (rule equalityI) + apply (rule bigo_plus_self_subset) + apply (rule set_zero_plus2) + apply (rule bigo_zero) +done + +lemma bigo_plus_subset [intro]: "O(f + g) <= O(f) + O(g)" + apply (rule subsetI) + apply (auto simp add: bigo_def bigo_pos_const func_plus set_plus) + apply (subst bigo_pos_const [symmetric])+ + apply (rule_tac x = + "%n. if abs (g n) <= (abs (f n)) then x n else 0" in exI) + apply (rule conjI) + apply (rule_tac x = "c + c" in exI) + apply (clarsimp) + apply (auto) + apply (subgoal_tac "c * abs (f xa + g xa) <= (c + c) * abs (f xa)") + apply (erule_tac x = xa in allE) + apply (erule order_trans) + apply (simp) + apply (subgoal_tac "c * abs (f xa + g xa) <= c * (abs (f xa) + abs (g xa))") + apply (erule order_trans) + apply (simp add: ring_distrib) + apply (rule mult_left_mono) + apply assumption + apply (simp add: order_less_le) + apply (rule mult_left_mono) + apply (simp add: abs_triangle_ineq) + apply (simp add: order_less_le) + apply (rule mult_nonneg_nonneg) + apply (rule add_nonneg_nonneg) + apply auto + apply (rule_tac x = "%n. if (abs (f n)) < abs (g n) then x n else 0" + in exI) + apply (rule conjI) + apply (rule_tac x = "c + c" in exI) + apply auto + apply (subgoal_tac "c * abs (f xa + g xa) <= (c + c) * abs (g xa)") + apply (erule_tac x = xa in allE) + apply (erule order_trans) + apply (simp) + apply (subgoal_tac "c * abs (f xa + g xa) <= c * (abs (f xa) + abs (g xa))") + apply (erule order_trans) + apply (simp add: ring_distrib) + apply (rule mult_left_mono) + apply (simp add: order_less_le) + apply (simp add: order_less_le) + apply (rule mult_left_mono) + apply (rule abs_triangle_ineq) + apply (simp add: order_less_le) + apply (rule mult_nonneg_nonneg) + apply (rule add_nonneg_nonneg) + apply (erule order_less_imp_le)+ + apply simp + apply (rule ext) + apply (auto simp add: if_splits linorder_not_le) +done + +lemma bigo_plus_subset2 [intro]: "A <= O(f) ==> B <= O(f) ==> A + B <= O(f)" + apply (subgoal_tac "A + B <= O(f) + O(f)") + apply (erule order_trans) + apply simp + apply (auto del: subsetI simp del: bigo_plus_idemp) +done + +lemma bigo_plus_eq: "ALL x. 0 <= f x ==> ALL x. 0 <= g x ==> + O(f + g) = O(f) + O(g)" + apply (rule equalityI) + apply (rule bigo_plus_subset) + apply (simp add: bigo_alt_def set_plus func_plus) + apply clarify + apply (rule_tac x = "max c ca" in exI) + apply (rule conjI) + apply (subgoal_tac "c <= max c ca") + apply (erule order_less_le_trans) + apply assumption + apply (rule le_maxI1) + apply clarify + apply (drule_tac x = "xa" in spec)+ + apply (subgoal_tac "0 <= f xa + g xa") + apply (simp add: ring_distrib) + apply (subgoal_tac "abs(a xa + b xa) <= abs(a xa) + abs(b xa)") + apply (subgoal_tac "abs(a xa) + abs(b xa) <= + max c ca * f xa + max c ca * g xa") + apply (force) + apply (rule add_mono) + apply (subgoal_tac "c * f xa <= max c ca * f xa") + apply (force) + apply (rule mult_right_mono) + apply (rule le_maxI1) + apply assumption + apply (subgoal_tac "ca * g xa <= max c ca * g xa") + apply (force) + apply (rule mult_right_mono) + apply (rule le_maxI2) + apply assumption + apply (rule abs_triangle_ineq) + apply (rule add_nonneg_nonneg) + apply assumption+ +done + +lemma bigo_bounded_alt: "ALL x. 0 <= f x ==> ALL x. f x <= c * g x ==> + f : O(g)" + apply (auto simp add: bigo_def) + apply (rule_tac x = "abs c" in exI) + apply auto + apply (drule_tac x = x in spec)+ + apply (simp add: abs_mult [symmetric]) +done + +lemma bigo_bounded: "ALL x. 0 <= f x ==> ALL x. f x <= g x ==> + f : O(g)" + apply (erule bigo_bounded_alt [of f 1 g]) + apply simp +done + +lemma bigo_bounded2: "ALL x. lb x <= f x ==> ALL x. f x <= lb x + g x ==> + f : lb +o O(g)" + apply (rule set_minus_imp_plus) + apply (rule bigo_bounded) + apply (auto simp add: diff_minus func_minus func_plus) + apply (drule_tac x = x in spec)+ + apply force + apply (drule_tac x = x in spec)+ + apply force +done + +lemma bigo_abs: "(%x. abs(f x)) =o O(f)" + apply (unfold bigo_def) + apply auto + apply (rule_tac x = 1 in exI) + apply auto +done + +lemma bigo_abs2: "f =o O(%x. abs(f x))" + apply (unfold bigo_def) + apply auto + apply (rule_tac x = 1 in exI) + apply auto +done + +lemma bigo_abs3: "O(f) = O(%x. abs(f x))" + apply (rule equalityI) + apply (rule bigo_elt_subset) + apply (rule bigo_abs2) + apply (rule bigo_elt_subset) + apply (rule bigo_abs) +done + +lemma bigo_abs4: "f =o g +o O(h) ==> + (%x. abs (f x)) =o (%x. abs (g x)) +o O(h)" + apply (drule set_plus_imp_minus) + apply (rule set_minus_imp_plus) + apply (subst func_diff) +proof - + assume a: "f - g : O(h)" + have "(%x. abs (f x) - abs (g x)) =o O(%x. abs(abs (f x) - abs (g x)))" + by (rule bigo_abs2) + also have "... <= O(%x. abs (f x - g x))" + apply (rule bigo_elt_subset) + apply (rule bigo_bounded) + apply force + apply (rule allI) + apply (rule abs_triangle_ineq3) + done + also have "... <= O(f - g)" + apply (rule bigo_elt_subset) + apply (subst func_diff) + apply (rule bigo_abs) + done + also have "... <= O(h)" + by (rule bigo_elt_subset) + finally show "(%x. abs (f x) - abs (g x)) : O(h)". +qed + +lemma bigo_abs5: "f =o O(g) ==> (%x. abs(f x)) =o O(g)" +by (unfold bigo_def, auto) + +lemma bigo_elt_subset2 [intro]: "f : g +o O(h) ==> O(f) <= O(g) + O(h)" +proof - + assume "f : g +o O(h)" + also have "... <= O(g) + O(h)" + by (auto del: subsetI) + also have "... = O(%x. abs(g x)) + O(%x. abs(h x))" + apply (subst bigo_abs3 [symmetric])+ + apply (rule refl) + done + also have "... = O((%x. abs(g x)) + (%x. abs(h x)))" + by (rule bigo_plus_eq [symmetric], auto) + finally have "f : ...". + then have "O(f) <= ..." + by (elim bigo_elt_subset) + also have "... = O(%x. abs(g x)) + O(%x. abs(h x))" + by (rule bigo_plus_eq, auto) + finally show ?thesis + by (simp add: bigo_abs3 [symmetric]) +qed + +lemma bigo_mult [intro]: "O(f)*O(g) <= O(f * g)" + apply (rule subsetI) + apply (subst bigo_def) + apply (auto simp add: bigo_alt_def set_times func_times) + apply (rule_tac x = "c * ca" in exI) + apply(rule allI) + apply(erule_tac x = x in allE)+ + apply(subgoal_tac "c * ca * abs(f x * g x) = + (c * abs(f x)) * (ca * abs(g x))") + apply(erule ssubst) + apply (subst abs_mult) + apply (rule mult_mono) + apply assumption+ + apply (rule mult_nonneg_nonneg) + apply auto + apply (simp add: mult_ac abs_mult) +done + +lemma bigo_mult2 [intro]: "f *o O(g) <= O(f * g)" + apply (auto simp add: bigo_def elt_set_times_def func_times abs_mult) + apply (rule_tac x = c in exI) + apply auto + apply (drule_tac x = x in spec) + apply (subgoal_tac "abs(f x) * abs(b x) <= abs(f x) * (c * abs(g x))") + apply (force simp add: mult_ac) + apply (rule mult_left_mono, assumption) + apply (rule abs_ge_zero) +done + +lemma bigo_mult3: "f : O(h) ==> g : O(j) ==> f * g : O(h * j)" + apply (rule subsetD) + apply (rule bigo_mult) + apply (erule set_times_intro, assumption) +done + +lemma bigo_mult4 [intro]:"f : k +o O(h) ==> g * f : (g * k) +o O(g * h)" + apply (drule set_plus_imp_minus) + apply (rule set_minus_imp_plus) + apply (drule bigo_mult3 [where g = g and j = g]) + apply (auto simp add: ring_eq_simps mult_ac) +done + +lemma bigo_mult5: "ALL x. f x ~= 0 ==> + O(f * g) <= (f::'a => ('b::ordered_field)) *o O(g)" +proof - + assume "ALL x. f x ~= 0" + show "O(f * g) <= f *o O(g)" + proof + fix h + assume "h : O(f * g)" + then have "(%x. 1 / (f x)) * h : (%x. 1 / f x) *o O(f * g)" + by auto + also have "... <= O((%x. 1 / f x) * (f * g))" + by (rule bigo_mult2) + also have "(%x. 1 / f x) * (f * g) = g" + apply (simp add: func_times) + apply (rule ext) + apply (simp add: prems nonzero_divide_eq_eq mult_ac) + done + finally have "(%x. (1::'b) / f x) * h : O(g)". + then have "f * ((%x. (1::'b) / f x) * h) : f *o O(g)" + by auto + also have "f * ((%x. (1::'b) / f x) * h) = h" + apply (simp add: func_times) + apply (rule ext) + apply (simp add: prems nonzero_divide_eq_eq mult_ac) + done + finally show "h : f *o O(g)". + qed +qed + +lemma bigo_mult6: "ALL x. f x ~= 0 ==> + O(f * g) = (f::'a => ('b::ordered_field)) *o O(g)" + apply (rule equalityI) + apply (erule bigo_mult5) + apply (rule bigo_mult2) +done + +lemma bigo_mult7: "ALL x. f x ~= 0 ==> + O(f * g) <= O(f::'a => ('b::ordered_field)) * O(g)" + apply (subst bigo_mult6) + apply assumption + apply (rule set_times_mono3) + apply (rule bigo_refl) +done + +lemma bigo_mult8: "ALL x. f x ~= 0 ==> + O(f * g) = O(f::'a => ('b::ordered_field)) * O(g)" + apply (rule equalityI) + apply (erule bigo_mult7) + apply (rule bigo_mult) +done + +lemma bigo_minus [intro]: "f : O(g) ==> - f : O(g)" + by (auto simp add: bigo_def func_minus) + +lemma bigo_minus2: "f : g +o O(h) ==> -f : -g +o O(h)" + apply (rule set_minus_imp_plus) + apply (drule set_plus_imp_minus) + apply (drule bigo_minus) + apply (simp add: diff_minus) +done + +lemma bigo_minus3: "O(-f) = O(f)" + by (auto simp add: bigo_def func_minus abs_minus_cancel) + +lemma bigo_plus_absorb_lemma1: "f : O(g) ==> f +o O(g) <= O(g)" +proof - + assume a: "f : O(g)" + show "f +o O(g) <= O(g)" + proof - + have "f : O(f)" by auto + then have "f +o O(g) <= O(f) + O(g)" + by (auto del: subsetI) + also have "... <= O(g) + O(g)" + proof - + from a have "O(f) <= O(g)" by (auto del: subsetI) + thus ?thesis by (auto del: subsetI) + qed + also have "... <= O(g)" by (simp add: bigo_plus_idemp) + finally show ?thesis . + qed +qed + +lemma bigo_plus_absorb_lemma2: "f : O(g) ==> O(g) <= f +o O(g)" +proof - + assume a: "f : O(g)" + show "O(g) <= f +o O(g)" + proof - + from a have "-f : O(g)" by auto + then have "-f +o O(g) <= O(g)" by (elim bigo_plus_absorb_lemma1) + then have "f +o (-f +o O(g)) <= f +o O(g)" by auto + also have "f +o (-f +o O(g)) = O(g)" + by (simp add: set_plus_rearranges) + finally show ?thesis . + qed +qed + +lemma bigo_plus_absorb [simp]: "f : O(g) ==> f +o O(g) = O(g)" + apply (rule equalityI) + apply (erule bigo_plus_absorb_lemma1) + apply (erule bigo_plus_absorb_lemma2) +done + +lemma bigo_plus_absorb2 [intro]: "f : O(g) ==> A <= O(g) ==> f +o A <= O(g)" + apply (subgoal_tac "f +o A <= f +o O(g)") + apply force+ +done + +lemma bigo_add_commute_imp: "f : g +o O(h) ==> g : f +o O(h)" + apply (subst set_minus_plus [symmetric]) + apply (subgoal_tac "g - f = - (f - g)") + apply (erule ssubst) + apply (rule bigo_minus) + apply (subst set_minus_plus) + apply assumption + apply (simp add: diff_minus add_ac) +done + +lemma bigo_add_commute: "(f : g +o O(h)) = (g : f +o O(h))" + apply (rule iffI) + apply (erule bigo_add_commute_imp)+ +done + +lemma bigo_const1: "(%x. c) : O(%x. 1)" +by (auto simp add: bigo_def mult_ac) + +lemma bigo_const2 [intro]: "O(%x. c) <= O(%x. 1)" + apply (rule bigo_elt_subset) + apply (rule bigo_const1) +done + +lemma bigo_const3: "(c::'a::ordered_field) ~= 0 ==> (%x. 1) : O(%x. c)" + apply (simp add: bigo_def) + apply (rule_tac x = "abs(inverse c)" in exI) + apply (simp add: abs_mult [symmetric]) +done + +lemma bigo_const4: "(c::'a::ordered_field) ~= 0 ==> O(%x. 1) <= O(%x. c)" +by (rule bigo_elt_subset, rule bigo_const3, assumption) + +lemma bigo_const [simp]: "(c::'a::ordered_field) ~= 0 ==> + O(%x. c) = O(%x. 1)" +by (rule equalityI, rule bigo_const2, rule bigo_const4, assumption) + +lemma bigo_const_mult1: "(%x. c * f x) : O(f)" + apply (simp add: bigo_def) + apply (rule_tac x = "abs(c)" in exI) + apply (auto simp add: abs_mult [symmetric]) +done + +lemma bigo_const_mult2: "O(%x. c * f x) <= O(f)" +by (rule bigo_elt_subset, rule bigo_const_mult1) + +lemma bigo_const_mult3: "(c::'a::ordered_field) ~= 0 ==> f : O(%x. c * f x)" + apply (simp add: bigo_def) + apply (rule_tac x = "abs(inverse c)" in exI) + apply (simp add: abs_mult [symmetric] mult_assoc [symmetric]) +done + +lemma bigo_const_mult4: "(c::'a::ordered_field) ~= 0 ==> + O(f) <= O(%x. c * f x)" +by (rule bigo_elt_subset, rule bigo_const_mult3, assumption) + +lemma bigo_const_mult [simp]: "(c::'a::ordered_field) ~= 0 ==> + O(%x. c * f x) = O(f)" +by (rule equalityI, rule bigo_const_mult2, erule bigo_const_mult4) + +lemma bigo_const_mult5 [simp]: "(c::'a::ordered_field) ~= 0 ==> + (%x. c) *o O(f) = O(f)" + apply (auto del: subsetI) + apply (rule order_trans) + apply (rule bigo_mult2) + apply (simp add: func_times) + apply (auto intro!: subsetI simp add: bigo_def elt_set_times_def func_times) + apply (rule_tac x = "%y. inverse c * x y" in exI) + apply (simp add: mult_assoc [symmetric] abs_mult) + apply (rule_tac x = "abs (inverse c) * ca" in exI) + apply (rule allI) + apply (subst mult_assoc) + apply (rule mult_left_mono) + apply (erule spec) + apply force +done + +lemma bigo_const_mult6 [intro]: "(%x. c) *o O(f) <= O(f)" + apply (auto intro!: subsetI + simp add: bigo_def elt_set_times_def func_times) + apply (rule_tac x = "ca * (abs c)" in exI) + apply (rule allI) + apply (subgoal_tac "ca * abs(c) * abs(f x) = abs(c) * (ca * abs(f x))") + apply (erule ssubst) + apply (subst abs_mult) + apply (rule mult_left_mono) + apply (erule spec) + apply simp + apply(simp add: mult_ac) +done + +lemma bigo_const_mult7 [intro]: "f =o O(g) ==> (%x. c * f x) =o O(g)" +proof - + assume "f =o O(g)" + then have "(%x. c) * f =o (%x. c) *o O(g)" + by auto + also have "(%x. c) * f = (%x. c * f x)" + by (simp add: func_times) + also have "(%x. c) *o O(g) <= O(g)" + by (auto del: subsetI) + finally show ?thesis . +qed + +lemma bigo_compose1: "f =o O(g) ==> (%x. f(k x)) =o O(%x. g(k x))" +by (unfold bigo_def, auto) + +lemma bigo_compose2: "f =o g +o O(h) ==> (%x. f(k x)) =o (%x. g(k x)) +o + O(%x. h(k x))" + apply (simp only: set_minus_plus [symmetric] diff_minus func_minus + func_plus) + apply (erule bigo_compose1) +done + +subsection {* Setsum *} + +lemma bigo_setsum_main: "ALL x. ALL y : A x. 0 <= h x y ==> + EX c. ALL x. ALL y : A x. abs(f x y) <= c * (h x y) ==> + (%x. SUM y : A x. f x y) =o O(%x. SUM y : A x. h x y)" + apply (auto simp add: bigo_def) + apply (rule_tac x = "abs c" in exI) + apply (subst abs_of_nonneg);back;back + apply (rule setsum_nonneg) + apply force + apply (subst setsum_mult) + apply (rule allI) + apply (rule order_trans) + apply (rule setsum_abs) + apply (rule setsum_mono) + apply (rule order_trans) + apply (drule spec)+ + apply (drule bspec)+ + apply assumption+ + apply (drule bspec) + apply assumption+ + apply (rule mult_right_mono) + apply (rule abs_ge_self) + apply force +done + +lemma bigo_setsum1: "ALL x y. 0 <= h x y ==> + EX c. ALL x y. abs(f x y) <= c * (h x y) ==> + (%x. SUM y : A x. f x y) =o O(%x. SUM y : A x. h x y)" + apply (rule bigo_setsum_main) + apply force + apply clarsimp + apply (rule_tac x = c in exI) + apply force +done + +lemma bigo_setsum2: "ALL y. 0 <= h y ==> + EX c. ALL y. abs(f y) <= c * (h y) ==> + (%x. SUM y : A x. f y) =o O(%x. SUM y : A x. h y)" +by (rule bigo_setsum1, auto) + +lemma bigo_setsum3: "f =o O(h) ==> + (%x. SUM y : A x. (l x y) * f(k x y)) =o + O(%x. SUM y : A x. abs(l x y * h(k x y)))" + apply (rule bigo_setsum1) + apply (rule allI)+ + apply (rule abs_ge_zero) + apply (unfold bigo_def) + apply auto + apply (rule_tac x = c in exI) + apply (rule allI)+ + apply (subst abs_mult)+ + apply (subst mult_left_commute) + apply (rule mult_left_mono) + apply (erule spec) + apply (rule abs_ge_zero) +done + +lemma bigo_setsum4: "f =o g +o O(h) ==> + (%x. SUM y : A x. l x y * f(k x y)) =o + (%x. SUM y : A x. l x y * g(k x y)) +o + O(%x. SUM y : A x. abs(l x y * h(k x y)))" + apply (rule set_minus_imp_plus) + apply (subst func_diff) + apply (subst setsum_subtractf [symmetric]) + apply (subst right_diff_distrib [symmetric]) + apply (rule bigo_setsum3) + apply (subst func_diff [symmetric]) + apply (erule set_plus_imp_minus) +done + +lemma bigo_setsum5: "f =o O(h) ==> ALL x y. 0 <= l x y ==> + ALL x. 0 <= h x ==> + (%x. SUM y : A x. (l x y) * f(k x y)) =o + O(%x. SUM y : A x. (l x y) * h(k x y))" + apply (subgoal_tac "(%x. SUM y : A x. (l x y) * h(k x y)) = + (%x. SUM y : A x. abs((l x y) * h(k x y)))") + apply (erule ssubst) + apply (erule bigo_setsum3) + apply (rule ext) + apply (rule setsum_cong2) + apply (subst abs_of_nonneg) + apply (rule mult_nonneg_nonneg) + apply auto +done + +lemma bigo_setsum6: "f =o g +o O(h) ==> ALL x y. 0 <= l x y ==> + ALL x. 0 <= h x ==> + (%x. SUM y : A x. (l x y) * f(k x y)) =o + (%x. SUM y : A x. (l x y) * g(k x y)) +o + O(%x. SUM y : A x. (l x y) * h(k x y))" + apply (rule set_minus_imp_plus) + apply (subst func_diff) + apply (subst setsum_subtractf [symmetric]) + apply (subst right_diff_distrib [symmetric]) + apply (rule bigo_setsum5) + apply (subst func_diff [symmetric]) + apply (drule set_plus_imp_minus) + apply auto +done + +subsection {* Misc useful stuff *} + +lemma bigo_useful_intro: "A <= O(f) ==> B <= O(f) ==> + A + B <= O(f)" + apply (subst bigo_plus_idemp [symmetric]) + apply (rule set_plus_mono2) + apply assumption+ +done + +lemma bigo_useful_add: "f =o O(h) ==> g =o O(h) ==> f + g =o O(h)" + apply (subst bigo_plus_idemp [symmetric]) + apply (rule set_plus_intro) + apply assumption+ +done + +lemma bigo_useful_const_mult: "(c::'a::ordered_field) ~= 0 ==> + (%x. c) * f =o O(h) ==> f =o O(h)" + apply (rule subsetD) + apply (subgoal_tac "(%x. 1 / c) *o O(h) <= O(h)") + apply assumption + apply (rule bigo_const_mult6) + apply (subgoal_tac "f = (%x. 1 / c) * ((%x. c) * f)") + apply (erule ssubst) + apply (erule set_times_intro2) + apply (simp add: func_times) + apply (rule ext) + apply (subst times_divide_eq_left [symmetric]) + apply (subst divide_self) + apply (assumption, simp) +done + +lemma bigo_fix: "(%x. f ((x::nat) + 1)) =o O(%x. h(x + 1)) ==> f 0 = 0 ==> + f =o O(h)" + apply (simp add: bigo_alt_def) + apply auto + apply (rule_tac x = c in exI) + apply auto + apply (case_tac "x = 0") + apply simp + apply (rule mult_nonneg_nonneg) + apply force + apply force + apply (subgoal_tac "x = Suc (x - 1)") + apply (erule ssubst)back + apply (erule spec) + apply simp +done + +lemma bigo_fix2: + "(%x. f ((x::nat) + 1)) =o (%x. g(x + 1)) +o O(%x. h(x + 1)) ==> + f 0 = g 0 ==> f =o g +o O(h)" + apply (rule set_minus_imp_plus) + apply (rule bigo_fix) + apply (subst func_diff) + apply (subst func_diff [symmetric]) + apply (rule set_plus_imp_minus) + apply simp + apply (simp add: func_diff) +done + +subsection {* Less than or equal to *} + +constdefs + lesso :: "('a => 'b::ordered_idom) => ('a => 'b) => ('a => 'b)" + (infixl " ALL x. abs (g x) <= abs (f x) ==> + g =o O(h)" + apply (unfold bigo_def) + apply clarsimp + apply (rule_tac x = c in exI) + apply (rule allI) + apply (rule order_trans) + apply (erule spec)+ +done + +lemma bigo_lesseq2: "f =o O(h) ==> ALL x. abs (g x) <= f x ==> + g =o O(h)" + apply (erule bigo_lesseq1) + apply (rule allI) + apply (drule_tac x = x in spec) + apply (rule order_trans) + apply assumption + apply (rule abs_ge_self) +done + +lemma bigo_lesseq3: "f =o O(h) ==> ALL x. 0 <= g x ==> ALL x. g x <= f x ==> + g =o O(h)" + apply (erule bigo_lesseq2) + apply (rule allI) + apply (subst abs_of_nonneg) + apply (erule spec)+ +done + +lemma bigo_lesseq4: "f =o O(h) ==> + ALL x. 0 <= g x ==> ALL x. g x <= abs (f x) ==> + g =o O(h)" + apply (erule bigo_lesseq1) + apply (rule allI) + apply (subst abs_of_nonneg) + apply (erule spec)+ +done + +lemma bigo_lesso1: "ALL x. f x <= g x ==> f + ALL x. 0 <= k x ==> ALL x. k x <= f x ==> + k + ALL x. 0 <= k x ==> ALL x. g x <= k x ==> + f 'b::ordered_field) ==> + g =o h +o O(k) ==> f + EX C. ALL x. f x <= g x + C * abs(h x)" + apply (simp only: lesso_def bigo_alt_def) + apply clarsimp + apply (rule_tac x = c in exI) + apply (rule allI) + apply (drule_tac x = x in spec) + apply (subgoal_tac "abs(max (f x - g x) 0) = max (f x - g x) 0") + apply (clarsimp simp add: compare_rls add_ac) + apply (rule abs_of_nonneg) + apply (rule le_maxI2) +done + +lemma lesso_add: "f + k (f + k) g ----> 0 ==> f ----> 0" + apply (simp add: LIMSEQ_def bigo_alt_def) + apply clarify + apply (drule_tac x = "r / c" in spec) + apply (drule mp) + apply (erule divide_pos_pos) + apply assumption + apply clarify + apply (rule_tac x = no in exI) + apply (rule allI) + apply (drule_tac x = n in spec)+ + apply (rule impI) + apply (drule mp) + apply assumption + apply (rule order_le_less_trans) + apply assumption + apply (rule order_less_le_trans) + apply (subgoal_tac "c * abs(g n) < c * (r / c)") + apply assumption + apply (erule mult_strict_left_mono) + apply assumption + apply simp +done + +lemma bigo_LIMSEQ2: "f =o g +o O(h) ==> h ----> 0 ==> f ----> a + ==> g ----> a" + apply (drule set_plus_imp_minus) + apply (drule bigo_LIMSEQ1) + apply assumption + apply (simp only: func_diff) + apply (erule LIMSEQ_diff_approach_zero2) + apply assumption +done + +*) + +end diff -r 2187e3f94761 -r d374530bfaaa src/HOL/Library/Library.thy --- a/src/HOL/Library/Library.thy Mon Jul 25 15:51:30 2005 +0200 +++ b/src/HOL/Library/Library.thy Mon Jul 25 18:54:49 2005 +0200 @@ -2,6 +2,7 @@ theory Library imports Accessible_Part + BigO Continuity EfficientNat FuncSet diff -r 2187e3f94761 -r d374530bfaaa src/HOL/Library/SetsAndFunctions.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Library/SetsAndFunctions.thy Mon Jul 25 18:54:49 2005 +0200 @@ -0,0 +1,376 @@ +(* Title: SetsAndFunctions.thy + Author: Jeremy Avigad and Kevin Donnelly +*) + +header {* Operations on sets and functions *} + +theory SetsAndFunctions +imports Main +begin + +text {* +This library lifts operations like addition and muliplication to sets and +functions of appropriate types. It was designed to support asymptotic +calculations. See the comments at the top of BigO.thy +*} + +subsection {* Basic definitions *} + +instance set :: (plus)plus +by intro_classes + +instance fun :: (type,plus)plus +by intro_classes + +defs (overloaded) + func_plus: "f + g == (%x. f x + g x)" + set_plus: "A + B == {c. EX a:A. EX b:B. c = a + b}" + +instance set :: (times)times +by intro_classes + +instance fun :: (type,times)times +by intro_classes + +defs (overloaded) + func_times: "f * g == (%x. f x * g x)" + set_times:"A * B == {c. EX a:A. EX b:B. c = a * b}" + +instance fun :: (type,minus)minus +by intro_classes + +defs (overloaded) + func_minus: "- f == (%x. - f x)" + func_diff: "f - g == %x. f x - g x" + +instance fun :: (type,zero)zero +by intro_classes + +instance set :: (zero)zero +by(intro_classes) + +defs (overloaded) + func_zero: "0::(('a::type) => ('b::zero)) == %x. 0" + set_zero: "0::('a::zero)set == {0}" + +instance fun :: (type,one)one +by intro_classes + +instance set :: (one)one +by intro_classes + +defs (overloaded) + func_one: "1::(('a::type) => ('b::one)) == %x. 1" + set_one: "1::('a::one)set == {1}" + +constdefs + elt_set_plus :: "'a::plus => 'a set => 'a set" (infixl "+o" 70) + "a +o B == {c. EX b:B. c = a + b}" + + elt_set_times :: "'a::times => 'a set => 'a set" (infixl "*o" 80) + "a *o B == {c. EX b:B. c = a * b}" + +syntax + "elt_set_eq" :: "'a => 'a set => bool" (infix "=o" 50) + +translations + "x =o A" => "x : A" + +instance fun :: (type,semigroup_add)semigroup_add + apply intro_classes + apply (auto simp add: func_plus add_assoc) +done + +instance fun :: (type,comm_monoid_add)comm_monoid_add + apply intro_classes + apply (auto simp add: func_zero func_plus add_ac) +done + +instance fun :: (type,ab_group_add)ab_group_add + apply intro_classes + apply (simp add: func_minus func_plus func_zero) + apply (simp add: func_minus func_plus func_diff diff_minus) +done + +instance fun :: (type,semigroup_mult)semigroup_mult + apply intro_classes + apply (auto simp add: func_times mult_assoc) +done + +instance fun :: (type,comm_monoid_mult)comm_monoid_mult + apply intro_classes + apply (auto simp add: func_one func_times mult_ac) +done + +instance fun :: (type,comm_ring_1)comm_ring_1 + apply intro_classes + apply (auto simp add: func_plus func_times func_minus func_diff ext + func_one func_zero ring_eq_simps) + apply (drule fun_cong) + apply simp +done + +instance set :: (semigroup_add)semigroup_add + apply intro_classes + apply (unfold set_plus) + apply (force simp add: add_assoc) +done + +instance set :: (semigroup_mult)semigroup_mult + apply intro_classes + apply (unfold set_times) + apply (force simp add: mult_assoc) +done + +instance set :: (comm_monoid_add)comm_monoid_add + apply intro_classes + apply (unfold set_plus) + apply (force simp add: add_ac) + apply (unfold set_zero) + apply force +done + +instance set :: (comm_monoid_mult)comm_monoid_mult + apply intro_classes + apply (unfold set_times) + apply (force simp add: mult_ac) + apply (unfold set_one) + apply force +done + +subsection {* Basic properties *} + +lemma set_plus_intro [intro]: "a : C ==> b : D ==> a + b : C + D" +by (auto simp add: set_plus) + +lemma set_plus_intro2 [intro]: "b : C ==> a + b : a +o C" +by (auto simp add: elt_set_plus_def) + +lemma set_plus_rearrange: "((a::'a::comm_monoid_add) +o C) + + (b +o D) = (a + b) +o (C + D)" + apply (auto simp add: elt_set_plus_def set_plus add_ac) + apply (rule_tac x = "ba + bb" in exI) + apply (auto simp add: add_ac) + apply (rule_tac x = "aa + a" in exI) + apply (auto simp add: add_ac) +done + +lemma set_plus_rearrange2: "(a::'a::semigroup_add) +o (b +o C) = + (a + b) +o C" +by (auto simp add: elt_set_plus_def add_assoc) + +lemma set_plus_rearrange3: "((a::'a::semigroup_add) +o B) + C = + a +o (B + C)" + apply (auto simp add: elt_set_plus_def set_plus) + apply (blast intro: add_ac) + apply (rule_tac x = "a + aa" in exI) + apply (rule conjI) + apply (rule_tac x = "aa" in bexI) + apply auto + apply (rule_tac x = "ba" in bexI) + apply (auto simp add: add_ac) +done + +theorem set_plus_rearrange4: "C + ((a::'a::comm_monoid_add) +o D) = + a +o (C + D)" + apply (auto intro!: subsetI simp add: elt_set_plus_def set_plus add_ac) + apply (rule_tac x = "aa + ba" in exI) + apply (auto simp add: add_ac) +done + +theorems set_plus_rearranges = set_plus_rearrange set_plus_rearrange2 + set_plus_rearrange3 set_plus_rearrange4 + +lemma set_plus_mono [intro!]: "C <= D ==> a +o C <= a +o D" +by (auto simp add: elt_set_plus_def) + +lemma set_plus_mono2 [intro]: "(C::('a::plus) set) <= D ==> E <= F ==> + C + E <= D + F" +by (auto simp add: set_plus) + +lemma set_plus_mono3 [intro]: "a : C ==> a +o D <= C + D" +by (auto simp add: elt_set_plus_def set_plus) + +lemma set_plus_mono4 [intro]: "(a::'a::comm_monoid_add) : C ==> + a +o D <= D + C" +by (auto simp add: elt_set_plus_def set_plus add_ac) + +lemma set_plus_mono5: "a:C ==> B <= D ==> a +o B <= C + D" + apply (subgoal_tac "a +o B <= a +o D") + apply (erule order_trans) + apply (erule set_plus_mono3) + apply (erule set_plus_mono) +done + +lemma set_plus_mono_b: "C <= D ==> x : a +o C + ==> x : a +o D" + apply (frule set_plus_mono) + apply auto +done + +lemma set_plus_mono2_b: "C <= D ==> E <= F ==> x : C + E ==> + x : D + F" + apply (frule set_plus_mono2) + prefer 2 + apply force + apply assumption +done + +lemma set_plus_mono3_b: "a : C ==> x : a +o D ==> x : C + D" + apply (frule set_plus_mono3) + apply auto +done + +lemma set_plus_mono4_b: "(a::'a::comm_monoid_add) : C ==> + x : a +o D ==> x : D + C" + apply (frule set_plus_mono4) + apply auto +done + +lemma set_zero_plus [simp]: "(0::'a::comm_monoid_add) +o C = C" +by (auto simp add: elt_set_plus_def) + +lemma set_zero_plus2: "(0::'a::comm_monoid_add) : A ==> B <= A + B" + apply (auto intro!: subsetI simp add: set_plus) + apply (rule_tac x = 0 in bexI) + apply (rule_tac x = x in bexI) + apply (auto simp add: add_ac) +done + +lemma set_plus_imp_minus: "(a::'a::ab_group_add) : b +o C ==> (a - b) : C" +by (auto simp add: elt_set_plus_def add_ac diff_minus) + +lemma set_minus_imp_plus: "(a::'a::ab_group_add) - b : C ==> a : b +o C" + apply (auto simp add: elt_set_plus_def add_ac diff_minus) + apply (subgoal_tac "a = (a + - b) + b") + apply (rule bexI, assumption, assumption) + apply (auto simp add: add_ac) +done + +lemma set_minus_plus: "((a::'a::ab_group_add) - b : C) = (a : b +o C)" +by (rule iffI, rule set_minus_imp_plus, assumption, rule set_plus_imp_minus, + assumption) + +lemma set_times_intro [intro]: "a : C ==> b : D ==> a * b : C * D" +by (auto simp add: set_times) + +lemma set_times_intro2 [intro!]: "b : C ==> a * b : a *o C" +by (auto simp add: elt_set_times_def) + +lemma set_times_rearrange: "((a::'a::comm_monoid_mult) *o C) * + (b *o D) = (a * b) *o (C * D)" + apply (auto simp add: elt_set_times_def set_times) + apply (rule_tac x = "ba * bb" in exI) + apply (auto simp add: mult_ac) + apply (rule_tac x = "aa * a" in exI) + apply (auto simp add: mult_ac) +done + +lemma set_times_rearrange2: "(a::'a::semigroup_mult) *o (b *o C) = + (a * b) *o C" +by (auto simp add: elt_set_times_def mult_assoc) + +lemma set_times_rearrange3: "((a::'a::semigroup_mult) *o B) * C = + a *o (B * C)" + apply (auto simp add: elt_set_times_def set_times) + apply (blast intro: mult_ac) + apply (rule_tac x = "a * aa" in exI) + apply (rule conjI) + apply (rule_tac x = "aa" in bexI) + apply auto + apply (rule_tac x = "ba" in bexI) + apply (auto simp add: mult_ac) +done + +theorem set_times_rearrange4: "C * ((a::'a::comm_monoid_mult) *o D) = + a *o (C * D)" + apply (auto intro!: subsetI simp add: elt_set_times_def set_times + mult_ac) + apply (rule_tac x = "aa * ba" in exI) + apply (auto simp add: mult_ac) +done + +theorems set_times_rearranges = set_times_rearrange set_times_rearrange2 + set_times_rearrange3 set_times_rearrange4 + +lemma set_times_mono [intro]: "C <= D ==> a *o C <= a *o D" +by (auto simp add: elt_set_times_def) + +lemma set_times_mono2 [intro]: "(C::('a::times) set) <= D ==> E <= F ==> + C * E <= D * F" +by (auto simp add: set_times) + +lemma set_times_mono3 [intro]: "a : C ==> a *o D <= C * D" +by (auto simp add: elt_set_times_def set_times) + +lemma set_times_mono4 [intro]: "(a::'a::comm_monoid_mult) : C ==> + a *o D <= D * C" +by (auto simp add: elt_set_times_def set_times mult_ac) + +lemma set_times_mono5: "a:C ==> B <= D ==> a *o B <= C * D" + apply (subgoal_tac "a *o B <= a *o D") + apply (erule order_trans) + apply (erule set_times_mono3) + apply (erule set_times_mono) +done + +lemma set_times_mono_b: "C <= D ==> x : a *o C + ==> x : a *o D" + apply (frule set_times_mono) + apply auto +done + +lemma set_times_mono2_b: "C <= D ==> E <= F ==> x : C * E ==> + x : D * F" + apply (frule set_times_mono2) + prefer 2 + apply force + apply assumption +done + +lemma set_times_mono3_b: "a : C ==> x : a *o D ==> x : C * D" + apply (frule set_times_mono3) + apply auto +done + +lemma set_times_mono4_b: "(a::'a::comm_monoid_mult) : C ==> + x : a *o D ==> x : D * C" + apply (frule set_times_mono4) + apply auto +done + +lemma set_one_times [simp]: "(1::'a::comm_monoid_mult) *o C = C" +by (auto simp add: elt_set_times_def) + +lemma set_times_plus_distrib: "(a::'a::semiring) *o (b +o C)= + (a * b) +o (a *o C)" +by (auto simp add: elt_set_plus_def elt_set_times_def ring_distrib) + +lemma set_times_plus_distrib2: "(a::'a::semiring) *o (B + C) = + (a *o B) + (a *o C)" + apply (auto simp add: set_plus elt_set_times_def ring_distrib) + apply blast + apply (rule_tac x = "b + bb" in exI) + apply (auto simp add: ring_distrib) +done + +lemma set_times_plus_distrib3: "((a::'a::semiring) +o C) * D <= + a *o D + C * D" + apply (auto intro!: subsetI simp add: + elt_set_plus_def elt_set_times_def set_times + set_plus ring_distrib) + apply auto +done + +theorems set_times_plus_distribs = set_times_plus_distrib + set_times_plus_distrib2 + +lemma set_neg_intro: "(a::'a::ring_1) : (- 1) *o C ==> + - a : C" +by (auto simp add: elt_set_times_def) + +lemma set_neg_intro2: "(a::'a::ring_1) : C ==> + - a : (- 1) *o C" +by (auto simp add: elt_set_times_def) + +end