src/HOL/ex/Primes.ML
author berghofe
Tue, 25 Jun 1996 13:11:29 +0200
changeset 1824 44254696843a
parent 1804 cfa0052d5fe9
child 2102 41a667d2c3fa
permissions -rw-r--r--
Changed argument order of nat_rec.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1804
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     1
(*  Title:      HOL/ex/Primes.ML
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     2
    ID:         $Id$
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     3
    Author:     Christophe Tabacznyj and Lawrence C Paulson
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     4
    Copyright   1996  University of Cambridge
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     5
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     6
The "divides" relation, the greatest common divisor and Euclid's algorithm
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     7
*)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     8
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
     9
eta_contract:=false;
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    10
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    11
open Primes;
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    12
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    13
(************************************************)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    14
(** Divides Relation                           **)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    15
(************************************************)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    16
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    17
goalw thy [dvd_def] "m dvd 0";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    18
by (fast_tac (!claset addIs [mult_0_right RS sym]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    19
qed "dvd_0_right";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    20
Addsimps [dvd_0_right];
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    21
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    22
goalw thy [dvd_def] "!!m. 0 dvd m ==> m = 0";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    23
by (fast_tac (!claset addss !simpset) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    24
qed "dvd_0_left";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    25
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    26
goalw thy [dvd_def] "m dvd m";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    27
by (fast_tac (!claset addIs [mult_1_right RS sym]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    28
qed "dvd_refl";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    29
Addsimps [dvd_refl];
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    30
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    31
goalw thy [dvd_def] "!!m n p. [| m dvd n; n dvd p |] ==> m dvd p";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    32
by (fast_tac (!claset addIs [mult_assoc] ) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    33
qed "dvd_trans";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    34
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    35
goalw thy [dvd_def] "!!m n. [| m dvd n; n dvd m |] ==> m=n";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    36
by (fast_tac (!claset addDs [mult_eq_self_implies_10]
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    37
                     addss (!simpset addsimps [mult_assoc, mult_eq_1_iff])) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    38
qed "dvd_anti_sym";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    39
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    40
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    41
(************************************************)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    42
(** Greatest Common Divisor                    **)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    43
(************************************************)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    44
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    45
(* GCD by Euclid's Algorithm *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    46
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    47
val [rew] = goal HOL.thy "x==y ==> x=y";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    48
by (rewtac rew);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    49
by (rtac refl 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    50
qed "equals_reflection";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    51
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    52
goal thy "(%n m. egcd m n) = wfrec (pred_nat^+)   \
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    53
\                                  (%f n m. if n=0 then m else f (m mod n) n)";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    54
by (simp_tac (HOL_ss addsimps [egcd_def]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    55
val egcd_def1 = result() RS eq_reflection;
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    56
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    57
goalw thy [egcd_def] "egcd m 0 = m";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    58
by (simp_tac (!simpset addsimps [wf_pred_nat RS wf_trancl RS wfrec]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    59
qed "egcd_0";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    60
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    61
goal thy "!!m. 0<n ==> egcd m n = egcd n (m mod n)";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    62
by (rtac (egcd_def1 RS wf_less_trans RS fun_cong) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    63
by (asm_simp_tac (!simpset addsimps [mod_less_divisor, cut_apply, less_eq]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    64
qed "egcd_less_0";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    65
Addsimps [egcd_0, egcd_less_0];
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    66
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    67
goal thy "(egcd m 0) dvd m";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    68
by (Simp_tac 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    69
qed "egcd_0_dvd_m";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    70
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    71
goal thy "(egcd m 0) dvd 0";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    72
by (Simp_tac 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    73
qed "egcd_0_dvd_0";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    74
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    75
goalw thy [dvd_def] "!!k. [| k dvd m; k dvd n |] ==> k dvd (m + n)";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    76
by (fast_tac (!claset addIs [add_mult_distrib2 RS sym]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    77
qed "dvd_add";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    78
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    79
goalw thy [dvd_def] "!!k. k dvd m ==> k dvd (q * m)";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    80
by (fast_tac (!claset addIs [mult_left_commute]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    81
qed "dvd_mult";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    82
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    83
goal thy "!!k. [| k dvd n; k dvd (m mod n); 0 < n |] ==> k dvd m";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    84
by (deepen_tac 
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    85
    (!claset addIs [mod_div_equality RS subst]
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    86
             addSIs [dvd_add, dvd_mult]) 0 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    87
qed "gcd_ind";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    88
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    89
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    90
(* Property 1: egcd m n divides m and n *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    91
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    92
goal thy "ALL m. (egcd m n dvd m) & (egcd m n dvd n)";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    93
by (res_inst_tac [("n","n")] less_induct 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    94
by (rtac allI 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    95
by (excluded_middle_tac "n=0" 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    96
(* case n = 0 *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    97
by (Asm_simp_tac 2);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    98
(* case n > 0 *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
    99
by (asm_full_simp_tac (!simpset addsimps [zero_less_eq RS sym]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   100
by (eres_inst_tac [("x","m mod n")] allE 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   101
by (asm_full_simp_tac (!simpset addsimps [mod_less_divisor]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   102
by (fast_tac (!claset addIs [gcd_ind]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   103
qed "egcd_prop1";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   104
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   105
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   106
(* if f divides m and n then f divides egcd m n *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   107
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   108
Delsimps [add_mult_distrib,add_mult_distrib2];
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   109
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   110
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   111
goalw thy [dvd_def] "!!m. [| f dvd m; f dvd n; 0<n |] ==> f dvd (m mod n)";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   112
by (Step_tac 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   113
by (rtac (zero_less_mult_iff RS iffD1 RS conjE) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   114
by (REPEAT_SOME assume_tac);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   115
by (res_inst_tac 
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   116
    [("x", "(((k div ka)*ka + k mod ka) - ((f*k) div (f*ka)) * ka)")] 
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   117
    exI 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   118
by (asm_simp_tac (!simpset addsimps [diff_mult_distrib2, div_cancel,
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   119
                                     mult_mod_distrib, add_mult_distrib2,
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   120
                                     diff_add_inverse]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   121
qed "dvd_mod";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   122
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   123
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   124
(* Property 2: for all m,n,f naturals, 
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   125
               if f divides m and f divides n then f divides egcd m n*)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   126
goal thy "!!k. ALL m. (f dvd m) & (f dvd k) --> f dvd egcd m k";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   127
by (res_inst_tac [("n","k")] less_induct 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   128
by (rtac allI 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   129
by (excluded_middle_tac "n=0" 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   130
(* case n = 0 *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   131
by (Asm_simp_tac 2);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   132
(* case n > 0 *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   133
by (Step_tac 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   134
by (asm_full_simp_tac (!simpset addsimps [zero_less_eq RS sym]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   135
by (eres_inst_tac [("x","m mod n")] allE 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   136
by (asm_full_simp_tac (!simpset addsimps [mod_less_divisor]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   137
by (fast_tac (!claset addSIs [dvd_mod]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   138
qed "egcd_prop2";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   139
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   140
(* GCD PROOF : GCD exists and egcd fits the definition *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   141
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   142
goalw thy [gcd_def] "gcd (egcd m n) m n";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   143
by (asm_simp_tac (!simpset addsimps [egcd_prop1]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   144
by (fast_tac (!claset addIs [egcd_prop2 RS spec RS mp]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   145
qed "gcd";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   146
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   147
(* GCD is unique *)
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   148
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   149
goalw thy [gcd_def] "gcd m a b & gcd n a b --> m=n";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   150
by (fast_tac (!claset addIs [dvd_anti_sym]) 1);
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   151
qed "gcd_unique";
cfa0052d5fe9 New example of greatest common divisor
paulson
parents:
diff changeset
   152