| author | wenzelm | 
| Fri, 24 Jan 2025 20:05:01 +0100 | |
| changeset 81973 | 82cf33956a17 | 
| parent 81467 | 3fab5b28027d | 
| child 82664 | e9f3b94eb6a0 | 
| permissions | -rw-r--r-- | 
| 59349 | 1 | (* Author: Florian Haftmann, TU Muenchen *) | 
| 51174 | 2 | |
| 60500 | 3 | section \<open>Common discrete functions\<close> | 
| 51174 | 4 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 5 | theory Discrete_Functions | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 6 | imports Complex_Main | 
| 51174 | 7 | begin | 
| 8 | ||
| 60500 | 9 | subsection \<open>Discrete logarithm\<close> | 
| 51174 | 10 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 11 | fun floor_log :: "nat \<Rightarrow> nat" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 12 | where [simp del]: "floor_log n = (if n < 2 then 0 else Suc (floor_log (n div 2)))" | 
| 61115 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
60500diff
changeset | 13 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 14 | lemma floor_log_induct [consumes 1, case_names one double]: | 
| 61831 | 15 | fixes n :: nat | 
| 16 | assumes "n > 0" | |
| 17 | assumes one: "P 1" | |
| 18 | assumes double: "\<And>n. n \<ge> 2 \<Longrightarrow> P (n div 2) \<Longrightarrow> P n" | |
| 19 | shows "P n" | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 20 | using \<open>n > 0\<close> proof (induct n rule: floor_log.induct) | 
| 61831 | 21 | fix n | 
| 22 | assume "\<not> n < 2 \<Longrightarrow> | |
| 23 | 0 < n div 2 \<Longrightarrow> P (n div 2)" | |
| 24 | then have *: "n \<ge> 2 \<Longrightarrow> P (n div 2)" by simp | |
| 25 | assume "n > 0" | |
| 26 | show "P n" | |
| 27 | proof (cases "n = 1") | |
| 63540 | 28 | case True | 
| 29 | with one show ?thesis by simp | |
| 61831 | 30 | next | 
| 63540 | 31 | case False | 
| 32 | with \<open>n > 0\<close> have "n \<ge> 2" by auto | |
| 33 | with * have "P (n div 2)" . | |
| 34 | with \<open>n \<ge> 2\<close> show ?thesis by (rule double) | |
| 61831 | 35 | qed | 
| 36 | qed | |
| 81332 | 37 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 38 | lemma floor_log_zero [simp]: "floor_log 0 = 0" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 39 | by (simp add: floor_log.simps) | 
| 51174 | 40 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 41 | lemma floor_log_one [simp]: "floor_log 1 = 0" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 42 | by (simp add: floor_log.simps) | 
| 51174 | 43 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 44 | lemma floor_log_Suc_zero [simp]: "floor_log (Suc 0) = 0" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 45 | using floor_log_one by simp | 
| 51174 | 46 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 47 | lemma floor_log_rec: "n \<ge> 2 \<Longrightarrow> floor_log n = Suc (floor_log (n div 2))" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 48 | by (simp add: floor_log.simps) | 
| 51174 | 49 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 50 | lemma floor_log_twice [simp]: "n \<noteq> 0 \<Longrightarrow> floor_log (2 * n) = Suc (floor_log n)" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 51 | by (simp add: floor_log_rec) | 
| 51174 | 52 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 53 | lemma floor_log_half [simp]: "floor_log (n div 2) = floor_log n - 1" | 
| 51174 | 54 | proof (cases "n < 2") | 
| 55 | case True | |
| 56 | then have "n = 0 \<or> n = 1" by arith | |
| 57 | then show ?thesis by (auto simp del: One_nat_def) | |
| 58 | next | |
| 59349 | 59 | case False | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 60 | then show ?thesis by (simp add: floor_log_rec) | 
| 51174 | 61 | qed | 
| 62 | ||
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 63 | lemma floor_log_power [simp]: "floor_log (2 ^ n) = n" | 
| 51174 | 64 | by (induct n) simp_all | 
| 65 | ||
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 66 | lemma floor_log_mono: "mono floor_log" | 
| 51174 | 67 | proof | 
| 68 | fix m n :: nat | |
| 69 | assume "m \<le> n" | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 70 | then show "floor_log m \<le> floor_log n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 71 | proof (induct m arbitrary: n rule: floor_log.induct) | 
| 51174 | 72 | case (1 m) | 
| 73 | then have mn2: "m div 2 \<le> n div 2" by arith | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 74 | show "floor_log m \<le> floor_log n" | 
| 61831 | 75 | proof (cases "m \<ge> 2") | 
| 76 | case False | |
| 51174 | 77 | then have "m = 0 \<or> m = 1" by arith | 
| 78 | then show ?thesis by (auto simp del: One_nat_def) | |
| 79 | next | |
| 61831 | 80 | case True then have "\<not> m < 2" by simp | 
| 81 | with mn2 have "n \<ge> 2" by arith | |
| 82 | from True have m2_0: "m div 2 \<noteq> 0" by arith | |
| 51174 | 83 | with mn2 have n2_0: "n div 2 \<noteq> 0" by arith | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 84 | from \<open>\<not> m < 2\<close> "1.hyps" mn2 have "floor_log (m div 2) \<le> floor_log (n div 2)" by blast | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 85 | with m2_0 n2_0 have "floor_log (2 * (m div 2)) \<le> floor_log (2 * (n div 2))" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 86 | with m2_0 n2_0 \<open>m \<ge> 2\<close> \<open>n \<ge> 2\<close> show ?thesis by (simp only: floor_log_rec [of m] floor_log_rec [of n]) simp | 
| 51174 | 87 | qed | 
| 88 | qed | |
| 89 | qed | |
| 90 | ||
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 91 | lemma floor_log_exp2_le: | 
| 61831 | 92 | assumes "n > 0" | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 93 | shows "2 ^ floor_log n \<le> n" | 
| 63516 | 94 | using assms | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 95 | proof (induct n rule: floor_log_induct) | 
| 63516 | 96 | case one | 
| 97 | then show ?case by simp | |
| 61831 | 98 | next | 
| 63516 | 99 | case (double n) | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 100 | with floor_log_mono have "floor_log n \<ge> Suc 0" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 101 | by (simp add: floor_log.simps) | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 102 | assume "2 ^ floor_log (n div 2) \<le> n div 2" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 103 | with \<open>n \<ge> 2\<close> have "2 ^ (floor_log n - Suc 0) \<le> n div 2" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 104 | then have "2 ^ (floor_log n - Suc 0) * 2 ^ 1 \<le> n div 2 * 2" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 105 | with \<open>floor_log n \<ge> Suc 0\<close> have "2 ^ floor_log n \<le> n div 2 * 2" | 
| 61831 | 106 | unfolding power_add [symmetric] by simp | 
| 107 | also have "n div 2 * 2 \<le> n" by (cases "even n") simp_all | |
| 63516 | 108 | finally show ?case . | 
| 61831 | 109 | qed | 
| 110 | ||
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 111 | lemma floor_log_exp2_gt: "2 * 2 ^ floor_log n > n" | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 112 | proof (cases "n > 0") | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 113 | case True | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 114 | thus ?thesis | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 115 | proof (induct n rule: floor_log_induct) | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 116 | case (double n) | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 117 | thus ?case | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 118 | by (cases "even n") (auto elim!: evenE oddE simp: field_simps floor_log.simps) | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 119 | qed simp_all | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 120 | qed simp_all | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 121 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 122 | lemma floor_log_exp2_ge: "2 * 2 ^ floor_log n \<ge> n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 123 | using floor_log_exp2_gt[of n] by simp | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 124 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 125 | lemma floor_log_le_iff: "m \<le> n \<Longrightarrow> floor_log m \<le> floor_log n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 126 | by (rule monoD [OF floor_log_mono]) | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 127 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 128 | lemma floor_log_eqI: | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 129 | assumes "n > 0" "2^k \<le> n" "n < 2 * 2^k" | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 130 | shows "floor_log n = k" | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 131 | proof (rule antisym) | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 132 | from \<open>n > 0\<close> have "2 ^ floor_log n \<le> n" by (rule floor_log_exp2_le) | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 133 | also have "\<dots> < 2 ^ Suc k" using assms by simp | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 134 | finally have "floor_log n < Suc k" by (subst (asm) power_strict_increasing_iff) simp_all | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 135 | thus "floor_log n \<le> k" by simp | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 136 | next | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 137 | have "2^k \<le> n" by fact | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 138 | also have "\<dots> < 2^(Suc (floor_log n))" by (simp add: floor_log_exp2_gt) | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 139 | finally have "k < Suc (floor_log n)" by (subst (asm) power_strict_increasing_iff) simp_all | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 140 | thus "k \<le> floor_log n" by simp | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 141 | qed | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 142 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 143 | lemma floor_log_altdef: "floor_log n = (if n = 0 then 0 else nat \<lfloor>log 2 (real_of_nat n)\<rfloor>)" | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 144 | proof (cases "n = 0") | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 145 | case False | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 146 | have "\<lfloor>log 2 (real_of_nat n)\<rfloor> = int (floor_log n)" | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 147 | proof (rule floor_unique) | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 148 | from False have "2 powr (real (floor_log n)) \<le> real n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 149 | by (simp add: powr_realpow floor_log_exp2_le) | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 150 | hence "log 2 (2 powr (real (floor_log n))) \<le> log 2 (real n)" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 151 | using False by (subst log_le_cancel_iff) simp_all | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 152 | also have "log 2 (2 powr (real (floor_log n))) = real (floor_log n)" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 153 | finally show "real_of_int (int (floor_log n)) \<le> log 2 (real n)" by simp | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 154 | next | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 155 | have "real n < real (2 * 2 ^ floor_log n)" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 156 | by (subst of_nat_less_iff) (rule floor_log_exp2_gt) | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 157 | also have "\<dots> = 2 powr (real (floor_log n) + 1)" | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 158 | by (simp add: powr_add powr_realpow) | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 159 | finally have "log 2 (real n) < log 2 \<dots>" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 160 | using False by (subst log_less_cancel_iff) simp_all | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 161 | also have "\<dots> = real (floor_log n) + 1" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 162 | finally show "log 2 (real n) < real_of_int (int (floor_log n)) + 1" by simp | 
| 64449 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 163 | qed | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 164 | thus ?thesis by simp | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 165 | qed simp_all | 
| 
8c44dfb4ca8a
Merged natlog2 into Discrete.log
 eberlm <eberlm@in.tum.de> parents: 
63766diff
changeset | 166 | |
| 51174 | 167 | |
| 60500 | 168 | subsection \<open>Discrete square root\<close> | 
| 51174 | 169 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 170 | definition floor_sqrt :: "nat \<Rightarrow> nat" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 171 |   where "floor_sqrt n = Max {m. m\<^sup>2 \<le> n}"
 | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 172 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 173 | lemma floor_sqrt_aux: | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 174 | fixes n :: nat | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 175 |   shows "finite {m. m\<^sup>2 \<le> n}" and "{m. m\<^sup>2 \<le> n} \<noteq> {}"
 | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 176 | proof - | 
| 81332 | 177 | have **: "m \<le> n" if "m\<^sup>2 \<le> n" for m | 
| 178 | using that by (cases m) (simp_all add: power2_eq_square) | |
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 179 |   then have "{m. m\<^sup>2 \<le> n} \<subseteq> {m. m \<le> n}" by auto
 | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 180 |   then show "finite {m. m\<^sup>2 \<le> n}" by (rule finite_subset) rule
 | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 181 | have "0\<^sup>2 \<le> n" by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 182 |   then show *: "{m. m\<^sup>2 \<le> n} \<noteq> {}" by blast
 | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 183 | qed | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 184 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 185 | lemma floor_sqrt_unique: | 
| 63766 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 186 | assumes "m^2 \<le> n" "n < (Suc m)^2" | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 187 | shows "floor_sqrt n = m" | 
| 63766 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 188 | proof - | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 189 | have "m' \<le> m" if "m'^2 \<le> n" for m' | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 190 | proof - | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 191 | note that | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 192 | also note assms(2) | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 193 | finally have "m' < Suc m" by (rule power_less_imp_less_base) simp_all | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 194 | thus "m' \<le> m" by simp | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 195 | qed | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 196 | with \<open>m^2 \<le> n\<close> floor_sqrt_aux[of n] show ?thesis unfolding floor_sqrt_def | 
| 63766 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 197 | by (intro antisym Max.boundedI Max.coboundedI) simp_all | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 198 | qed | 
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 199 | |
| 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 200 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 201 | lemma floor_sqrt_code[code]: "floor_sqrt n = Max (Set.filter (\<lambda>m. m\<^sup>2 \<le> n) {0..n})"
 | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 202 | proof - | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 203 |   from power2_nat_le_imp_le [of _ n] have "{m. m \<le> n \<and> m\<^sup>2 \<le> n} = {m. m\<^sup>2 \<le> n}" by auto
 | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 204 | then show ?thesis by (simp add: floor_sqrt_def Set.filter_def) | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 205 | qed | 
| 51174 | 206 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 207 | lemma floor_sqrt_inverse_power2 [simp]: "floor_sqrt (n\<^sup>2) = n" | 
| 51174 | 208 | proof - | 
| 209 |   have "{m. m \<le> n} \<noteq> {}" by auto
 | |
| 210 |   then have "Max {m. m \<le> n} \<le> n" by auto
 | |
| 211 | then show ?thesis | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 212 | by (auto simp add: floor_sqrt_def power2_nat_le_eq_le intro: antisym) | 
| 51174 | 213 | qed | 
| 214 | ||
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 215 | lemma floor_sqrt_zero [simp]: "floor_sqrt 0 = 0" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 216 | using floor_sqrt_inverse_power2 [of 0] by simp | 
| 58787 | 217 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 218 | lemma floor_sqrt_one [simp]: "floor_sqrt 1 = 1" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 219 | using floor_sqrt_inverse_power2 [of 1] by simp | 
| 58787 | 220 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 221 | lemma mono_floor_sqrt: "mono floor_sqrt" | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 222 | proof | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 223 | fix m n :: nat | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 224 | have *: "0 * 0 \<le> m" by simp | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 225 | assume "m \<le> n" | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 226 | then show "floor_sqrt m \<le> floor_sqrt n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 227 | by (auto intro!: Max_mono \<open>0 * 0 \<le> m\<close> finite_less_ub simp add: power2_eq_square floor_sqrt_def) | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 228 | qed | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 229 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 230 | lemma mono_floor_sqrt': "m \<le> n \<Longrightarrow> floor_sqrt m \<le> floor_sqrt n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 231 | using mono_floor_sqrt unfolding mono_def by auto | 
| 63766 
695d60817cb1
Some facts about factorial and binomial coefficients
 Manuel Eberl <eberlm@in.tum.de> parents: 
63540diff
changeset | 232 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 233 | lemma floor_sqrt_greater_zero_iff [simp]: "floor_sqrt n > 0 \<longleftrightarrow> n > 0" | 
| 51174 | 234 | proof - | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 235 |   have *: "0 < Max {m. m\<^sup>2 \<le> n} \<longleftrightarrow> (\<exists>a\<in>{m. m\<^sup>2 \<le> n}. 0 < a)"
 | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 236 | by (rule Max_gr_iff) (fact floor_sqrt_aux)+ | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 237 | show ?thesis | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 238 | proof | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 239 | assume "0 < floor_sqrt n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 240 |     then have "0 < Max {m. m\<^sup>2 \<le> n}" by (simp add: floor_sqrt_def)
 | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 241 | with * show "0 < n" by (auto dest: power2_nat_le_imp_le) | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 242 | next | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 243 | assume "0 < n" | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 244 | then have "1\<^sup>2 \<le> n \<and> 0 < (1::nat)" by simp | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 245 | then have "\<exists>q. q\<^sup>2 \<le> n \<and> 0 < q" .. | 
| 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 246 |     with * have "0 < Max {m. m\<^sup>2 \<le> n}" by blast
 | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 247 | then show "0 < floor_sqrt n" by (simp add: floor_sqrt_def) | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 248 | qed | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 249 | qed | 
| 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 250 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 251 | lemma floor_sqrt_power2_le [simp]: "(floor_sqrt n)\<^sup>2 \<le> n" (* FIXME tune proof *) | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 252 | proof (cases "n > 0") | 
| 58787 | 253 | case False then show ?thesis by simp | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 254 | next | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 255 | case True then have "floor_sqrt n > 0" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 256 |   then have "mono (times (Max {m. m\<^sup>2 \<le> n}))" by (auto intro: mono_times_nat simp add: floor_sqrt_def)
 | 
| 53015 
a1119cf551e8
standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
 wenzelm parents: 
51263diff
changeset | 257 |   then have *: "Max {m. m\<^sup>2 \<le> n} * Max {m. m\<^sup>2 \<le> n} = Max (times (Max {m. m\<^sup>2 \<le> n}) ` {m. m\<^sup>2 \<le> n})"
 | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 258 | using floor_sqrt_aux [of n] by (rule mono_Max_commute) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 259 |   have "\<And>a. a * a \<le> n \<Longrightarrow> Max {m. m * m \<le> n} * a \<le> n"
 | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 260 | proof - | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 261 | fix q | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 262 | assume "q * q \<le> n" | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 263 |     show "Max {m. m * m \<le> n} * q \<le> n"
 | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 264 | proof (cases "q > 0") | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 265 | case False then show ?thesis by simp | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 266 | next | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 267 | case True then have "mono (times q)" by (rule mono_times_nat) | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 268 |       then have "q * Max {m. m * m \<le> n} = Max (times q ` {m. m * m \<le> n})"
 | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 269 | using floor_sqrt_aux [of n] by (auto simp add: power2_eq_square intro: mono_Max_commute) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 270 |       then have "Max {m. m * m \<le> n} * q = Max (times q ` {m. m * m \<le> n})" by (simp add: ac_simps)
 | 
| 69064 
5840724b1d71
Prefix form of infix with * on either side no longer needs special treatment
 nipkow parents: 
67399diff
changeset | 271 |       moreover have "finite ((*) q ` {m. m * m \<le> n})"
 | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 272 | by (metis (mono_tags) finite_imageI finite_less_ub le_square) | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 273 | moreover have "\<exists>x. x * x \<le> n" | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 274 | by (metis \<open>q * q \<le> n\<close>) | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 275 | ultimately show ?thesis | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 276 | by simp (metis \<open>q * q \<le> n\<close> le_cases mult_le_mono1 mult_le_mono2 order_trans) | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 277 | qed | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 278 | qed | 
| 69064 
5840724b1d71
Prefix form of infix with * on either side no longer needs special treatment
 nipkow parents: 
67399diff
changeset | 279 |   then have "Max ((*) (Max {m. m * m \<le> n}) ` {m. m * m \<le> n}) \<le> n"
 | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 280 | apply (subst Max_le_iff) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 281 | apply (metis (mono_tags) finite_imageI finite_less_ub le_square) | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 282 | apply auto | 
| 51263 
31e786e0e6a7
turned example into library for comparing growth of functions
 haftmann parents: 
51174diff
changeset | 283 | apply (metis le0 mult_0_right) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 284 | done | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 285 | with * show ?thesis by (simp add: floor_sqrt_def power2_eq_square) | 
| 51174 | 286 | qed | 
| 287 | ||
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 288 | lemma floor_sqrt_le: "floor_sqrt n \<le> n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 289 | using floor_sqrt_aux [of n] by (auto simp add: floor_sqrt_def intro: power2_nat_le_imp_le) | 
| 51174 | 290 | |
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 291 | text \<open>Additional facts about the discrete square root, thanks to Julian Biendarra, Manuel Eberl\<close> | 
| 81332 | 292 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 293 | lemma Suc_floor_sqrt_power2_gt: "n < (Suc (floor_sqrt n))^2" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 294 | using Max_ge[OF floor_sqrt_aux(1), of "floor_sqrt n + 1" n] | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 295 | by (cases "n < (Suc (floor_sqrt n))^2") (simp_all add: floor_sqrt_def) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 296 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 297 | lemma le_floor_sqrt_iff: "x \<le> floor_sqrt y \<longleftrightarrow> x^2 \<le> y" | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 298 | proof - | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 299 | have "x \<le> floor_sqrt y \<longleftrightarrow> (\<exists>z. z\<^sup>2 \<le> y \<and> x \<le> z)" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 300 | using Max_ge_iff[OF floor_sqrt_aux, of x y] by (simp add: floor_sqrt_def) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 301 | also have "\<dots> \<longleftrightarrow> x^2 \<le> y" | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 302 | proof safe | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 303 | fix z assume "x \<le> z" "z ^ 2 \<le> y" | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 304 | thus "x^2 \<le> y" by (intro le_trans[of "x^2" "z^2" y]) (simp_all add: power2_nat_le_eq_le) | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 305 | qed auto | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 306 | finally show ?thesis . | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 307 | qed | 
| 81332 | 308 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 309 | lemma le_floor_sqrtI: "x^2 \<le> y \<Longrightarrow> x \<le> floor_sqrt y" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 310 | by (simp add: le_floor_sqrt_iff) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 311 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 312 | lemma floor_sqrt_le_iff: "floor_sqrt y \<le> x \<longleftrightarrow> (\<forall>z. z^2 \<le> y \<longrightarrow> z \<le> x)" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 313 | using Max.bounded_iff[OF floor_sqrt_aux] by (simp add: floor_sqrt_def) | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 314 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 315 | lemma floor_sqrt_leI: | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 316 | "(\<And>z. z^2 \<le> y \<Longrightarrow> z \<le> x) \<Longrightarrow> floor_sqrt y \<le> x" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 317 | by (simp add: floor_sqrt_le_iff) | 
| 81332 | 318 | |
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 319 | lemma floor_sqrt_Suc: | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 320 | "floor_sqrt (Suc n) = (if \<exists>m. Suc n = m^2 then Suc (floor_sqrt n) else floor_sqrt n)" | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 321 | proof cases | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 322 | assume "\<exists> m. Suc n = m^2" | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 323 | then obtain m where m_def: "Suc n = m^2" by blast | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 324 | then have lhs: "floor_sqrt (Suc n) = m" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 325 | from m_def floor_sqrt_power2_le[of n] | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 326 | have "(floor_sqrt n)^2 < m^2" by linarith | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 327 | with power2_less_imp_less have lt_m: "floor_sqrt n < m" by blast | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 328 | from m_def Suc_floor_sqrt_power2_gt[of "n"] | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 329 | have "m^2 \<le> (Suc(floor_sqrt n))^2" | 
| 70365 
4df0628e8545
a few new lemmas and a bit of tidying
 paulson <lp15@cam.ac.uk> parents: 
69064diff
changeset | 330 | by linarith | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 331 | with power2_nat_le_eq_le have "m \<le> Suc (floor_sqrt n)" by blast | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 332 | with lt_m have "m = Suc (floor_sqrt n)" by simp | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 333 | with lhs m_def show ?thesis by fastforce | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 334 | next | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 335 | assume asm: "\<not> (\<exists> m. Suc n = m^2)" | 
| 81467 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 336 | hence "Suc n \<noteq> (floor_sqrt (Suc n))^2" by simp | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 337 | with floor_sqrt_power2_le[of "Suc n"] | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 338 | have "floor_sqrt (Suc n) \<le> floor_sqrt n" by (intro le_floor_sqrtI) linarith | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 339 | moreover have "floor_sqrt (Suc n) \<ge> floor_sqrt n" | 
| 
3fab5b28027d
renamed Discrete -> Discrete_Functions to avoid name clashes;
 nipkow parents: 
81332diff
changeset | 340 | by (intro monoD[OF mono_floor_sqrt]) simp_all | 
| 64919 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 341 | ultimately show ?thesis using asm by simp | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 342 | qed | 
| 
7e0c8924dfda
New material from Bertrand's postulate (file Bertrand_Discrete_Sqrt), and tidied an old messy proof
 paulson <lp15@cam.ac.uk> parents: 
64449diff
changeset | 343 | |
| 51174 | 344 | end |