paulson@10751: (* Title : HyperPow.thy paulson@10751: Author : Jacques D. Fleuriot paulson@10751: Copyright : 1998 University of Cambridge paulson@14387: Conversion to Isar and new proofs by Lawrence C Paulson, 2003/4 paulson@10751: *) paulson@10751: paulson@14348: header{*Exponentials on the Hyperreals*} paulson@14348: nipkow@15131: theory HyperPow nipkow@15131: import HyperArith HyperNat "../Real/RealPow" nipkow@15131: begin paulson@10778: paulson@14348: instance hypreal :: power .. paulson@10751: paulson@10751: consts hpowr :: "[hypreal,nat] => hypreal" paulson@10751: primrec paulson@14348: hpowr_0: "r ^ 0 = (1::hypreal)" paulson@14348: hpowr_Suc: "r ^ (Suc n) = (r::hypreal) * (r ^ n)" paulson@14348: paulson@14348: paulson@15003: instance hypreal :: recpower paulson@14348: proof paulson@14348: fix z :: hypreal paulson@14348: fix n :: nat paulson@14348: show "z^0 = 1" by simp paulson@14348: show "z^(Suc n) = z * (z^n)" by simp paulson@14348: qed paulson@14348: paulson@10751: paulson@10751: consts paulson@14348: "pow" :: "[hypreal,hypnat] => hypreal" (infixr 80) paulson@10751: paulson@10751: defs paulson@10751: paulson@10751: (* hypernatural powers of hyperreals *) paulson@14348: hyperpow_def: paulson@14348: "(R::hypreal) pow (N::hypnat) == paulson@14348: Abs_hypreal(\X \ Rep_hypreal(R). \Y \ Rep_hypnat(N). paulson@14348: hyprel``{%n::nat. (X n) ^ (Y n)})" paulson@14348: paulson@14348: lemma hrealpow_two: "(r::hypreal) ^ Suc (Suc 0) = r * r" paulson@14443: by simp paulson@14348: paulson@15003: lemma hrealpow_two_le [simp]: "(0::hypreal) \ r ^ Suc (Suc 0)" paulson@14371: by (auto simp add: zero_le_mult_iff) paulson@14348: paulson@15003: lemma hrealpow_two_le_add_order [simp]: paulson@14348: "(0::hypreal) \ u ^ Suc (Suc 0) + v ^ Suc (Suc 0)" paulson@14443: by (simp only: hrealpow_two_le hypreal_le_add_order) paulson@14348: paulson@15003: lemma hrealpow_two_le_add_order2 [simp]: paulson@14348: "(0::hypreal) \ u ^ Suc (Suc 0) + v ^ Suc (Suc 0) + w ^ Suc (Suc 0)" paulson@15003: by (simp only: hrealpow_two_le hypreal_le_add_order) paulson@14348: paulson@14348: lemma hypreal_add_nonneg_eq_0_iff: paulson@14348: "[| 0 \ x; 0 \ y |] ==> (x+y = 0) = (x = 0 & y = (0::hypreal))" paulson@15003: by arith paulson@15003: paulson@14348: paulson@14348: text{*FIXME: DELETE THESE*} paulson@14348: lemma hypreal_three_squares_add_zero_iff: paulson@14348: "(x*x + y*y + z*z = 0) = (x = 0 & y = 0 & z = (0::hypreal))" paulson@14371: apply (simp only: zero_le_square hypreal_le_add_order hypreal_add_nonneg_eq_0_iff, auto) paulson@14348: done paulson@14348: paulson@14348: lemma hrealpow_three_squares_add_zero_iff [simp]: paulson@14348: "(x ^ Suc (Suc 0) + y ^ Suc (Suc 0) + z ^ Suc (Suc 0) = (0::hypreal)) = paulson@14348: (x = 0 & y = 0 & z = 0)" paulson@14348: by (simp only: hypreal_three_squares_add_zero_iff hrealpow_two) paulson@14348: paulson@14348: paulson@14348: lemma hrabs_hrealpow_two [simp]: paulson@14348: "abs(x ^ Suc (Suc 0)) = (x::hypreal) ^ Suc (Suc 0)" paulson@14348: by (simp add: abs_mult) paulson@14348: paulson@14348: lemma two_hrealpow_ge_one [simp]: "(1::hypreal) \ 2 ^ n" paulson@14348: by (insert power_increasing [of 0 n "2::hypreal"], simp) paulson@14348: paulson@15003: lemma two_hrealpow_gt [simp]: "hypreal_of_nat n < 2 ^ n" paulson@14348: apply (induct_tac "n") paulson@14348: apply (auto simp add: hypreal_of_nat_Suc left_distrib) paulson@14371: apply (cut_tac n = n in two_hrealpow_ge_one, arith) paulson@14348: done paulson@14348: paulson@14348: lemma hrealpow: paulson@14348: "Abs_hypreal(hyprel``{%n. X n}) ^ m = Abs_hypreal(hyprel``{%n. (X n) ^ m})" paulson@14348: apply (induct_tac "m") paulson@14348: apply (auto simp add: hypreal_one_def hypreal_mult) paulson@14348: done paulson@14348: paulson@14348: lemma hrealpow_sum_square_expand: paulson@14348: "(x + (y::hypreal)) ^ Suc (Suc 0) = paulson@14348: x ^ Suc (Suc 0) + y ^ Suc (Suc 0) + (hypreal_of_nat (Suc (Suc 0)))*x*y" paulson@14348: by (simp add: right_distrib left_distrib hypreal_of_nat_Suc) paulson@14348: paulson@14348: paulson@14348: subsection{*Literal Arithmetic Involving Powers and Type @{typ hypreal}*} paulson@14348: paulson@15003: lemma hypreal_of_real_power [simp]: paulson@15003: "hypreal_of_real (x ^ n) = hypreal_of_real x ^ n" paulson@15003: by (induct_tac "n", simp_all add: nat_mult_distrib) paulson@14348: paulson@14348: lemma power_hypreal_of_real_number_of: paulson@14348: "(number_of v :: hypreal) ^ n = hypreal_of_real ((number_of v) ^ n)" paulson@14387: by (simp only: hypreal_number_of [symmetric] hypreal_of_real_power) paulson@14348: paulson@14348: declare power_hypreal_of_real_number_of [of _ "number_of w", standard, simp] paulson@14348: paulson@14348: lemma hrealpow_HFinite: "x \ HFinite ==> x ^ n \ HFinite" paulson@14348: apply (induct_tac "n") paulson@14348: apply (auto intro: HFinite_mult) paulson@14348: done paulson@14348: paulson@14348: paulson@14348: subsection{*Powers with Hypernatural Exponents*} paulson@14348: paulson@14348: lemma hyperpow_congruent: paulson@14348: "congruent hyprel paulson@14348: (%X Y. hyprel``{%n. ((X::nat=>real) n ^ (Y::nat=>nat) n)})" paulson@14348: apply (unfold congruent_def) paulson@14371: apply (auto intro!: ext, fuf+) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow: paulson@14348: "Abs_hypreal(hyprel``{%n. X n}) pow Abs_hypnat(hypnatrel``{%n. Y n}) = paulson@14348: Abs_hypreal(hyprel``{%n. X n ^ Y n})" paulson@14348: apply (unfold hyperpow_def) paulson@14371: apply (rule_tac f = Abs_hypreal in arg_cong) paulson@14348: apply (auto intro!: lemma_hyprel_refl bexI paulson@14348: simp add: hyprel_in_hypreal [THEN Abs_hypreal_inverse] equiv_hyprel paulson@14371: hyperpow_congruent, fuf) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_zero: "(0::hypreal) pow (n + (1::hypnat)) = 0" paulson@14348: apply (unfold hypnat_one_def) paulson@14348: apply (simp (no_asm) add: hypreal_zero_def) paulson@14371: apply (rule_tac z = n in eq_Abs_hypnat) paulson@14348: apply (auto simp add: hyperpow hypnat_add) paulson@14348: done paulson@14348: declare hyperpow_zero [simp] paulson@14348: paulson@14348: lemma hyperpow_not_zero [rule_format (no_asm)]: paulson@14348: "r \ (0::hypreal) --> r pow n \ 0" paulson@14468: apply (simp (no_asm) add: hypreal_zero_def, cases n, cases r) paulson@14348: apply (auto simp add: hyperpow) paulson@14371: apply (drule FreeUltrafilterNat_Compl_mem, ultra) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_inverse: paulson@14348: "r \ (0::hypreal) --> inverse(r pow n) = (inverse r) pow n" paulson@14468: apply (simp (no_asm) add: hypreal_zero_def, cases n, cases r) paulson@14348: apply (auto dest!: FreeUltrafilterNat_Compl_mem simp add: hypreal_inverse hyperpow) paulson@14348: apply (rule FreeUltrafilterNat_subset) paulson@14348: apply (auto dest: realpow_not_zero intro: power_inverse) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_hrabs: "abs r pow n = abs (r pow n)" paulson@14468: apply (cases n, cases r) paulson@14348: apply (auto simp add: hypreal_hrabs hyperpow power_abs [symmetric]) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_add: "r pow (n + m) = (r pow n) * (r pow m)" paulson@14468: apply (cases n, cases m, cases r) paulson@14348: apply (auto simp add: hyperpow hypnat_add hypreal_mult power_add) paulson@14348: done paulson@14348: paulson@15003: lemma hyperpow_one [simp]: "r pow (1::hypnat) = r" paulson@14468: apply (unfold hypnat_one_def, cases r) paulson@14348: apply (auto simp add: hyperpow) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_two: paulson@14348: "r pow ((1::hypnat) + (1::hypnat)) = r * r" paulson@14468: apply (unfold hypnat_one_def, cases r) paulson@14348: apply (auto simp add: hyperpow hypnat_add hypreal_mult) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_gt_zero: "(0::hypreal) < r ==> 0 < r pow n" paulson@14468: apply (simp add: hypreal_zero_def, cases n, cases r) paulson@14348: apply (auto elim!: FreeUltrafilterNat_subset zero_less_power paulson@14348: simp add: hyperpow hypreal_less hypreal_le) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_ge_zero: "(0::hypreal) \ r ==> 0 \ r pow n" paulson@14468: apply (simp add: hypreal_zero_def, cases n, cases r) paulson@14348: apply (auto elim!: FreeUltrafilterNat_subset zero_le_power paulson@14348: simp add: hyperpow hypreal_le) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_le: "[|(0::hypreal) < x; x \ y|] ==> x pow n \ y pow n" paulson@14468: apply (simp add: hypreal_zero_def, cases n, cases x, cases y) paulson@14348: apply (auto simp add: hyperpow hypreal_le hypreal_less) paulson@14371: apply (erule FreeUltrafilterNat_Int [THEN FreeUltrafilterNat_subset], assumption) paulson@14348: apply (auto intro: power_mono) paulson@14348: done paulson@14348: paulson@15003: lemma hyperpow_eq_one [simp]: "1 pow n = (1::hypreal)" paulson@14468: apply (cases n) paulson@14348: apply (auto simp add: hypreal_one_def hyperpow) paulson@14348: done paulson@14348: paulson@15003: lemma hrabs_hyperpow_minus_one [simp]: "abs(-1 pow n) = (1::hypreal)" paulson@14348: apply (subgoal_tac "abs ((- (1::hypreal)) pow n) = (1::hypreal) ") paulson@14348: apply simp paulson@14468: apply (cases n) paulson@14348: apply (auto simp add: hypreal_one_def hyperpow hypreal_minus hypreal_hrabs) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_mult: "(r * s) pow n = (r pow n) * (s pow n)" paulson@14468: apply (cases n, cases r, cases s) paulson@14348: apply (auto simp add: hyperpow hypreal_mult power_mult_distrib) paulson@14348: done paulson@14348: paulson@15003: lemma hyperpow_two_le [simp]: "0 \ r pow (1 + 1)" paulson@14371: by (auto simp add: hyperpow_two zero_le_mult_iff) paulson@14348: paulson@14371: lemma hrabs_hyperpow_two [simp]: "abs(x pow (1 + 1)) = x pow (1 + 1)" paulson@15003: by (simp add: abs_if hyperpow_two_le linorder_not_less) paulson@14348: paulson@15003: lemma hyperpow_two_hrabs [simp]: "abs(x) pow (1 + 1) = x pow (1 + 1)" paulson@15003: by (simp add: hyperpow_hrabs) paulson@14348: paulson@15003: lemma hyperpow_two_gt_one: "1 < r ==> 1 < r pow (1 + 1)" paulson@14348: apply (auto simp add: hyperpow_two) paulson@14348: apply (rule_tac y = "1*1" in order_le_less_trans) paulson@14371: apply (rule_tac [2] hypreal_mult_less_mono, auto) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_two_ge_one: paulson@15003: "1 \ r ==> 1 \ r pow (1 + 1)" paulson@15003: by (auto dest!: order_le_imp_less_or_eq intro: hyperpow_two_gt_one order_less_imp_le) paulson@14348: paulson@15003: lemma two_hyperpow_ge_one [simp]: "(1::hypreal) \ 2 pow n" paulson@14348: apply (rule_tac y = "1 pow n" in order_trans) paulson@14371: apply (rule_tac [2] hyperpow_le, auto) paulson@14348: done paulson@14348: paulson@15003: lemma hyperpow_minus_one2 [simp]: paulson@14348: "-1 pow ((1 + 1)*n) = (1::hypreal)" paulson@14348: apply (subgoal_tac " (- ((1::hypreal))) pow ((1 + 1)*n) = (1::hypreal) ") paulson@14348: apply simp paulson@14468: apply (simp only: hypreal_one_def, cases n) paulson@14435: apply (auto simp add: nat_mult_2 [symmetric] hyperpow hypnat_add hypreal_minus paulson@14371: left_distrib) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_less_le: paulson@14348: "[|(0::hypreal) \ r; r \ 1; n < N|] ==> r pow N \ r pow n" paulson@14468: apply (cases n, cases N, cases r) paulson@14348: apply (auto simp add: hyperpow hypreal_le hypreal_less hypnat_less paulson@14348: hypreal_zero_def hypreal_one_def) paulson@14348: apply (erule FreeUltrafilterNat_Int [THEN FreeUltrafilterNat_subset]) paulson@14371: apply (erule FreeUltrafilterNat_Int, assumption) paulson@14348: apply (auto intro: power_decreasing) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_SHNat_le: paulson@14348: "[| 0 \ r; r \ (1::hypreal); N \ HNatInfinite |] paulson@14348: ==> ALL n: Nats. r pow N \ r pow n" paulson@14348: by (auto intro!: hyperpow_less_le simp add: HNatInfinite_iff) paulson@14348: paulson@14348: lemma hyperpow_realpow: paulson@14348: "(hypreal_of_real r) pow (hypnat_of_nat n) = hypreal_of_real (r ^ n)" paulson@15003: by (simp add: hypreal_of_real_def hypnat_of_nat_eq hyperpow) paulson@14348: paulson@15003: lemma hyperpow_SReal [simp]: paulson@15003: "(hypreal_of_real r) pow (hypnat_of_nat n) \ Reals" paulson@15003: by (simp del: hypreal_of_real_power add: hyperpow_realpow SReal_def) paulson@14348: paulson@15003: paulson@15003: lemma hyperpow_zero_HNatInfinite [simp]: paulson@15003: "N \ HNatInfinite ==> (0::hypreal) pow N = 0" paulson@14371: by (drule HNatInfinite_is_Suc, auto) paulson@14348: paulson@14348: lemma hyperpow_le_le: paulson@14348: "[| (0::hypreal) \ r; r \ 1; n \ N |] ==> r pow N \ r pow n" paulson@14371: apply (drule order_le_less [of n, THEN iffD1]) paulson@14348: apply (auto intro: hyperpow_less_le) paulson@14348: done paulson@14348: paulson@14348: lemma hyperpow_Suc_le_self2: paulson@14348: "[| (0::hypreal) \ r; r < 1 |] ==> r pow (n + (1::hypnat)) \ r" paulson@14348: apply (drule_tac n = " (1::hypnat) " in hyperpow_le_le) paulson@14348: apply auto paulson@14348: done paulson@14348: paulson@14348: lemma lemma_Infinitesimal_hyperpow: paulson@14348: "[| x \ Infinitesimal; 0 < N |] ==> abs (x pow N) \ abs x" paulson@14348: apply (unfold Infinitesimal_def) paulson@14348: apply (auto intro!: hyperpow_Suc_le_self2 paulson@14348: simp add: hyperpow_hrabs [symmetric] hypnat_gt_zero_iff2 abs_ge_zero) paulson@14348: done paulson@14348: paulson@14348: lemma Infinitesimal_hyperpow: paulson@14348: "[| x \ Infinitesimal; 0 < N |] ==> x pow N \ Infinitesimal" paulson@14348: apply (rule hrabs_le_Infinitesimal) paulson@14371: apply (rule_tac [2] lemma_Infinitesimal_hyperpow, auto) paulson@14348: done paulson@14348: paulson@14348: lemma hrealpow_hyperpow_Infinitesimal_iff: paulson@14348: "(x ^ n \ Infinitesimal) = (x pow (hypnat_of_nat n) \ Infinitesimal)" paulson@14468: apply (cases x) paulson@14378: apply (simp add: hrealpow hyperpow hypnat_of_nat_eq) paulson@14348: done paulson@14348: paulson@14348: lemma Infinitesimal_hrealpow: paulson@14348: "[| x \ Infinitesimal; 0 < n |] ==> x ^ n \ Infinitesimal" paulson@14348: by (force intro!: Infinitesimal_hyperpow paulson@14348: simp add: hrealpow_hyperpow_Infinitesimal_iff paulson@14371: hypnat_of_nat_less_iff [symmetric] hypnat_of_nat_zero paulson@14371: simp del: hypnat_of_nat_less_iff) paulson@14348: paulson@14348: ML paulson@14348: {* paulson@14348: val hrealpow_two = thm "hrealpow_two"; paulson@14348: val hrealpow_two_le = thm "hrealpow_two_le"; paulson@14348: val hrealpow_two_le_add_order = thm "hrealpow_two_le_add_order"; paulson@14348: val hrealpow_two_le_add_order2 = thm "hrealpow_two_le_add_order2"; paulson@14348: val hypreal_add_nonneg_eq_0_iff = thm "hypreal_add_nonneg_eq_0_iff"; paulson@14348: val hypreal_three_squares_add_zero_iff = thm "hypreal_three_squares_add_zero_iff"; paulson@14348: val hrealpow_three_squares_add_zero_iff = thm "hrealpow_three_squares_add_zero_iff"; paulson@14348: val hrabs_hrealpow_two = thm "hrabs_hrealpow_two"; paulson@14348: val two_hrealpow_ge_one = thm "two_hrealpow_ge_one"; paulson@14348: val two_hrealpow_gt = thm "two_hrealpow_gt"; paulson@14348: val hrealpow = thm "hrealpow"; paulson@14348: val hrealpow_sum_square_expand = thm "hrealpow_sum_square_expand"; paulson@14348: val hypreal_of_real_power = thm "hypreal_of_real_power"; paulson@14348: val power_hypreal_of_real_number_of = thm "power_hypreal_of_real_number_of"; paulson@14348: val hrealpow_HFinite = thm "hrealpow_HFinite"; paulson@14348: val hyperpow_congruent = thm "hyperpow_congruent"; paulson@14348: val hyperpow = thm "hyperpow"; paulson@14348: val hyperpow_zero = thm "hyperpow_zero"; paulson@14348: val hyperpow_not_zero = thm "hyperpow_not_zero"; paulson@14348: val hyperpow_inverse = thm "hyperpow_inverse"; paulson@14348: val hyperpow_hrabs = thm "hyperpow_hrabs"; paulson@14348: val hyperpow_add = thm "hyperpow_add"; paulson@14348: val hyperpow_one = thm "hyperpow_one"; paulson@14348: val hyperpow_two = thm "hyperpow_two"; paulson@14348: val hyperpow_gt_zero = thm "hyperpow_gt_zero"; paulson@14348: val hyperpow_ge_zero = thm "hyperpow_ge_zero"; paulson@14348: val hyperpow_le = thm "hyperpow_le"; paulson@14348: val hyperpow_eq_one = thm "hyperpow_eq_one"; paulson@14348: val hrabs_hyperpow_minus_one = thm "hrabs_hyperpow_minus_one"; paulson@14348: val hyperpow_mult = thm "hyperpow_mult"; paulson@14348: val hyperpow_two_le = thm "hyperpow_two_le"; paulson@14348: val hrabs_hyperpow_two = thm "hrabs_hyperpow_two"; paulson@14348: val hyperpow_two_hrabs = thm "hyperpow_two_hrabs"; paulson@14348: val hyperpow_two_gt_one = thm "hyperpow_two_gt_one"; paulson@14348: val hyperpow_two_ge_one = thm "hyperpow_two_ge_one"; paulson@14348: val two_hyperpow_ge_one = thm "two_hyperpow_ge_one"; paulson@14348: val hyperpow_minus_one2 = thm "hyperpow_minus_one2"; paulson@14348: val hyperpow_less_le = thm "hyperpow_less_le"; paulson@14348: val hyperpow_SHNat_le = thm "hyperpow_SHNat_le"; paulson@14348: val hyperpow_realpow = thm "hyperpow_realpow"; paulson@14348: val hyperpow_SReal = thm "hyperpow_SReal"; paulson@14348: val hyperpow_zero_HNatInfinite = thm "hyperpow_zero_HNatInfinite"; paulson@14348: val hyperpow_le_le = thm "hyperpow_le_le"; paulson@14348: val hyperpow_Suc_le_self2 = thm "hyperpow_Suc_le_self2"; paulson@14348: val lemma_Infinitesimal_hyperpow = thm "lemma_Infinitesimal_hyperpow"; paulson@14348: val Infinitesimal_hyperpow = thm "Infinitesimal_hyperpow"; paulson@14348: val hrealpow_hyperpow_Infinitesimal_iff = thm "hrealpow_hyperpow_Infinitesimal_iff"; paulson@14348: val Infinitesimal_hrealpow = thm "Infinitesimal_hrealpow"; paulson@14348: *} paulson@14348: paulson@10751: end