doc-src/TutorialI/Rules/Primes.thy
author haftmann
Sun, 20 Jul 2008 11:10:04 +0200
changeset 27657 0efc8b68ee4a
parent 25261 3dc292be0b54
child 33750 0a0d6d79d984
permissions -rw-r--r--
(adjusted)
paulson@10341
     1
(* ID:         $Id$ *)
paulson@10295
     2
(* EXTRACT from HOL/ex/Primes.thy*)
paulson@10295
     3
paulson@11080
     4
(*Euclid's algorithm 
paulson@11080
     5
  This material now appears AFTER that of Forward.thy *)
haftmann@16417
     6
theory Primes imports Main begin
paulson@10295
     7
nipkow@25261
     8
fun gcd :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
nipkow@25261
     9
  "gcd m n = (if n=0 then m else gcd n (m mod n))"
paulson@10295
    10
paulson@10295
    11
paulson@10295
    12
ML "Pretty.setmargin 64"
wenzelm@22097
    13
ML "ThyOutput.indent := 5"  (*that is, Doc/TutorialI/settings.ML*)
paulson@10295
    14
paulson@10295
    15
paulson@11234
    16
text {*Now in Basic.thy!
paulson@10295
    17
@{thm[display]"dvd_def"}
paulson@10295
    18
\rulename{dvd_def}
paulson@10295
    19
*};
paulson@10295
    20
paulson@10295
    21
paulson@10295
    22
(*** Euclid's Algorithm ***)
paulson@10295
    23
nipkow@25261
    24
lemma gcd_0 [simp]: "gcd m 0 = m"
paulson@10846
    25
apply (simp);
paulson@10846
    26
done
paulson@10295
    27
nipkow@25261
    28
lemma gcd_non_0 [simp]: "0<n \<Longrightarrow> gcd m n = gcd n (m mod n)"
paulson@10846
    29
apply (simp)
paulson@10846
    30
done;
paulson@10295
    31
paulson@10295
    32
declare gcd.simps [simp del];
paulson@10295
    33
paulson@10295
    34
(*gcd(m,n) divides m and n.  The conjunctions don't seem provable separately*)
nipkow@25261
    35
lemma gcd_dvd_both: "(gcd m n dvd m) \<and> (gcd m n dvd n)"
paulson@10846
    36
apply (induct_tac m n rule: gcd.induct)
paulson@11080
    37
  --{* @{subgoals[display,indent=0,margin=65]} *}
paulson@10846
    38
apply (case_tac "n=0")
paulson@11080
    39
txt{*subgoals after the case tac
paulson@11080
    40
@{subgoals[display,indent=0,margin=65]}
paulson@11080
    41
*};
paulson@11080
    42
apply (simp_all) 
paulson@11080
    43
  --{* @{subgoals[display,indent=0,margin=65]} *}
paulson@10846
    44
by (blast dest: dvd_mod_imp_dvd)
paulson@10846
    45
paulson@10295
    46
paulson@10295
    47
paulson@10295
    48
text {*
paulson@10295
    49
@{thm[display] dvd_mod_imp_dvd}
paulson@10295
    50
\rulename{dvd_mod_imp_dvd}
paulson@10295
    51
paulson@10295
    52
@{thm[display] dvd_trans}
paulson@10295
    53
\rulename{dvd_trans}
paulson@11080
    54
*}
paulson@10295
    55
paulson@10295
    56
lemmas gcd_dvd1 [iff] = gcd_dvd_both [THEN conjunct1]
paulson@10295
    57
lemmas gcd_dvd2 [iff] = gcd_dvd_both [THEN conjunct2];
paulson@10295
    58
paulson@10295
    59
paulson@10295
    60
text {*
paulson@10295
    61
\begin{quote}
paulson@10295
    62
@{thm[display] gcd_dvd1}
paulson@10295
    63
\rulename{gcd_dvd1}
paulson@10295
    64
paulson@10295
    65
@{thm[display] gcd_dvd2}
paulson@10295
    66
\rulename{gcd_dvd2}
paulson@10295
    67
\end{quote}
paulson@10295
    68
*};
paulson@10295
    69
paulson@10295
    70
(*Maximality: for all m,n,k naturals, 
paulson@10295
    71
                if k divides m and k divides n then k divides gcd(m,n)*)
paulson@10295
    72
lemma gcd_greatest [rule_format]:
nipkow@25261
    73
      "k dvd m \<longrightarrow> k dvd n \<longrightarrow> k dvd gcd m n"
paulson@10846
    74
apply (induct_tac m n rule: gcd.induct)
paulson@10846
    75
apply (case_tac "n=0")
paulson@10853
    76
txt{*subgoals after the case tac
paulson@10853
    77
@{subgoals[display,indent=0,margin=65]}
paulson@10853
    78
*};
paulson@10846
    79
apply (simp_all add: dvd_mod)
paulson@10846
    80
done
paulson@10295
    81
paulson@11080
    82
text {*
paulson@11080
    83
@{thm[display] dvd_mod}
paulson@11080
    84
\rulename{dvd_mod}
paulson@11080
    85
*}
paulson@11080
    86
paulson@10853
    87
(*just checking the claim that case_tac "n" works too*)
nipkow@25261
    88
lemma "k dvd m \<longrightarrow> k dvd n \<longrightarrow> k dvd gcd m n"
paulson@10853
    89
apply (induct_tac m n rule: gcd.induct)
paulson@10853
    90
apply (case_tac "n")
paulson@11080
    91
apply (simp_all add: dvd_mod)
paulson@11080
    92
done
paulson@11080
    93
paulson@10853
    94
paulson@10295
    95
theorem gcd_greatest_iff [iff]: 
nipkow@25261
    96
        "(k dvd gcd m n) = (k dvd m \<and> k dvd n)"
paulson@10846
    97
by (blast intro!: gcd_greatest intro: dvd_trans)
paulson@10295
    98
paulson@10295
    99
paulson@10846
   100
(**** The material below was omitted from the book ****)
paulson@10846
   101
paulson@10295
   102
constdefs
paulson@10300
   103
  is_gcd  :: "[nat,nat,nat] \<Rightarrow> bool"        (*gcd as a relation*)
paulson@10295
   104
    "is_gcd p m n == p dvd m  \<and>  p dvd n  \<and>
paulson@10295
   105
                     (ALL d. d dvd m \<and> d dvd n \<longrightarrow> d dvd p)"
paulson@10295
   106
paulson@10295
   107
(*Function gcd yields the Greatest Common Divisor*)
nipkow@25261
   108
lemma is_gcd: "is_gcd (gcd m n) m n"
paulson@10846
   109
apply (simp add: is_gcd_def gcd_greatest);
paulson@10846
   110
done
paulson@10295
   111
paulson@10295
   112
(*uniqueness of GCDs*)
paulson@10295
   113
lemma is_gcd_unique: "\<lbrakk> is_gcd m a b; is_gcd n a b \<rbrakk> \<Longrightarrow> m=n"
paulson@10846
   114
apply (simp add: is_gcd_def);
paulson@10846
   115
apply (blast intro: dvd_anti_sym)
paulson@10846
   116
done
paulson@10295
   117
paulson@10295
   118
paulson@10295
   119
text {*
paulson@10295
   120
@{thm[display] dvd_anti_sym}
paulson@10295
   121
\rulename{dvd_anti_sym}
paulson@10295
   122
paulson@10295
   123
\begin{isabelle}
paulson@10295
   124
proof\ (prove):\ step\ 1\isanewline
paulson@10295
   125
\isanewline
paulson@10295
   126
goal\ (lemma\ is_gcd_unique):\isanewline
paulson@10295
   127
\isasymlbrakk is_gcd\ m\ a\ b;\ is_gcd\ n\ a\ b\isasymrbrakk \ \isasymLongrightarrow \ m\ =\ n\isanewline
paulson@10295
   128
\ 1.\ \isasymlbrakk m\ dvd\ a\ \isasymand \ m\ dvd\ b\ \isasymand \ (\isasymforall d.\ d\ dvd\ a\ \isasymand \ d\ dvd\ b\ \isasymlongrightarrow \ d\ dvd\ m);\isanewline
paulson@10295
   129
\ \ \ \ \ \ \ n\ dvd\ a\ \isasymand \ n\ dvd\ b\ \isasymand \ (\isasymforall d.\ d\ dvd\ a\ \isasymand \ d\ dvd\ b\ \isasymlongrightarrow \ d\ dvd\ n)\isasymrbrakk \isanewline
paulson@10295
   130
\ \ \ \ \isasymLongrightarrow \ m\ =\ n
paulson@10295
   131
\end{isabelle}
paulson@10295
   132
*};
paulson@10295
   133
nipkow@25261
   134
lemma gcd_assoc: "gcd (gcd k m) n = gcd k (gcd m n)"
paulson@10295
   135
  apply (rule is_gcd_unique)
paulson@10295
   136
  apply (rule is_gcd)
paulson@10295
   137
  apply (simp add: is_gcd_def);
paulson@10295
   138
  apply (blast intro: dvd_trans);
nipkow@25261
   139
  done
paulson@10295
   140
paulson@10295
   141
text{*
paulson@10295
   142
\begin{isabelle}
paulson@10295
   143
proof\ (prove):\ step\ 3\isanewline
paulson@10295
   144
\isanewline
paulson@10295
   145
goal\ (lemma\ gcd_assoc):\isanewline
paulson@10295
   146
gcd\ (gcd\ (k,\ m),\ n)\ =\ gcd\ (k,\ gcd\ (m,\ n))\isanewline
paulson@10295
   147
\ 1.\ gcd\ (k,\ gcd\ (m,\ n))\ dvd\ k\ \isasymand \isanewline
paulson@10295
   148
\ \ \ \ gcd\ (k,\ gcd\ (m,\ n))\ dvd\ m\ \isasymand \ gcd\ (k,\ gcd\ (m,\ n))\ dvd\ n
paulson@10295
   149
\end{isabelle}
paulson@10295
   150
*}
paulson@10295
   151
paulson@10295
   152
nipkow@25261
   153
lemma gcd_dvd_gcd_mult: "gcd m n dvd gcd (k*m) n"
haftmann@27657
   154
  apply (auto intro: dvd_trans [of _ m])
paulson@10295
   155
  done
paulson@10295
   156
paulson@10295
   157
(*This is half of the proof (by dvd_anti_sym) of*)
nipkow@25261
   158
lemma gcd_mult_cancel: "gcd k n = 1 \<Longrightarrow> gcd (k*m) n = gcd m n"
paulson@10295
   159
  oops
paulson@10295
   160
paulson@10295
   161
end