1open HolKernel Parse boolLib; 2infix THEN THENL THENC ORELSE ORELSEC THEN_TCL ORELSE_TCL ## |->; 3infixr -->; 4 5 6 7val _ = new_theory "eta"; 8 9 10(* In interactive sessions, do: 11 12app load ["pairTheory", 13 "listTheory", "listLib", "numTheory", "numLib", 14 "pred_setTheory", "pred_setLib", 15 "MutualIndThen", "bossLib", "relationTheory", 16 "ind_rel", "dep_rewrite", "quotient", 17 "more_listTheory", "more_setTheory", "variableTheory", 18 "termTheory", "alphaTheory", "liftTheory", 19 "barendregt", "reductionTheory", "betaTheory" 20 ]; 21 22*) 23 24open prim_recTheory pairTheory listTheory rich_listTheory; 25open combinTheory; 26open listLib; 27open pred_setTheory pred_setLib; 28open numTheory; 29open numLib; 30open arithmeticTheory; 31open bossLib; 32open relationTheory; 33open Mutual; 34open ind_rel; 35open dep_rewrite; 36open quotient; 37open more_listTheory; 38open more_setTheory; 39open variableTheory; 40open termTheory; 41open alphaTheory; 42open liftTheory; 43open barendregt; 44open reductionTheory; 45open betaTheory; 46 47 48open tactics; 49 50 51val term = ty_antiq ( ==`:'a term`== ); 52val subs = ty_antiq ( ==`:(var # 'a term) list`== ); 53val term_rel = ty_antiq ( ==`:'a term -> 'a term -> bool`== ); 54 55 56(* Reflexive closure of a relation. *) 57(* copied from relationScript.sml: *) 58 59val RC_INDUCT_TAC = 60 let val rc_thm = RC_INDUCT 61 fun tac (asl,w) = 62 let open Rsyntax 63 val {Bvar=u,Body} = dest_forall w 64 val {Bvar=v,Body} = dest_forall Body 65 val {ant,conseq} = dest_imp Body 66 val (RC,Ru'v') = strip_comb ant 67 val R = hd Ru'v' 68 val u'v' = tl Ru'v' 69 val u' = hd u'v' 70 val v' = hd (tl u'v') 71 (*val (RC,[R,u',v']) = strip_comb ant*) 72 (*val {Name = "RC",...} = dest_const RC*) 73 val _ = if #Name(dest_const RC) = "RC" then true else raise Match 74 val _ = assert (aconv u) u' 75 val _ = assert (aconv v) v' 76 val P = list_mk_abs([u,v], conseq) 77 val rc_thm' = BETA_RULE(ISPEC P (ISPEC R rc_thm)) 78 in MATCH_MP_TAC rc_thm' (asl,w) 79 end 80 handle _ => raise HOL_ERR{origin_structure = "<top-level>", 81 origin_function = "RC_INDUCT_TAC", 82 message = "Unanticipated term structure"} 83 in tac 84 end; 85 86(* Also see RC_REFLEXIVE, RC_SUBSET, RC_INDUCT, RC_CASES. *) 87 88 89(* Define the transitive closure of a relation. *) 90(* Wait, it's already done: see file src/relation/relationScript.sml. *) 91(* This defines TC in the logic as TC R is the transitive closure of R, *) 92(* and "transitive R" as the property that R is transitite on 'a. *) 93(* There are also a bunch of theorems in structure TCScript, as well as *) 94(* induction tactics, cases theorems, etc. It's theory "TC". *) 95 96(* copied: *) 97 98val TC_INDUCT_TAC = 99 let val tc_thm = TC_INDUCT 100 fun tac (asl,w) = 101 let open Rsyntax 102 val {Bvar=u,Body} = dest_forall w 103 val {Bvar=v,Body} = dest_forall Body 104 val {ant,conseq} = dest_imp Body 105 val (TC,Ru'v') = strip_comb ant 106 val R = hd Ru'v' 107 val u'v' = tl Ru'v' 108 val u' = hd u'v' 109 val v' = hd (tl u'v') 110 (*val (TC,[R,u',v']) = strip_comb ant*) 111 (*val {Name = "TC",...} = dest_const TC*) 112 val _ = if #Name(dest_const TC) = "TC" then true else raise Match 113 val _ = assert (aconv u) u' 114 val _ = assert (aconv v) v' 115 val P = list_mk_abs([u,v], conseq) 116 val tc_thm' = BETA_RULE(ISPEC P (ISPEC R tc_thm)) 117 in MATCH_MP_TAC tc_thm' (asl,w) 118 end 119 handle _ => raise HOL_ERR{origin_structure = "<top-level>", 120 origin_function = "TC_INDUCT_TAC", 121 message = "Unanticipated term structure"} 122 in tac 123 end; 124 125val TC_TRANS = REWRITE_RULE[transitive_def] TC_TRANSITIVE; 126(* Also see TC_SUBSET, TC_CASES1, TC_CASES2, TC_RC_RED1_IS_RED, TC_MONOTONIC *) 127 128 129 130(* --------------------------------------------------------------------- *) 131(* Definition of the relation of eta reduction. *) 132(* This is simple, but we define it by rule induction. *) 133(* --------------------------------------------------------------------- *) 134 135(* --------------------------------------------------------------------- *) 136(* (ETA_R t1 t2) means that the term t1 reduces entirely to the term t2 *) 137(* in exactly one eta-reduction step, as defined in Barendregt, *) 138(* Section 3.3.1, page 63. Note that this is true ONLY on t1 of *) 139(* the form (Lam x (App t (Var x))). *) 140(* --------------------------------------------------------------------- *) 141 142 143val ETA_R = 144���ETA_R : ^term_rel���; 145 146val ETA_R_patterns = [���^ETA_R t1 t2���]; 147 148val ETA_R_rules_tm = 149��� (~(x IN FV t) 150 (* -------------------------------------------- *) ==> 151 (^ETA_R (Lam x (App t (Var x))) t)) 152���; 153 154val (ETA_R_rules_sat,ETA_R_ind_thm) = 155 define_inductive_relations ETA_R_patterns ETA_R_rules_tm; 156 157val ETA_R_inv_thms = prove_inversion_theorems 158 ETA_R_rules_sat ETA_R_ind_thm; 159 160val ETA_R_strong_ind = prove_strong_induction 161 ETA_R_rules_sat ETA_R_ind_thm; 162 163val _ = save_thm ("ETA_R_rules_sat", ETA_R_rules_sat); 164val _ = save_thm ("ETA_R_ind_thm", ETA_R_ind_thm); 165val _ = save_thm ("ETA_R_inv_thms", LIST_CONJ ETA_R_inv_thms); 166val _ = save_thm ("ETA_R_strong_ind", ETA_R_strong_ind); 167 168 169 170 171(* --------------------------------------------------------------------- *) 172(* We claim that ETA_R is a binary relation on the lambda calculus *) 173(* language which is *) 174(* 1) a notion of reduction on the sigma calculus, in the sense of *) 175(* Berendregt, Definition 3.1.2, pg 51 (trivial, since a relation) *) 176(* 2) deterministic *) 177(* --------------------------------------------------------------------- *) 178 179 180(* ETA_R is a deterministic relation. *) 181 182val ETA_R_deterministic = store_thm 183 ("ETA_R_deterministic", 184 ���!t:^term u1 u2. 185 ETA_R t u1 /\ ETA_R t u2 ==> (u1 = u2)���, 186 REWRITE_TAC ETA_R_inv_thms 187 THEN REPEAT STRIP_TAC 188 THEN UNDISCH_TAC ``(t:^term) = Lam x' (App u2 (Var x'))`` 189 THEN ASM_REWRITE_TAC[] 190 THEN REWRITE_TAC[Lam_one_one] 191 THEN REWRITE_TAC[SUB_term] 192 THEN REWRITE_TAC[SUB] 193 THEN REWRITE_TAC[term_one_one] 194 THEN REWRITE_TAC[GSYM Lam_one_one] 195 THEN STRIP_TAC 196 THEN IMP_RES_TAC SUB_RENAME_TERM 197 THEN POP_ASSUM (MP_TAC o SPEC ���Var x:^term���) 198 THEN IMP_RES_THEN REWRITE_THM subst_EMPTY 199 ); 200 201(* Note that ETA_R is not reflexive, symmetric, or transitive. *) 202 203(* ETA_R is monotonically decreasing with respect to free variables. *) 204 205val ETA_FV = store_thm 206 ("ETA_FV", 207 ���!t1:^term t2. ETA_R t1 t2 ==> 208 (FV t2 SUBSET FV t1)���, 209 rule_induct ETA_R_strong_ind 210 THEN REWRITE_TAC[FV_term] 211 THEN REPEAT STRIP_TAC 212 THEN REWRITE_TAC[SUBSET_DEF] 213 THEN REPEAT STRIP_TAC 214 THEN IMP_RES_TAC IN_NOT_IN 215 THEN REWRITE_TAC[IN_UNION,IN_DIFF] 216 THEN ASM_REWRITE_TAC[IN] 217 ); 218 219 220 221(* --------------------------------------------------------------- *) 222(* If substituting one variable for another across a term does not *) 223(* change the term, then either the variables were the same, or *) 224(* the substitution never happened because the target variable did *) 225(* not appear free in the term. *) 226(* --------------------------------------------------------------- *) 227 228val SUBST_IS_SAME = store_thm 229 ("SUBST_IS_SAME", 230 ���!t:^term x y. ((t <[ [x,Var y]) = t) ==> 231 ((x = y) \/ ~(x IN FV t))���, 232 MUTUAL_INDUCT_THEN term_height_induct ASSUME_TAC 233 THEN REPEAT GEN_TAC 234 THENL (* 4 subgoals *) 235 [ REWRITE_TAC[SUB_term,term_one_one,FV_term,IN], 236 237 REWRITE_TAC[SUB_term,SUB] 238 THEN COND_CASES_TAC 239 THENL 240 [ REWRITE_TAC[term_one_one] 241 THEN DISCH_TAC 242 THEN ASM_REWRITE_TAC[], 243 244 REWRITE_TAC[FV_term,IN] 245 THEN FIRST_ASSUM (REWRITE_THM o GSYM) 246 ], 247 248 REWRITE_TAC[SUB_term,term_one_one,FV_term,IN_UNION] 249 THEN STRIP_TAC 250 THEN RES_TAC 251 THEN ASM_REWRITE_TAC[], 252 253 SIMPLE_SUBST_TAC 254 THEN REWRITE_TAC[term_one_one,FV_term,IN_DIFF,IN] 255 THEN REWRITE_TAC[GSYM (ASSUME ���~((z:var) = x')���)] 256 THEN STRIP_TAC 257 THEN RES_TAC 258 THEN ASM_REWRITE_TAC[] 259 ] 260 ); 261 262 263(* -------------------------------------------------------------------- *) 264(* The following is remarkably simple, given that Lam x u = Lam x' u' *) 265(* for many choices of x', u'. *) 266(* -------------------------------------------------------------------- *) 267 268val ETA_R_equals = store_thm 269 ("ETA_R_equals", 270 ���(!x t:^term. ETA_R (Var x) t = F) /\ 271 (!t u t':^term. ETA_R (App t u) t' = F) /\ 272 (!x u t:^term. ETA_R (Lam x u) t = 273 ~(x IN FV t) /\ (u = App t (Var x)))���, 274 REWRITE_TAC ETA_R_inv_thms 275 THEN REWRITE_TAC[term_distinct,term_one_one] 276 THEN REPEAT STRIP_TAC 277 THEN EQ_TAC 278 THEN STRIP_TAC 279 THENL 280 [ IMP_RES_TAC Lam_one_one 281 THEN POP_ASSUM (REWRITE_ALL_THM o SYM) 282 THEN UNDISCH_LAST_TAC 283 THEN REWRITE_TAC[SUB_term] 284 THEN IMP_RES_THEN REWRITE_THM subst_EMPTY 285 THEN REWRITE_TAC[SUB_term,SUB] 286 THEN REWRITE_TAC[term_one_one] 287 THEN DISCH_TAC 288 THEN IMP_RES_TAC SUBST_IS_SAME 289 THEN ASM_REWRITE_TAC[], 290 291 EXISTS_TAC ���x:var��� 292 THEN ASM_REWRITE_TAC[] 293 ] 294 ); 295 296 297(* --------------------------------------------------------------------- *) 298(* Now we claim that using the results of theory "reduction", that *) 299(* 1) RED1 ETA_R, RED ETA_R, and REQ ETA_R are compatible, *) 300(* 2) RED ETA_R is a reduction relation, *) 301(* 3) REQ ETA_R is an equality relation, *) 302(* 4) various theorems and relations hold (see the theory "reduction") *) 303(* --------------------------------------------------------------------- *) 304 305 306(* --------------------------------------------------------------------- *) 307(* Now we begin to prove the Church-Rosser theorem for ETA_R. *) 308(* --------------------------------------------------------------------- *) 309 310 311(* Barendregt Proposition 3.3.3, ETA_R is substitutive. *) 312 313val ETA_R_SUBSTITUTIVE = store_thm 314 ("ETA_R_SUBSTITUTIVE", 315 ���SUBSTITUTIVE (ETA_R:^term_rel)���, 316 REWRITE_TAC[SUBSTITUTIVE] 317 THEN REPEAT GEN_TAC 318 THEN DISCH_THEN (STRIP_ASSUME_TAC o REWRITE_RULE ETA_R_inv_thms) 319 THEN ASM_REWRITE_TAC[] 320 THEN DEFINE_NEW_VAR ���(Nx:^term) = App N (Var x')��� 321 THEN FIRST_ASSUM (REWRITE_THM o SYM) 322 THEN SIMPLE_SUBST_TAC 323 THEN REWRITE_TAC[ETA_R_equals] 324 THEN REWRITE_TAC[FV_term_subst] 325 THEN DEP_REWRITE_TAC[NOT_IN_FV_subst] 326 THEN ASM_REWRITE_TAC[] 327 THEN IMP_RES_TAC Lam_one_one 328 THEN POP_TAC 329 THEN POP_ASSUM (REWRITE_THM o GSYM) 330 THEN ASM_REWRITE_TAC[SUB_term,SUB] 331 THEN REWRITE_TAC[term_one_one] 332 THEN IMP_RES_THEN REWRITE_THM subst_EMPTY 333 ); 334 335(* --------------------------------------------------------------- *) 336(* Much of the following development could be moved to the theory *) 337(* "reduction", as it is general for all notions of reduction. *) 338(* --------------------------------------------------------------- *) 339 340(* ----------------------------------------------------- *) 341(* We define what it means for two relations to commute. *) 342(* ----------------------------------------------------- *) 343 344val COMMUTE = 345 new_infixl_definition 346 ("COMMUTE", 347 ���$COMMUTE R1 R2 = 348 (!a b c:'a. R1 a b /\ R2 a c ==> (?d. R2 b d /\ R1 c d))���, 349 250); 350 351(* Define the infix substitution operator, <[, with higher precedence *) 352(* than the substitution-creation operator //, but lower than CONS: *) 353 354val _ = add_infix("<=>",250,LEFT); 355 356(* Now overload the operator <=> to refer to COMMUTE: *) 357 358val _ = overload_on("<=>", 359 ���$COMMUTE:('a->'a->bool)->('a->'a->bool)->bool���) 360handle e => (Raise e); 361 362 363(* Now R |= <> iff R <=> R. *) 364 365val DIAMOND_COMMUTES_SELF = store_thm 366 ("DIAMOND_COMMUTES_SELF", 367 ���!R:'a->'a->bool. DIAMOND R = R <=> R���, 368 REWRITE_TAC[DIAMOND,COMMUTE] 369 ); 370 371 372(* ------------------------------------- *) 373(* We define the union of two relations. *) 374(* ------------------------------------- *) 375 376val UNION_R = 377 new_infixl_definition 378 ("UNION_R", 379 ���$UNION_R R1 R2 = 380 (\(a:'a) (b:'b). R1 a b \/ R2 a b)���, 381 500); 382 383val IN_UNION_R = store_thm 384 ("IN_UNION_R", 385 ���!(R1:'a->'b->bool) R2 x y. (R1 UNION_R R2) x y = R1 x y \/ R2 x y���, 386 REWRITE_TAC[UNION_R] 387 THEN BETA_TAC 388 THEN REWRITE_TAC[] 389 ); 390 391 392(* --------------------------------------------------------- *) 393(* We prove the Hindley-Rosen Lemma on the Diamond property. *) 394(* --------------------------------------------------------- *) 395 396val DIAMOND_TC_UNION1 = TAC_PROOF(([], 397 ���!R1 R2 (a:'a) b. TC (R1 UNION_R R2) a b ==> 398 (DIAMOND R1 /\ DIAMOND R2 /\ (R1 <=> R2) ==> 399 (!c. (R1 UNION_R R2) a c ==> 400 (?d. (R1 UNION_R R2) b d /\ TC (R1 UNION_R R2) c d)))���), 401 GEN_TAC 402 THEN GEN_TAC 403 THEN TC_INDUCT_TAC 404 THEN CONJ_TAC 405 THENL 406 [ REWRITE_TAC[IN_UNION_R] 407 THEN REPEAT STRIP_TAC 408 THEN REWRITE_ALL_TAC[DIAMOND,COMMUTE] 409 THEN RES_TAC 410 THEN EXISTS_TAC ���d':'a��� 411 THEN ASM_REWRITE_TAC[] 412 THEN MATCH_MP_TAC TC_SUBSET 413 THEN REWRITE_TAC[IN_UNION_R] 414 THEN ASM_REWRITE_TAC[], 415 416 REPEAT GEN_TAC 417 THEN STRIP_TAC 418 THEN DISCH_THEN REWRITE_ALL_THM 419 THEN GEN_TAC 420 THEN DISCH_TAC 421 THEN RES_TAC 422 THEN RES_TAC 423 THEN EXISTS_TAC ���d':'a��� 424 THEN ASM_REWRITE_TAC[] 425 THEN IMP_RES_TAC TC_TRANS 426 ] 427 ); 428 429val DIAMOND_TC_UNION2 = TAC_PROOF(([], 430 ���!R1 R2 (a:'a) b. TC (R1 UNION_R R2) a b ==> 431 (DIAMOND R1 /\ DIAMOND R2 /\ (R1 <=> R2) ==> 432 (!c. TC (R1 UNION_R R2) a c ==> 433 (?d. TC (R1 UNION_R R2) b d /\ TC (R1 UNION_R R2) c d)))���), 434 GEN_TAC 435 THEN GEN_TAC 436 THEN TC_INDUCT_TAC 437 THEN CONJ_TAC 438 THENL 439 [ REPEAT STRIP_TAC 440 THEN IMP_RES_TAC DIAMOND_TC_UNION1 441 THEN EXISTS_TAC ���d:'a��� 442 THEN ASM_REWRITE_TAC[] 443 THEN IMP_RES_TAC TC_SUBSET, 444 445 REPEAT GEN_TAC 446 THEN STRIP_TAC 447 THEN DISCH_THEN REWRITE_ALL_THM 448 THEN GEN_TAC 449 THEN DISCH_TAC 450 THEN RES_TAC 451 THEN RES_TAC 452 THEN EXISTS_TAC ���d':'a��� 453 THEN ASM_REWRITE_TAC[] 454 THEN IMP_RES_TAC TC_TRANS 455 ] 456 ); 457 458(* -------------------------------------------- *) 459(* Hindley-Rosen Lemma on the Diamond property. *) 460(* Barendregt Proposition 3.3.5(i) (page 64): *) 461(* -------------------------------------------- *) 462 463val DIAMOND_TC_UNION = store_thm 464 ("DIAMOND_TC_UNION", 465 ���!(R1:'a->'a->bool) R2. 466 DIAMOND R1 /\ DIAMOND R2 /\ (R1 <=> R2) ==> 467 DIAMOND (TC (R1 UNION_R R2))���, 468 REPEAT STRIP_TAC 469 THEN REWRITE_TAC[DIAMOND] 470 THEN REPEAT STRIP_TAC 471 THEN IMP_RES_TAC DIAMOND_TC_UNION2 472 THEN EXISTS_TAC ``d'':'a`` 473 THEN ASM_REWRITE_TAC[] 474 ); 475 476 477val RED1_COMPAT = REWRITE_RULE[compatible] RED1_compatible; 478 479 480(* -------------------------------------------------------------- *) 481(* We now prove that the reduction based on a notion which is the *) 482(* union of two notions of reduction, is itself a union of the *) 483(* reductions of the two notions. *) 484(* -------------------------------------------------------------- *) 485 486val RED1_UNION1 = TAC_PROOF(([], 487 ���!R1 R2 R t1:^term t2. 488 RED1 R t1 t2 ==> 489 (R = R1 UNION_R R2) ==> 490 (RED1 R1 UNION_R RED1 R2) t1 t2���), 491 GEN_TAC THEN GEN_TAC 492 THEN rule_induct RED1_ind_thm 493 THEN REPEAT STRIP_TAC (* 4 subgoals *) 494 THEN POP_ASSUM REWRITE_ALL_THM 495 THEN REWRITE_ALL_TAC[IN_UNION_R] 496 THEN POP_ASSUM STRIP_ASSUME_TAC 497 THEN IMP_RES_TAC RED1_rules_sat 498 THEN ASM_REWRITE_TAC[] 499 ); 500 501val RED1_UNION2 = TAC_PROOF(([], 502 ���!R2 R1 t1:^term t2. RED1 R1 t1 t2 ==> 503 RED1 (R1 UNION_R R2) t1 t2���), 504 GEN_TAC 505 THEN rule_induct RED1_ind_thm 506 THEN REPEAT STRIP_TAC (* 4 subgoals *) 507 THENL 508 [ DEP_REWRITE_TAC[RED1_rules_sat] 509 THEN ASM_REWRITE_TAC[IN_UNION_R], 510 511 IMP_RES_TAC RED1_rules_sat 512 THEN ASM_REWRITE_TAC[], 513 514 IMP_RES_TAC RED1_rules_sat 515 THEN ASM_REWRITE_TAC[], 516 517 IMP_RES_TAC RED1_rules_sat 518 THEN ASM_REWRITE_TAC[] 519 ] 520 ); 521 522val RED1_UNION3 = TAC_PROOF(([], 523 ���!R1 R2 t1:^term t2. RED1 R2 t1 t2 ==> 524 RED1 (R1 UNION_R R2) t1 t2���), 525 GEN_TAC 526 THEN rule_induct RED1_ind_thm 527 THEN REPEAT STRIP_TAC (* 4 subgoals *) 528 THENL 529 [ DEP_REWRITE_TAC[RED1_rules_sat] 530 THEN ASM_REWRITE_TAC[IN_UNION_R], 531 532 IMP_RES_TAC RED1_rules_sat 533 THEN ASM_REWRITE_TAC[], 534 535 IMP_RES_TAC RED1_rules_sat 536 THEN ASM_REWRITE_TAC[], 537 538 IMP_RES_TAC RED1_rules_sat 539 THEN ASM_REWRITE_TAC[] 540 ] 541 ); 542 543val RED1_UNION = store_thm 544 ("RED1_UNION", 545 ���!R1:^term_rel R2. RED1 (R1 UNION_R R2) = (RED1 R1 UNION_R RED1 R2)���, 546 CONV_TAC (TOP_DEPTH_CONV FUN_EQ_CONV) 547 THEN REPEAT GEN_TAC 548 THEN EQ_TAC 549 THEN REPEAT STRIP_TAC 550 THENL 551 [ MATCH_MP_TAC (IMP2AND RED1_UNION1) 552 THEN EXISTS_TAC ���(R1:^term_rel) UNION_R R2��� 553 THEN ASM_REWRITE_TAC[], 554 555 POP_ASSUM (STRIP_ASSUME_TAC o REWRITE_RULE[IN_UNION_R]) 556 THENL 557 [ MATCH_MP_TAC RED1_UNION2, 558 MATCH_MP_TAC RED1_UNION3 559 ] 560 THEN FIRST_ASSUM ACCEPT_TAC 561 ] 562 ); 563 564(* --------------------------------------------------------------------- *) 565(* The above was for one-step reduction, RED1. We now prove the *) 566(* corresponding property for the reflexive, transitive closure, RED. *) 567(* --------------------------------------------------------------------- *) 568 569val RED_UNION1 = TAC_PROOF(([], 570 ���!R1 R2 R t1:^term t2. RED R t1 t2 ==> 571 (R = R1 UNION_R R2) ==> 572 TC (RED R1 UNION_R RED R2) t1 t2���), 573 GEN_TAC THEN GEN_TAC 574 THEN rule_induct RED_ind_thm 575 THEN REPEAT STRIP_TAC (* 3 subgoals *) 576 THEN POP_ASSUM REWRITE_ALL_THM 577 THENL 578 [ MATCH_MP_TAC TC_SUBSET 579 THEN REWRITE_ALL_TAC[RED1_UNION] 580 THEN REWRITE_ALL_TAC[IN_UNION_R] 581 THEN POP_ASSUM STRIP_ASSUME_TAC 582 THEN IMP_RES_TAC RED_rules_sat 583 THEN ASM_REWRITE_TAC[], 584 585 MATCH_MP_TAC TC_SUBSET 586 THEN REWRITE_TAC[IN_UNION_R] 587 THEN REWRITE_TAC[RED_rules_sat], 588 589 IMP_RES_TAC TC_TRANS 590 ] 591 ); 592 593val RED_UNION2 = TAC_PROOF(([], 594 ���!R2 R1 t1:^term t2. RED R1 t1 t2 ==> 595 RED (R1 UNION_R R2) t1 t2���), 596 GEN_TAC 597 THEN rule_induct RED_ind_thm 598 THEN REPEAT STRIP_TAC (* 3 subgoals *) 599 THENL 600 [ DEP_REWRITE_TAC[RED_rules_sat] 601 THEN REWRITE_TAC[RED1_UNION] 602 THEN ASM_REWRITE_TAC[IN_UNION_R], 603 604 REWRITE_TAC[RED_rules_sat], 605 606 IMP_RES_TAC RED_rules_sat 607 ] 608 ); 609 610val RED_UNION3 = TAC_PROOF(([], 611 ���!R1 R2 t1:^term t2. RED R2 t1 t2 ==> 612 RED (R1 UNION_R R2) t1 t2���), 613 GEN_TAC 614 THEN rule_induct RED_ind_thm 615 THEN REPEAT STRIP_TAC (* 3 subgoals *) 616 THENL 617 [ DEP_REWRITE_TAC[RED_rules_sat] 618 THEN REWRITE_TAC[RED1_UNION] 619 THEN ASM_REWRITE_TAC[IN_UNION_R], 620 621 REWRITE_TAC[RED_rules_sat], 622 623 IMP_RES_TAC RED_rules_sat 624 ] 625 ); 626 627val RED_UNION4 = TAC_PROOF(([], 628 ���!R1 R2 t1:^term t2. TC (RED R1 UNION_R RED R2) t1 t2 ==> 629 RED (R1 UNION_R R2) t1 t2���), 630 GEN_TAC 631 THEN GEN_TAC 632 THEN TC_INDUCT_TAC 633 THEN CONJ_TAC 634 THENL 635 [ REWRITE_TAC[IN_UNION_R] 636 THEN REPEAT STRIP_TAC 637 THENL 638 [ MATCH_MP_TAC RED_UNION2, 639 MATCH_MP_TAC RED_UNION3 640 ] 641 THEN FIRST_ASSUM ACCEPT_TAC, 642 643 REPEAT STRIP_TAC 644 THEN IMP_RES_TAC RED_rules_sat 645 ] 646 ); 647 648(* Remark of Barendregt at bottom of page 64. *) 649 650val RED_UNION = store_thm 651 ("RED_UNION", 652 ���!R1:^term_rel R2. RED (R1 UNION_R R2) = TC (RED R1 UNION_R RED R2)���, 653 CONV_TAC (TOP_DEPTH_CONV FUN_EQ_CONV) 654 THEN REPEAT GEN_TAC 655 THEN EQ_TAC 656 THEN REPEAT STRIP_TAC 657 THENL 658 [ IMP_RES_TAC RED_UNION1 659 THEN POP_ASSUM MATCH_MP_TAC 660 THEN REFL_TAC, 661 662 IMP_RES_TAC RED_UNION4 663 ] 664 ); 665 666 667(* Barendregt Proposition 3.3.5(ii) (page 64): *) 668 669val COMMUTE_CHURCH_ROSSER = store_thm 670 ("COMMUTE_CHURCH_ROSSER", 671 ���!R1:^term_rel R2. 672 CHURCH_ROSSER R1 /\ CHURCH_ROSSER R2 /\ 673 (RED R1 <=> RED R2) ==> 674 CHURCH_ROSSER (R1 UNION_R R2)���, 675 REWRITE_TAC[CHURCH_ROSSER] 676 THEN REWRITE_TAC[RED_UNION] 677 THEN REWRITE_TAC[DIAMOND_TC_UNION] 678 ); 679 680 681(* -------------------------------------------------------------- *) 682(* We now prove Barendregt's Lemma 3.3.6, as a way to prove that *) 683(* the reflexive, transitive closures of two relations commute. *) 684(* -------------------------------------------------------------- *) 685 686val COMMUTE_TC_RC1 = TAC_PROOF(([], 687 ���!R2 a b. 688 RC R2 a b ==> 689 !R1. 690 (!a b c:'a. R1 a b /\ R2 a c ==> 691 ?d. TC (RC R2) b d /\ RC R1 c d) ==> 692 (!c. R1 a c ==> 693 ?d. RC R1 b d /\ TC (RC R2) c d)���), 694 GEN_TAC 695 THEN RC_INDUCT_TAC 696 THEN REPEAT STRIP_TAC 697 THENL 698 [ RES_TAC 699 THEN EXISTS_TAC ���d:'a��� 700 THEN ASM_REWRITE_TAC[], 701 702 EXISTS_TAC ``c:'a`` 703 THEN DEP_REWRITE_TAC[TC_SUBSET] 704 THEN REWRITE_TAC[RC_REFLEXIVE] 705 THEN MATCH_MP_TAC RC_SUBSET 706 THEN ASM_REWRITE_TAC[] 707 ] 708 ); 709 710val COMMUTE_TC_RC2 = TAC_PROOF(([], 711 ���!R1 a b. 712 RC R1 a b ==> 713 !R2. 714 (!a b c:'a. R1 a b /\ R2 a c ==> 715 ?d. TC (RC R2) b d /\ RC R1 c d) ==> 716 (!c. RC R2 a c ==> 717 ?d. TC (RC R2) b d /\ RC R1 c d)���), 718 GEN_TAC 719 THEN RC_INDUCT_TAC 720 THEN REPEAT STRIP_TAC 721 THENL 722 [ IMP_RES_TAC COMMUTE_TC_RC1 723 THEN EXISTS_TAC ���d:'a��� 724 THEN ASM_REWRITE_TAC[], 725 726 EXISTS_TAC ``c:'a`` 727 THEN DEP_REWRITE_TAC[TC_SUBSET] 728 THEN ASM_REWRITE_TAC[RC_REFLEXIVE] 729 ] 730 ); 731 732val COMMUTE_TC_RC3 = TAC_PROOF(([], 733 ���!R2 a b. 734 TC (RC R2) a b ==> 735 !R1. 736 (!a b c:'a. R1 a b /\ R2 a c ==> 737 ?d. TC (RC R2) b d /\ RC R1 c d) ==> 738 (!c. RC R1 a c ==> 739 ?d. RC R1 b d /\ TC (RC R2) c d)���), 740 GEN_TAC 741 THEN TC_INDUCT_TAC 742 THEN REPEAT STRIP_TAC 743 THENL 744 [ IMP_RES_TAC COMMUTE_TC_RC2 745 THEN EXISTS_TAC ���d:'a��� 746 THEN ASM_REWRITE_TAC[], 747 748 RES_TAC 749 THEN RES_TAC 750 THEN EXISTS_TAC ``d':'a`` 751 THEN ASM_REWRITE_TAC[] 752 THEN IMP_RES_TAC TC_TRANS 753 ] 754 ); 755 756val COMMUTE_TC_RC4 = TAC_PROOF(([], 757 ���!R1 a b. 758 TC (RC R1) a b ==> 759 !R2. 760 (!a b c:'a. R1 a b /\ R2 a c ==> 761 ?d. TC (RC R2) b d /\ RC R1 c d) ==> 762 (!c. TC (RC R2) a c ==> 763 ?d. TC (RC R2) b d /\ TC (RC R1) c d)���), 764 GEN_TAC 765 THEN TC_INDUCT_TAC 766 THEN REPEAT STRIP_TAC 767 THENL 768 [ IMP_RES_TAC COMMUTE_TC_RC3 769 THEN EXISTS_TAC ���d:'a��� 770 THEN ASM_REWRITE_TAC[] 771 THEN MATCH_MP_TAC TC_SUBSET 772 THEN ASM_REWRITE_TAC[], 773 774 RES_TAC 775 THEN RES_TAC 776 THEN EXISTS_TAC ``d':'a`` 777 THEN ASM_REWRITE_TAC[] 778 THEN IMP_RES_TAC TC_TRANS 779 ] 780 ); 781 782(* Barendregt Lemma 3.3.6, page 65. *) 783 784val COMMUTE_TC_RC = store_thm 785 ("COMMUTE_TC_RC", 786 ���!R1 R2. 787 (!a b c:'a. R1 a b /\ R2 a c ==> 788 ?d. TC (RC R2) b d /\ RC R1 c d) ==> 789 (TC (RC R1) <=> TC (RC R2))���, 790 REWRITE_TAC[COMMUTE] 791 THEN REPEAT STRIP_TAC 792 THEN IMP_RES_TAC COMMUTE_TC_RC4 793 THEN EXISTS_TAC ���d:'a��� 794 THEN ASM_REWRITE_TAC[] 795 ); 796 797 798val RED1_ETA_FV = MATCH_MP RED1_FV ETA_FV; 799val RED1_BETA_FV = MATCH_MP RED1_FV BETA_FV; 800 801 802val RED1_ETA_RENAME = store_thm 803 ("RED1_ETA_RENAME", 804 ���!t1:^term t2 t1' x y. 805 RED1 ETA_R t1 t2 /\ (Lam x t1 = Lam y t1') ==> 806 (Lam x t2 = Lam y (t2 <[ [x, Var y]))���, 807 REPEAT STRIP_TAC 808 THEN IMP_RES_TAC RED1_ETA_FV 809 THEN IMP_RES_TAC LAMBDA_RENAME 810 ); 811 812 813val [RED1_R, RED1_App1, RED1_App2, RED1_Lam] = CONJUNCTS RED1_rules_sat; 814 815val RED1_ETA_SUBSTITUTIVE = REWRITE_RULE[SUBSTITUTIVE] 816 (MATCH_MP RED1_SUBSTITUTIVE ETA_R_SUBSTITUTIVE); 817 818(* This is necessary for when we change a bound variable: *) 819 820val RED1_ETA_CHANGE_VAR = store_thm 821 ("RED1_ETA_CHANGE_VAR", 822 ���!t1:^term t2 x y t1'. 823 RED1 ETA_R t1 t2 /\ (Lam x t1 = Lam y t1') ==> 824 RED1 ETA_R t1' (t2 <[ [x, Var y])���, 825 REPEAT STRIP_TAC 826 THEN IMP_RES_THEN REWRITE_THM Lam_one_one_RENAME 827 THEN MATCH_MP_TAC RED1_ETA_SUBSTITUTIVE 828 THEN ASM_REWRITE_TAC[] 829 ); 830 831 832val RED1_ETA_cases = store_thm 833 ("RED1_ETA_cases", 834 ���(!a t2:^term. 835 RED1 ETA_R (Con a) t2 ==> F) /\ 836 (!x t2:^term. 837 RED1 ETA_R (Var x) t2 ==> F) /\ 838 (!t u t2:^term. 839 RED1 ETA_R (App t u) t2 ==> 840 ((?t'. RED1 ETA_R t t' /\ (t2 = App t' u)) \/ 841 (?u'. RED1 ETA_R u u' /\ (t2 = App t u')))) /\ 842 (!x t t2:^term. 843 RED1 ETA_R (Lam x t) t2 ==> 844 ((~(x IN FV t2) /\ (t = App t2 (Var x)))) \/ 845 (?t'. RED1 ETA_R t t' /\ (t2 = Lam x t')))���, 846 REPEAT CONJ_TAC 847 THEN REPEAT GEN_TAC THEN DISCH_THEN (STRIP_ASSUME_TAC o 848 REWRITE_RULE[term_distinct,term_one_one] o 849 ONCE_REWRITE_RULE[RED1_inv_thms]) 850 THENL (* 7 subgoals *) 851 [ UNDISCH_LAST_TAC 852 THEN REWRITE_TAC ETA_R_inv_thms 853 THEN REWRITE_TAC[term_distinct], 854 855 UNDISCH_LAST_TAC 856 THEN REWRITE_TAC ETA_R_inv_thms 857 THEN REWRITE_TAC[term_distinct], 858 859 UNDISCH_LAST_TAC 860 THEN REWRITE_TAC ETA_R_inv_thms 861 THEN REWRITE_TAC[term_distinct], 862 863 DISJ1_TAC 864 THEN EXISTS_TAC ���t2':^term��� 865 THEN ASM_REWRITE_TAC[], 866 867 DISJ2_TAC 868 THEN EXISTS_TAC ���u2:^term��� 869 THEN ASM_REWRITE_TAC[], 870 871 IMP_RES_TAC ETA_R_equals 872 THEN ASM_REWRITE_TAC[], 873 874 DISJ2_TAC 875 THEN EXISTS_TAC ���(t2':^term) <[ [x', Var x]��� 876 THEN ASSUM_LIST (ASSUME_TAC o SYM o hd o rev) 877 THEN IMP_RES_THEN IMP_RES_TAC RED1_ETA_RENAME 878 THEN IMP_RES_TAC RED1_ETA_CHANGE_VAR 879 THEN ASM_REWRITE_TAC[] 880 ] 881 ); 882 883val [RED1_ETA_Con_case, RED1_ETA_Var_case, 884 RED1_ETA_App_case, RED1_ETA_Lam_case] 885 = CONJUNCTS RED1_ETA_cases; 886 887val RED1_ETA_App_Var_case = store_thm 888 ("RED1_ETA_App_Var_case", 889 ���!t x t2:^term. 890 RED1 ETA_R (App t (Var x)) t2 ==> 891 (?t'. RED1 ETA_R t t' /\ (t2 = App t' (Var x)))���, 892 REPEAT GEN_TAC THEN DISCH_THEN (STRIP_ASSUME_TAC o 893 REWRITE_RULE[term_distinct,term_one_one] o 894 ONCE_REWRITE_RULE[RED1_inv_thms]) 895 THENL (* 3 subgoals *) 896 [ UNDISCH_LAST_TAC 897 THEN REWRITE_TAC[ETA_R_equals], 898 899 EXISTS_TAC ���t2':^term��� 900 THEN ASM_REWRITE_TAC[], 901 902 UNDISCH_LAST_TAC 903 THEN POP_TAC 904 THEN POP_ASSUM (REWRITE_THM o SYM) 905 THEN DISCH_TAC 906 THEN IMP_RES_TAC RED1_ETA_Var_case 907 ] 908 ); 909 910 911val RC_RED1_COMPAT = REWRITE_RULE[compatible] RC_RED1_compatible; 912val TC_RC_RED1_COMPAT = REWRITE_RULE[compatible] TC_RC_RED1_compatible; 913 914 915(* RC -->eta satisfies the diamond property. *) 916 917(* Barendregt Lemma 3.3.7, page 65. *) 918 919val DIAMOND_RED1_ETA_LEMMA = store_thm 920 ("DIAMOND_RED1_ETA_LEMMA", 921 ���!R (M:^term) M1. RED1 R M M1 ==> 922 !M2. RED1 ETA_R M M2 /\ (R = ETA_R) ==> 923 ?M3. RC (RED1 ETA_R) M1 M3 /\ RC (RED1 ETA_R) M2 M3���, 924 rule_induct RED1_strong_ind 925 THEN REPEAT STRIP_TAC (* 4 subgoals *) 926 THEN POP_ASSUM REWRITE_ALL_THM 927 THENL 928 [ (* Case 1: M --> M1 is \x.Px --> P, and M=t1, M1 = P = t2. *) 929 IMP_RES_TAC (hd ETA_R_inv_thms) 930 THEN UNDISCH_LAST_TAC 931 THEN POP_ASSUM REWRITE_ALL_THM 932 THEN IMP_RES_TAC RED1_ETA_Lam_case 933 THENL 934 [ (* Case 1.1: M2 = t2 (= M1). *) 935 POP_ASSUM (REWRITE_ALL_THM o REWRITE_RULE[term_one_one]) 936 THEN STRIP_TAC 937 THEN EXISTS_TAC ``M2:^term`` 938 THEN REWRITE_TAC[RC_REFLEXIVE], 939 940 (* Case 1.2: M2 = \x.t' = \x.P'x and P --> P'. *) 941 IMP_RES_TAC RED1_ETA_App_Var_case (* t'' = P'. *) 942 THEN POP_ASSUM REWRITE_ALL_THM 943 THEN DISCH_TAC 944 THEN EXISTS_TAC ``t'':^term`` (* Take M3 = P'. *) 945 THEN DEP_REWRITE_TAC[RC_SUBSET] 946 THEN ASM_REWRITE_TAC[] 947 THEN MATCH_MP_TAC RED1_R 948 THEN MATCH_MP_TAC ETA_R_rules_sat 949 THEN IMP_RES_THEN MATCH_MP_TAC NOT_IN_SUBSET 950 THEN IMP_RES_TAC RED1_ETA_FV 951 ], 952 953 (* Case 3: M --> M1 is PZ --> P'Z and is conseq of P --> P'. *) 954 (* P = t1, Z = u, P' = t2. *) 955 IMP_RES_TAC RED1_ETA_App_case 956 THENL 957 [ (* Case 3.1: P --> P'', M2 = P''Z. P'' = t'. *) 958 POP_ASSUM REWRITE_ALL_THM 959 THEN RES_TAC 960 (* By ind. hyp, ?P'''. P' -->= P''' /\ P'' -->= P'''. 961 P''' appears as M3. *) 962 THEN EXISTS_TAC ``App M3 u:^term`` (* Take M3 = P'''Z. *) 963 THEN IMP_RES_THEN REWRITE_THM RC_RED1_COMPAT, 964 965 (* Case 3.2: Z --> Z', M2 = P'Z'. Z' = u'. *) 966 POP_ASSUM REWRITE_ALL_THM 967 THEN EXISTS_TAC ``App t2 u':^term`` (* Take M3 = P'Z'. *) 968 THEN DEP_REWRITE_TAC[RC_SUBSET] 969 THEN IMP_RES_THEN REWRITE_THM RED1_COMPAT 970 ], 971 972 (* Case 2: M --> M1 is ZP --> ZP' and is conseq of P --> P'. *) 973 (* Z = t, P = u1, P' = u2. *) 974 IMP_RES_TAC RED1_ETA_App_case 975 THENL 976 [ (* Case 2.1: Z --> Z', M2 = Z'P'. Z' = t'. *) 977 POP_ASSUM REWRITE_ALL_THM 978 THEN EXISTS_TAC ``App t' u2:^term`` (* Take M3 = Z'P'. *) 979 THEN DEP_REWRITE_TAC[RC_SUBSET] 980 THEN IMP_RES_THEN REWRITE_THM RED1_COMPAT, 981 982 (* Case 2.2: P --> P'', M2 = ZP''. P'' = u'. *) 983 POP_ASSUM REWRITE_ALL_THM 984 THEN RES_TAC 985 (* By ind. hyp, ?P'''. P' -->= P''' /\ P'' -->= P'''. 986 P''' appears as M3. *) 987 THEN EXISTS_TAC ``App t M3:^term`` (* Take M3 = ZP'''. *) 988 THEN IMP_RES_THEN REWRITE_THM RC_RED1_COMPAT 989 ], 990 991 (* Case 4: M --> M1 is \x.P --> \x.P' and is conseq of P --> P'. *) 992 (* P = t1, P' = t2. *) 993 IMP_RES_TAC RED1_ETA_Lam_case 994 THENL 995 [ (* Case 4.2: P = P0 x, P0=M2, and so M --> M2 is \x.P0 x --> P0. *) 996 POP_ASSUM REWRITE_ALL_THM 997 THEN IMP_RES_TAC RED1_ETA_App_Var_case (* t' = P0'. *) 998 THEN POP_ASSUM REWRITE_ALL_THM 999 THEN EXISTS_TAC ``t':^term`` (* Take M3 = P0'. *) 1000 THEN DEP_REWRITE_TAC[RC_SUBSET] 1001 THEN ASM_REWRITE_TAC[] 1002 THEN MATCH_MP_TAC RED1_R 1003 THEN MATCH_MP_TAC ETA_R_rules_sat 1004 THEN IMP_RES_THEN MATCH_MP_TAC NOT_IN_SUBSET 1005 THEN MATCH_MP_TAC RED1_ETA_FV 1006 THEN ASM_REWRITE_TAC[], 1007 1008 (* Case 4.1: M2 = \x.P'' with P --> P''. P'' = t'. *) 1009 POP_ASSUM REWRITE_ALL_THM 1010 THEN RES_TAC 1011 (* By ind. hyp, ?P'''. P' -->= P''' /\ P'' -->= P'''. 1012 P''' appears as M3. *) 1013 THEN EXISTS_TAC ``Lam x M3:^term`` (* Take M3 = \x.P'''. *) 1014 THEN IMP_RES_THEN REWRITE_THM RC_RED1_COMPAT 1015 ] 1016 ] 1017 ); 1018 1019val DIAMOND_RED1_ETA_LEMMA1 = 1020 REWRITE_RULE[] (SPEC ``ETA_R:^term_rel`` DIAMOND_RED1_ETA_LEMMA); 1021 1022val DIAMOND_RC_RED1_ETA1 = TAC_PROOF(([], 1023 ���!(M:^term) M1. 1024 RC (RED1 ETA_R) M M1 ==> 1025 !M2. RED1 ETA_R M M2 ==> 1026 ?M3. RC (RED1 ETA_R) M1 M3 /\ RC (RED1 ETA_R) M2 M3���), 1027 RC_INDUCT_TAC 1028 THEN REPEAT STRIP_TAC 1029 THENL 1030 [ IMP_RES_TAC DIAMOND_RED1_ETA_LEMMA1 1031 THEN EXISTS_TAC ���M3':^term��� 1032 THEN ASM_REWRITE_TAC[], 1033 1034 EXISTS_TAC ``M2:^term`` 1035 THEN REWRITE_TAC[RC_REFLEXIVE] 1036 THEN MATCH_MP_TAC RC_SUBSET 1037 THEN ASM_REWRITE_TAC[] 1038 ] 1039 ); 1040 1041val DIAMOND_RC_RED1_ETA2 = TAC_PROOF(([], 1042 ���!(M:^term) M1. 1043 RC (RED1 ETA_R) M M1 ==> 1044 !M2. RC (RED1 ETA_R) M M2 ==> 1045 ?M3. RC (RED1 ETA_R) M1 M3 /\ RC (RED1 ETA_R) M2 M3���), 1046 RC_INDUCT_TAC 1047 THEN REPEAT STRIP_TAC 1048 THENL 1049 [ IMP_RES_TAC DIAMOND_RC_RED1_ETA1 1050 THEN EXISTS_TAC ���M3:^term��� 1051 THEN ASM_REWRITE_TAC[], 1052 1053 EXISTS_TAC ``M2:^term`` 1054 THEN ASM_REWRITE_TAC[RC_REFLEXIVE] 1055 ] 1056 ); 1057 1058val DIAMOND_RC_RED1_ETA_LEMMA = store_thm 1059 ("DIAMOND_RC_RED1_ETA_LEMMA", 1060 ���!(M:^term) M1 M2. 1061 RC (RED1 ETA_R) M M1 /\ RC (RED1 ETA_R) M M2 ==> 1062 ?M3. RC (RED1 ETA_R) M1 M3 /\ RC (RED1 ETA_R) M2 M3���, 1063 REPEAT STRIP_TAC 1064 THEN IMP_RES_TAC DIAMOND_RC_RED1_ETA2 1065 THEN EXISTS_TAC ���M3':^term��� 1066 THEN ASM_REWRITE_TAC[] 1067 ); 1068 1069val DIAMOND_RC_RED1_ETA = store_thm 1070 ("DIAMOND_RC_RED1_ETA", 1071 ���DIAMOND (RC (RED1 (ETA_R:^term_rel)))���, 1072 REWRITE_TAC[DIAMOND] 1073 THEN REWRITE_TAC[DIAMOND_RC_RED1_ETA_LEMMA] 1074 ); 1075 1076 1077 1078val ETA_R_CHURCH_ROSSER = store_thm 1079 ("ETA_R_CHURCH_ROSSER", 1080 ���CHURCH_ROSSER (ETA_R:^term_rel)���, 1081 REWRITE_TAC[CHURCH_ROSSER] 1082 THEN REWRITE_TAC[GSYM TC_RC_RED1_IS_RED] 1083 THEN MATCH_MP_TAC TC_DIAMOND 1084 THEN REWRITE_TAC[DIAMOND_RC_RED1_ETA] 1085 ); 1086 1087 1088 1089val [RED_RED1, RED_REFL, RED_TRANS] 1090 = CONJUNCTS (CONV_RULE (DEPTH_CONV LEFT_IMP_EXISTS_CONV) RED_rules_sat); 1091 1092 1093val RED1_BETA_Var_case = store_thm 1094 ("RED1_BETA_Var_case", 1095 ���!x t2:^term. 1096 RED1 BETA_R (Var x) t2 ==> F���, 1097 REPEAT GEN_TAC THEN DISCH_THEN (STRIP_ASSUME_TAC o 1098 REWRITE_RULE[term_distinct,term_one_one] o 1099 ONCE_REWRITE_RULE[RED1_inv_thms]) 1100 THEN UNDISCH_ALL_TAC 1101 THEN REWRITE_TAC[BETA_R_inv_thms] 1102 THEN REWRITE_TAC[term_distinct] 1103 ); 1104 1105 1106val RED1_BETA_App_case = store_thm 1107 ("RED1_BETA_App_case", 1108 ���!(t:^term) u t2. 1109 RED1 BETA_R (App t u) t2 ==> 1110 ((?t'. RED1 BETA_R t t' /\ (t2 = App t' u)) \/ 1111 (?u'. RED1 BETA_R u u' /\ (t2 = App t u')) \/ 1112 (?x t'. (t = Lam x t') /\ (t2 = t' <[ [x,u])))���, 1113 REPEAT GEN_TAC THEN DISCH_THEN (STRIP_ASSUME_TAC o 1114 REWRITE_RULE[term_distinct,term_one_one] o 1115 ONCE_REWRITE_RULE[RED1_inv_thms]) 1116 THENL (* 3 subgoals *) 1117 [ DISJ2_TAC 1118 THEN DISJ2_TAC 1119 THEN UNDISCH_LAST_TAC 1120 THEN REWRITE_TAC[BETA_R_inv_thms] 1121 THEN REWRITE_TAC[term_one_one] 1122 THEN STRIP_TAC 1123 THEN EXISTS_TAC ``x:var`` 1124 THEN EXISTS_TAC ``u':^term`` 1125 THEN ASM_REWRITE_TAC[], 1126 1127 DISJ1_TAC 1128 THEN EXISTS_TAC ``t2':^term`` 1129 THEN ASM_REWRITE_TAC[], 1130 1131 DISJ2_TAC 1132 THEN DISJ1_TAC 1133 THEN EXISTS_TAC ``u2:^term`` 1134 THEN ASM_REWRITE_TAC[] 1135 ] 1136 ); 1137 1138 1139val TC_RC_RED1_SUBSTITUTION_REMARK = 1140 REWRITE_RULE[GSYM TC_RC_RED1_IS_RED] BARENDREGT_SUBSTITUTION_REMARK; 1141 1142 1143val RED1_BETA_COMMUTES_RED1_ETA_LEMMA1 = store_thm 1144 ("RED1_BETA_COMMUTES_RED1_ETA_LEMMA1", 1145 ���!R (M:^term) M1. 1146 RED1 R M M1 ==> !M2. BETA_R M M2 /\ (R = ETA_R) ==> 1147 ?M3. RC (RED1 BETA_R) M1 M3 /\ TC (RC (RED1 ETA_R)) M2 M3���, 1148 rule_induct RED1_height_strong_ind 1149 THEN REPEAT STRIP_TAC (* 4 subgoals *) 1150 THEN POP_ASSUM REWRITE_ALL_THM 1151 THENL 1152 [ (* Case 1: ETA M M1, BETA M M2, impossible. *) 1153 UNDISCH_ALL_TAC 1154 THEN REWRITE_TAC (BETA_R_inv_thms :: ETA_R_inv_thms) 1155 THEN STRIP_TAC 1156 THEN ASM_REWRITE_TAC[term_distinct], 1157 1158 (* Case 2: t1 -->e t2, BETA (t1 u) M2. *) 1159 IMP_RES_TAC BETA_R_inv_thms 1160 THEN POP_ASSUM REWRITE_ALL_THM 1161 THEN POP_ASSUM (REWRITE_ALL_THM o REWRITE_RULE[term_one_one]) 1162 THEN IMP_RES_TAC RED1_ETA_Lam_case 1163 THENL 1164 [ (* Case 2.1: u' = t2 x, x not in FV t2. *) 1165 POP_ASSUM REWRITE_ALL_THM 1166 THEN EXISTS_TAC ``App t2 t:^term`` (* Take M3 = P0 Q, = t2 t. *) 1167 THEN REWRITE_TAC[SUB_term,SUB] 1168 THEN IMP_RES_THEN REWRITE_THM subst_EMPTY 1169 THEN DEP_REWRITE_TAC[TC_SUBSET] 1170 THEN REWRITE_TAC[RC_REFLEXIVE], 1171 1172 (* Case 2.2: \x.u' -->e \x.t', u' -->e t', BETA ((\x.u') t) M2. *) 1173 POP_ASSUM REWRITE_ALL_THM 1174 THEN EXISTS_TAC ``(t':^term) <[ [x,t]`` (* Take M3 = P'[x:=Q]. *) 1175 THEN DEP_REWRITE_TAC[TC_SUBSET,RC_SUBSET] 1176 THEN IMP_RES_THEN REWRITE_THM 1177 (REWRITE_RULE[SUBSTITUTIVE] RED1_ETA_SUBSTITUTIVE) 1178 THEN MATCH_MP_TAC RED1_R 1179 THEN REWRITE_TAC[BETA_R_rules_sat] 1180 ], 1181 1182 (* Case 3: t' -->e u2, BETA (t u1) M2. *) 1183 IMP_RES_TAC BETA_R_inv_thms 1184 THEN POP_ASSUM REWRITE_ALL_THM 1185 THEN POP_ASSUM (REWRITE_ALL_THM o REWRITE_RULE[term_one_one]) 1186 THEN EXISTS_TAC ``(u:^term) <[ [x,u2]`` (* Take M3 = P[x:=Q']. *) 1187 THEN DEP_REWRITE_TAC[TC_RC_RED1_SUBSTITUTION_REMARK] 1188 THEN DEP_REWRITE_TAC[TC_SUBSET,RC_SUBSET] 1189 THEN ASM_REWRITE_TAC[] 1190 THEN MATCH_MP_TAC RED1_R 1191 THEN REWRITE_TAC[BETA_R_rules_sat], 1192 1193 (* Case 4: t1 -->e u2, BETA (t u1) M2. *) 1194 IMP_RES_TAC BETA_R_inv_thms 1195 THEN POP_ASSUM REWRITE_ALL_THM 1196 THEN UNDISCH_LAST_TAC 1197 THEN REWRITE_TAC[term_distinct] 1198 ] 1199 ); 1200 1201 1202 1203val RED1_BETA_COMMUTES_RED1_ETA_LEMMA2 = store_thm 1204 ("RED1_BETA_COMMUTES_RED1_ETA_LEMMA2", 1205 ���!R (M:^term) M1. 1206 RED1 R M M1 ==> !M2. RED1 ETA_R M M2 /\ (R = BETA_R) ==> 1207 ?M3. TC (RC (RED1 ETA_R)) M1 M3 /\ RC (RED1 BETA_R) M2 M3���, 1208 rule_induct RED1_height_strong_ind 1209 THEN REPEAT STRIP_TAC (* 4 subgoals *) 1210 THEN POP_ASSUM REWRITE_ALL_THM 1211 THENL 1212 [ (* Case 1: *) 1213 IMP_RES_TAC RED1_BETA_COMMUTES_RED1_ETA_LEMMA1 1214 THEN POP_TAC 1215 THEN REWRITE_ALL_TAC[] 1216 THEN POP_ASSUM STRIP_ASSUME_TAC 1217 THEN EXISTS_TAC ``M3:^term`` 1218 THEN ASM_REWRITE_TAC[], 1219 1220 (* Case 2: *) 1221 IMP_RES_TAC RED1_ETA_App_case 1222 THENL 1223 [ POP_ASSUM REWRITE_ALL_THM 1224 THEN RES_TAC 1225 THEN EXISTS_TAC ``App M3 u:^term`` 1226 THEN IMP_RES_THEN REWRITE_THM TC_RC_RED1_COMPAT 1227 THEN IMP_RES_THEN REWRITE_THM RC_RED1_COMPAT, 1228 1229 POP_ASSUM REWRITE_ALL_THM 1230 THEN EXISTS_TAC ``App t2 u':^term`` 1231 THEN DEP_REWRITE_TAC[TC_SUBSET,RC_SUBSET] 1232 THEN IMP_RES_THEN REWRITE_THM RED1_COMPAT 1233 ], 1234 1235 (* Case 3: *) 1236 IMP_RES_TAC RED1_ETA_App_case 1237 THENL 1238 [ POP_ASSUM REWRITE_ALL_THM 1239 THEN EXISTS_TAC ``App t' u2:^term`` 1240 THEN DEP_REWRITE_TAC[TC_SUBSET,RC_SUBSET] 1241 THEN IMP_RES_THEN REWRITE_THM RED1_COMPAT, 1242 1243 POP_ASSUM REWRITE_ALL_THM 1244 THEN RES_TAC 1245 THEN EXISTS_TAC ``App t M3:^term`` 1246 THEN IMP_RES_THEN REWRITE_THM TC_RC_RED1_COMPAT 1247 THEN IMP_RES_THEN REWRITE_THM RC_RED1_COMPAT 1248 ], 1249 1250 (* Case 4: *) 1251 IMP_RES_TAC RED1_ETA_Lam_case 1252 THENL 1253 [ POP_ASSUM REWRITE_ALL_THM 1254 THEN IMP_RES_TAC RED1_BETA_App_case 1255 THENL (* 3 subgoals *) 1256 [ (* Case 4.1: *) 1257 POP_ASSUM REWRITE_ALL_THM 1258 THEN EXISTS_TAC ``t':^term`` 1259 THEN DEP_REWRITE_TAC[TC_SUBSET,RC_SUBSET] 1260 THEN ASM_REWRITE_TAC[] 1261 THEN MATCH_MP_TAC RED1_R 1262 THEN MATCH_MP_TAC ETA_R_rules_sat 1263 THEN IMP_RES_THEN MATCH_MP_TAC NOT_IN_SUBSET 1264 THEN IMP_RES_TAC RED1_BETA_FV, 1265 1266 (* Case 4.2: *) 1267 POP_ASSUM REWRITE_ALL_THM 1268 THEN IMP_RES_TAC RED1_BETA_Var_case, 1269 1270 (* Case 4.3: *) 1271 POP_ASSUM REWRITE_ALL_THM 1272 THEN POP_ASSUM REWRITE_ALL_THM 1273 THEN EXISTS_TAC ``Lam x' t':^term`` 1274 THEN REWRITE_TAC[RC_REFLEXIVE] 1275 THEN DEP_REWRITE_TAC[ 1276 ONCE_REWRITE_RULE[EQ_SYM_EQ] LAMBDA_CHANGE_BOUND_VAR] 1277 THEN ASM_REWRITE_TAC[GSYM FV_term] 1278 THEN MATCH_MP_TAC TC_SUBSET 1279 THEN REWRITE_TAC[RC_REFLEXIVE] 1280 ], 1281 1282 POP_ASSUM REWRITE_ALL_THM 1283 THEN RES_THEN (STRIP_ASSUME_TAC o REWRITE_RULE[]) 1284 THEN POP_ASSUM IMP_RES_TAC 1285 THEN EXISTS_TAC ``Lam x M3:^term`` 1286 THEN IMP_RES_THEN REWRITE_THM TC_RC_RED1_COMPAT 1287 THEN IMP_RES_THEN REWRITE_THM RC_RED1_COMPAT 1288 ] 1289 ] 1290 ); 1291 1292 1293val RED_BETA_COMMUTES_RED_ETA = store_thm 1294 ("RED_BETA_COMMUTES_RED_ETA", 1295 ���RED (BETA_R:^term_rel) <=> RED ETA_R���, 1296 REWRITE_TAC[GSYM TC_RC_RED1_IS_RED] 1297 THEN MATCH_MP_TAC COMMUTE_TC_RC 1298 THEN REPEAT STRIP_TAC 1299 THEN IMP_RES_TAC RED1_BETA_COMMUTES_RED1_ETA_LEMMA2 1300 THEN FIRST_ASSUM MATCH_MP_TAC 1301 THEN REFL_TAC 1302 ); 1303 1304 1305(* ====================================== *) 1306(* Beta-eta reduction is Church-Rosser. *) 1307(* Barendregt Theorem 3.3.9(i), page 66. *) 1308(* ====================================== *) 1309 1310val BETA_ETA_R_CHURCH_ROSSER = store_thm 1311 ("BETA_ETA_R_CHURCH_ROSSER", 1312 ���CHURCH_ROSSER ((BETA_R:^term_rel) UNION_R ETA_R)���, 1313 MATCH_MP_TAC COMMUTE_CHURCH_ROSSER 1314 THEN REWRITE_TAC[BETA_R_CHURCH_ROSSER,ETA_R_CHURCH_ROSSER, 1315 RED_BETA_COMMUTES_RED_ETA] 1316 ); 1317(* Soli Deo Gloria!!! To God Alone Be The Glory!!! *) 1318 1319 1320(* Barendregt Theorem 3.3.9 (ii), page 66. *) 1321 1322val BETA_ETA_R_NORMAL_FORM_EXISTS = store_thm 1323 ("BETA_ETA_R_NORMAL_FORM_EXISTS", 1324 ���!(M:^term) N. 1325 REQUAL (BETA_R UNION_R ETA_R) M N ==> 1326 (?Z. RED (BETA_R UNION_R ETA_R) M Z /\ 1327 RED (BETA_R UNION_R ETA_R) N Z)���, 1328 MATCH_MP_TAC NORMAL_FORM_EXISTS 1329 THEN REWRITE_TAC[BETA_ETA_R_CHURCH_ROSSER] 1330 ); 1331 1332(* Barendregt Corollary 3.3.10 (i), page 67. *) 1333 1334val BETA_ETA_R_NORMAL_FORM_REDUCED_TO = store_thm 1335 ("BETA_ETA_R_NORMAL_FORM_REDUCED_TO", 1336 ���!(M:^term) N. 1337 NORMAL_FORM_OF (BETA_R UNION_R ETA_R) N M ==> 1338 RED (BETA_R UNION_R ETA_R) M N���, 1339 MATCH_MP_TAC NORMAL_FORM_REDUCED_TO 1340 THEN REWRITE_TAC[BETA_ETA_R_CHURCH_ROSSER] 1341 ); 1342 1343(* Barendregt Corollary 3.3.10 (ii), page 67. *) 1344 1345val BETA_ETA_R_NORMAL_FORM_UNIQUE = store_thm 1346 ("BETA_ETA_R_NORMAL_FORM_UNIQUE", 1347 ���!(M:^term) N1 N2. 1348 NORMAL_FORM_OF (BETA_R UNION_R ETA_R) N1 M /\ 1349 NORMAL_FORM_OF (BETA_R UNION_R ETA_R) N2 M ==> 1350 (N1 = N2)���, 1351 MATCH_MP_TAC NORMAL_FORM_UNIQUE 1352 THEN REWRITE_TAC[BETA_ETA_R_CHURCH_ROSSER] 1353 ); 1354 1355 1356 1357 1358 1359val _ = export_theory(); 1360 1361val _ = print_theory_to_file "-" "eta.lst"; 1362 1363val _ = html_theory "eta"; 1364 1365val _ = print_theory_size(); 1366