1structure ANF :> ANF = 2struct 3 4(* For interactive use: 5 6 loadPath := 7 (concat Globals.HOLDIR "/examples/dev/sw") :: 8 !loadPath; 9 10app load ["pairLib", "cpsSyntax", "wordsLib"]; 11 quietdec := true; 12 open pairLib pairTheory PairRules pairSyntax cpsTheory cpsSyntax; 13 quietdec := false; 14*) 15open HolKernel Parse boolLib bossLib 16 pairLib pairSyntax pairTheory PairRules cpsTheory cpsSyntax; 17 18type env = (term * (bool * thm * thm * thm)) list; 19 20val _ = (Globals.priming := SOME ""); 21 22 23 24(*---------------------------------------------------------------------------*) 25(* Ensure that each let-bound variable name in a term is different than the *) 26(* others. *) 27(*---------------------------------------------------------------------------*) 28 29fun std_bvars stem tm = 30 let open Lib 31 fun num2name i = stem^Lib.int_to_string i 32 val nameStrm = Lib.mk_istream (fn x => x+1) 0 num2name 33 fun next_name () = state(next nameStrm) 34 fun trav M = 35 if is_comb M then 36 let val (M1,M2) = dest_comb M 37 val M1' = trav M1 38 val M2' = trav M2 39 in mk_comb(M1',M2') 40 end else 41 if is_abs M then 42 let val (v,N) = dest_abs(rename_bvar (next_name()) M) 43 in mk_abs(v,trav N) 44 end 45 else M 46 in 47 trav tm 48 end; 49 50fun STD_BVARS_CONV stem tm = 51 let val tm' = std_bvars stem tm 52 in Thm.ALPHA tm tm' 53 end; 54 55val STD_BVARS = CONV_RULE o STD_BVARS_CONV; 56val STD_BVARS_TAC = CONV_TAC o STD_BVARS_CONV; 57 58(*---------------------------------------------------------------------------*) 59(* Compiler frontend ... largely pinched from examples/dev/compile.sml *) 60(*---------------------------------------------------------------------------*) 61 62(*****************************************************************************) 63(* Error reporting function *) 64(*****************************************************************************) 65 66val ERR = mk_HOL_ERR "ANF"; 67 68(*****************************************************************************) 69(* List of definitions (useful for rewriting) *) 70(*****************************************************************************) 71 72val SimpThms = [Seq_def,Par_def,Ite_def,Rec_def]; 73 74(*****************************************************************************) 75(* An expression is just a HOL term built using expressions defined earlier *) 76(* in a program (see description of programs below) and Seq, Par, *) 77(* Ite and Rec: *) 78(* *) 79(* expr := Seq expr expr *) 80(* | Par expr expr *) 81(* | Ite expr expr expr *) 82(* | Rec expr expr expr *) 83(* *) 84(*****************************************************************************) 85 86(*****************************************************************************) 87(* Convert_CONV ``\(x1,...,xn). tm[x1,...,xn]`` returns a theorem *) 88(* *) 89(* |- (\(x1,...,xn). tm[x1,...,xn]) = p *) 90(* *) 91(* where p is a combinatory expression built from the combinators *) 92(* Seq, Par and Ite. An example is: *) 93(* *) 94(* - Convert_CONV ``\(x,y). if x < y then y-x else x-y``; *) 95(* > val it = *) 96(* |- (\(x,y). (if x < y then y - x else x - y)) = *) 97(* Ite (Seq (Par (\(x,y). x) (\(x,y). y)) (UNCURRY $<)) *) 98(* (Seq (Par (\(x,y). y) (\(x,y). x)) (UNCURRY $-)) *) 99(* (Seq (Par (\(x,y). x) (\(x,y). y)) (UNCURRY $-)) *) 100(* *) 101(* Notice that curried operators are uncurried. *) 102(* *) 103(*****************************************************************************) 104 105val LET_SEQ_PAR_THM = Q.prove 106(`!f1 f2 f3. Seq (Par f1 f2) f3 = \x. let v = f2 x in f3 (f1 x,v)`, 107 RW_TAC std_ss [Seq_def, Par_def, LET_DEF]); 108 109val SEQ_PAR_I_THM = Q.prove 110(`!f2 f3. Seq (Par (\x.x) f2) f3 = \x. let v = f2 x in f3 (x,v)`, 111 RW_TAC std_ss [LET_SEQ_PAR_THM,combinTheory.I_THM]); 112 113 114fun is_word_literal tm = 115 ((is_comb tm) andalso 116 let val (c,args) = strip_comb tm 117 val {Name,Thy,Ty} = dest_thy_const c 118 in Name = "n2w" andalso numSyntax.is_numeral (hd args) 119 end) 120 handle HOL_ERR _ => raise ERR "is_word_literal" ""; 121 122 123fun Convert_CONV f = 124 let val (args,t) = 125 dest_pabs f 126 handle HOL_ERR _ 127 => (print_term f; print"\n"; 128 print "is not an abstraction\n"; 129 raise ERR "Convert_CONV" "not an abstraction") 130 in 131 if not(free_vars f = []) 132 then (print_term f; print "\n"; 133 print "has free variables: "; 134 map (fn t => (print_term t; print " "))(rev(free_vars f)); print "\n"; 135 raise ERR "Convert_CONV" "disallowed free variables") 136 else if is_var t orelse is_word_literal t orelse numSyntax.is_numeral t orelse is_const t 137 then REFL f 138 else if is_pair t 139 then let val (t1,t2) = dest_pair t 140 val f1 = mk_pabs(args,t1) 141 val f2 = mk_pabs(args,t2) 142 val th1 = PBETA_CONV (mk_comb(f1,args)) 143 val th2 = PBETA_CONV (mk_comb(f2,args)) 144 val th3 = ISPECL [f1,f2] Par_def 145 val ptm = mk_pabs(args, mk_pair(mk_comb(f1,args),mk_comb(f2,args))) 146 val th4 = TRANS th3 (PALPHA (rhs(concl th3)) ptm) 147 val th5 = CONV_RULE 148 (RHS_CONV 149 (PABS_CONV 150 (RAND_CONV(REWR_CONV th2) 151 THENC RATOR_CONV(RAND_CONV(REWR_CONV th1))))) 152 th4 153 val th6 = GSYM th5 154 in 155 if aconv (lhs(concl th6)) f 156 then CONV_RULE 157 (RHS_CONV 158 ((RAND_CONV Convert_CONV) 159 THENC (RATOR_CONV(RAND_CONV Convert_CONV)))) 160 th6 161 else (print "bad Par case\n"; 162 raise ERR "Convert_CONV" "shouldn't happen") 163 end 164 else if is_cond t 165 then let val (b,t1,t2) = dest_cond t 166 val fb = mk_pabs(args,b) 167 val f1 = mk_pabs(args,t1) 168 val f2 = mk_pabs(args,t2) 169 val thb = PBETA_CONV (mk_comb(fb,args)) 170 val th1 = PBETA_CONV (mk_comb(f1,args)) 171 val th2 = PBETA_CONV (mk_comb(f2,args)) 172 val th3 = ISPECL [fb,f1,f2] Ite_def 173 val ptm = mk_pabs 174 (args, 175 mk_cond(mk_comb(fb,args),mk_comb(f1,args),mk_comb(f2,args))) 176 val th4 = TRANS th3 (PALPHA (rhs(concl th3)) ptm) 177 val th5 = CONV_RULE 178 (RHS_CONV 179 (PABS_CONV 180 (RAND_CONV(REWR_CONV th2) 181 THENC RATOR_CONV(RAND_CONV(REWR_CONV th1)) 182 THENC RATOR_CONV(RATOR_CONV(RAND_CONV(REWR_CONV thb)))))) 183 th4 184 val th6 = GSYM th5 185 in 186 if aconv (lhs(concl th6)) f 187 then CONV_RULE 188 (RHS_CONV 189 ((RAND_CONV Convert_CONV) 190 THENC (RATOR_CONV(RAND_CONV Convert_CONV)) 191 THENC (RATOR_CONV(RATOR_CONV(RAND_CONV Convert_CONV))))) 192 th6 193 else (print "bad Ite case\n"; 194 raise ERR "Convert_CONV" "shouldn't happen") 195 end 196 else if is_let t (* t = LET (\v. N) M *) 197 then let val (v,M,N) = dest_plet t 198 val f1 = mk_pabs(args,args) 199 val f2 = mk_pabs(args,M) 200 val f3 = mk_pabs(mk_pair(args,v),N) 201 val th1 = ISPECL [f1,f2,f3] LET_SEQ_PAR_THM 202 val th2 = CONV_RULE(RHS_CONV(SIMP_CONV std_ss [LAMBDA_PROD])) th1 203 val th3 = TRANS th2 (SYM (QCONV (SIMP_CONV std_ss [LAMBDA_PROD]) f)) 204 val th4 = SYM th3 205 in 206 if aconv (lhs(concl th4)) f 207 then CONV_RULE 208 (RHS_CONV 209 ((RAND_CONV Convert_CONV) 210 THENC (RATOR_CONV(RAND_CONV (RAND_CONV Convert_CONV))))) 211 th4 212 else (print "bad let case\n"; 213 raise ERR "Convert_CONV" "shouldn't happen") 214 end 215 else if is_comb t 216 then let val th0 = (REWR_CONV (GSYM UNCURRY_DEF) ORELSEC REFL) t 217 val (t1,t2) = dest_comb(rhs(concl th0)) 218 val f1 = mk_pabs(args,t1) 219 val f2 = mk_pabs(args,t2) 220 val th1 = ISPECL [f2,t1] Seq_def 221 val ptm = mk_pabs(args, mk_comb(t1,mk_comb(f2,args))) 222 val th2 = TRANS th1 (PALPHA (rhs(concl th1)) ptm) 223 val th3 = PBETA_CONV(mk_comb(f2,args)) 224 val th4 = GSYM(CONV_RULE(RHS_CONV(PABS_CONV(RAND_CONV(REWR_CONV th3))))th2) 225 val th5 = CONV_RULE(LHS_CONV(PABS_CONV(REWR_CONV(GSYM th0)))) th4 226 in 227 if aconv (lhs(concl th5)) f 228 then CONV_RULE 229 (RHS_CONV 230 (RATOR_CONV(RAND_CONV Convert_CONV))) 231 th5 232 else (print "bad Seq case\n"; 233 raise ERR "Convert_CONV" "shouldn't happen") 234 end 235 else (print_term f; print "\n"; 236 print "shouldn't get this case (not first-order)!\n"; 237 raise ERR "Convert_CONV" "shouldn't happen") 238 end; 239 240(*****************************************************************************) 241(* Predicate to test whether a term occurs in another term *) 242(*****************************************************************************) 243 244fun occurs_in t1 t2 = can (find_term (aconv t1)) t2; 245 246(*****************************************************************************) 247(* Convert (|- f x = e) returns a theorem *) 248(* *) 249(* |- f = p *) 250(* *) 251(* where p is a combinatory expression built from the combinators Seq, Par *) 252(* and Ite. *) 253(*****************************************************************************) 254fun Convert defth = 255 let val (lt,rt) = 256 dest_eq(concl(SPEC_ALL defth)) 257 handle HOL_ERR _ 258 => (print "not an equation\n"; 259 raise ERR "Convert" "not an equation") 260 val (func,args) = 261 dest_comb lt 262 handle HOL_ERR _ => 263 (print "lhs not a comb\n"; 264 raise ERR "Convert" "lhs not a comb") 265 val _ = if not(is_const func) 266 then (print_term func; print " is not a constant\n"; 267 raise ERR "Convert" "rator of lhs not a constant") 268 else () 269 val _ = if not(subtract (free_vars rt) (free_vars lt) = []) 270 then (print "definition rhs has unbound variables: "; 271 map (fn t => (print_term t; print " ")) 272 (rev(subtract (free_vars rt) (free_vars lt))); 273 print "\n"; 274 raise ERR "Convert" "definition rhs has unbound variables") 275 else () 276 in 277 let val f = mk_pabs(args,rt) 278 val th1 = Convert_CONV f 279 val th2 = PABS args (SPEC_ALL defth) 280 val th3 = TRANS th2 th1 281 in 282 CONV_RULE (LHS_CONV PETA_CONV) th3 283 end 284 end; 285 286 287(*****************************************************************************) 288(* RecConvert (|- f x = if f1 x then f2 x else f(f3 x)) *) 289(* (|- TOTAL(f1,f2,f3)) *) 290(* *) 291(* returns a theorem *) 292(* *) 293(* |- f = Rec(p1,p2,p3) *) 294(* *) 295(* where p1, p2 and p3 are combinatory expressions built from the *) 296(* combinators Seq, Par and Ite. *) 297(* *) 298(* For example, given: *) 299(* *) 300(* FactIter; *) 301(* > val it = *) 302(* |- FactIter (n,acc) = *) 303(* (if n = 0 then (n,acc) else FactIter (n - 1,n * acc)) *) 304(* *) 305(* - FactIter_TOTAL; *) 306(* > val it = *) 307(* |- TOTAL *) 308(* ((\(n,acc). n = 0), *) 309(* (\(n,acc). (n,acc)), *) 310(* (\(n,acc). (n-1, n*acc))) *) 311(* *) 312(* then: *) 313(* *) 314(* - RecConvert FactIter FactIter_TOTAL; *) 315(* > val it = *) 316(* |- FactIter = *) 317(* Rec (Seq (Par (\(n,acc). n) (\(n,acc). 0)) (UNCURRY $=)) *) 318(* (Par (\(n,acc). n) (\(n,acc). acc)) *) 319(* (Par (Seq (Par (\(n,acc). n) (\(n,acc). 1)) (UNCURRY $-)) *) 320(* (Seq (Par (\(n,acc). n) (\(n,acc). acc)) (UNCURRY $* ))) *) 321(* *) 322(*****************************************************************************) 323 324val I_DEF_ALT = Q.prove(`I = \x.x`,SIMP_TAC std_ss [FUN_EQ_THM]); 325val Rec_INTRO_ALT = REWRITE_RULE[I_DEF_ALT] Rec_INTRO; 326val Seq_o = Q.prove(`!f g. f o g = Seq g f`, 327 SIMP_TAC std_ss [combinTheory.o_DEF,Seq_def]); 328 329fun RecConvert defth = 330 let val (lt,rt) = 331 dest_eq(concl(SPEC_ALL defth)) 332 handle HOL_ERR _ 333 => (print "not an equation\n"; 334 raise ERR "RecConvert" "not an equation") 335 val (func,args) = 336 dest_comb lt 337 handle HOL_ERR _ => 338 (print "lhs not a comb\n"; 339 raise ERR "RecConvert" "lhs not a comb") 340 val _ = if not(is_const func) 341 then (print_term func; print " is not a constant\n"; 342 raise ERR "RecConvert" "rator of lhs not a constant") 343 else () 344 val (b,t1,t2) = 345 dest_cond rt 346 handle HOL_ERR _ 347 => (print "rhs not a conditional\n"; 348 raise ERR "RecConvert" "rhs not a conditional") 349 val _ = if not(subtract (free_vars rt) (free_vars lt) = []) 350 then (print "definition rhs has unbound variables: "; 351 map (fn t => (print_term t; print " ")) 352 (rev(subtract (free_vars rt) (free_vars lt))); 353 print "\n"; 354 raise ERR "RecConvert" "definition rhs has unbound variables") 355 else() 356 in 357 if (is_comb t2 358 andalso aconv (rator t2) func 359 andalso not(occurs_in func b) 360 andalso not(occurs_in func t1) 361 andalso not(occurs_in func (rand t2))) 362 then 363 let val fb = mk_pabs(args,b) 364 val f1 = mk_pabs(args,t1) 365 val f2 = mk_pabs(args,rand t2) 366 val thm = ISPECL[func,fb,f1,f2] Rec_INTRO 367 val M = fst(dest_imp(concl thm)) 368 val (v,body) = dest_forall M 369 val M' = rhs(concl(DEPTH_CONV PBETA_CONV 370 (mk_pforall(args,subst [v |-> args]body)))) 371 val MeqM' = prove(mk_eq(M,M'), 372 Ho_Rewrite.REWRITE_TAC[LAMBDA_PROD] 373 THEN PBETA_TAC THEN REFL_TAC) 374 val thm1 = PURE_REWRITE_RULE[MeqM'] thm 375 val thm2 = PGEN args defth 376 val thm3 = MP thm1 thm2 377 val N = fst(dest_imp(concl thm3)) 378 val (R,tm) = dest_exists N 379 val (tm1,tm2) = dest_conj tm 380 val (v,body) = dest_forall tm2 381 val tm2' = rhs(concl(DEPTH_CONV PBETA_CONV 382 (mk_pforall(args,subst [v |-> args]body)))) 383 val N' = mk_exists(R,mk_conj(tm1,tm2')) 384 val NeqN' = prove(mk_eq(N,N'), 385 Ho_Rewrite.REWRITE_TAC[LAMBDA_PROD] 386 THEN PBETA_TAC THEN REFL_TAC) 387 val thm4 = PURE_REWRITE_RULE[NeqN'] thm3 388 val thm5 = UNDISCH thm4 389 val thm6 = CONV_RULE (RHS_CONV 390 (RAND_CONV Convert_CONV THENC 391 RATOR_CONV(RAND_CONV Convert_CONV) THENC 392 RATOR_CONV(RATOR_CONV(RAND_CONV Convert_CONV)))) 393 thm5 394 in thm6 395 end 396 else if occurs_in func rt 397 then (print "definition of: "; print_term func; 398 print " is not tail recursive"; print "\n"; 399 raise ERR "RecConvert" "not tail recursive") 400 else raise ERR "RecConvert" "this shouldn't happen" 401 end; 402 403(*---------------------------------------------------------------------------*) 404(* Convert a possibly (tail) recursive equation to combinator form, either *) 405(* by calling Convert or RecConvert. *) 406(*---------------------------------------------------------------------------*) 407 408fun toComb def = 409 let val (l,r) = dest_eq(snd(strip_forall(concl def))) 410 val (func,args) = dest_comb l 411 val is_recursive = Lib.can (find_term (aconv func)) r 412(* val comb_exp_thm = if is_recursive then RecConvert def else Convert def *) 413 val comb_exp_thm = Convert def 414 in 415 (is_recursive,lhs(concl comb_exp_thm), args, comb_exp_thm) 416 end; 417 418(*---------------------------------------------------------------------------*) 419(* Takes theorem |- f = <combinator-form> , where f is not a recursive *) 420(* function, and returns the CPS-ed version of <combinator-form>. Actually, *) 421(* the returned value is in "A-Normal" form (uses lets). *) 422(*---------------------------------------------------------------------------*) 423 424val LET_ID = METIS_PROVE [] ``!f M. (LET M (\x. x)) = M (\x. x)`` 425 426fun REPAIR_SYNTAX_RESTRICTIONS_CONV t = 427 if (is_comb t) then 428 let 429 val (f, args) = strip_comb t; 430 val {Name,Thy,Ty} = dest_thy_const f; 431 in 432 if ((Name = "UNCURRY") andalso (Thy = "pair") andalso 433 (length args = 2)) then 434 let 435 val pair = (el 2 args); 436 val (l, r) = dest_pair pair; 437 val is_word_l = is_word_literal l; 438 val is_word_r = is_word_literal r; 439 440 val _ = if (is_word_l andalso is_word_r) then 441 (raise (ERR "" "Can't repair syntax")) 442 else () 443 in 444 if (is_word_l orelse is_word_r) then 445 let 446 val oper = el 1 args; 447 val {Name,Thy,Ty} = dest_thy_const oper; 448 449 val _ = if (not ((Thy="words") orelse (Name = "=" andalso (Thy="min")))) then 450 raise (ERR "" "Can't repair syntax") 451 else () 452 453 val _ = if ((Name = "word_mul")) then 454 raise (ERR "" "Can't repair syntax") 455 else () 456 457 458 fun COMM_OPER_CONV t = 459 (CURRY_CONV THENC 460 ONCE_REWRITE_CONV [wordsTheory.WORD_ADD_COMM, 461 wordsTheory.WORD_OR_COMM, 462 wordsTheory.WORD_AND_COMM, 463 wordsTheory.WORD_XOR_COMM, 464 EQ_SYM_EQ 465 ] THENC 466 UNCURRY_CONV) t 467 in 468 if (is_word_l) then 469 if ((Name = "word_add") orelse 470 (Name = "word_or") orelse 471 (Name = "word_and") orelse 472 (Name = "word_xor") orelse 473 (Name = "=")) then 474 COMM_OPER_CONV t 475 else 476 raise (ERR "" "Can't repair syntax") 477 else REFL t 478 end 479 else 480 REFL t 481 end 482 else 483 (COMB_CONV REPAIR_SYNTAX_RESTRICTIONS_CONV) t 484 end 485 else if (is_abs t) then 486 (ABS_CONV REPAIR_SYNTAX_RESTRICTIONS_CONV) t 487 else 488 REFL t; 489 490fun VAR_LET_CONV t = 491 let open pairSyntax 492 val (_,tm) = dest_let t; 493 in 494 if is_vstruct tm orelse 495 ((is_word_literal tm orelse numSyntax.is_numeral tm)) 496 497 then 498 (REWR_CONV LET_THM THENC GEN_BETA_CONV THENC REPAIR_SYNTAX_RESTRICTIONS_CONV) t 499 else raise ERR "VAR_LET_CONV" "" 500 end; 501 502fun LET_UNCURRY_CONV t = 503 let open pairSyntax 504 val (_,tm) = dest_let t; 505 val (f, _) = strip_comb tm 506 val {Name,Thy,Ty} = dest_thy_const f; 507 val _ = if (((Name = "UNCURRY") andalso (Thy = "pair")) orelse 508 ((Name = "COND") andalso (Thy = "bool"))) 509 then raise UNCHANGED else () 510 in 511 (RAND_CONV UNCURRY_CONV) t 512 end; 513 514(*val t = rhs (concl (SPEC_ALL thm16)) 515 val thm17 = CONV_RULE (DEPTH_CONV VAR_LET_CONV) thm16*) 516 517 518fun ELIM_PAIR_LET_CONV t = 519let 520 val (body, value) = dest_let t; 521in 522 if (is_vstruct value) then 523 (REWR_CONV LET_THM THENC GEN_BETA_CONV) t 524 else 525 let 526 val thm = CURRY_CONV (liteLib.mk_icomb (body, value)) 527 val rhs_thm = rhs (concl thm); 528 val (body, v1) = dest_comb rhs_thm 529 val (body, v2) = dest_comb body 530 val (varlist, body) = strip_pabs body; 531 532 val body = mk_let (mk_pabs(el 2 varlist, body), v1); 533 val body = mk_let (mk_pabs(el 1 varlist, body), v2); 534 val thm = prove (mk_eq (t, body), 535 CONV_TAC (DEPTH_CONV let_CONV) THEN REWRITE_TAC[]) 536 in 537 thm 538 end 539end; 540 541 542val CPS_REWRITES = prove (`` 543 (!f1 f2. Seq f1 f2 = \arg. let z1 = f1 arg in 544 let z2 = f2 z1 in 545 z2) /\ 546 (!f1 f2. Par f1 f2 = \arg. let z1 = f1 arg in 547 let z2 = f2 arg in 548 (z1, z2)) /\ 549 (!f1 f2 f3. Ite f1 f2 f3 = \arg. 550 let (z1 = f1 arg) in 551 (if z1 then 552 let z2 = f2 arg in z2 553 else 554 let z3 = f3 arg in z3))``, 555 SIMP_TAC std_ss [Seq_def, Par_def, Ite_def, LET_THM]) 556 557 558val LET_PAIR = prove (`` 559 !f y. (let (x = (a, b)) in f x) = 560 let x1 = a in 561 let x2 = b in 562 f (x1,x2)``, 563 564 SIMP_TAC std_ss [LET_THM]); 565 566val LET_LET = prove (`` 567 !f1 f2 z. (let (x = let y = z in f1 y) in f2 x) = 568 let y = z in 569 let x = f1 y in 570 f2 x``, 571 572 SIMP_TAC std_ss [LET_THM]) 573 574 575(* 576fun old_ANFof (args,thm) = 577 let 578 val thm1 = Q.AP_TERM `CPS` thm 579 val thm2 = REWRITE_RULE [CPS_SEQ_INTRO, CPS_PAR_INTRO,(* CPS_REC_INTRO, *) 580 CPS_ITE_INTRO] thm1 581 val thm3 = CONV_RULE (DEPTH_CONV (REWR_CONV CPS_SEQ_def ORELSEC 582 REWR_CONV CPS_PAR_def ORELSEC 583 REWR_CONV CPS_ITE_def 584(* ORELSEC REWR_CONV CPS_REC_def *))) thm2 585 val thm4 = CONV_RULE (DEPTH_CONV (REWR_CONV UNCPS)) thm3 586 val thm5 = CONV_RULE (LAND_CONV (REWR_CONV CPS_def)) thm4 587 val thm6 = CONV_RULE (REPEATC (STRIP_QUANT_CONV (HO_REWR_CONV FUN_EQ_THM))) 588 thm5 589 val x = mk_var("x",fst (dom_rng (type_of (fst (dest_forall (concl thm6)))))) 590 val thm7 = ISPEC (mk_abs(x,x)) thm6 591 val thm8 = BETA_RULE thm7 592 val thm9 = BETA_RULE thm8 593 val thm10 = SIMP_RULE bool_ss [LET_ID] thm9 594 val thm11 = SIMP_RULE bool_ss [pairTheory.FORALL_PROD] thm10 595 val thm12 = PBETA_RULE thm11 596 val thm13 = SIMP_RULE bool_ss [pairTheory.LAMBDA_PROD] thm12 597 val thm14 = PURE_REWRITE_RULE [FST,SND] thm13 598 val thm15 = CONV_RULE (DEPTH_CONV ELIM_PAIR_LET_CONV) thm14 599 val thm16 = STD_BVARS "v" thm15 600 val thm17 = CONV_RULE (DEPTH_CONV VAR_LET_CONV) thm16 601in 602 thm17 603end 604 605*) 606 607(*val (args,thm) = (args,const_eq_comb) *) 608fun ANFof (args,thm) = 609 let val thm1 = CONV_RULE (REPEATC (STRIP_QUANT_CONV (HO_REWR_CONV FUN_EQ_THM))) 610 thm 611 val thm2 = SIMP_RULE bool_ss [pairTheory.FORALL_PROD] thm1 612 val thm3 = SIMP_RULE std_ss [CPS_REWRITES, LET_LET] thm2 613 val thm4 = PBETA_RULE thm3 614 val thm5 = SIMP_RULE std_ss [pairTheory.LAMBDA_PROD, LET_PAIR] thm4 615 val thm6 = CONV_RULE (DEPTH_CONV LET_UNCURRY_CONV) thm5 616 val thm7 = STD_BVARS "v" thm6 617 val thm8 = CONV_RULE (DEPTH_CONV VAR_LET_CONV) thm7 618 val thm9 = STD_BVARS "v" thm8 619 in thm8 620 end; 621 622 623(*---------------------------------------------------------------------------*) 624(* Given an environment and a possibly (tail) recursive definition, convert *) 625(* to combinator form, then to A-Normal form and add the result to the *) 626(* environment. *) 627(*---------------------------------------------------------------------------*) 628fun toANF env def = 629 let val (is_recursive,func,args,const_eq_comb) = toComb def 630 val anf = STD_BVARS "v" (ANFof (args,const_eq_comb)) 631(* val old_anf = STD_BVARS "v" (old_ANFof (args,const_eq_comb))*) 632 in 633 (func,(is_recursive,def,anf,const_eq_comb))::env 634 end; 635 636 637end 638 639