src/HOL/ex/ThreeDivides.thy
changeset 19026 87cd1ecae3a4
parent 19022 0e6ec4fd204c
child 19106 6e6b5b1fdc06
equal deleted inserted replaced
19025:596fb1eb7856 19026:87cd1ecae3a4
    13 
    13 
    14 text {*
    14 text {*
    15 The following document presents a proof of the Three Divides N theorem
    15 The following document presents a proof of the Three Divides N theorem
    16 formalised in the Isabelle/Isar theorem proving system.
    16 formalised in the Isabelle/Isar theorem proving system.
    17 
    17 
    18 {\em Theorem}: 3 divides n if and only if 3 divides the sum of all
    18 {\em Theorem}: $3$ divides $n$ if and only if $3$ divides the sum of all
    19 digits in n.
    19 digits in $n$.
    20 
    20 
    21 {\em Informal Proof}:
    21 {\em Informal Proof}:
    22 Take $n = \sum{n_j * 10^j}$ where $n_j$ is the $j$'th least
    22 Take $n = \sum{n_j * 10^j}$ where $n_j$ is the $j$'th least
    23 significant digit of the decimal denotation of the number n and the
    23 significant digit of the decimal denotation of the number n and the
    24 sum ranges over all digits. Then $$ (n - \sum{n_j}) = \sum{n_j * (10^j
    24 sum ranges over all digits. Then $$ (n - \sum{n_j}) = \sum{n_j * (10^j
    59 true for all natural numbers. Note we are using @{term "D i"} to
    59 true for all natural numbers. Note we are using @{term "D i"} to
    60 denote the $i$'th element in a sequence of numbers. *}
    60 denote the $i$'th element in a sequence of numbers. *}
    61 
    61 
    62 lemma digit_diff_split:
    62 lemma digit_diff_split:
    63   fixes n::nat and nd::nat and x::nat
    63   fixes n::nat and nd::nat and x::nat
    64   shows "\<And>n. n = (\<Sum>x\<in>{..<nd}. (D x)*((10::nat)^x)) \<Longrightarrow>
    64   shows "n = (\<Sum>x\<in>{..<nd}. (D x)*((10::nat)^x)) \<Longrightarrow>
    65              (n - (\<Sum>x<nd. (D x))) = (\<Sum>x<nd. (D x)*(10^x - 1))"
    65              (n - (\<Sum>x<nd. (D x))) = (\<Sum>x<nd. (D x)*(10^x - 1))"
    66 by (simp add: sum_diff_distrib diff_mult_distrib2)
    66 by (simp add: sum_diff_distrib diff_mult_distrib2)
    67 
    67 
    68 text {* Now we prove that 3 always divides numbers of the form $10^x - 1$. *}
    68 text {* Now we prove that 3 always divides numbers of the form $10^x - 1$. *}
    69 lemma three_divs_0 [rule_format, simplified]:
    69 lemma three_divs_0:
    70   shows "(3::nat) dvd (10^x - 1)"
    70   shows "(3::nat) dvd (10^x - 1)"
    71 proof (induct x)
    71 proof (induct x)
    72   case 0 show ?case by simp
    72   case 0 show ?case by simp
    73 next
    73 next
    74   case (Suc n)
    74   case (Suc n)
    81   have"?thr dvd ((10^(n+1) - 10) + 9)"
    81   have"?thr dvd ((10^(n+1) - 10) + 9)"
    82     by (simp only: add_ac) (rule dvd_add)
    82     by (simp only: add_ac) (rule dvd_add)
    83   thus ?case by simp
    83   thus ?case by simp
    84 qed
    84 qed
    85 
    85 
    86 text {* Expanding on the previous lemma and lemma @{text "div_sum\<dots>"} *}
    86 text {* Expanding on the previous lemma and lemma @{text "div_sum"}. *}
    87 lemma three_divs_1:
    87 lemma three_divs_1:
    88   fixes D :: "nat \<Rightarrow> nat"
    88   fixes D :: "nat \<Rightarrow> nat"
    89   shows "3 dvd (\<Sum>x<nd. D x * (10^x - 1))"
    89   shows "3 dvd (\<Sum>x<nd. D x * (10^x - 1))"
    90   by (subst nat_mult_commute, rule div_sum) (simp add: three_divs_0)
    90   by (subst nat_mult_commute, rule div_sum) (simp add: three_divs_0 [simplified])
    91 
    91 
    92 text {* Using lemmas @{text "digit_diff_split"} and 
    92 text {* Using lemmas @{text "digit_diff_split"} and 
    93 @{text "three_divs_1"} we now prove the following lemma. 
    93 @{text "three_divs_1"} we now prove the following lemma. 
    94 *}
    94 *}
    95 lemma three_divs_2:
    95 lemma three_divs_2:
    96   fixes nd::nat and D::"nat\<Rightarrow>nat"
    96   fixes nd::nat and D::"nat\<Rightarrow>nat"
    97   shows "3 dvd ((\<Sum>x<nd. (D x)*(10^x)) - (\<Sum>x<nd. (D x)))"
    97   shows "3 dvd ((\<Sum>x<nd. (D x)*(10^x)) - (\<Sum>x<nd. (D x)))"
    98 proof (simp only: digit_diff_split)
    98 proof -
    99   from three_divs_1 show "3 dvd (\<Sum>x<nd. D x * (10 ^ x - 1))" .
    99   from three_divs_1 have "3 dvd (\<Sum>x<nd. D x * (10 ^ x - 1))" .
       
   100   thus ?thesis by (simp only: digit_diff_split)
   100 qed
   101 qed
   101 
   102 
   102 text {* 
   103 text {* 
   103 We now present the final theorem of this section. For any
   104 We now present the final theorem of this section. For any
   104 sequence of numbers (defined by a function @{term "D :: (nat\<Rightarrow>nat)"}),
   105 sequence of numbers (defined by a function @{term "D :: (nat\<Rightarrow>nat)"}),
   109 lemma three_div_general:
   110 lemma three_div_general:
   110   fixes D :: "nat \<Rightarrow> nat"
   111   fixes D :: "nat \<Rightarrow> nat"
   111   shows "(3 dvd (\<Sum>x<nd. D x * 10^x)) = (3 dvd (\<Sum>x<nd. D x))"
   112   shows "(3 dvd (\<Sum>x<nd. D x * 10^x)) = (3 dvd (\<Sum>x<nd. D x))"
   112 proof
   113 proof
   113   have mono: "(\<Sum>x<nd. D x) \<le> (\<Sum>x<nd. D x * 10^x)"
   114   have mono: "(\<Sum>x<nd. D x) \<le> (\<Sum>x<nd. D x * 10^x)"
   114     by (rule setsum_mono, simp)
   115     by (rule setsum_mono) simp
   115   txt {* This lets us form the term
   116   txt {* This lets us form the term
   116          @{term "(\<Sum>x<nd. D x * 10^x) - (\<Sum>x<nd. D x)"} *}
   117          @{term "(\<Sum>x<nd. D x * 10^x) - (\<Sum>x<nd. D x)"} *}
   117 
   118 
   118   {
   119   {
   119     assume "3 dvd (\<Sum>x<nd. D x)"
   120     assume "3 dvd (\<Sum>x<nd. D x)"
   172 text {* The following lemma is the principle lemma required to prove
   173 text {* The following lemma is the principle lemma required to prove
   173 our theorem. It states that an expansion of some natural number $n$
   174 our theorem. It states that an expansion of some natural number $n$
   174 into a sequence of its individual digits is always possible. *}
   175 into a sequence of its individual digits is always possible. *}
   175 
   176 
   176 lemma exp_exists:
   177 lemma exp_exists:
   177   "\<And>m. nd = nlen m \<Longrightarrow> m = (\<Sum>x<nd. (m div (10::nat)^x mod 10) * 10^x)"
   178   "m = (\<Sum>x<nlen m. (m div (10::nat)^x mod 10) * 10^x)"
   178 proof (induct nd)
   179 proof (induct nd \<equiv> "nlen m" fixing: m)
   179   case 0 thus ?case by (simp add: nlen_zero)
   180   case 0 thus ?case by (simp add: nlen_zero)
   180 next
   181 next
   181   case (Suc nd)
   182   case (Suc nd)
   182   hence IH:
   183   hence IH:
   183     "nd = nlen (m div 10) \<Longrightarrow>
   184     "nd = nlen (m div 10) \<Longrightarrow>
   184     m div 10 = (\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^x)"
   185     m div 10 = (\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^x)"
   185     by blast
   186     by blast
   186   have "\<exists>c. m = 10*(m div 10) + c \<and> c < 10" by presburger
   187   have "\<exists>c. m = 10*(m div 10) + c \<and> c < 10" by presburger
   187   from this obtain c where mexp: "m = 10*(m div 10) + c \<and> c < 10" ..
   188   then obtain c where mexp: "m = 10*(m div 10) + c \<and> c < 10" ..
   188   then have cdef: "c = m mod 10" by arith
   189   then have cdef: "c = m mod 10" by arith
   189   show "m = (\<Sum>x<Suc nd. m div 10^x mod 10 * 10^x)"
   190   show "m = (\<Sum>x<nlen m. m div 10^x mod 10 * 10^x)"
   190   proof -
   191   proof -
   191     have "Suc nd = nlen m" .
   192     from `Suc nd = nlen m`
   192     then have
   193     have "nd = nlen (m div 10)" by (rule nlen_suc)
   193       "nd = nlen (m div 10)" by (rule nlen_suc)
       
   194     with IH have
   194     with IH have
   195       "m div 10 = (\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^x)"  by simp
   195       "m div 10 = (\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^x)" by simp
   196     with mexp have
   196     with mexp have
   197       "m = 10*(\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^x) + c" by simp
   197       "m = 10*(\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^x) + c" by simp
   198     also have
   198     also have
   199       "\<dots> = (\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^(x+1)) + c"
   199       "\<dots> = (\<Sum>x<nd. m div 10 div 10^x mod 10 * 10^(x+1)) + c"
   200       by (subst setsum_mult) (simp add: mult_ac)
   200       by (subst setsum_mult) (simp add: mult_ac)
   206       by (simp only: setsum_shift_bounds_Suc_ivl)
   206       by (simp only: setsum_shift_bounds_Suc_ivl)
   207          (simp add: atLeast0LessThan)
   207          (simp add: atLeast0LessThan)
   208     also have
   208     also have
   209       "\<dots> = (\<Sum>x<Suc nd. m div 10^x mod 10 * 10^x)"
   209       "\<dots> = (\<Sum>x<Suc nd. m div 10^x mod 10 * 10^x)"
   210       by (simp add: setsum_rmv_head [symmetric] cdef)
   210       by (simp add: setsum_rmv_head [symmetric] cdef)
   211     finally 
   211     also note `Suc nd = nlen m`
   212     show "m = (\<Sum>x<Suc nd. m div 10^x mod 10 * 10^x)" .
   212     finally
       
   213     show "m = (\<Sum>x<nlen m. m div 10^x mod 10 * 10^x)" .
   213   qed
   214   qed
   214 qed
   215 qed
   215 
   216 
   216 
   217 
   217 subsubsection {* Final theorem *}
   218 subsubsection {* Final theorem *}
   221 theorem. *}
   222 theorem. *}
   222 
   223 
   223 theorem three_divides_nat:
   224 theorem three_divides_nat:
   224   shows "(3 dvd n) = (3 dvd sumdig n)"
   225   shows "(3 dvd n) = (3 dvd sumdig n)"
   225 proof (unfold sumdig_def)
   226 proof (unfold sumdig_def)
   226   obtain nd where "nd = nlen n" by simp
   227   have "n = (\<Sum>x<nlen n. (n div (10::nat)^x mod 10) * 10^x)"
   227   moreover
       
   228   have "n = (\<Sum>x<nd. (n div (10::nat)^x mod 10) * 10^x)"
       
   229     by (rule exp_exists)
   228     by (rule exp_exists)
   230   moreover
   229   moreover
   231   have "3 dvd (\<Sum>x<nlen n. (n div (10::nat)^x mod 10) * 10^x) =
   230   have "3 dvd (\<Sum>x<nlen n. (n div (10::nat)^x mod 10) * 10^x) =
   232         (3 dvd (\<Sum>x<nlen n. n div 10^x mod 10))"
   231         (3 dvd (\<Sum>x<nlen n. n div 10^x mod 10))"
   233     by (rule three_div_general)
   232     by (rule three_div_general)