src/HOL/Library/Discrete.thy
changeset 81332 f94b30fa2b6c
parent 80621 6c369fec315a
equal deleted inserted replaced
81331:405f7fd15f4e 81332:f94b30fa2b6c
    35     with \<open>n > 0\<close> have "n \<ge> 2" by auto
    35     with \<open>n > 0\<close> have "n \<ge> 2" by auto
    36     with * have "P (n div 2)" .
    36     with * have "P (n div 2)" .
    37     with \<open>n \<ge> 2\<close> show ?thesis by (rule double)
    37     with \<open>n \<ge> 2\<close> show ?thesis by (rule double)
    38   qed
    38   qed
    39 qed
    39 qed
    40   
    40 
    41 lemma log_zero [simp]: "log 0 = 0"
    41 lemma log_zero [simp]: "log 0 = 0"
    42   by (simp add: log.simps)
    42   by (simp add: log.simps)
    43 
    43 
    44 lemma log_one [simp]: "log 1 = 0"
    44 lemma log_one [simp]: "log 1 = 0"
    45   by (simp add: log.simps)
    45   by (simp add: log.simps)
   175 
   175 
   176 lemma sqrt_aux:
   176 lemma sqrt_aux:
   177   fixes n :: nat
   177   fixes n :: nat
   178   shows "finite {m. m\<^sup>2 \<le> n}" and "{m. m\<^sup>2 \<le> n} \<noteq> {}"
   178   shows "finite {m. m\<^sup>2 \<le> n}" and "{m. m\<^sup>2 \<le> n} \<noteq> {}"
   179 proof -
   179 proof -
   180   { fix m
   180   have **: "m \<le> n" if "m\<^sup>2 \<le> n" for m
   181     assume "m\<^sup>2 \<le> n"
   181     using that by (cases m) (simp_all add: power2_eq_square)
   182     then have "m \<le> n"
       
   183       by (cases m) (simp_all add: power2_eq_square)
       
   184   } note ** = this
       
   185   then have "{m. m\<^sup>2 \<le> n} \<subseteq> {m. m \<le> n}" by auto
   182   then have "{m. m\<^sup>2 \<le> n} \<subseteq> {m. m \<le> n}" by auto
   186   then show "finite {m. m\<^sup>2 \<le> n}" by (rule finite_subset) rule
   183   then show "finite {m. m\<^sup>2 \<le> n}" by (rule finite_subset) rule
   187   have "0\<^sup>2 \<le> n" by simp
   184   have "0\<^sup>2 \<le> n" by simp
   188   then show *: "{m. m\<^sup>2 \<le> n} \<noteq> {}" by blast
   185   then show *: "{m. m\<^sup>2 \<le> n} \<noteq> {}" by blast
   189 qed
   186 qed
   293 
   290 
   294 lemma sqrt_le: "sqrt n \<le> n"
   291 lemma sqrt_le: "sqrt n \<le> n"
   295   using sqrt_aux [of n] by (auto simp add: sqrt_def intro: power2_nat_le_imp_le)
   292   using sqrt_aux [of n] by (auto simp add: sqrt_def intro: power2_nat_le_imp_le)
   296 
   293 
   297 text \<open>Additional facts about the discrete square root, thanks to Julian Biendarra, Manuel Eberl\<close>
   294 text \<open>Additional facts about the discrete square root, thanks to Julian Biendarra, Manuel Eberl\<close>
   298   
   295 
   299 lemma Suc_sqrt_power2_gt: "n < (Suc (Discrete.sqrt n))^2"
   296 lemma Suc_sqrt_power2_gt: "n < (Suc (Discrete.sqrt n))^2"
   300   using Max_ge[OF Discrete.sqrt_aux(1), of "Discrete.sqrt n + 1" n]
   297   using Max_ge[OF Discrete.sqrt_aux(1), of "Discrete.sqrt n + 1" n]
   301   by (cases "n < (Suc (Discrete.sqrt n))^2") (simp_all add: Discrete.sqrt_def)
   298   by (cases "n < (Suc (Discrete.sqrt n))^2") (simp_all add: Discrete.sqrt_def)
   302 
   299 
   303 lemma le_sqrt_iff: "x \<le> Discrete.sqrt y \<longleftrightarrow> x^2 \<le> y"
   300 lemma le_sqrt_iff: "x \<le> Discrete.sqrt y \<longleftrightarrow> x^2 \<le> y"
   304 proof -
   301 proof -
   305   have "x \<le> Discrete.sqrt y \<longleftrightarrow> (\<exists>z. z\<^sup>2 \<le> y \<and> x \<le> z)"    
   302   have "x \<le> Discrete.sqrt y \<longleftrightarrow> (\<exists>z. z\<^sup>2 \<le> y \<and> x \<le> z)"
   306     using Max_ge_iff[OF Discrete.sqrt_aux, of x y] by (simp add: Discrete.sqrt_def)
   303     using Max_ge_iff[OF Discrete.sqrt_aux, of x y] by (simp add: Discrete.sqrt_def)
   307   also have "\<dots> \<longleftrightarrow> x^2 \<le> y"
   304   also have "\<dots> \<longleftrightarrow> x^2 \<le> y"
   308   proof safe
   305   proof safe
   309     fix z assume "x \<le> z" "z ^ 2 \<le> y"
   306     fix z assume "x \<le> z" "z ^ 2 \<le> y"
   310     thus "x^2 \<le> y" by (intro le_trans[of "x^2" "z^2" y]) (simp_all add: power2_nat_le_eq_le)
   307     thus "x^2 \<le> y" by (intro le_trans[of "x^2" "z^2" y]) (simp_all add: power2_nat_le_eq_le)
   311   qed auto
   308   qed auto
   312   finally show ?thesis .
   309   finally show ?thesis .
   313 qed
   310 qed
   314   
   311 
   315 lemma le_sqrtI: "x^2 \<le> y \<Longrightarrow> x \<le> Discrete.sqrt y"
   312 lemma le_sqrtI: "x^2 \<le> y \<Longrightarrow> x \<le> Discrete.sqrt y"
   316   by (simp add: le_sqrt_iff)
   313   by (simp add: le_sqrt_iff)
   317 
   314 
   318 lemma sqrt_le_iff: "Discrete.sqrt y \<le> x \<longleftrightarrow> (\<forall>z. z^2 \<le> y \<longrightarrow> z \<le> x)"
   315 lemma sqrt_le_iff: "Discrete.sqrt y \<le> x \<longleftrightarrow> (\<forall>z. z^2 \<le> y \<longrightarrow> z \<le> x)"
   319   using Max.bounded_iff[OF Discrete.sqrt_aux] by (simp add: Discrete.sqrt_def)
   316   using Max.bounded_iff[OF Discrete.sqrt_aux] by (simp add: Discrete.sqrt_def)
   320 
   317 
   321 lemma sqrt_leI:
   318 lemma sqrt_leI:
   322   "(\<And>z. z^2 \<le> y \<Longrightarrow> z \<le> x) \<Longrightarrow> Discrete.sqrt y \<le> x"
   319   "(\<And>z. z^2 \<le> y \<Longrightarrow> z \<le> x) \<Longrightarrow> Discrete.sqrt y \<le> x"
   323   by (simp add: sqrt_le_iff)
   320   by (simp add: sqrt_le_iff)
   324     
   321 
   325 lemma sqrt_Suc:
   322 lemma sqrt_Suc:
   326   "Discrete.sqrt (Suc n) = (if \<exists>m. Suc n = m^2 then Suc (Discrete.sqrt n) else Discrete.sqrt n)"
   323   "Discrete.sqrt (Suc n) = (if \<exists>m. Suc n = m^2 then Suc (Discrete.sqrt n) else Discrete.sqrt n)"
   327 proof cases
   324 proof cases
   328   assume "\<exists> m. Suc n = m^2"
   325   assume "\<exists> m. Suc n = m^2"
   329   then obtain m where m_def: "Suc n = m^2" by blast
   326   then obtain m where m_def: "Suc n = m^2" by blast
   330   then have lhs: "Discrete.sqrt (Suc n) = m" by simp
   327   then have lhs: "Discrete.sqrt (Suc n) = m" by simp
   331   from m_def sqrt_power2_le[of n] 
   328   from m_def sqrt_power2_le[of n]
   332     have "(Discrete.sqrt n)^2 < m^2" by linarith
   329     have "(Discrete.sqrt n)^2 < m^2" by linarith
   333   with power2_less_imp_less have lt_m: "Discrete.sqrt n < m" by blast
   330   with power2_less_imp_less have lt_m: "Discrete.sqrt n < m" by blast
   334   from m_def Suc_sqrt_power2_gt[of "n"]
   331   from m_def Suc_sqrt_power2_gt[of "n"]
   335     have "m^2 \<le> (Suc(Discrete.sqrt n))^2"
   332     have "m^2 \<le> (Suc(Discrete.sqrt n))^2"
   336       by linarith
   333       by linarith
   338   with lt_m have "m = Suc (Discrete.sqrt n)" by simp
   335   with lt_m have "m = Suc (Discrete.sqrt n)" by simp
   339   with lhs m_def show ?thesis by fastforce
   336   with lhs m_def show ?thesis by fastforce
   340 next
   337 next
   341   assume asm: "\<not> (\<exists> m. Suc n = m^2)"
   338   assume asm: "\<not> (\<exists> m. Suc n = m^2)"
   342   hence "Suc n \<noteq> (Discrete.sqrt (Suc n))^2" by simp
   339   hence "Suc n \<noteq> (Discrete.sqrt (Suc n))^2" by simp
   343   with sqrt_power2_le[of "Suc n"] 
   340   with sqrt_power2_le[of "Suc n"]
   344     have "Discrete.sqrt (Suc n) \<le> Discrete.sqrt n" by (intro le_sqrtI) linarith
   341     have "Discrete.sqrt (Suc n) \<le> Discrete.sqrt n" by (intro le_sqrtI) linarith
   345   moreover have "Discrete.sqrt (Suc n) \<ge> Discrete.sqrt n"
   342   moreover have "Discrete.sqrt (Suc n) \<ge> Discrete.sqrt n"
   346     by (intro monoD[OF mono_sqrt]) simp_all
   343     by (intro monoD[OF mono_sqrt]) simp_all
   347   ultimately show ?thesis using asm by simp
   344   ultimately show ?thesis using asm by simp
   348 qed
   345 qed