1(* ========================================================================= *) 2(* Create "fieldTheory" setting up the theory of field curves *) 3(* ========================================================================= *) 4 5(* ------------------------------------------------------------------------- *) 6(* Load and open relevant theories. *) 7(* (Comment out "load"s and "quietdec"s for compilation.) *) 8(* ------------------------------------------------------------------------- *) 9(* 10val () = loadPath := [] @ !loadPath; 11val () = app load 12 ["Algebra", 13 "bossLib", "metisLib", "res_quanTools", 14 "optionTheory", "listTheory", 15 "arithmeticTheory", "dividesTheory", "gcdTheory", 16 "pred_setTheory", "pred_setSyntax", 17 "primalityTools"]; 18val () = quietdec := true; 19*) 20 21open HolKernel Parse boolLib bossLib metisLib res_quanTools; 22open optionTheory listTheory arithmeticTheory dividesTheory gcdTheory; 23open pred_setTheory; 24open primalityTools; 25open groupTheory groupTools; 26 27(* 28val () = quietdec := false; 29*) 30 31(* ------------------------------------------------------------------------- *) 32(* Start a new theory called "field". *) 33(* ------------------------------------------------------------------------- *) 34 35val _ = new_theory "field"; 36 37val ERR = mk_HOL_ERR "field"; 38val Bug = mlibUseful.Bug; 39val Error = ERR ""; 40 41val Bug = fn s => (print ("\n\nBUG: " ^ s ^ "\n\n"); Bug s); 42 43(* ------------------------------------------------------------------------- *) 44(* Sort out the parser. *) 45(* ------------------------------------------------------------------------- *) 46 47val () = Parse.add_infix ("/", 600, HOLgrammars.LEFT); 48 49(* ------------------------------------------------------------------------- *) 50(* Show oracle tags. *) 51(* ------------------------------------------------------------------------- *) 52 53val () = show_tags := true; 54 55(* ------------------------------------------------------------------------- *) 56(* The subtype context. *) 57(* ------------------------------------------------------------------------- *) 58 59val context = group_context; 60val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 61 62(* ------------------------------------------------------------------------- *) 63(* Helper proof tools. *) 64(* ------------------------------------------------------------------------- *) 65 66infixr 0 << 67infixr 1 ++ || THENC ORELSEC ORELSER ## orelse_bdd_conv 68infix 2 >> 69 70val op ++ = op THEN; 71val op << = op THENL; 72val op >> = op THEN1; 73val op || = op ORELSE; 74val Know = Q_TAC KNOW_TAC; 75val Suff = Q_TAC SUFF_TAC; 76val REVERSE = Tactical.REVERSE; 77val lemma = Tactical.prove; 78 79val cond_rewr_conv = subtypeTools.cond_rewr_conv; 80 81val cond_rewrs_conv = subtypeTools.cond_rewrs_conv; 82 83val named_conv_to_simpset_conv = subtypeTools.named_conv_to_simpset_conv; 84 85val norm_rule = 86 SIMP_RULE (simpLib.++ (pureSimps.pure_ss, resq_SS)) 87 [GSYM LEFT_FORALL_IMP_THM, GSYM RIGHT_FORALL_IMP_THM, 88 AND_IMP_INTRO, GSYM CONJ_ASSOC]; 89 90fun match_tac th = 91 let 92 val th = norm_rule th 93 val (_,tm) = strip_forall (concl th) 94 in 95 (if is_imp tm then MATCH_MP_TAC else MATCH_ACCEPT_TAC) th 96 end; 97 98(* ------------------------------------------------------------------------- *) 99(* Helper theorems. *) 100(* ------------------------------------------------------------------------- *) 101 102val DIV_THEN_MULT = store_thm 103 ("DIV_THEN_MULT", 104 ``!p q. SUC q * (p DIV SUC q) <= p``, 105 NTAC 2 STRIP_TAC 106 ++ Know `?r. p = (p DIV SUC q) * SUC q + r` 107 >> (Know `0 < SUC q` >> DECIDE_TAC 108 ++ PROVE_TAC [DIVISION]) 109 ++ STRIP_TAC 110 ++ Suff `p = SUC q * (p DIV SUC q) + r` 111 >> (POP_ASSUM_LIST (K ALL_TAC) ++ DECIDE_TAC) 112 ++ PROVE_TAC [MULT_COMM]); 113 114val MOD_EXP = store_thm 115 ("MOD_EXP", 116 ``!a n m. 0 < m ==> (((a MOD m) ** n) MOD m = (a ** n) MOD m)``, 117 RW_TAC std_ss [] 118 ++ Induct_on `n` 119 ++ RW_TAC std_ss [EXP] 120 ++ MP_TAC (Q.SPEC `m` MOD_TIMES2) 121 ++ ASM_REWRITE_TAC [] 122 ++ DISCH_THEN (fn th => ONCE_REWRITE_TAC [GSYM th]) 123 ++ ASM_SIMP_TAC std_ss [MOD_MOD]); 124 125val MULT_EXP = store_thm 126 ("MULT_EXP", 127 ``!a b n. (a * b) ** n = (a ** n) * (b ** n)``, 128 RW_TAC std_ss [] 129 ++ Induct_on `n` 130 ++ RW_TAC std_ss [EXP, EQ_MULT_LCANCEL, GSYM MULT_ASSOC] 131 ++ RW_TAC std_ss 132 [EXP, ONCE_REWRITE_RULE [MULT_COMM] EQ_MULT_LCANCEL, MULT_ASSOC] 133 ++ METIS_TAC [MULT_COMM]); 134 135val EXP_EXP = store_thm 136 ("EXP_EXP", 137 ``!a b c. (a ** b) ** c = a ** (b * c)``, 138 RW_TAC std_ss [] 139 ++ Induct_on `b` 140 ++ RW_TAC std_ss [EXP, MULT, EXP_1] 141 ++ RW_TAC std_ss [MULT_EXP, EXP_ADD] 142 ++ METIS_TAC [MULT_COMM]); 143 144(* ========================================================================= *) 145(* Fields *) 146(* ========================================================================= *) 147 148(* ------------------------------------------------------------------------- *) 149(* The basic definitions *) 150(* ------------------------------------------------------------------------- *) 151 152val () = Hol_datatype 153 `field = <| carrier : 'a -> bool; 154 sum : 'a group; 155 prod : 'a group |>`; 156 157val field_accessors = fetch "-" "field_accessors"; 158 159val field_zero_def = Define `field_zero (f : 'a field) = f.sum.id`; 160 161val field_one_def = Define `field_one (f : 'a field) = f.prod.id`; 162 163val field_neg_def = Define `field_neg (f : 'a field) = f.sum.inv`; 164 165val field_inv_def = Define `field_inv (f : 'a field) = f.prod.inv`; 166 167val field_add_def = Define `field_add (f : 'a field) = f.sum.mult`; 168 169val field_sub_def = Define 170 `field_sub (f : 'a field) x y = field_add f x (field_neg f y)`; 171 172val field_mult_def = Define `field_mult (f : 'a field) = f.prod.mult`; 173 174val field_div_def = Define 175 `field_div (f : 'a field) x y = field_mult f x (field_inv f y)`; 176 177val field_nonzero_def = Define 178 `field_nonzero f = f.carrier DIFF {field_zero f}`; 179 180val field_num_def = Define 181 `(field_num (f : 'a field) 0 = field_zero f) /\ 182 (field_num (f : 'a field) (SUC n) = 183 field_add f (field_num f n) (field_one f))`; 184 185val field_exp_def = Define 186 `(field_exp (f : 'a field) x 0 = field_one f) /\ 187 (field_exp (f : 'a field) x (SUC n) = field_mult f x (field_exp f x n))`; 188 189val Field_def = Define 190 `Field = 191 { (f : 'a field) | 192 f.sum IN AbelianGroup /\ 193 f.prod IN AbelianGroup /\ 194 (f.sum.carrier = f.carrier) /\ 195 (f.prod.carrier = field_nonzero f) /\ 196 (!x :: (f.carrier). field_mult f (field_zero f) x = field_zero f) /\ 197 (!x y z :: (f.carrier). 198 field_mult f x (field_add f y z) = 199 field_add f (field_mult f x y) (field_mult f x z)) }`; 200 201val FiniteField_def = Define 202 `FiniteField = { (f : 'a field) | f IN Field /\ FINITE f.carrier }`; 203 204val context = subtypeTools.add_rewrite2'' field_sub_def context; 205(*val context = subtypeTools.add_rewrite2'' field_div_def context;*) 206val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 207 208(* ------------------------------------------------------------------------- *) 209(* Syntax operations *) 210(* ------------------------------------------------------------------------- *) 211 212val field_ty_op = "field"; 213 214fun mk_field_type ty = mk_type (field_ty_op,[ty]); 215 216fun dest_field_type ty = 217 case dest_type ty of 218 (ty_op,[a]) => if ty_op = field_ty_op then a 219 else raise ERR "dest_field_type" "" 220 | _ => raise ERR "dest_field_type" ""; 221 222val is_field_type = can dest_field_type; 223 224val field_zero_tm = ``field_zero : 'a field -> 'a``; 225 226fun mk_field_zero f = 227 let 228 val ty = dest_field_type (type_of f) 229 val zero_tm = inst [{redex = alpha, residue = ty}] field_zero_tm 230 in 231 mk_comb (zero_tm,f) 232 end; 233 234fun dest_field_zero tm = 235 let 236 val (tm,f) = dest_comb tm 237 val _ = same_const tm field_zero_tm orelse raise ERR "dest_field_zero" "" 238 in 239 f 240 end; 241 242val is_field_zero = can dest_field_zero; 243 244val field_one_tm = ``field_one : 'a field -> 'a``; 245 246fun mk_field_one f = 247 let 248 val ty = dest_field_type (type_of f) 249 val one_tm = inst [{redex = alpha, residue = ty}] field_one_tm 250 in 251 mk_comb (one_tm,f) 252 end; 253 254fun dest_field_one tm = 255 let 256 val (tm,f) = dest_comb tm 257 val _ = same_const tm field_one_tm orelse raise ERR "dest_field_one" "" 258 in 259 f 260 end; 261 262val is_field_one = can dest_field_one; 263 264val field_num_tm = ``field_num : 'a field -> num -> 'a``; 265 266fun mk_field_num (f,n) = 267 let 268 val ty = dest_field_type (type_of f) 269 val num_tm = inst [{redex = alpha, residue = ty}] field_num_tm 270 in 271 list_mk_comb (num_tm,[f,n]) 272 end; 273 274fun dest_field_num tm = 275 let 276 val (tm,x) = dest_comb tm 277 val (tm,f) = dest_comb tm 278 val _ = same_const tm field_num_tm orelse raise ERR "dest_field_num" "" 279 in 280 (f,x) 281 end; 282 283val is_field_num = can dest_field_num; 284 285val field_neg_tm = ``field_neg : 'a field -> 'a -> 'a``; 286 287fun mk_field_neg (f,x) = 288 let 289 val ty = dest_field_type (type_of f) 290 val neg_tm = inst [{redex = alpha, residue = ty}] field_neg_tm 291 in 292 list_mk_comb (neg_tm,[f,x]) 293 end; 294 295fun dest_field_neg tm = 296 let 297 val (tm,x) = dest_comb tm 298 val (tm,f) = dest_comb tm 299 val _ = same_const tm field_neg_tm orelse raise ERR "dest_field_neg" "" 300 in 301 (f,x) 302 end; 303 304val is_field_neg = can dest_field_neg; 305 306val field_add_tm = ``field_add : 'a field -> 'a -> 'a -> 'a``; 307 308fun mk_field_add (f,x,y) = 309 let 310 val ty = dest_field_type (type_of f) 311 val add_tm = inst [{redex = alpha, residue = ty}] field_add_tm 312 in 313 list_mk_comb (add_tm,[f,x,y]) 314 end; 315 316fun dest_field_add tm = 317 let 318 val (tm,y) = dest_comb tm 319 val (tm,x) = dest_comb tm 320 val (tm,f) = dest_comb tm 321 val _ = same_const tm field_add_tm orelse raise ERR "dest_field_add" "" 322 in 323 (f,x,y) 324 end; 325 326val is_field_add = can dest_field_add; 327 328val field_sub_tm = ``field_sub : 'a field -> 'a -> 'a -> 'a``; 329 330fun mk_field_sub (f,x,y) = 331 let 332 val ty = dest_field_type (type_of f) 333 val sub_tm = inst [{redex = alpha, residue = ty}] field_sub_tm 334 in 335 list_mk_comb (sub_tm,[f,x,y]) 336 end; 337 338fun dest_field_sub tm = 339 let 340 val (tm,y) = dest_comb tm 341 val (tm,x) = dest_comb tm 342 val (tm,f) = dest_comb tm 343 val _ = same_const tm field_sub_tm orelse raise ERR "dest_field_sub" "" 344 in 345 (f,x,y) 346 end; 347 348val is_field_sub = can dest_field_sub; 349 350val field_inv_tm = ``field_inv : 'a field -> 'a -> 'a``; 351 352fun mk_field_inv (f,x) = 353 let 354 val ty = dest_field_type (type_of f) 355 val inv_tm = inst [{redex = alpha, residue = ty}] field_inv_tm 356 in 357 list_mk_comb (inv_tm,[f,x]) 358 end; 359 360fun dest_field_inv tm = 361 let 362 val (tm,x) = dest_comb tm 363 val (tm,f) = dest_comb tm 364 val _ = same_const tm field_inv_tm orelse raise ERR "dest_field_inv" "" 365 in 366 (f,x) 367 end; 368 369val is_field_inv = can dest_field_inv; 370 371val field_mult_tm = ``field_mult : 'a field -> 'a -> 'a -> 'a``; 372 373fun mk_field_mult (f,x,y) = 374 let 375 val ty = dest_field_type (type_of f) 376 val mult_tm = inst [{redex = alpha, residue = ty}] field_mult_tm 377 in 378 list_mk_comb (mult_tm,[f,x,y]) 379 end; 380 381fun dest_field_mult tm = 382 let 383 val (tm,y) = dest_comb tm 384 val (tm,x) = dest_comb tm 385 val (tm,f) = dest_comb tm 386 val _ = same_const tm field_mult_tm orelse raise ERR "dest_field_mult" "" 387 in 388 (f,x,y) 389 end; 390 391val is_field_mult = can dest_field_mult; 392 393val field_exp_tm = ``field_exp : 'a field -> 'a -> num -> 'a``; 394 395fun mk_field_exp (f,x,n) = 396 let 397 val ty = dest_field_type (type_of f) 398 val exp_tm = inst [{redex = alpha, residue = ty}] field_exp_tm 399 in 400 list_mk_comb (exp_tm,[f,x,n]) 401 end; 402 403fun dest_field_exp tm = 404 let 405 val (tm,n) = dest_comb tm 406 val (tm,x) = dest_comb tm 407 val (tm,f) = dest_comb tm 408 val _ = same_const tm field_exp_tm orelse raise ERR "dest_field_exp" "" 409 in 410 (f,x,n) 411 end; 412 413val is_field_exp = can dest_field_exp; 414 415val field_div_tm = ``field_div : 'a field -> 'a -> 'a -> 'a``; 416 417fun mk_field_div (f,x,y) = 418 let 419 val ty = dest_field_type (type_of f) 420 val div_tm = inst [{redex = alpha, residue = ty}] field_div_tm 421 in 422 list_mk_comb (div_tm,[f,x,y]) 423 end; 424 425fun dest_field_div tm = 426 let 427 val (tm,y) = dest_comb tm 428 val (tm,x) = dest_comb tm 429 val (tm,f) = dest_comb tm 430 val _ = same_const tm field_div_tm orelse raise ERR "dest_field_div" "" 431 in 432 (f,x,y) 433 end; 434 435val is_field_div = can dest_field_div; 436 437fun mk_field_num_mult (f,x,n) = mk_field_mult (f, mk_field_num (f,n), x); 438 439fun dest_field_num_mult tm = 440 let 441 val (f,t,x) = dest_field_mult tm 442 val (_,n) = dest_field_num t 443 in 444 (f,x,n) 445 end; 446 447val is_field_num_mult = can dest_field_num_mult; 448 449fun field_compare (x,y) = 450 case (total dest_field_num x, total dest_field_num y) of 451 (NONE,NONE) => compare (x,y) 452 | (SOME _, NONE) => LESS 453 | (NONE, SOME _) => GREATER 454 | (SOME (_,x), SOME (_,y)) => compare (x,y); 455 456(* ------------------------------------------------------------------------- *) 457(* Theorems *) 458(* ------------------------------------------------------------------------- *) 459 460val FiniteField_Field = store_thm 461 ("FiniteField_Field", 462 ``!f. f IN FiniteField ==> f IN Field``, 463 RW_TAC std_ss [FiniteField_def, GSPECIFICATION]); 464 465val context = subtypeTools.add_judgement2 FiniteField_Field context; 466val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 467 468val field_nonzero_carrier = store_thm 469 ("field_nonzero_carrier", 470 ``!f :: Field. !x :: field_nonzero f. x IN f.carrier``, 471 RW_TAC resq_ss [field_nonzero_def, IN_DIFF]); 472 473val context = subtypeTools.add_judgement2 field_nonzero_carrier context; 474val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 475 476val field_nonzero_alt = store_thm 477 ("field_nonzero_alt", 478 ``!f x. x IN f.carrier /\ ~(x = field_zero f) ==> x IN field_nonzero f``, 479 RW_TAC std_ss [field_nonzero_def, IN_DIFF, IN_SING]); 480 481val field_nonzero_eq = store_thm 482 ("field_nonzero_eq", 483 ``!f :: Field. !x :: (f.carrier). 484 ~(x = field_zero f) = x IN field_nonzero f``, 485 RW_TAC std_ss [field_nonzero_def, IN_DIFF, IN_SING]); 486 487val field_zero_carrier = store_thm 488 ("field_zero_carrier", 489 ``!f :: Field. field_zero f IN f.carrier``, 490 RW_TAC resq_ss [Field_def, field_one_def, GSPECIFICATION, field_zero_def] 491 ++ Q.UNDISCH_TAC `f.sum IN AbelianGroup` 492 ++ RW_TAC std_ss [AbelianGroup_def, GSPECIFICATION, Group_def]); 493 494val context = subtypeTools.add_reduction2 field_zero_carrier context; 495val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 496 497val field_one_carrier = store_thm 498 ("field_one_carrier", 499 ``!f :: Field. field_one f IN f.carrier``, 500 RW_TAC resq_ss [Field_def, field_one_def, GSPECIFICATION, field_zero_def] 501 ++ Q.UNDISCH_TAC `f.prod IN AbelianGroup` 502 ++ RW_TAC std_ss 503 [AbelianGroup_def, GSPECIFICATION, Group_def, IN_DIFF, 504 field_nonzero_def]); 505 506val field_one_zero = store_thm 507 ("field_one_zero", 508 ``!f :: Field. ~(field_one f = field_zero f)``, 509 RW_TAC resq_ss 510 [Field_def, field_one_def, field_zero_def, GSPECIFICATION, 511 AbelianGroup_def, field_nonzero_def] 512 ++ Know `f.prod.id IN f.prod.carrier` 513 >> METIS_TAC [group_id_carrier] 514 ++ RW_TAC std_ss [IN_DIFF, IN_SING]); 515 516val context = subtypeTools.add_rewrite2 field_one_zero context; 517val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 518 519val field_zero_one = store_thm 520 ("field_zero_one", 521 ``!f :: Field. ~(field_zero f = field_one f)``, 522 RW_TAC alg_ss []); 523 524val field_one_nonzero = store_thm 525 ("field_one_nonzero", 526 ``!f :: Field. field_one f IN field_nonzero f``, 527 RW_TAC resq_ss 528 [field_nonzero_def, IN_DIFF, IN_SING, field_one_carrier, field_one_zero]); 529 530val context = subtypeTools.add_reduction2 field_one_nonzero context; 531val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 532 533val field_neg_carrier = store_thm 534 ("field_neg_carrier", 535 ``!f :: Field. !x :: (f.carrier). field_neg f x IN f.carrier``, 536 RW_TAC resq_ss [Field_def, GSPECIFICATION, field_neg_def, AbelianGroup_def] 537 ++ METIS_TAC [group_inv_carrier]); 538 539val context = subtypeTools.add_reduction2 field_neg_carrier context; 540val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 541 542val field_add_carrier = store_thm 543 ("field_add_carrier", 544 ``!f :: Field. !x y :: (f.carrier). field_add f x y IN f.carrier``, 545 RW_TAC resq_ss [Field_def, GSPECIFICATION, field_add_def, AbelianGroup_def] 546 ++ METIS_TAC [group_mult_carrier]); 547 548val context = subtypeTools.add_reduction2 field_add_carrier context; 549val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 550 551val field_add_assoc = store_thm 552 ("field_add_assoc", 553 ``!f :: Field. !x y z :: (f.carrier). 554 field_add f (field_add f x y) z = field_add f x (field_add f y z)``, 555 RW_TAC resq_ss 556 [Field_def, GSPECIFICATION, field_add_def, AbelianGroup_def, 557 Group_def]); 558 559val context = subtypeTools.add_rewrite2'' field_add_assoc context; 560val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 561 562val field_add_comm = store_thm 563 ("field_add_comm", 564 ``!f :: Field. !x y :: (f.carrier). field_add f x y = field_add f y x``, 565 RW_TAC resq_ss 566 [Field_def, GSPECIFICATION, field_add_def, AbelianGroup_def]); 567 568val field_add_comm' = store_thm 569 ("field_add_comm'", 570 ``!f :: Field. !x y z :: (f.carrier). 571 field_add f x (field_add f y z) = field_add f y (field_add f x z)``, 572 RW_TAC resq_ss [] 573 ++ RW_TAC alg_ss [GSYM field_add_assoc] 574 ++ METIS_TAC [field_add_comm]); 575 576val field_num_zero = store_thm 577 ("field_num_zero", 578 ``!f. field_num f 0 = field_zero f``, 579 RW_TAC std_ss [field_num_def]); 580 581val context = subtypeTools.add_rewrite2 field_num_zero context; 582val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 583 584val field_add_lzero = store_thm 585 ("field_add_lzero", 586 ``!f :: Field. !x :: (f.carrier). field_add f (field_zero f) x = x``, 587 RW_TAC resq_ss 588 [Field_def, GSPECIFICATION, field_add_def, field_zero_def, 589 AbelianGroup_def] 590 ++ match_tac group_lid 591 ++ RW_TAC std_ss []); 592 593val context = subtypeTools.add_rewrite2 field_add_lzero context; 594val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 595 596val field_num_one = store_thm 597 ("field_num_one", 598 ``!f :: Field. field_num f 1 = field_one f``, 599 REWRITE_TAC [ONE, field_num_def] 600 ++ RW_TAC alg_ss []); 601 602val context = subtypeTools.add_rewrite2'' (GSYM field_num_one) context; 603val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 604 605val field_add_lzero' = store_thm 606 ("field_add_lzero'", 607 ``!f :: Field. !x :: (f.carrier). field_add f (field_num f 0) x = x``, 608 RW_TAC alg_ss [field_num_zero]); 609 610val context = subtypeTools.add_rewrite2 field_add_lzero' context; 611val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 612 613val field_add_rzero = store_thm 614 ("field_add_rzero", 615 ``!f :: Field. !x :: (f.carrier). field_add f x (field_zero f) = x``, 616 METIS_TAC [field_add_lzero, field_add_comm, field_zero_carrier]); 617 618val context = subtypeTools.add_rewrite2 field_add_rzero context; 619val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 620 621val field_add_rzero' = store_thm 622 ("field_add_rzero'", 623 ``!f :: Field. !x :: (f.carrier). field_add f x (field_num f 0) = x``, 624 RW_TAC alg_ss [field_num_zero]); 625 626val context = subtypeTools.add_rewrite2 field_add_rzero' context; 627val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 628 629val field_lneg = store_thm 630 ("field_lneg", 631 ``!f :: Field. !x :: (f.carrier). 632 (field_add f (field_neg f x) x = field_zero f)``, 633 RW_TAC resq_ss 634 [Field_def, GSPECIFICATION, field_add_def, field_zero_def, 635 AbelianGroup_def, field_neg_def] 636 ++ match_tac group_linv 637 ++ RW_TAC std_ss [IN_DIFF, IN_SING]); 638 639val context = subtypeTools.add_rewrite2 field_lneg context; 640val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 641 642val field_lneg' = store_thm 643 ("field_lneg'", 644 ``!f :: Field. !x y :: (f.carrier). 645 (field_add f (field_neg f x) (field_add f x y) = y)``, 646 RW_TAC resq_ss [] 647 ++ RW_TAC alg_ss [GSYM field_add_assoc]); 648 649val context = subtypeTools.add_rewrite2 field_lneg' context; 650val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 651 652val field_rneg = store_thm 653 ("field_rneg", 654 ``!f :: Field. !x :: (f.carrier). 655 (field_add f x (field_neg f x) = field_zero f)``, 656 METIS_TAC [field_lneg, field_add_comm, field_neg_carrier]); 657 658val context = subtypeTools.add_rewrite2 field_rneg context; 659val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 660 661val field_rneg' = store_thm 662 ("field_rneg'", 663 ``!f :: Field. !x y :: (f.carrier). 664 (field_add f x (field_add f (field_neg f x) y) = y)``, 665 RW_TAC resq_ss [] 666 ++ RW_TAC alg_ss [GSYM field_add_assoc]); 667 668val context = subtypeTools.add_rewrite2 field_rneg' context; 669val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 670 671val field_add_lcancel_imp = store_thm 672 ("field_add_lcancel_imp", 673 ``!f :: Field. !x y z :: (f.carrier). 674 (field_add f x y = field_add f x z) ==> (y = z)``, 675 RW_TAC resq_ss [Field_def, GSPECIFICATION, AbelianGroup_def, field_add_def] 676 ++ match_tac group_lcancel_imp 677 ++ Q.EXISTS_TAC `f.sum` 678 ++ Q.EXISTS_TAC `x` 679 ++ RW_TAC std_ss []); 680 681val field_add_lcancel = store_thm 682 ("field_add_lcancel", 683 ``!f :: Field. !x y z :: (f.carrier). 684 (field_add f x y = field_add f x z) = (y = z)``, 685 METIS_TAC [field_add_lcancel_imp]); 686 687val context = subtypeTools.add_rewrite2' field_add_lcancel context; 688val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 689 690val field_add_rcancel_imp = store_thm 691 ("field_add_rcancel_imp", 692 ``!f :: Field. !x y z :: (f.carrier). 693 (field_add f y x = field_add f z x) ==> (y = z)``, 694 METIS_TAC [field_add_lcancel_imp, field_add_comm]); 695 696val field_add_rcancel = store_thm 697 ("field_add_rcancel", 698 ``!f :: Field. !x y z :: (f.carrier). 699 (field_add f y x = field_add f z x) = (y = z)``, 700 METIS_TAC [field_add_rcancel_imp]); 701 702val context = subtypeTools.add_rewrite2' field_add_rcancel context; 703val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 704 705val field_inv_nonzero = store_thm 706 ("field_inv_nonzero", 707 ``!f :: Field. !x :: field_nonzero f. field_inv f x IN field_nonzero f``, 708 RW_TAC resq_ss [Field_def, GSPECIFICATION, field_nonzero_def] 709 ++ Suff `field_inv f x IN f.prod.carrier` 710 >> RW_TAC std_ss [] 711 ++ Know `x IN f.prod.carrier` 712 >> RW_TAC std_ss [IN_DIFF, IN_INSERT, NOT_IN_EMPTY] 713 ++ Q.UNDISCH_TAC `f.prod IN AbelianGroup` 714 ++ POP_ASSUM_LIST (K ALL_TAC) 715 ++ RW_TAC std_ss 716 [AbelianGroup_def, GSPECIFICATION, Group_def, field_inv_def]); 717 718val context = subtypeTools.add_reduction2 field_inv_nonzero context; 719val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 720 721val field_mult_lzero = store_thm 722 ("field_mult_lzero", 723 ``!f :: Field. !x :: (f.carrier). 724 field_mult f (field_zero f) x = field_zero f``, 725 RW_TAC resq_ss [Field_def, GSPECIFICATION]); 726 727val context = subtypeTools.add_rewrite2 field_mult_lzero context; 728val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 729 730val field_mult_lzero' = store_thm 731 ("field_mult_lzero'", 732 ``!f :: Field. !x :: (f.carrier). 733 field_mult f (field_num f 0) x = field_zero f``, 734 RW_TAC alg_ss [field_num_zero]); 735 736val context = subtypeTools.add_rewrite2 field_mult_lzero' context; 737val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 738 739val field_distrib_ladd = store_thm 740 ("field_distrib_ladd", 741 ``!f :: Field. !x y z :: (f.carrier). 742 field_mult f x (field_add f y z) = 743 field_add f (field_mult f x y) (field_mult f x z)``, 744 RW_TAC resq_ss [Field_def, GSPECIFICATION]); 745 746(*** 747val context = subtypeTools.add_rewrite2'' field_distrib_ladd context; 748val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 749***) 750 751val field_mult_rzero = store_thm 752 ("field_mult_rzero", 753 ``!f :: Field. !x :: (f.carrier). 754 field_mult f x (field_zero f) = field_zero f``, 755 RW_TAC resq_ss [] 756 ++ Cases_on `x = field_zero f` 757 >> METIS_TAC [field_mult_lzero] 758 ++ Know `field_mult f x (field_zero f) IN f.carrier` 759 >> (Suff 760 `field_mult f x (field_add f (field_one f) (field_neg f (field_one f))) 761 IN f.carrier` 762 >> RW_TAC alg_ss [field_rneg] 763 ++ RW_TAC alg_ss [field_distrib_ladd] 764 ++ match_tac field_add_carrier 765 ++ Q.UNDISCH_TAC `f IN Field` 766 ++ RW_TAC std_ss 767 [GSPECIFICATION, Field_def, AbelianGroup_def, field_one_def, 768 field_mult_def, field_neg_def, field_nonzero_def] 769 >> (Suff `f.prod.mult x f.prod.id IN f.prod.carrier` 770 >> RW_TAC std_ss [IN_DIFF] 771 ++ match_tac group_mult_carrier 772 ++ RW_TAC std_ss [group_id_carrier, IN_DIFF, IN_SING]) 773 ++ Suff `f.prod.mult x (f.sum.inv f.prod.id) IN f.prod.carrier` 774 >> RW_TAC std_ss [IN_DIFF] 775 ++ Q.PAT_ASSUM `f.sum.carrier = f.carrier` 776 (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) 777 ++ STRIP_TAC 778 ++ match_tac group_mult_carrier 779 ++ ASM_SIMP_TAC std_ss [IN_DIFF, IN_SING] 780 ++ Know `f.prod.id IN f.prod.carrier` 781 >> RW_TAC std_ss [group_id_carrier] 782 ++ ASM_SIMP_TAC std_ss [IN_DIFF, IN_SING] 783 ++ FULL_SIMP_TAC std_ss [field_zero_def] 784 ++ RW_TAC std_ss [] 785 >> (match_tac group_inv_carrier 786 ++ RW_TAC std_ss []) 787 ++ STRIP_TAC 788 ++ Q.PAT_ASSUM `~(X = Y)` MP_TAC 789 ++ RW_TAC std_ss [] 790 ++ match_tac group_lcancel_imp 791 ++ Q.EXISTS_TAC `f.sum` 792 ++ Q.EXISTS_TAC `f.sum.inv f.prod.id` 793 ++ CONJ_TAC >> METIS_TAC [group_linv, group_id_carrier] 794 ++ CONJ_TAC >> METIS_TAC [group_linv, group_id_carrier] 795 ++ CONJ_TAC >> METIS_TAC [group_linv, group_id_carrier] 796 ++ CONJ_TAC >> METIS_TAC [group_linv, group_id_carrier] 797 ++ POP_ASSUM (fn th => CONV_TAC (RAND_CONV (REWRITE_CONV [th]))) 798 ++ RW_TAC std_ss [group_linv, group_lid, group_id_carrier]) 799 ++ RW_TAC std_ss [] 800 ++ Suff 801 `field_add f (field_mult f x (field_zero f)) 802 (field_mult f x (field_zero f)) = 803 field_add f (field_zero f) (field_mult f x (field_zero f))` 804 >> RW_TAC alg_ss [] 805 ++ MATCH_MP_TAC EQ_TRANS 806 ++ Q.EXISTS_TAC 807 `field_mult f x (field_add f (field_zero f) (field_zero f))` 808 ++ REVERSE CONJ_TAC 809 >> RW_TAC alg_ss [] 810 ++ MATCH_MP_TAC EQ_SYM 811 ++ match_tac field_distrib_ladd 812 ++ RW_TAC alg_ss []); 813 814val context = subtypeTools.add_rewrite2 field_mult_rzero context; 815val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 816 817val field_mult_rzero' = store_thm 818 ("field_mult_rzero'", 819 ``!f :: Field. !x :: (f.carrier). 820 field_mult f x (field_num f 0) = field_zero f``, 821 RW_TAC alg_ss [field_num_zero]); 822 823val context = subtypeTools.add_rewrite2 field_mult_rzero' context; 824val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 825 826val field_mult_nonzero = store_thm 827 ("field_mult_nonzero", 828 ``!f :: Field. !x y :: field_nonzero f. 829 field_mult f x y IN field_nonzero f``, 830 RW_TAC resq_ss 831 [Field_def, GSPECIFICATION, field_mult_def, AbelianGroup_def, 832 field_nonzero_def] 833 ++ Suff `f.prod.mult x y IN f.prod.carrier` 834 >> RW_TAC std_ss [] 835 ++ match_tac group_mult_carrier 836 ++ RW_TAC std_ss []); 837 838val context = subtypeTools.add_reduction2 field_mult_nonzero context; 839val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 840 841val field_mult_carrier = store_thm 842 ("field_mult_carrier", 843 ``!f :: Field. !x y :: (f.carrier). field_mult f x y IN f.carrier``, 844 RW_TAC resq_ss [] 845 ++ Cases_on `x = field_zero f` 846 >> RW_TAC std_ss [field_mult_lzero] 847 ++ Cases_on `y = field_zero f` 848 >> RW_TAC std_ss [field_mult_rzero] 849 ++ match_tac field_nonzero_carrier 850 ++ RW_TAC std_ss [] 851 ++ match_tac field_mult_nonzero 852 ++ RW_TAC std_ss [field_nonzero_def, IN_DIFF, IN_SING]); 853 854val context = subtypeTools.add_reduction2 field_mult_carrier context; 855val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 856 857val field_mult_assoc = store_thm 858 ("field_mult_assoc", 859 ``!f :: Field. !x y z :: (f.carrier). 860 field_mult f (field_mult f x y) z = field_mult f x (field_mult f y z)``, 861 RW_TAC resq_ss [] 862 ++ Cases_on `x = field_zero f` 863 >> RW_TAC std_ss [field_mult_lzero, field_mult_rzero, field_mult_carrier] 864 ++ Cases_on `y = field_zero f` 865 >> RW_TAC std_ss [field_mult_lzero, field_mult_rzero, field_mult_carrier] 866 ++ Cases_on `z = field_zero f` 867 >> RW_TAC std_ss [field_mult_lzero, field_mult_rzero, field_mult_carrier] 868 ++ Q.UNDISCH_TAC `f IN Field` 869 ++ RW_TAC std_ss 870 [Field_def, GSPECIFICATION, field_add_def, AbelianGroup_def, 871 Group_def, field_mult_def, field_nonzero_def] 872 ++ FIRST_ASSUM match_tac 873 ++ RW_TAC std_ss [IN_DIFF, IN_SING]); 874 875val context = subtypeTools.add_rewrite2'' field_mult_assoc context; 876val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 877 878val field_mult_comm = store_thm 879 ("field_mult_comm", 880 ``!f :: Field. !x y :: (f.carrier). field_mult f x y = field_mult f y x``, 881 RW_TAC resq_ss [] 882 ++ Cases_on `x = field_zero f` 883 >> RW_TAC std_ss [field_mult_lzero, field_mult_rzero] 884 ++ Cases_on `y = field_zero f` 885 >> RW_TAC std_ss [field_mult_lzero, field_mult_rzero] 886 ++ Q.UNDISCH_TAC `f IN Field` 887 ++ RW_TAC std_ss 888 [Field_def, GSPECIFICATION, field_mult_def, AbelianGroup_def, 889 field_nonzero_def] 890 ++ Q.PAT_ASSUM `!x y :: (f.prod.carrier). P x y` match_tac 891 ++ RW_TAC std_ss [IN_DIFF, IN_INSERT, NOT_IN_EMPTY]); 892 893val field_mult_comm' = store_thm 894 ("field_mult_comm'", 895 ``!f :: Field. !x y z :: (f.carrier). 896 field_mult f x (field_mult f y z) = field_mult f y (field_mult f x z)``, 897 RW_TAC resq_ss [] 898 ++ RW_TAC alg_ss [GSYM field_mult_assoc] 899 ++ METIS_TAC [field_mult_comm]); 900 901val field_entire = store_thm 902 ("field_entire", 903 ``!f :: Field. !x y :: (f.carrier). 904 (field_mult f x y = field_zero f) = 905 (x = field_zero f) \/ (y = field_zero f)``, 906 RW_TAC resq_ss [] 907 ++ REVERSE EQ_TAC 908 >> (STRIP_TAC ++ RW_TAC std_ss [field_mult_lzero, field_mult_rzero]) 909 ++ MATCH_MP_TAC (PROVE [] ``(~b ==> ~a) ==> (a ==> b)``) 910 ++ Know `field_mult f x y IN f.carrier` 911 >> METIS_TAC [field_mult_carrier] 912 ++ RW_TAC std_ss [] 913 ++ Q.UNDISCH_TAC `f IN Field` 914 ++ RW_TAC std_ss 915 [Field_def, GSPECIFICATION, AbelianGroup_def, field_nonzero_def] 916 ++ Suff `f.prod.mult x y IN f.prod.carrier` 917 >> RW_TAC std_ss [IN_DIFF, IN_INSERT, NOT_IN_EMPTY, field_mult_def] 918 ++ match_tac group_mult_carrier 919 ++ RW_TAC std_ss [IN_DIFF, IN_INSERT, NOT_IN_EMPTY]); 920 921val context = subtypeTools.add_rewrite2' field_entire context; 922val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 923 924val field_mult_lone = store_thm 925 ("field_mult_lone", 926 ``!f :: Field. !x :: (f.carrier). field_mult f (field_one f) x = x``, 927 RW_TAC resq_ss [] 928 ++ Cases_on `x = field_zero f` 929 >> RW_TAC std_ss [field_mult_rzero, field_one_carrier] 930 ++ Q.UNDISCH_TAC `f IN Field` 931 ++ RW_TAC std_ss 932 [Field_def, GSPECIFICATION, field_mult_def, field_one_def, 933 AbelianGroup_def, field_nonzero_def] 934 ++ match_tac group_lid 935 ++ RW_TAC std_ss [IN_DIFF, IN_INSERT, NOT_IN_EMPTY]); 936 937val context = subtypeTools.add_rewrite2 field_mult_lone context; 938val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 939 940val field_mult_lone' = store_thm 941 ("field_mult_lone'", 942 ``!f :: Field. !x :: (f.carrier). field_mult f (field_num f 1) x = x``, 943 RW_TAC alg_ss [field_num_one]); 944 945val context = subtypeTools.add_rewrite2 field_mult_lone' context; 946val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 947 948val field_mult_rone = store_thm 949 ("field_mult_rone", 950 ``!f :: Field. !x :: (f.carrier). field_mult f x (field_one f) = x``, 951 METIS_TAC [field_mult_lone, field_mult_comm, field_one_carrier]); 952 953val context = subtypeTools.add_rewrite2 field_mult_rone context; 954val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 955 956val field_mult_rone' = store_thm 957 ("field_mult_rone'", 958 ``!f :: Field. !x :: (f.carrier). field_mult f x (field_num f 1) = x``, 959 RW_TAC alg_ss [field_num_one]); 960 961val context = subtypeTools.add_rewrite2 field_mult_rone' context; 962val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 963 964val field_linv = store_thm 965 ("field_linv", 966 ``!f :: Field. !x :: field_nonzero f. 967 field_mult f (field_inv f x) x = field_one f``, 968 RW_TAC resq_ss 969 [Field_def, GSPECIFICATION, field_mult_def, field_one_def, 970 AbelianGroup_def, field_inv_def, field_nonzero_def] 971 ++ match_tac group_linv 972 ++ RW_TAC std_ss []); 973 974val context = subtypeTools.add_rewrite2 field_linv context; 975val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 976 977val field_linv' = store_thm 978 ("field_linv'", 979 ``!f :: Field. !x :: field_nonzero f. !y :: (f.carrier). 980 (field_mult f (field_inv f x) (field_mult f x y) = y)``, 981 RW_TAC resq_ss [] 982 ++ RW_TAC alg_ss [GSYM field_mult_assoc]); 983 984val context = subtypeTools.add_rewrite2 field_linv' context; 985val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 986 987val field_rinv = store_thm 988 ("field_rinv", 989 ``!f :: Field. !x :: field_nonzero f. 990 (field_mult f x (field_inv f x) = field_one f)``, 991 METIS_TAC 992 [field_linv, field_mult_comm, field_inv_nonzero, field_nonzero_carrier]); 993 994val context = subtypeTools.add_rewrite2 field_rinv context; 995val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 996 997val field_rinv' = store_thm 998 ("field_rinv'", 999 ``!f :: Field. !x :: field_nonzero f. !y :: (f.carrier). 1000 (field_mult f x (field_mult f (field_inv f x) y) = y)``, 1001 RW_TAC resq_ss [] 1002 ++ RW_TAC alg_ss [GSYM field_mult_assoc]); 1003 1004val context = subtypeTools.add_rewrite2 field_rinv' context; 1005val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1006 1007val field_mult_lcancel_imp = store_thm 1008 ("field_mult_lcancel_imp", 1009 ``!f :: Field. !x :: field_nonzero f. !y z :: (f.carrier). 1010 (field_mult f x y = field_mult f x z) ==> (y = z)``, 1011 RW_TAC resq_ss [field_nonzero_def, IN_DIFF, IN_SING] 1012 ++ POP_ASSUM MP_TAC 1013 ++ Cases_on `y = field_zero f` 1014 >> RW_TAC std_ss [field_mult_rzero, field_entire] 1015 ++ Cases_on `z = field_zero f` 1016 >> RW_TAC std_ss [field_mult_rzero, field_entire] 1017 ++ Q.UNDISCH_TAC `f IN Field` 1018 ++ RW_TAC std_ss 1019 [field_mult_def, Field_def, GSPECIFICATION, AbelianGroup_def, 1020 field_nonzero_def] 1021 ++ match_tac group_lcancel_imp 1022 ++ Q.EXISTS_TAC `f.prod` 1023 ++ Q.EXISTS_TAC `x` 1024 ++ RW_TAC std_ss [IN_DIFF, IN_INSERT, NOT_IN_EMPTY]); 1025 1026val field_mult_lcancel = store_thm 1027 ("field_mult_lcancel", 1028 ``!f :: Field. !x :: field_nonzero f. !y z :: (f.carrier). 1029 (field_mult f x y = field_mult f x z) = (y = z)``, 1030 METIS_TAC [field_mult_lcancel_imp]); 1031 1032val context = subtypeTools.add_rewrite2' field_mult_lcancel context; 1033val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1034 1035val field_mult_rcancel_imp = store_thm 1036 ("field_mult_rcancel_imp", 1037 ``!f :: Field. !x :: field_nonzero f. !y z :: (f.carrier). 1038 (field_mult f y x = field_mult f z x) ==> (y = z)``, 1039 METIS_TAC [field_mult_lcancel_imp, field_mult_comm, field_nonzero_carrier]); 1040 1041val field_mult_rcancel = store_thm 1042 ("field_mult_rcancel", 1043 ``!f :: Field. !x :: field_nonzero f. !y z :: (f.carrier). 1044 (field_mult f y x = field_mult f z x) = (y = z)``, 1045 METIS_TAC [field_mult_rcancel_imp]); 1046 1047val context = subtypeTools.add_rewrite2' field_mult_rcancel context; 1048val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1049 1050val field_neg_neg = store_thm 1051 ("field_neg_neg", 1052 ``!f :: Field. !x :: (f.carrier). field_neg f (field_neg f x) = x``, 1053 RW_TAC resq_ss [field_neg_def, Field_def, GSPECIFICATION, AbelianGroup_def] 1054 ++ METIS_TAC [group_inv_inv]); 1055 1056val context = subtypeTools.add_rewrite2 field_neg_neg context; 1057val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1058 1059val field_neg_cancel = store_thm 1060 ("field_neg_cancel", 1061 ``!f :: Field. !x y :: (f.carrier). 1062 (field_neg f x = field_neg f y) = (x = y)``, 1063 RW_TAC resq_ss [field_neg_def, Field_def, GSPECIFICATION, AbelianGroup_def] 1064 ++ METIS_TAC [group_inv_cancel]); 1065 1066val context = subtypeTools.add_rewrite2 field_neg_cancel context; 1067val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1068 1069val field_neg_cancel_imp = store_thm 1070 ("field_neg_cancel_imp", 1071 ``!f :: Field. !x y :: (f.carrier). 1072 (field_neg f x = field_neg f y) ==> (x = y)``, 1073 METIS_TAC [field_neg_cancel]); 1074 1075val field_neg_eq_swap_imp = store_thm 1076 ("field_neg_eq_swap_imp", 1077 ``!f :: Field. !x y :: (f.carrier). 1078 (field_neg f x = y) ==> (x = field_neg f y)``, 1079 METIS_TAC [field_neg_neg]); 1080 1081val field_neg_eq_swap = store_thm 1082 ("field_neg_eq_swap", 1083 ``!f :: Field. !x y :: (f.carrier). 1084 (field_neg f x = y) = (x = field_neg f y)``, 1085 METIS_TAC [field_neg_eq_swap_imp]); 1086 1087val field_neg_eq_swap_imp' = store_thm 1088 ("field_neg_eq_swap_imp'", 1089 ``!f :: Field. !x y :: (f.carrier). 1090 (x = field_neg f y) ==> (field_neg f x = y)``, 1091 METIS_TAC [field_neg_eq_swap]); 1092 1093val field_neg_eq_imp = store_thm 1094 ("field_neg_eq_imp", 1095 ``!f :: Field. !x y :: (f.carrier). 1096 (field_neg f x = y) ==> (field_add f x y = field_zero f)``, 1097 RW_TAC resq_ss [field_rneg]); 1098 1099val field_neg_eq_imp' = store_thm 1100 ("field_neg_eq_imp'", 1101 ``!f :: Field. !x y :: (f.carrier). 1102 (field_add f x y = field_zero f) ==> (field_neg f x = y)``, 1103 RW_TAC resq_ss [] 1104 ++ match_tac field_add_lcancel_imp 1105 ++ Q.EXISTS_TAC `f` 1106 ++ Q.EXISTS_TAC `x` 1107 ++ RW_TAC std_ss [field_neg_carrier, field_rneg]); 1108 1109val field_neg_eq = store_thm 1110 ("field_neg_eq", 1111 ``!f :: Field. !x y :: (f.carrier). 1112 (field_neg f x = y) = (field_add f x y = field_zero f)``, 1113 METIS_TAC [field_neg_eq_imp, field_neg_eq_imp']); 1114 1115val field_neg_zero = store_thm 1116 ("field_neg_zero", 1117 ``!f :: Field. field_neg f (field_zero f) = field_zero f``, 1118 RW_TAC resq_ss 1119 [Field_def, GSPECIFICATION, AbelianGroup_def, field_zero_def, 1120 field_neg_def] 1121 ++ METIS_TAC [group_inv_id]); 1122 1123val context = subtypeTools.add_rewrite2 field_neg_zero context; 1124val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1125 1126val field_add_eq = store_thm 1127 ("field_add_eq", 1128 ``!f x1 y1 x2 y2. 1129 (x1 = x2) /\ (y1 = y2) ==> (field_add f x1 y1 = field_add f x2 y2)``, 1130 RW_TAC std_ss []); 1131 1132val field_distrib_radd = store_thm 1133 ("field_distrib_radd", 1134 ``!f :: Field. !x y z :: (f.carrier). 1135 field_mult f (field_add f y z) x = 1136 field_add f (field_mult f y x) (field_mult f z x)``, 1137 RW_TAC resq_ss [] 1138 ++ METIS_TAC [field_mult_comm, field_add_carrier, field_distrib_ladd]); 1139 1140(*** 1141val context = subtypeTools.add_rewrite2'' field_distrib_radd context; 1142val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1143***) 1144 1145val field_distrib = save_thm 1146 ("field_distrib", CONJ field_distrib_ladd field_distrib_radd); 1147 1148val field_mult_lneg = store_thm 1149 ("field_mult_lneg", 1150 ``!f :: Field. !x y :: (f.carrier). 1151 field_mult f (field_neg f x) y = field_neg f (field_mult f x y)``, 1152 RW_TAC resq_ss [] 1153 ++ match_tac (GSYM field_neg_eq_imp') 1154 ++ RW_TAC std_ss [field_mult_carrier, field_neg_carrier] 1155 ++ RW_TAC std_ss 1156 [GSYM field_distrib_radd, field_neg_carrier, field_rneg, 1157 field_mult_lzero]); 1158 1159val context = subtypeTools.add_rewrite2 field_mult_lneg context; 1160val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1161 1162val field_mult_rneg = store_thm 1163 ("field_mult_rneg", 1164 ``!f :: Field. !x y :: (f.carrier). 1165 field_mult f x (field_neg f y) = field_neg f (field_mult f x y)``, 1166 METIS_TAC [field_mult_lneg, field_mult_comm, field_neg_carrier]); 1167 1168val context = subtypeTools.add_rewrite2 field_mult_rneg context; 1169val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1170 1171val field_inv_mult' = store_thm 1172 ("field_inv_mult'", 1173 ``!f :: Field. !x y :: field_nonzero f. 1174 field_inv f (field_mult f x y) = 1175 field_mult f (field_inv f y) (field_inv f x)``, 1176 RW_TAC resq_ss 1177 [field_mult_def, Field_def, GSPECIFICATION, field_inv_def, 1178 AbelianGroup_def, field_nonzero_def] 1179 ++ match_tac group_inv_mult 1180 ++ RW_TAC std_ss []); 1181 1182val field_inv_mult = store_thm 1183 ("field_inv_mult", 1184 ``!f :: Field. !x y :: field_nonzero f. 1185 field_inv f (field_mult f x y) = 1186 field_mult f (field_inv f x) (field_inv f y)``, 1187 METIS_TAC [field_inv_nonzero, field_nonzero_carrier, field_mult_comm, 1188 field_inv_mult']); 1189 1190val context = subtypeTools.add_rewrite2'' field_inv_mult context; 1191val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1192 1193val field_exp_carrier = store_thm 1194 ("field_exp_carrier", 1195 ``!f :: Field. !x :: (f.carrier). !n. field_exp f x n IN f.carrier``, 1196 RW_TAC resq_ss [] 1197 ++ Induct_on `n` 1198 ++ RW_TAC std_ss [field_exp_def, field_one_carrier, field_mult_carrier]); 1199 1200val context = subtypeTools.add_reduction2 field_exp_carrier context; 1201val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1202 1203val field_exp_nonzero = store_thm 1204 ("field_exp_nonzero", 1205 ``!f :: Field. !x :: field_nonzero f. !n. 1206 field_exp f x n IN field_nonzero f``, 1207 RW_TAC resq_ss [] 1208 ++ Induct_on `n` 1209 ++ RW_TAC std_ss [field_exp_def, field_one_nonzero, field_mult_nonzero]); 1210 1211val context = subtypeTools.add_reduction2 field_exp_nonzero context; 1212val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1213 1214val field_num_carrier = store_thm 1215 ("field_num_carrier", 1216 ``!f :: Field. !n. field_num f n IN f.carrier``, 1217 RW_TAC resq_ss [] 1218 ++ Induct_on `n` 1219 ++ RW_TAC alg_ss [field_num_def]); 1220 1221val context = subtypeTools.add_reduction2 field_num_carrier context; 1222val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1223 1224val field_mult_small = store_thm 1225 ("field_mult_small", 1226 ``!f :: Field. !x :: (f.carrier). 1227 (field_mult f (field_num f 0) x = field_zero f) /\ 1228 (field_mult f (field_num f 1) x = x) /\ 1229 (field_mult f (field_num f 2) x = field_add f x x) /\ 1230 (field_mult f (field_num f 3) x = 1231 field_add f x (field_mult f (field_num f 2) x))``, 1232 RW_TAC (simpLib.++ (std_ss, numSimps.SUC_FILTER_ss)) [field_num_def] 1233 ++ RW_TAC alg_ss [field_distrib_radd, field_add_assoc]); 1234 1235val field_exp_small = store_thm 1236 ("field_exp_small", 1237 ``!f :: Field. !x :: (f.carrier). 1238 (field_exp f x 0 = field_one f) /\ 1239 (field_exp f x 1 = x) /\ 1240 (field_exp f x 2 = field_mult f x x) /\ 1241 (field_exp f x 3 = field_mult f x (field_exp f x 2)) /\ 1242 (field_exp f x 4 = field_mult f x (field_exp f x 3)) /\ 1243 (field_exp f x 5 = field_mult f x (field_exp f x 4)) /\ 1244 (field_exp f x 6 = field_mult f x (field_exp f x 5)) /\ 1245 (field_exp f x 7 = field_mult f x (field_exp f x 6)) /\ 1246 (field_exp f x 8 = field_mult f x (field_exp f x 7)) /\ 1247 (field_exp f x 9 = field_mult f x (field_exp f x 8))``, 1248 RW_TAC (simpLib.++ (std_ss, numSimps.SUC_FILTER_ss)) 1249 [field_exp_def, field_mult_rone]); 1250 1251val field_inv_one = store_thm 1252 ("field_inv_one", 1253 ``!f :: Field. field_inv f (field_one f) = field_one f``, 1254 RW_TAC resq_ss [field_inv_def, field_one_def, Field_def, GSPECIFICATION] 1255 ++ RW_TAC alg_ss []); 1256 1257val context = subtypeTools.add_rewrite2 field_inv_one context; 1258val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1259 1260val field_exp_zero = store_thm 1261 ("field_exp_zero", 1262 ``!f :: Field. !x :: (f.carrier). field_exp f x 0 = field_one f``, 1263 RW_TAC alg_ss [field_exp_def]); 1264 1265val context = subtypeTools.add_rewrite2 field_exp_zero context; 1266val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1267 1268val field_exp_one = store_thm 1269 ("field_exp_one", 1270 ``!f :: Field. !x :: (f.carrier). field_exp f x 1 = x``, 1271 REWRITE_TAC [ONE, field_exp_def] 1272 ++ RW_TAC alg_ss []); 1273 1274val context = subtypeTools.add_rewrite2 field_exp_one context; 1275val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1276 1277val field_neg_add' = store_thm 1278 ("field_neg_add'", 1279 ``!f :: Field. !x y :: (f.carrier). 1280 field_neg f (field_add f x y) = 1281 field_add f (field_neg f y) (field_neg f x)``, 1282 RW_TAC resq_ss 1283 [field_add_def, Field_def, GSPECIFICATION, field_neg_def, 1284 AbelianGroup_def] 1285 ++ match_tac group_inv_mult 1286 ++ RW_TAC std_ss []); 1287 1288val field_neg_add = store_thm 1289 ("field_neg_add", 1290 ``!f :: Field. !x y :: (f.carrier). 1291 field_neg f (field_add f x y) = 1292 field_add f (field_neg f x) (field_neg f y)``, 1293 METIS_TAC [field_neg_carrier, field_add_comm, field_neg_add']); 1294 1295val context = subtypeTools.add_rewrite2'' field_neg_add context; 1296val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1297 1298val field_exp_suc = store_thm 1299 ("field_exp_suc", 1300 ``!f :: Field. !x :: (f.carrier). !n. 1301 field_exp f x (SUC n) = field_mult f (field_exp f x n) x``, 1302 RW_TAC alg_ss [field_exp_def] 1303 ++ METIS_TAC [field_mult_comm, field_exp_carrier]); 1304 1305val field_num_suc = store_thm 1306 ("field_num_suc", 1307 ``!f :: Field. !n. 1308 field_num f (SUC n) = field_add f (field_one f) (field_num f n)``, 1309 RW_TAC alg_ss [field_num_def] 1310 ++ METIS_TAC [field_add_comm, field_one_carrier, field_num_carrier]); 1311 1312val field_num_add = store_thm 1313 ("field_num_add", 1314 ``!f :: Field. !m n. 1315 field_add f (field_num f m) (field_num f n) = field_num f (m + n)``, 1316 RW_TAC resq_ss [] 1317 ++ Induct_on `m` 1318 ++ RW_TAC alg_ss [] 1319 ++ RW_TAC alg_ss [field_num_suc, ADD, field_add_assoc]); 1320 1321val context = subtypeTools.add_rewrite2 field_num_add context; 1322val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1323 1324val field_num_add' = store_thm 1325 ("field_num_add'", 1326 ``!f :: Field. !m n. !x :: (f.carrier). 1327 field_add f (field_num f m) (field_add f (field_num f n) x) = 1328 field_add f (field_num f (m + n)) x``, 1329 RW_TAC alg_ss [GSYM field_add_assoc, field_num_add]); 1330 1331val context = subtypeTools.add_rewrite2'' field_num_add' context; 1332val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1333 1334val field_num_mult = store_thm 1335 ("field_num_mult", 1336 ``!f :: Field. !m n. 1337 field_mult f (field_num f m) (field_num f n) = field_num f (m * n)``, 1338 RW_TAC resq_ss [] 1339 ++ Induct_on `m` 1340 ++ RW_TAC alg_ss [] 1341 ++ RW_TAC alg_ss [field_num_def, MULT, field_distrib_radd]); 1342 1343val context = subtypeTools.add_rewrite2 field_num_mult context; 1344val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1345 1346val field_num_mult' = store_thm 1347 ("field_num_mult'", 1348 ``!f :: Field. !m n. !x :: (f.carrier). 1349 field_mult f (field_num f m) (field_mult f (field_num f n) x) = 1350 field_mult f (field_num f (m * n)) x``, 1351 RW_TAC alg_ss [GSYM field_mult_assoc, field_num_mult]); 1352 1353val context = subtypeTools.add_rewrite2'' field_num_mult' context; 1354val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1355 1356val field_num_exp = store_thm 1357 ("field_num_exp", 1358 ``!f :: Field. !m n. 1359 field_exp f (field_num f m) n = field_num f (m ** n)``, 1360 RW_TAC resq_ss [] 1361 ++ Induct_on `n` 1362 ++ RW_TAC alg_ss [EXP, field_num_one, field_exp_def]); 1363 1364val context = subtypeTools.add_rewrite2 field_num_exp context; 1365val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1366 1367val field_single_add_single = store_thm 1368 ("field_single_add_single", 1369 ``!f :: Field. !x :: (f.carrier). 1370 field_add f x x = field_mult f (field_num f 2) x``, 1371 RW_TAC alg_ss [field_mult_small]); 1372 1373val context = subtypeTools.add_rewrite2'' field_single_add_single context; 1374val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1375 1376val field_single_add_single' = store_thm 1377 ("field_single_add_single'", 1378 ``!f :: Field. !x y :: (f.carrier). 1379 field_add f x (field_add f x y) = 1380 field_add f (field_mult f (field_num f 2) x) y``, 1381 RW_TAC alg_ss [GSYM field_add_assoc, field_single_add_single]); 1382 1383val context = subtypeTools.add_rewrite2'' field_single_add_single' context; 1384val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1385 1386val field_single_add_mult = store_thm 1387 ("field_single_add_mult", 1388 ``!f :: Field. !x :: (f.carrier). !n. 1389 field_add f x (field_mult f (field_num f n) x) = 1390 field_mult f (field_num f (n + 1)) x``, 1391 RW_TAC bool_ss [field_num_suc, GSYM ADD1] 1392 ++ RW_TAC alg_ss [field_distrib_radd]); 1393 1394val context = subtypeTools.add_rewrite2'' field_single_add_mult context; 1395val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1396 1397val field_single_add_mult' = store_thm 1398 ("field_single_add_mult'", 1399 ``!f :: Field. !x y :: (f.carrier). !n. 1400 field_add f x (field_add f (field_mult f (field_num f n) x) y) = 1401 field_add f (field_mult f (field_num f (n + 1)) x) y``, 1402 RW_TAC alg_ss [GSYM field_add_assoc, field_single_add_mult]); 1403 1404val context = subtypeTools.add_rewrite2'' field_single_add_mult' context; 1405val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1406 1407val field_single_add_neg_mult = store_thm 1408 ("field_single_add_neg_mult", 1409 ``!f :: Field. !x :: (f.carrier). !n. 1410 field_add f x (field_neg f (field_mult f (field_num f n) x)) = 1411 (if n = 0 then x 1412 else field_neg f (field_mult f (field_num f (n - 1)) x))``, 1413 RW_TAC resq_ss [] 1414 ++ RW_TAC alg_ss [] 1415 ++ Cases_on `n` 1416 ++ RW_TAC alg_ss [] 1417 ++ RW_TAC alg_ss [field_num_suc, field_distrib_radd] 1418 ++ RW_TAC alg_ss [field_neg_add, GSYM field_add_assoc]); 1419 1420val context = subtypeTools.add_rewrite2'' field_single_add_neg_mult context; 1421val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1422 1423val field_single_add_neg_mult' = store_thm 1424 ("field_single_add_neg_mult'", 1425 ``!f :: Field. !x y :: (f.carrier). !n. 1426 field_add f x 1427 (field_add f (field_neg f (field_mult f (field_num f n) x)) y) = 1428 (if n = 0 then field_add f x y 1429 else field_add f 1430 (field_neg f (field_mult f (field_num f (n - 1)) x)) y)``, 1431 RW_TAC alg_ss [GSYM field_add_assoc, field_single_add_neg_mult] 1432 ++ RW_TAC resq_ss [] 1433 ++ RW_TAC resq_ss []); 1434 1435val context = subtypeTools.add_rewrite2'' field_single_add_neg_mult' context; 1436val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1437 1438val field_mult_add_mult = store_thm 1439 ("field_mult_add_mult", 1440 ``!f :: Field. !x :: (f.carrier). !m n. 1441 field_add f (field_mult f (field_num f m) x) 1442 (field_mult f (field_num f n) x) = 1443 field_mult f (field_num f (m + n)) x``, 1444 RW_TAC resq_ss [] 1445 ++ Induct_on `m` 1446 ++ RW_TAC alg_ss [] 1447 ++ RW_TAC alg_ss [field_num_suc, field_distrib_radd, ADD] 1448 ++ POP_ASSUM (fn th => REWRITE_TAC [GSYM th]) 1449 ++ RW_TAC alg_ss [field_add_assoc]); 1450 1451val context = subtypeTools.add_rewrite2'' field_mult_add_mult context; 1452val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1453 1454val field_mult_add_mult' = store_thm 1455 ("field_mult_add_mult'", 1456 ``!f :: Field. !x y :: (f.carrier). !m n. 1457 field_add f (field_mult f (field_num f m) x) 1458 (field_add f (field_mult f (field_num f n) x) y) = 1459 field_add f (field_mult f (field_num f (m + n)) x) y``, 1460 RW_TAC alg_ss [GSYM field_add_assoc, field_mult_add_mult]); 1461 1462val context = subtypeTools.add_rewrite2'' field_mult_add_mult' context; 1463val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1464 1465val field_mult_add_neg = store_thm 1466 ("field_mult_add_neg", 1467 ``!f :: Field. !x :: (f.carrier). !n. 1468 field_add f (field_mult f (field_num f n) x) (field_neg f x) = 1469 (if n = 0 then field_neg f x 1470 else field_mult f (field_num f (n - 1)) x)``, 1471 RW_TAC resq_ss [] 1472 ++ RW_TAC alg_ss [] 1473 ++ Cases_on `n` 1474 ++ RW_TAC alg_ss [] 1475 ++ RW_TAC alg_ss [field_num_def, field_distrib_radd, field_add_assoc]); 1476 1477val context = subtypeTools.add_rewrite2'' field_mult_add_neg context; 1478val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1479 1480val field_mult_add_neg' = store_thm 1481 ("field_mult_add_neg'", 1482 ``!f :: Field. !x y :: (f.carrier). !n. 1483 field_add f (field_mult f (field_num f n) x) 1484 (field_add f (field_neg f x) y) = 1485 (if n = 0 then field_add f (field_neg f x) y 1486 else field_add f (field_mult f (field_num f (n - 1)) x) y)``, 1487 RW_TAC alg_ss [GSYM field_add_assoc, field_mult_add_neg] 1488 ++ RW_TAC resq_ss [] 1489 ++ RW_TAC resq_ss []); 1490 1491val context = subtypeTools.add_rewrite2'' field_mult_add_neg' context; 1492val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1493 1494val field_mult_add_neg_mult = store_thm 1495 ("field_mult_add_neg_mult", 1496 ``!f :: Field. !x :: (f.carrier). !m n. 1497 field_add f (field_mult f (field_num f m) x) 1498 (field_neg f (field_mult f (field_num f n) x)) = 1499 (if m < n then field_neg f (field_mult f (field_num f (n - m)) x) 1500 else field_mult f (field_num f (m - n)) x)``, 1501 RW_TAC resq_ss [] 1502 ++ RW_TAC alg_ss [] 1503 << [Know `m <= n` >> DECIDE_TAC 1504 ++ POP_ASSUM (K ALL_TAC) 1505 ++ Induct_on `m` 1506 ++ RW_TAC alg_ss [] 1507 ++ Cases_on `n = SUC m` >> RW_TAC alg_ss' [] 1508 ++ Q.PAT_ASSUM `X ==> Y` MP_TAC 1509 ++ MATCH_MP_TAC (PROVE [] ``a /\ (b ==> c) ==> ((a ==> b) ==> c)``) 1510 ++ CONJ_TAC >> DECIDE_TAC 1511 ++ RW_TAC alg_ss [field_num_suc, field_distrib_radd, field_add_assoc] 1512 ++ Know `n - m = SUC (n - SUC m)` >> DECIDE_TAC 1513 ++ RW_TAC alg_ss [field_num_suc, field_distrib_radd, 1514 GSYM field_add_assoc, field_neg_add], 1515 Know `n <= m` >> DECIDE_TAC 1516 ++ POP_ASSUM (K ALL_TAC) 1517 ++ Induct_on `m` 1518 ++ RW_TAC alg_ss [] 1519 ++ Cases_on `n = SUC m` >> RW_TAC alg_ss' [] 1520 ++ Q.PAT_ASSUM `X ==> Y` MP_TAC 1521 ++ MATCH_MP_TAC (PROVE [] ``a /\ (b ==> c) ==> ((a ==> b) ==> c)``) 1522 ++ CONJ_TAC >> DECIDE_TAC 1523 ++ RW_TAC alg_ss [field_num_suc, field_distrib_radd, field_add_assoc] 1524 ++ Know `SUC m - n = SUC (m - n)` >> DECIDE_TAC 1525 ++ RW_TAC alg_ss [field_num_suc, field_distrib_radd, 1526 GSYM field_add_assoc, field_neg_add]]); 1527 1528val context = subtypeTools.add_rewrite2'' field_mult_add_neg_mult context; 1529val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1530 1531val field_mult_add_neg_mult' = store_thm 1532 ("field_mult_add_neg_mult'", 1533 ``!f :: Field. !x y :: (f.carrier). !m n. 1534 field_add f (field_mult f (field_num f m) x) 1535 (field_add f (field_neg f (field_mult f (field_num f n) x)) y) = 1536 (if m < n then 1537 field_add f (field_neg f (field_mult f (field_num f (n - m)) x)) y 1538 else field_add f (field_mult f (field_num f (m - n)) x) y)``, 1539 RW_TAC alg_ss [GSYM field_add_assoc, field_mult_add_neg_mult] 1540 ++ RW_TAC resq_ss [] 1541 ++ RW_TAC resq_ss []); 1542 1543val context = subtypeTools.add_rewrite2'' field_mult_add_neg_mult' context; 1544val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1545 1546val field_neg_add_neg = store_thm 1547 ("field_neg_add_neg", 1548 ``!f :: Field. !x :: (f.carrier). 1549 field_add f (field_neg f x) (field_neg f x) = 1550 field_neg f (field_mult f (field_num f 2) x)``, 1551 RW_TAC alg_ss [field_mult_small, field_neg_add]); 1552 1553val context = subtypeTools.add_rewrite2'' field_neg_add_neg context; 1554val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1555 1556val field_neg_add_neg' = store_thm 1557 ("field_neg_add_neg'", 1558 ``!f :: Field. !x y :: (f.carrier). 1559 field_add f (field_neg f x) (field_add f (field_neg f x) y) = 1560 field_add f (field_neg f (field_mult f (field_num f 2) x)) y``, 1561 RW_TAC alg_ss [GSYM field_add_assoc, field_neg_add_neg]); 1562 1563val context = subtypeTools.add_rewrite2'' field_neg_add_neg' context; 1564val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1565 1566val field_neg_add_neg_mult = store_thm 1567 ("field_neg_add_neg_mult", 1568 ``!f :: Field. !x :: (f.carrier). !n. 1569 field_add f (field_neg f x) 1570 (field_neg f (field_mult f (field_num f n) x)) = 1571 field_neg f (field_mult f (field_num f (n + 1)) x)``, 1572 RW_TAC alg_ss [GSYM field_single_add_mult] 1573 ++ RW_TAC alg_ss' []); 1574 1575val context = subtypeTools.add_rewrite2'' field_neg_add_neg_mult context; 1576val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1577 1578val field_neg_add_neg_mult' = store_thm 1579 ("field_neg_add_neg_mult'", 1580 ``!f :: Field. !x y :: (f.carrier). !n. 1581 field_add f (field_neg f x) 1582 (field_add f (field_neg f (field_mult f (field_num f n) x)) y) = 1583 field_add f (field_neg f (field_mult f (field_num f (n + 1)) x)) y``, 1584 RW_TAC alg_ss [GSYM field_add_assoc, field_neg_add_neg_mult]); 1585 1586val context = subtypeTools.add_rewrite2'' field_neg_add_neg_mult' context; 1587val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1588 1589val field_neg_mult_add_neg_mult = store_thm 1590 ("field_neg_mult_add_neg_mult", 1591 ``!f :: Field. !x :: (f.carrier). !m n. 1592 field_add f (field_neg f (field_mult f (field_num f m) x)) 1593 (field_neg f (field_mult f (field_num f n) x)) = 1594 field_neg f (field_mult f (field_num f (m + n)) x)``, 1595 RW_TAC resq_ss [] 1596 ++ Induct_on `m` 1597 ++ RW_TAC alg_ss [] 1598 ++ RW_TAC alg_ss [field_num_suc, field_distrib_radd, ADD, field_neg_add] 1599 ++ POP_ASSUM (fn th => REWRITE_TAC [GSYM th]) 1600 ++ RW_TAC alg_ss [field_add_assoc]); 1601 1602val context = subtypeTools.add_rewrite2'' field_neg_mult_add_neg_mult context; 1603val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1604 1605val field_neg_mult_add_neg_mult' = store_thm 1606 ("field_neg_mult_add_neg_mult'", 1607 ``!f :: Field. !x y :: (f.carrier). !m n. 1608 field_add f (field_neg f (field_mult f (field_num f m) x)) 1609 (field_add f (field_neg f (field_mult f (field_num f n) x)) y) = 1610 field_add f (field_neg f (field_mult f (field_num f (m + n)) x)) y``, 1611 RW_TAC alg_ss [GSYM field_add_assoc, field_neg_mult_add_neg_mult]); 1612 1613val context = subtypeTools.add_rewrite2'' field_neg_mult_add_neg_mult' context; 1614val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1615 1616val field_single_mult_single = store_thm 1617 ("field_single_mult_single", 1618 ``!f :: Field. !x :: (f.carrier). field_mult f x x = field_exp f x 2``, 1619 RW_TAC alg_ss' [field_exp_small]); 1620 1621val context = subtypeTools.add_rewrite2'' field_single_mult_single context; 1622val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1623 1624val field_single_mult_single' = store_thm 1625 ("field_single_mult_single'", 1626 ``!f :: Field. !x y :: (f.carrier). 1627 field_mult f x (field_mult f x y) = field_mult f (field_exp f x 2) y``, 1628 RW_TAC alg_ss [GSYM field_mult_assoc, field_single_mult_single]); 1629 1630val context = subtypeTools.add_rewrite2'' field_single_mult_single' context; 1631val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1632 1633val field_single_mult_exp = store_thm 1634 ("field_single_mult_exp", 1635 ``!f :: Field. !x :: (f.carrier). !n. 1636 field_mult f x (field_exp f x n) = field_exp f x (n + 1)``, 1637 METIS_TAC [field_exp_def, ADD1]); 1638 1639val context = subtypeTools.add_rewrite2'' field_single_mult_exp context; 1640val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1641 1642val field_single_mult_exp' = store_thm 1643 ("field_single_mult_exp'", 1644 ``!f :: Field. !x y :: (f.carrier). !n. 1645 field_mult f x (field_mult f (field_exp f x n) y) = 1646 field_mult f (field_exp f x (n + 1)) y``, 1647 RW_TAC alg_ss [GSYM field_mult_assoc, field_single_mult_exp]); 1648 1649val context = subtypeTools.add_rewrite2'' field_single_mult_exp' context; 1650val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1651 1652val field_single_mult_inv_exp = store_thm 1653 ("field_single_mult_inv_exp", 1654 ``!f :: Field. !x :: field_nonzero f. !n. 1655 field_mult f x (field_inv f (field_exp f x n)) = 1656 (if n = 0 then x else field_inv f (field_exp f x (n - 1)))``, 1657 RW_TAC resq_ss [] 1658 ++ RW_TAC alg_ss [] 1659 ++ Cases_on `n` 1660 ++ RW_TAC alg_ss [] 1661 ++ RW_TAC alg_ss [field_exp_def, GSYM field_mult_assoc, field_inv_mult]); 1662 1663val context = subtypeTools.add_rewrite2'' field_single_mult_inv_exp context; 1664val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1665 1666val field_single_mult_inv_exp' = store_thm 1667 ("field_single_mult_inv_exp'", 1668 ``!f :: Field. !x :: field_nonzero f. !n. !y :: (f.carrier). 1669 field_mult f x (field_mult f (field_inv f (field_exp f x n)) y) = 1670 (if n = 0 then field_mult f x y 1671 else field_mult f (field_inv f (field_exp f x (n - 1))) y)``, 1672 RW_TAC alg_ss [GSYM field_mult_assoc, field_single_mult_inv_exp] 1673 ++ RW_TAC resq_ss [] 1674 ++ RW_TAC resq_ss []); 1675 1676val context = subtypeTools.add_rewrite2'' field_single_mult_inv_exp' context; 1677val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1678 1679val field_exp_mult_exp = store_thm 1680 ("field_exp_mult_exp", 1681 ``!f :: Field. !x :: (f.carrier). !m n. 1682 field_mult f (field_exp f x m) (field_exp f x n) = 1683 field_exp f x (m + n)``, 1684 RW_TAC resq_ss [] 1685 ++ Induct_on `m` 1686 ++ RW_TAC alg_ss [] 1687 ++ RW_TAC alg_ss [field_exp_def, ADD_CLAUSES] 1688 ++ POP_ASSUM (fn th => REWRITE_TAC [GSYM th]) 1689 ++ RW_TAC alg_ss [field_mult_assoc]); 1690 1691val context = subtypeTools.add_rewrite2'' field_exp_mult_exp context; 1692val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1693 1694val field_exp_mult_exp' = store_thm 1695 ("field_exp_mult_exp'", 1696 ``!f :: Field. !x y :: (f.carrier). !m n. 1697 field_mult f (field_exp f x m) (field_mult f (field_exp f x n) y) = 1698 field_mult f (field_exp f x (m + n)) y``, 1699 RW_TAC alg_ss [GSYM field_mult_assoc, field_exp_mult_exp]); 1700 1701val context = subtypeTools.add_rewrite2'' field_exp_mult_exp' context; 1702val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1703 1704val field_exp_mult_inv = store_thm 1705 ("field_exp_mult_inv", 1706 ``!f :: Field. !x :: field_nonzero f. !n. 1707 field_mult f (field_exp f x n) (field_inv f x) = 1708 (if n = 0 then field_inv f x else field_exp f x (n - 1))``, 1709 RW_TAC resq_ss [] 1710 ++ RW_TAC alg_ss [] 1711 ++ Cases_on `n` 1712 ++ RW_TAC alg_ss [] 1713 ++ RW_TAC alg_ss [field_exp_suc, field_mult_assoc]); 1714 1715val context = subtypeTools.add_rewrite2'' field_exp_mult_inv context; 1716val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1717 1718val field_exp_mult_inv' = store_thm 1719 ("field_exp_mult_inv'", 1720 ``!f :: Field. !x :: field_nonzero f. !n. !y :: (f.carrier). 1721 field_mult f (field_exp f x n) (field_mult f (field_inv f x) y) = 1722 (if n = 0 then field_mult f (field_inv f x) y 1723 else field_mult f (field_exp f x (n - 1)) y)``, 1724 RW_TAC alg_ss [GSYM field_mult_assoc, field_exp_mult_inv] 1725 ++ RW_TAC resq_ss [] 1726 ++ RW_TAC resq_ss []); 1727 1728val context = subtypeTools.add_rewrite2'' field_exp_mult_inv' context; 1729val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1730 1731val field_exp_mult_inv_exp = store_thm 1732 ("field_exp_mult_inv_exp", 1733 ``!f :: Field. !x :: field_nonzero f. !m n. 1734 field_mult f (field_exp f x m) (field_inv f (field_exp f x n)) = 1735 (if m < n then field_inv f (field_exp f x (n - m)) 1736 else field_exp f x (m - n))``, 1737 RW_TAC resq_ss [] 1738 ++ RW_TAC alg_ss [] 1739 << [Know `m <= n` >> DECIDE_TAC 1740 ++ POP_ASSUM (K ALL_TAC) 1741 ++ Induct_on `m` 1742 ++ RW_TAC alg_ss [] 1743 ++ Cases_on `n = SUC m` >> RW_TAC alg_ss [] 1744 ++ Q.PAT_ASSUM `X ==> Y` MP_TAC 1745 ++ MATCH_MP_TAC (PROVE [] ``a /\ (b ==> c) ==> ((a ==> b) ==> c)``) 1746 ++ CONJ_TAC >> DECIDE_TAC 1747 ++ RW_TAC alg_ss [field_exp_def, field_mult_assoc] 1748 ++ Know `n - m = SUC (n - SUC m)` >> DECIDE_TAC 1749 ++ RW_TAC alg_ss [field_exp_def, GSYM field_mult_assoc, field_inv_mult], 1750 Know `n <= m` >> DECIDE_TAC 1751 ++ POP_ASSUM (K ALL_TAC) 1752 ++ Induct_on `m` 1753 ++ RW_TAC alg_ss [] 1754 ++ Cases_on `n = SUC m` >> RW_TAC alg_ss [] 1755 ++ Q.PAT_ASSUM `X ==> Y` MP_TAC 1756 ++ MATCH_MP_TAC (PROVE [] ``a /\ (b ==> c) ==> ((a ==> b) ==> c)``) 1757 ++ CONJ_TAC >> DECIDE_TAC 1758 ++ RW_TAC alg_ss [field_exp_def, field_mult_assoc] 1759 ++ Know `SUC m - n = SUC (m - n)` >> DECIDE_TAC 1760 ++ RW_TAC alg_ss [field_exp_def, GSYM field_mult_assoc]]); 1761 1762val context = subtypeTools.add_rewrite2'' field_exp_mult_inv_exp context; 1763val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1764 1765val field_exp_mult_inv_exp' = store_thm 1766 ("field_exp_mult_inv_exp'", 1767 ``!f :: Field. !x :: field_nonzero f. !m n. !y :: (f.carrier). 1768 field_mult f (field_exp f x m) 1769 (field_mult f (field_inv f (field_exp f x n)) y) = 1770 (if m < n then field_mult f (field_inv f (field_exp f x (n - m))) y 1771 else field_mult f (field_exp f x (m - n)) y)``, 1772 RW_TAC alg_ss [GSYM field_mult_assoc, field_exp_mult_inv_exp] 1773 ++ RW_TAC resq_ss [] 1774 ++ RW_TAC resq_ss []); 1775 1776val context = subtypeTools.add_rewrite2'' field_exp_mult_inv_exp' context; 1777val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1778 1779val field_inv_mult_inv = store_thm 1780 ("field_inv_mult_inv", 1781 ``!f :: Field. !x :: field_nonzero f. 1782 field_mult f (field_inv f x) (field_inv f x) = 1783 field_inv f (field_exp f x 2)``, 1784 RW_TAC alg_ss [field_exp_small, field_inv_mult]); 1785 1786val context = subtypeTools.add_rewrite2'' field_inv_mult_inv context; 1787val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1788 1789val field_inv_mult_inv' = store_thm 1790 ("field_inv_mult_inv'", 1791 ``!f :: Field. !x :: field_nonzero f. !y :: (f.carrier). 1792 field_mult f (field_inv f x) (field_mult f (field_inv f x) y) = 1793 field_mult f (field_inv f (field_exp f x 2)) y``, 1794 RW_TAC alg_ss [GSYM field_mult_assoc, field_inv_mult_inv]); 1795 1796val context = subtypeTools.add_rewrite2'' field_inv_mult_inv' context; 1797val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1798 1799val field_inv_mult_inv_exp = store_thm 1800 ("field_inv_mult_inv_exp", 1801 ``!f :: Field. !x :: field_nonzero f. !n. 1802 field_mult f (field_inv f x) (field_inv f (field_exp f x n)) = 1803 field_inv f (field_exp f x (n + 1))``, 1804 RW_TAC alg_ss [GSYM field_single_mult_exp] 1805 ++ RW_TAC alg_ss' []); 1806 1807val context = subtypeTools.add_rewrite2'' field_inv_mult_inv_exp context; 1808val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1809 1810val field_inv_mult_inv_exp' = store_thm 1811 ("field_inv_mult_inv_exp'", 1812 ``!f :: Field. !x :: field_nonzero f. !n. !y :: (f.carrier). 1813 field_mult f (field_inv f x) 1814 (field_mult f (field_inv f (field_exp f x n)) y) = 1815 field_mult f (field_inv f (field_exp f x (n + 1))) y``, 1816 RW_TAC alg_ss [GSYM field_mult_assoc, field_inv_mult_inv_exp]); 1817 1818val context = subtypeTools.add_rewrite2'' field_inv_mult_inv_exp' context; 1819val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1820 1821val field_inv_exp_mult_inv_exp = store_thm 1822 ("field_inv_exp_mult_inv_exp", 1823 ``!f :: Field. !x :: field_nonzero f. !m n. 1824 field_mult f (field_inv f (field_exp f x m)) 1825 (field_inv f (field_exp f x n)) = 1826 field_inv f (field_exp f x (m + n))``, 1827 RW_TAC resq_ss [] 1828 ++ Induct_on `m` 1829 ++ RW_TAC alg_ss [] 1830 ++ RW_TAC alg_ss [field_exp_def, ADD_CLAUSES, field_inv_mult] 1831 ++ POP_ASSUM (fn th => REWRITE_TAC [GSYM th]) 1832 ++ RW_TAC alg_ss [field_mult_assoc]); 1833 1834val context = subtypeTools.add_rewrite2'' field_inv_exp_mult_inv_exp context; 1835val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1836 1837val field_inv_exp_mult_inv_exp' = store_thm 1838 ("field_inv_exp_mult_inv_exp'", 1839 ``!f :: Field. !x :: field_nonzero f. !m n. !y :: (f.carrier). 1840 field_mult f (field_inv f (field_exp f x m)) 1841 (field_mult f (field_inv f (field_exp f x n)) y) = 1842 field_mult f (field_inv f (field_exp f x (m + n))) y``, 1843 RW_TAC alg_ss [GSYM field_mult_assoc, field_inv_exp_mult_inv_exp]); 1844 1845val context = subtypeTools.add_rewrite2'' field_inv_exp_mult_inv_exp' context; 1846val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1847 1848val field_one_exp = store_thm 1849 ("field_one_exp", 1850 ``!f :: Field. !n. field_exp f (field_one f) n = field_one f``, 1851 RW_TAC resq_ss [] 1852 ++ Induct_on `n` 1853 ++ RW_TAC std_ss [field_exp_def, field_mult_rone, field_one_carrier]); 1854 1855val context = subtypeTools.add_rewrite2 field_one_exp context; 1856val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1857 1858val field_zero_exp = store_thm 1859 ("field_zero_exp", 1860 ``!f :: Field. !n. 1861 field_exp f (field_zero f) n = 1862 (if n = 0 then field_one f else field_zero f)``, 1863 RW_TAC resq_ss [] 1864 ++ Induct_on `n` 1865 ++ RW_TAC std_ss 1866 [field_exp_def, field_mult_rone, field_one_carrier] 1867 ++ RW_TAC alg_ss []); 1868 1869val context = subtypeTools.add_rewrite2 field_zero_exp context; 1870val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1871 1872val field_exp_eq_zero = store_thm 1873 ("field_exp_eq_zero", 1874 ``!f :: Field. !x :: (f.carrier). !n. 1875 (field_exp f x n = field_zero f) = ~(n = 0) /\ (x = field_zero f)``, 1876 RW_TAC resq_ss [] 1877 ++ Induct_on `n` 1878 ++ RW_TAC std_ss 1879 [field_exp_def, field_one_zero, field_entire, field_exp_carrier] 1880 ++ METIS_TAC []); 1881 1882val context = subtypeTools.add_rewrite2 field_exp_eq_zero context; 1883val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1884 1885val field_exp_neg = store_thm 1886 ("field_exp_neg", 1887 ``!f :: Field. !x :: (f.carrier). !n. 1888 field_exp f (field_neg f x) n = 1889 if EVEN n then field_exp f x n else field_neg f (field_exp f x n)``, 1890 RW_TAC resq_ss [] 1891 ++ Induct_on `n` 1892 ++ RW_TAC alg_ss [EVEN, field_exp_def]); 1893 1894val context = subtypeTools.add_rewrite2'' field_exp_neg context; 1895val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1896 1897val field_exp_exp = store_thm 1898 ("field_exp_exp", 1899 ``!f :: Field. !x :: (f.carrier). !m n. 1900 field_exp f (field_exp f x m) n = field_exp f x (m * n)``, 1901 RW_TAC resq_ss [] 1902 ++ Induct_on `n` 1903 >> RW_TAC alg_ss [field_exp_def] 1904 ++ RW_TAC alg_ss [field_exp_def, ONCE_REWRITE_RULE [MULT_COMM] MULT] 1905 ++ ONCE_REWRITE_TAC [ADD_COMM] 1906 ++ RW_TAC alg_ss [GSYM field_exp_mult_exp]); 1907 1908val context = subtypeTools.add_rewrite2'' field_exp_exp context; 1909val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1910 1911val field_sub_eq_zero = store_thm 1912 ("field_sub_eq_zero", 1913 ``!f :: Field. !x y :: (f.carrier). 1914 (field_sub f x y = field_zero f) = (x = y)``, 1915 RW_TAC resq_ss [] 1916 ++ RW_TAC alg_ss' [] 1917 ++ RW_TAC alg_ss [GSYM field_neg_eq]); 1918 1919local 1920 val field_sub_eq_zero_conv = 1921 let 1922 val th = CONV_RULE RES_FORALL_CONV (GSYM field_sub_eq_zero) 1923 in 1924 fn f => cond_rewr_conv (ISPEC f th) 1925 end; 1926 1927 fun left_conv solver tm = 1928 let 1929 val (x,y) = dest_eq tm 1930 val _ = not (is_field_zero y) orelse 1931 raise ERR "field_sub_eq_zero_conv (left)" "looping" 1932 val (f,_,_) = dest_field_add x 1933 in 1934 field_sub_eq_zero_conv f solver 1935 end tm; 1936 1937 fun right_conv solver tm = 1938 let 1939 val (_,y) = dest_eq tm 1940 val (f,_,_) = dest_field_add y 1941(*** 1942 val _ = print "right_conv\n"; 1943***) 1944 in 1945 field_sub_eq_zero_conv f solver 1946 end tm; 1947in 1948 val field_sub_eq_zero_l_conv = 1949 {name = "field_sub_eq_zero_conv (left)", 1950 key = ``field_add (f : 'a field) x y = z``, 1951 conv = left_conv} 1952 and field_sub_eq_zero_r_conv = 1953 {name = "field_sub_eq_zero_conv (right)", 1954 key = ``x = field_add (f : 'a field) y z``, 1955 conv = right_conv}; 1956end; 1957 1958val context = subtypeTools.add_conversion2'' field_sub_eq_zero_r_conv context; 1959val context = subtypeTools.add_conversion2'' field_sub_eq_zero_l_conv context; 1960val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1961 1962val field_sub_eq_zero_imp = store_thm 1963 ("field_sub_eq_zero_imp", 1964 ``!f :: Field. !x y :: (f.carrier). 1965 (field_sub f x y = field_zero f) ==> (x = y)``, 1966 RW_TAC std_ss [field_sub_eq_zero]); 1967 1968val field_inv_inv = store_thm 1969 ("field_inv_inv", 1970 ``!f :: Field. !x :: field_nonzero f. field_inv f (field_inv f x) = x``, 1971 RW_TAC resq_ss 1972 [field_inv_def, Field_def, GSPECIFICATION, AbelianGroup_def, 1973 field_nonzero_def] 1974 ++ METIS_TAC [group_inv_inv]); 1975 1976val context = subtypeTools.add_rewrite2 field_inv_inv context; 1977val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1978 1979val field_sub_carrier = store_thm 1980 ("field_sub_carrier", 1981 ``!f :: Field. !x y :: (f.carrier). field_sub f x y IN f.carrier``, 1982 RW_TAC resq_ss [] 1983 ++ RW_TAC alg_ss' []); 1984 1985val context = subtypeTools.add_reduction2 field_sub_carrier context; 1986val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 1987 1988val field_neg_nonzero = store_thm 1989 ("field_neg_nonzero", 1990 ``!f :: Field. !x :: field_nonzero f. field_neg f x IN field_nonzero f``, 1991 RW_TAC resq_ss [] 1992 ++ RW_TAC alg_ss [GSYM field_nonzero_eq] 1993 ++ POP_ASSUM MP_TAC 1994 ++ RW_TAC alg_ss [field_nonzero_def, GSPECIFICATION, IN_DIFF, IN_SING] 1995 ++ STRIP_TAC 1996 ++ Q.PAT_ASSUM `~(X = Y)` MP_TAC 1997 ++ RW_TAC alg_ss [] 1998 ++ match_tac field_add_lcancel_imp 1999 ++ Q.EXISTS_TAC `f` 2000 ++ Q.EXISTS_TAC `field_neg f x` 2001 ++ RW_TAC std_ss [field_lneg] 2002 ++ RW_TAC alg_ss []); 2003 2004val context = subtypeTools.add_reduction2 field_neg_nonzero context; 2005val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2006 2007val field_inv_neg = store_thm 2008 ("field_inv_neg", 2009 ``!f :: Field. !x :: field_nonzero f. 2010 field_inv f (field_neg f x) = field_neg f (field_inv f x)``, 2011 RW_TAC resq_ss [] 2012 ++ match_tac field_mult_lcancel_imp 2013 ++ Q.EXISTS_TAC `f` 2014 ++ Q.EXISTS_TAC `field_neg f x` 2015 ++ SIMP_TAC bool_ss [CONJ_ASSOC] 2016 ++ CONJ_TAC >> RW_TAC alg_ss [] 2017 ++ Know 2018 `field_mult f (field_neg f x) (field_inv f (field_neg f x)) = field_one f` 2019 >> (match_tac field_rinv ++ RW_TAC alg_ss []) 2020 ++ RW_TAC std_ss [] 2021 ++ RW_TAC alg_ss' []); 2022 2023val context = subtypeTools.add_rewrite2'' field_inv_neg context; 2024val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2025 2026val field_exp_mult = store_thm 2027 ("field_exp_mult", 2028 ``!f :: Field. !x y :: (f.carrier). !n. 2029 field_exp f (field_mult f x y) n = 2030 field_mult f (field_exp f x n) (field_exp f y n)``, 2031 RW_TAC resq_ss [] 2032 ++ Induct_on `n` 2033 ++ RW_TAC alg_ss [field_exp_def] 2034 ++ RW_TAC alg_ss [field_mult_assoc] 2035 ++ AP_TERM_TAC 2036 ++ RW_TAC alg_ss [GSYM field_mult_assoc] 2037 ++ AP_THM_TAC 2038 ++ AP_TERM_TAC 2039 ++ match_tac field_mult_comm 2040 ++ RW_TAC alg_ss []); 2041 2042val context = subtypeTools.add_rewrite2'' field_exp_mult context; 2043val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2044 2045val field_exp_inv = store_thm 2046 ("field_exp_inv", 2047 ``!f :: Field. !x :: field_nonzero f. !n. 2048 field_exp f (field_inv f x) n = field_inv f (field_exp f x n)``, 2049 RW_TAC resq_ss [] 2050 ++ Induct_on `n` 2051 ++ RW_TAC alg_ss [] 2052 ++ RW_TAC alg_ss [field_exp_def] 2053 ++ RW_TAC alg_ss' []); 2054 2055val context = subtypeTools.add_rewrite2'' field_exp_inv context; 2056val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2057 2058val field_add_ac_conv = 2059 {name = "field_add_ac_conv", 2060 key = ``field_add f x y``, 2061 conv = 2062 subtypeTools.binop_ac_conv 2063 {term_compare = field_compare, 2064 dest_binop = dest_field_add, 2065 dest_inv = dest_field_neg, 2066 dest_exp = dest_field_num_mult, 2067 assoc_th = field_add_assoc, 2068 comm_th = field_add_comm, 2069 comm_th' = field_add_comm', 2070 id_ths = 2071 [field_add_lzero, 2072 field_add_lzero', 2073 field_add_rzero, 2074 field_add_rzero'], 2075 simplify_ths = 2076 [GSYM field_num_one, 2077 field_neg_zero, 2078 field_neg_neg, 2079 field_neg_add, 2080 field_mult_lzero, 2081 field_mult_lzero', 2082 field_mult_rzero, 2083 field_mult_rzero', 2084 field_mult_lone, 2085 field_mult_lone', 2086 field_mult_rone, 2087 field_mult_rone'], 2088 combine_ths = 2089 [field_single_add_single, 2090 field_single_add_mult, 2091 field_rneg, 2092 field_single_add_neg_mult, 2093 field_mult_add_mult, 2094 field_mult_add_neg, 2095 field_mult_add_neg_mult, 2096 field_neg_add_neg, 2097 field_neg_add_neg_mult, 2098 field_neg_mult_add_neg_mult], 2099 combine_ths' = 2100 [field_single_add_single', 2101 field_single_add_mult', 2102 field_rneg', 2103 field_single_add_neg_mult', 2104 field_mult_add_mult', 2105 field_mult_add_neg', 2106 field_mult_add_neg_mult', 2107 field_neg_add_neg', 2108 field_neg_add_neg_mult', 2109 field_neg_mult_add_neg_mult']}}; 2110 2111val context = subtypeTools.add_conversion2'' field_add_ac_conv context; 2112val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2113 2114val field_mult_ac_conv = 2115 {name = "field_mult_ac_conv", 2116 key = ``field_mult f x y``, 2117 conv = 2118 subtypeTools.binop_ac_conv 2119 {term_compare = field_compare, 2120 dest_binop = dest_field_mult, 2121 dest_inv = dest_field_inv, 2122 dest_exp = dest_field_exp, 2123 assoc_th = field_mult_assoc, 2124 comm_th = field_mult_comm, 2125 comm_th' = field_mult_comm', 2126 id_ths = 2127 [field_mult_lone, 2128 field_mult_lone', 2129 field_mult_rone, 2130 field_mult_rone'], 2131 simplify_ths = 2132 [field_inv_one, 2133 field_inv_inv, 2134 field_inv_mult, 2135 field_exp_zero, 2136 field_exp_one, 2137 field_exp_exp, 2138 field_exp_mult, 2139 field_exp_inv], 2140 combine_ths = 2141 [field_single_mult_single, 2142 field_single_mult_exp, 2143 field_rinv, 2144 field_single_mult_inv_exp, 2145 field_exp_mult_exp, 2146 field_exp_mult_inv, 2147 field_exp_mult_inv_exp, 2148 field_inv_mult_inv, 2149 field_inv_mult_inv_exp, 2150 field_inv_exp_mult_inv_exp], 2151 combine_ths' = 2152 [field_single_mult_single', 2153 field_single_mult_exp', 2154 field_rinv', 2155 field_single_mult_inv_exp', 2156 field_exp_mult_exp', 2157 field_exp_mult_inv', 2158 field_exp_mult_inv_exp', 2159 field_inv_mult_inv', 2160 field_inv_mult_inv_exp', 2161 field_inv_exp_mult_inv_exp']}}; 2162 2163val context = subtypeTools.add_conversion2'' field_mult_ac_conv context; 2164val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2165 2166val field_binomial_2 = store_thm 2167 ("field_binomial_2", 2168 ``!f :: Field. !x y :: (f.carrier). 2169 field_exp f (field_add f x y) 2 = 2170 field_add f (field_exp f x 2) 2171 (field_add f (field_mult f (field_num f 2) (field_mult f x y)) 2172 (field_exp f y 2))``, 2173 RW_TAC alg_ss [field_exp_small] 2174 ++ RW_TAC alg_ss' [field_distrib]); 2175 2176val field_binomial_3 = store_thm 2177 ("field_binomial_3", 2178 ``!f :: Field. !x y :: (f.carrier). 2179 field_exp f (field_add f x y) 3 = 2180 field_add f 2181 (field_exp f x 3) 2182 (field_add f 2183 (field_mult f (field_num f 3) (field_mult f (field_exp f x 2) y)) 2184 (field_add f 2185 (field_mult f (field_num f 3) (field_mult f x (field_exp f y 2))) 2186 (field_exp f y 3)))``, 2187 RW_TAC alg_ss [field_exp_small] 2188 ++ RW_TAC alg_ss' [field_distrib, field_binomial_2]); 2189 2190val field_binomial_4 = store_thm 2191 ("field_binomial_4", 2192 ``!f :: Field. !x y :: (f.carrier). 2193 field_exp f (field_add f x y) 4 = 2194 field_add f 2195 (field_exp f x 4) 2196 (field_add f 2197 (field_mult f (field_num f 4) (field_mult f (field_exp f x 3) y)) 2198 (field_add f 2199 (field_mult f 2200 (field_num f 6) 2201 (field_mult f (field_exp f x 2) (field_exp f y 2))) 2202 (field_add f 2203 (field_mult f (field_num f 4) (field_mult f x (field_exp f y 3))) 2204 (field_exp f y 4))))``, 2205 RW_TAC alg_ss [field_exp_small] 2206 ++ RW_TAC alg_ss' [field_distrib, field_binomial_2, field_binomial_3]); 2207 2208val field_div_carrier = store_thm 2209 ("field_div_carrier", 2210 ``!f :: Field. !x :: (f.carrier). !y :: field_nonzero f. 2211 field_div f x y IN f.carrier``, 2212 RW_TAC resq_ss [] 2213 ++ RW_TAC alg_ss' [field_div_def]); 2214 2215val context = subtypeTools.add_reduction2 field_div_carrier context; 2216val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2217 2218val field_div_nonzero = store_thm 2219 ("field_div_nonzero", 2220 ``!f :: Field. !x y :: field_nonzero f. field_div f x y IN field_nonzero f``, 2221 RW_TAC resq_ss [] 2222 ++ RW_TAC alg_ss' [field_div_def]); 2223 2224val context = subtypeTools.add_reduction2 field_div_nonzero context; 2225val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2226 2227val field_div_lneg = store_thm 2228 ("field_div_lneg", 2229 ``!f :: Field. !x :: (f.carrier). !y :: field_nonzero f. 2230 field_div f (field_neg f x) y = field_neg f (field_div f x y)``, 2231 RW_TAC alg_ss' [field_div_def]); 2232 2233val field_div_rneg = store_thm 2234 ("field_div_rneg", 2235 ``!f :: Field. !x :: (f.carrier). !y :: field_nonzero f. 2236 field_div f x (field_neg f y) = field_neg f (field_div f x y)``, 2237 RW_TAC alg_ss' [field_inv_neg, field_div_def]); 2238 2239val field_div_addl = store_thm 2240 ("field_div_addl", 2241 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2242 field_add f x (field_div f y z) = 2243 field_div f (field_add f (field_mult f x z) y) z``, 2244 RW_TAC alg_ss' [field_div_def, field_distrib]); 2245 2246val field_div_addr = store_thm 2247 ("field_div_addr", 2248 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2249 field_add f (field_div f y z) x = 2250 field_div f (field_add f y (field_mult f x z)) z``, 2251 RW_TAC alg_ss' [field_div_def, field_distrib]); 2252 2253val field_div_subl = store_thm 2254 ("field_div_subl", 2255 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2256 field_sub f x (field_div f y z) = 2257 field_div f (field_sub f (field_mult f x z) y) z``, 2258 RW_TAC alg_ss' [field_div_def, field_distrib]); 2259 2260val field_div_subr = store_thm 2261 ("field_div_subr", 2262 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2263 field_sub f (field_div f y z) x = 2264 field_div f (field_sub f y (field_mult f x z)) z``, 2265 RW_TAC alg_ss' [field_div_def, field_distrib]); 2266 2267val field_div_multl = store_thm 2268 ("field_div_multl", 2269 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2270 field_mult f x (field_div f y z) = 2271 field_div f (field_mult f x y) z``, 2272 RW_TAC alg_ss' [field_div_def]); 2273 2274val field_div_multr = store_thm 2275 ("field_div_multr", 2276 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2277 field_mult f (field_div f y z) x = 2278 field_div f (field_mult f y x) z``, 2279 RW_TAC alg_ss' [field_div_def]); 2280 2281val field_div_exp = store_thm 2282 ("field_div_exp", 2283 ``!f :: Field. !x :: (f.carrier). !y :: field_nonzero f. !n. 2284 field_exp f (field_div f x y) n = 2285 field_div f (field_exp f x n) (field_exp f y n)``, 2286 RW_TAC alg_ss' [field_div_def, field_exp_mult, field_exp_inv]); 2287 2288val field_div_divl = store_thm 2289 ("field_div_divl", 2290 ``!f :: Field. !x :: (f.carrier). !y z :: field_nonzero f. 2291 field_div f (field_div f x y) z = 2292 field_div f x (field_mult f y z)``, 2293 RW_TAC alg_ss' [field_div_def]); 2294 2295val field_div_divr = store_thm 2296 ("field_div_divr", 2297 ``!f :: Field. !x :: (f.carrier). !y z :: field_nonzero f. 2298 field_div f x (field_div f y z) = 2299 field_div f (field_mult f x z) y``, 2300 RW_TAC alg_ss' [field_div_def]); 2301 2302val field_add_divl = store_thm 2303 ("field_add_divl", 2304 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2305 field_add f (field_div f y z) x = 2306 field_div f (field_add f y (field_mult f z x)) z``, 2307 RW_TAC alg_ss [field_div_def] 2308 ++ RW_TAC alg_ss' [field_distrib]); 2309 2310val field_add_divl' = store_thm 2311 ("field_add_divl'", 2312 ``!f :: Field. !x y t :: (f.carrier). !z :: field_nonzero f. 2313 field_add f (field_div f y z) (field_add f x t) = 2314 field_add f (field_div f (field_add f y (field_mult f z x)) z) t``, 2315 RW_TAC alg_ss [GSYM field_add_assoc] 2316 ++ RW_TAC resq_ss [] 2317 ++ match_tac field_add_divl 2318 ++ RW_TAC alg_ss []); 2319 2320val field_add_divr = store_thm 2321 ("field_add_divr", 2322 ``!f :: Field. !x y :: (f.carrier). !z :: field_nonzero f. 2323 field_add f x (field_div f y z) = 2324 field_div f (field_add f (field_mult f z x) y) z``, 2325 RW_TAC alg_ss [field_div_def] 2326 ++ RW_TAC alg_ss' [field_distrib]); 2327 2328val field_add_divr' = store_thm 2329 ("field_add_divr'", 2330 ``!f :: Field. !x y t :: (f.carrier). !z :: field_nonzero f. 2331 field_add f x (field_add f (field_div f y z) t) = 2332 field_add f (field_div f (field_add f (field_mult f z x) y) z) t``, 2333 RW_TAC alg_ss [GSYM field_add_assoc] 2334 ++ RW_TAC resq_ss [] 2335 ++ match_tac field_add_divr 2336 ++ RW_TAC alg_ss []); 2337 2338val field_add_div = store_thm 2339 ("field_add_div", 2340 ``!f :: Field. !v w :: (f.carrier). !x y z :: field_nonzero f. 2341 field_add f 2342 (field_div f v (field_mult f x y)) 2343 (field_div f w (field_mult f x z)) = 2344 field_div f 2345 (field_add f (field_mult f z v) (field_mult f y w)) 2346 (field_mult f x (field_mult f y z))``, 2347 RW_TAC alg_ss [field_div_def] 2348 ++ RW_TAC alg_ss' [field_distrib]); 2349 2350val field_add_div' = store_thm 2351 ("field_add_div'", 2352 ``!f :: Field. !v w t :: (f.carrier). !x y z :: field_nonzero f. 2353 field_add f 2354 (field_div f v (field_mult f x y)) 2355 (field_add f (field_div f w (field_mult f x z)) t) = 2356 field_add f 2357 (field_div f 2358 (field_add f (field_mult f z v) (field_mult f y w)) 2359 (field_mult f x (field_mult f y z))) t``, 2360 RW_TAC alg_ss [GSYM field_add_assoc] 2361 ++ RW_TAC resq_ss [] 2362 ++ match_tac field_add_div 2363 ++ RW_TAC alg_ss []); 2364 2365val field_div_cancel = store_thm 2366 ("field_div_cancel", 2367 ``!f :: Field. !x z :: field_nonzero f. !y :: (f.carrier). 2368 (field_div f (field_mult f x y) (field_mult f x z) = field_div f y z)``, 2369 RW_TAC resq_ss [field_div_def] 2370 ++ RW_TAC alg_ss' []); 2371 2372val field_inv_eq_zero = store_thm 2373 ("field_inv_eq_zero", 2374 ``!f :: Field. !x :: field_nonzero f. ~(field_inv f x = field_zero f)``, 2375 RW_TAC resq_ss [] 2376 ++ STRIP_TAC 2377 ++ Know `field_inv f x IN field_nonzero f` >> METIS_TAC [field_inv_nonzero] 2378 ++ RW_TAC alg_ss [field_nonzero_def, IN_DIFF, IN_SING]); 2379 2380val context = subtypeTools.add_rewrite2 field_inv_eq_zero context; 2381val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2382 2383val field_div_eq_zero = store_thm 2384 ("field_div_eq_zero", 2385 ``!f :: Field. !x :: (f.carrier). !y :: field_nonzero f. 2386 (field_div f x y = field_zero f) = (x = field_zero f)``, 2387 RW_TAC resq_ss [field_div_def] 2388 ++ RW_TAC alg_ss [field_entire]); 2389 2390val context = subtypeTools.add_rewrite2 field_div_eq_zero context; 2391val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2392 2393(* ------------------------------------------------------------------------- *) 2394(* Homomorphisms, isomorphisms, endomorphisms, automorphisms and subfields. *) 2395(* ------------------------------------------------------------------------- *) 2396 2397val FieldHom_def = Define 2398 `FieldHom g h = 2399 { f | 2400 (!x :: (g.carrier). f x IN h.carrier) /\ 2401 f IN GroupHom (g.sum) (h.sum) /\ 2402 f IN GroupHom (g.prod) (h.prod) }`; 2403 2404val FieldIso_def = Define 2405 `FieldIso g h = 2406 { f | 2407 f IN FieldHom g h /\ 2408 (!y :: (h.carrier). ?!x :: (g.carrier). f x = y) }`; 2409 2410val FieldEndo_def = Define `FieldEndo g = FieldHom g g`; 2411 2412val FieldAuto_def = Define `FieldAuto g = FieldIso g g`; 2413 2414val subfield_def = Define `subfield g h = I IN FieldHom g h`; 2415 2416(* ------------------------------------------------------------------------- *) 2417(* Polynomials over fields. *) 2418(* ------------------------------------------------------------------------- *) 2419 2420val () = type_abbrev ("poly", Type `:'a list`); 2421 2422val poly_zero_def = Define `poly_zero = ([] : 'a poly)`; 2423 2424val Poly_def = Define 2425 `Poly (f : 'a field) = 2426 { (p : 'a poly) | 2427 (p = poly_zero) \/ 2428 (EVERY (\c. c IN f.carrier) p /\ ~(LAST p = field_zero f)) }`; 2429 2430val poly_degree_def = Define 2431 `poly_degree (p : 'a poly) = if (p = poly_zero) then 0 else LENGTH p - 1`; 2432 2433val poly_eval_def = Define 2434 `(poly_eval (f : 'a field) [] x = field_zero f) /\ 2435 (poly_eval (f : 'a field) (c :: cs) x = 2436 field_add f c (field_mult f x (poly_eval f cs x)))`; 2437 2438val AlgebraicallyClosedField_def = Define 2439 `AlgebraicallyClosedField = 2440 { (f : 'a field) | 2441 f IN Field /\ 2442 !p :: Poly f. 2443 (poly_degree p = 0) \/ 2444 ?z :: (f.carrier). poly_eval f p z = field_zero f }`; 2445 2446(* ------------------------------------------------------------------------- *) 2447(* The trivial field. *) 2448(* ------------------------------------------------------------------------- *) 2449 2450val trivial_field_def = Define 2451 `(trivial_field zero_elt one_elt) : 'a field = 2452 <| carrier := {zero_elt; one_elt}; 2453 sum := <| carrier := {zero_elt; one_elt}; 2454 id := zero_elt; 2455 inv := (\x. x); 2456 mult := (\x y. if x = zero_elt then y 2457 else if y = zero_elt then x 2458 else zero_elt) |>; 2459 prod := <| carrier := {one_elt}; 2460 id := one_elt; 2461 inv := (\x. x); 2462 mult := (\x y. if x = zero_elt then zero_elt 2463 else if y = zero_elt then zero_elt 2464 else one_elt) |> |>`; 2465 2466val trivial_field = store_thm 2467 ("trivial_field", 2468 ``!zero_elt one_elt. 2469 ~(zero_elt = one_elt) ==> 2470 trivial_field zero_elt one_elt IN FiniteField``, 2471 RW_TAC resq_ss 2472 [trivial_field_def, FiniteField_def, Field_def, GSPECIFICATION, 2473 combinTheory.K_THM, field_add_def, field_mult_def, field_zero_def, 2474 AbelianGroup_def, Group_def, IN_INSERT, NOT_IN_EMPTY, EXTENSION, 2475 FINITE_INSERT, FINITE_EMPTY, IN_DIFF, field_nonzero_def] 2476 ++ RW_TAC std_ss [] 2477 ++ METIS_TAC []); 2478 2479(* ------------------------------------------------------------------------- *) 2480(* GF(p). *) 2481(* ------------------------------------------------------------------------- *) 2482 2483val modexp_def = Define 2484 `modexp a n m = 2485 if n = 0 then 1 2486 else if n MOD 2 = 0 then modexp ((a * a) MOD m) (n DIV 2) m 2487 else (a * modexp ((a * a) MOD m) (n DIV 2) m) MOD m`; 2488 2489val modexp_ind = fetch "-" "modexp_ind"; 2490 2491val GF_def = Define 2492 `GF p = 2493 <| carrier := { n | n < p }; 2494 sum := add_mod p; 2495 prod := mult_mod p |>`; 2496 2497val modexp = store_thm 2498 ("modexp", 2499 ``!a n m. 1 < m ==> (modexp a n m = (a ** n) MOD m)``, 2500 recInduct modexp_ind 2501 ++ RW_TAC std_ss [] 2502 ++ ONCE_REWRITE_TAC [modexp_def] 2503 ++ Cases_on `n = 0` >> RW_TAC arith_ss [EXP] 2504 ++ ASM_SIMP_TAC bool_ss [] 2505 ++ REPEAT (Q.PAT_ASSUM `X ==> Y` (K ALL_TAC)) 2506 ++ Know `0 < m` >> DECIDE_TAC 2507 ++ STRIP_TAC 2508 ++ MP_TAC (Q.SPEC `m` MOD_TIMES2) 2509 ++ ASM_REWRITE_TAC [] 2510 ++ DISCH_THEN (MP_TAC o Q.SPECL [`a`,`a`]) 2511 ++ DISCH_THEN (fn th => ONCE_REWRITE_TAC [GSYM th]) 2512 ++ ASM_SIMP_TAC bool_ss [MOD_MOD, MOD_EXP] 2513 ++ Know `a MOD m * a MOD m = (a MOD m) ** 2` 2514 >> RW_TAC bool_ss [TWO, ONE, EXP, REWRITE_RULE [ONE] MULT_CLAUSES] 2515 ++ DISCH_THEN (fn th => ASM_SIMP_TAC bool_ss [th]) 2516 ++ ASM_SIMP_TAC bool_ss [EXP_EXP] 2517 ++ MP_TAC (Q.SPEC `m` MOD_TIMES2) 2518 ++ ASM_REWRITE_TAC [] 2519 ++ DISCH_THEN (fn th => ONCE_REWRITE_TAC [GSYM th]) 2520 ++ MP_TAC (Q.SPECL [`a`,`n`,`m`] MOD_EXP) 2521 ++ ASM_REWRITE_TAC [] 2522 ++ DISCH_THEN (fn th => ONCE_REWRITE_TAC [GSYM th]) 2523 ++ Q.SPEC_TAC (`a MOD m`,`a`) 2524 ++ MP_TAC (Q.SPEC `m` MOD_TIMES2) 2525 ++ ASM_REWRITE_TAC [] 2526 ++ DISCH_THEN (fn th => ONCE_REWRITE_TAC [GSYM th]) 2527 ++ ASM_SIMP_TAC bool_ss [MOD_MOD] 2528 ++ ASM_SIMP_TAC bool_ss [MOD_TIMES2, GSYM EXP] 2529 ++ Know `(n MOD 2 = 0) \/ (n MOD 2 = 1)` 2530 >> (Suff `n MOD 2 < 2` >> DECIDE_TAC 2531 ++ RW_TAC std_ss [DIVISION]) 2532 ++ ASM_SIMP_TAC bool_ss [ADD1] 2533 ++ Suff `n = 2 * (n DIV 2) + n MOD 2` 2534 >> METIS_TAC [ADD_CLAUSES] 2535 ++ METIS_TAC [DIVISION, DECIDE ``0 < 2``, MULT_COMM]); 2536 2537val GF_carrier = store_thm 2538 ("GF_carrier", 2539 ``!p. (GF p).carrier = { n | n < p}``, 2540 RW_TAC std_ss [GF_def, field_accessors]); 2541 2542val GF_in_carrier = store_thm 2543 ("GF_in_carrier", 2544 ``!p x. x IN (GF p).carrier = x < p``, 2545 RW_TAC std_ss [GF_carrier, GSPECIFICATION]); 2546 2547val GF_in_carrier_imp = store_thm 2548 ("GF_in_carrier_imp", 2549 ``!p x. x < p ==> x IN (GF p).carrier``, 2550 METIS_TAC [GF_in_carrier]); 2551 2552val context = subtypeTools.add_judgement2 GF_in_carrier_imp context; 2553val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2554 2555val GF_zero = store_thm 2556 ("GF_zero", 2557 ``!p. field_zero (GF p) = 0``, 2558 RW_TAC std_ss [GF_def, field_accessors, field_zero_def, add_mod_def]); 2559 2560val GF_one = store_thm 2561 ("GF_one", 2562 ``!p. field_one (GF p) = 1``, 2563 RW_TAC std_ss [GF_def, field_accessors, field_one_def, mult_mod_def]); 2564 2565val GF_neg = store_thm 2566 ("GF_neg", 2567 ``!p x. field_neg (GF p) x = (p - x) MOD p``, 2568 RW_TAC std_ss [GF_def, field_accessors, field_neg_def, add_mod_def]); 2569 2570val GF_add = store_thm 2571 ("GF_add", 2572 ``!p x y. field_add (GF p) x y = (x + y) MOD p``, 2573 RW_TAC std_ss [GF_def, field_accessors, field_add_def, add_mod_def]); 2574 2575val GF_sub = store_thm 2576 ("GF_sub", 2577 ``!p :: Prime. !x y. field_sub (GF p) x y = (x + (p - y)) MOD p``, 2578 RW_TAC resq_ss [GF_add, GF_neg, field_sub_def, Prime_def, GSPECIFICATION] 2579 ++ Know `~(p = 0)` >> METIS_TAC [NOT_PRIME_0] 2580 ++ STRIP_TAC 2581 ++ MP_TAC (Q.SPEC `p` MOD_PLUS) 2582 ++ MATCH_MP_TAC (PROVE [] ``a /\ (b ==> c) ==> ((a ==> b) ==> c)``) 2583 ++ CONJ_TAC >> DECIDE_TAC 2584 ++ DISCH_THEN (fn th => ONCE_REWRITE_TAC [GSYM th]) 2585 ++ RW_TAC arith_ss [MOD_MOD]); 2586 2587val GF_inv = store_thm 2588 ("GF_inv", 2589 ``!p :: Prime. !x y. field_inv (GF p) x = modexp x (p - 2) p``, 2590 RW_TAC resq_ss 2591 [GF_def, field_accessors, field_inv_def, mult_mod_def, 2592 combinTheory.K_THM, Prime_def, GSPECIFICATION] 2593 ++ match_tac (GSYM modexp) 2594 ++ Suff `~(p = 0) /\ ~(p = 1)` >> DECIDE_TAC 2595 ++ METIS_TAC [NOT_PRIME_0, NOT_PRIME_1]); 2596 2597val GF_mult = store_thm 2598 ("GF_mult", 2599 ``!p x y. field_mult (GF p) x y = (x * y) MOD p``, 2600 RW_TAC std_ss [GF_def, field_accessors, field_mult_def, mult_mod_def]); 2601 2602val GF_div = store_thm 2603 ("GF_div", 2604 ``!p x y. field_div (GF p) x y = field_mult (GF p) x (field_inv (GF p) y)``, 2605 RW_TAC std_ss [field_div_def]); 2606 2607val GF_exp = store_thm 2608 ("GF_exp", 2609 ``!p :: Prime. !x n. field_exp (GF p) x n = modexp x n p``, 2610 RW_TAC resq_ss [Prime_def, GSPECIFICATION] 2611 ++ Know `1 < p` 2612 >> (Suff `~(p = 0) /\ ~(p = 1)` >> DECIDE_TAC 2613 ++ METIS_TAC [NOT_PRIME_0, NOT_PRIME_1]) 2614 ++ STRIP_TAC 2615 ++ Know `0 < p` >> DECIDE_TAC 2616 ++ STRIP_TAC 2617 ++ RW_TAC bool_ss [modexp] 2618 ++ (Induct_on `n` 2619 ++ RW_TAC bool_ss [field_exp_def, GF_one, GF_mult, EXP]) 2620 >> METIS_TAC [LESS_MOD] 2621 ++ METIS_TAC [MOD_MOD, MOD_TIMES2]); 2622 2623val GF_num = store_thm 2624 ("GF_num", 2625 ``!p :: Prime. !n. field_num (GF p) n = n MOD p``, 2626 RW_TAC resq_ss [] 2627 ++ Know `p IN Nonzero` >> RW_TAC alg_ss [] 2628 ++ RW_TAC std_ss [Nonzero_def, GSPECIFICATION] 2629 ++ Know `0 < p` >> DECIDE_TAC 2630 ++ POP_ASSUM_LIST (K ALL_TAC) 2631 ++ RW_TAC std_ss [] 2632 ++ Induct_on `n` 2633 ++ RW_TAC std_ss [field_num_def, GF_zero, ZERO_MOD, GF_add, GF_one] 2634 ++ REWRITE_TAC [ADD1] 2635 ++ MP_TAC (Q.SPEC `p` MOD_PLUS) 2636 ++ ASM_REWRITE_TAC [] 2637 ++ DISCH_THEN (fn th => ONCE_REWRITE_TAC [GSYM th]) 2638 ++ RW_TAC arith_ss [MOD_MOD]); 2639 2640val GF_alt = store_thm 2641 ("GF_alt", 2642 ``!p :: Prime. !x y n. 2643 (field_zero (GF p) = 0) /\ 2644 (field_one (GF p) = 1) /\ 2645 (field_neg (GF p) x = (p - x) MOD p) /\ 2646 (field_add (GF p) x y = (x + y) MOD p) /\ 2647 (field_sub (GF p) x y = (x + (p - y)) MOD p) /\ 2648 (field_inv (GF p) x = modexp x (p - 2) p) /\ 2649 (field_mult (GF p) x y = (x * y) MOD p) /\ 2650 (field_div (GF p) x y = field_mult (GF p) x (field_inv (GF p) y)) /\ 2651 (field_exp (GF p) x n = modexp x n p) /\ 2652 (field_num (GF p) x = x MOD p)``, 2653 RW_TAC std_ss 2654 [GF_zero, GF_one, GF_neg, GF_add, GF_sub, GF_inv, GF_mult, GF_div, 2655 GF_exp, GF_num]); 2656 2657val GF = store_thm 2658 ("GF", 2659 ``!p :: Prime. GF p IN FiniteField``, 2660 RW_TAC resq_ss [FiniteField_def, GSPECIFICATION, Field_def] 2661 << [RW_TAC alg_ss [GF_def, combinTheory.K_THM], 2662 RW_TAC alg_ss [GF_def, combinTheory.K_THM], 2663 RW_TAC alg_ss [GF_def, combinTheory.K_THM, add_mod_def], 2664 RW_TAC alg_ss [GF_alt] 2665 ++ RW_TAC alg_ss 2666 [GF_def, combinTheory.K_THM, mult_mod_def, 2667 EXTENSION, IN_DIFF, GSPECIFICATION, IN_SING, field_nonzero_def, 2668 field_zero_def, add_mod_def] 2669 ++ METIS_TAC [], 2670 RW_TAC std_ss [GF_alt, MULT] 2671 ++ MATCH_MP_TAC ZERO_MOD 2672 ++ Suff `p IN Nonzero` >> RW_TAC arith_ss [Nonzero_def, GSPECIFICATION] 2673 ++ RW_TAC alg_ss [], 2674 RW_TAC std_ss [GF_alt] 2675 ++ Know `0 < p` 2676 >> (Suff `p IN Nonzero` >> RW_TAC arith_ss [Nonzero_def, GSPECIFICATION] 2677 ++ RW_TAC alg_ss []) 2678 ++ STRIP_TAC 2679 ++ RW_TAC std_ss [Once (GSYM MOD_TIMES2), MOD_MOD] 2680 ++ RW_TAC std_ss [MOD_TIMES2, LEFT_ADD_DISTRIB, MOD_PLUS], 2681 RW_TAC std_ss [GF_def, finite_num, GSPECIFICATION] 2682 ++ METIS_TAC []]); 2683 2684val context = subtypeTools.add_reduction2 GF context; 2685val {simplify = alg_ss, normalize = alg_ss'} = subtypeTools.simpset2 context; 2686 2687(* ------------------------------------------------------------------------- *) 2688(* GF(2^n). *) 2689(* ------------------------------------------------------------------------- *) 2690 2691(* GF(2^n) = polynomials over GF(2) modulo an irreducible degree n poly *) 2692 2693(*** 2694val GF_2_def = Define 2695 `GF_2 n = 2696 <| carrier := ; 2697 sum := ; 2698 prod := |>`; 2699***) 2700 2701val _ = html_theory "field"; 2702 2703val () = export_theory (); 2704