1(*****************************************************************************) 2(* This file defines a type of s-expressions and various constants and *) 3(* functions on this type (t, nil, car, cdr, cons etc). *) 4(* *) 5(* One goal is to construct a model of ACL2 by proving the axioms in *) 6(* axioms.lisp. *) 7(* *) 8(* File written by Mike Gordon and Matt Kaufmann; maintained by Mike Gordon. *) 9(* *) 10(*****************************************************************************) 11 12(*****************************************************************************) 13(* Ignore everything up to "END BOILERPLATE" *) 14(*****************************************************************************) 15 16(*****************************************************************************) 17(* START BOILERPLATE NEEDED FOR COMPILATION *) 18(*****************************************************************************) 19 20(****************************************************************************** 21* Load theories 22******************************************************************************) 23(* The commented out stuff below should be loaded in interactive sessions 24quietdec := true; 25app 26 load 27 ["complex_rationalTheory", "sexp","acl2_packageTheory"]; 28open complex_rationalTheory sexp acl2_packageTheory stringLib; 29Globals.checking_const_names := false; 30quietdec := false; 31*) 32 33(****************************************************************************** 34* Boilerplate needed for compilation: open HOL4 systems modules. 35******************************************************************************) 36open HolKernel Parse boolLib bossLib; 37 38(****************************************************************************** 39* Open theories (including ratTheory from Jens Brandt). 40******************************************************************************) 41 42open stringLib complex_rationalTheory acl2_packageTheory sexp; 43 44(*****************************************************************************) 45(* END BOILERPLATE *) 46(*****************************************************************************) 47 48(*****************************************************************************) 49(* Start new theory "sexp" *) 50(*****************************************************************************) 51 52val _ = new_theory "sexp"; 53 54(*****************************************************************************) 55(* Define s-expressions. *) 56(*****************************************************************************) 57 58(*****************************************************************************) 59(* Introduce mnemonic abbreviations to indicate use of type ``:string`` *) 60(*****************************************************************************) 61val _ = type_abbrev("packagename", ``:string``); 62val _ = type_abbrev("name", ``:string``); 63 64(*****************************************************************************) 65(* ACL2 S-expressions defined as a HOL datatype. *) 66(* Definition below adapted from Mark Staples' code. *) 67(*****************************************************************************) 68val _ = Hol_datatype 69 `sexp = ACL2_SYMBOL of packagename => name (* only curried for style *) 70 | ACL2_STRING of string 71 | ACL2_CHARACTER of char 72 | ACL2_NUMBER of complex_rational 73 | ACL2_PAIR of sexp => sexp`; (* only curried for style *) 74 75(*****************************************************************************) 76(* Each ACL2 function or constant is given a name of the form "pkg::nam". *) 77(* Since "::" is not handled by the HOL parser (and there are also many *) 78(* other character sequences that HOL can't parse occurring in ACL2 *) 79(* names) we also provide a HOL friendly name which is overloaded onto the *) 80(* ACL2 name. For example the ACL2 name "ACL2::BAD-ATOM<=" is given the *) 81(* HOL friendly name "bad_atom_less_equal". *) 82(*****************************************************************************) 83 84(*****************************************************************************) 85(* Overload "cons" onto ``ACL2_PAIR`` rather than make a definition, so *) 86(* that cons behaves like a constructor and so can be used in patterns in *) 87(* definitions (e.g. see definition of car below). *) 88(*****************************************************************************) 89 90(*****************************************************************************) 91(* Overload short mnemonic names onto the sexp datatype constructors. *) 92(*****************************************************************************) 93val _ = declare_names ("ACL2_PAIR", "cons"); 94val _ = declare_names ("ACL2_SYMBOL", "sym"); 95val _ = declare_names ("ACL2_NUMBER", "num"); 96val _ = declare_names ("ACL2_STRING", "str"); 97val _ = declare_names ("ACL2_CHARACTER", "chr"); 98 99(*****************************************************************************) 100(* Introduce some constants to abbreviate common package names. *) 101(*****************************************************************************) 102val ACL2_def = Define `ACL2 = "ACL2"` 103and COMMON_LISP_def = Define `COMMON_LISP = "COMMON-LISP"` 104and KEYWORD_def = Define `KEYWORD = "KEYWORD"` 105and ACL2_OUTPUT_CHANNEL_def = Define `ACL2_OUTPUT_CHANNEL = "ACL2-OUTPUT-CHANNEL"`; 106 107val asym_def = Define `asym = sym ACL2`; 108val csym_def = Define `csym = sym COMMON_LISP`; 109val ksym_def = Define `ksym = sym KEYWORD`; 110val osym_def = Define `osym = sym ACL2_OUTPUT_CHANNEL`; 111 112val _ = 113 add_string_abbrevs 114 [("ACL2", lhs(concl ACL2_def )), 115 ("COMMON-LISP", lhs(concl COMMON_LISP_def)), 116 ("KEYWORD", lhs(concl KEYWORD_def)), 117 ("ACL2-OUTPUT-CHANNEL", lhs(concl ACL2_OUTPUT_CHANNEL_def)) 118 ]; 119 120(*****************************************************************************) 121(* Definition of primitive constants and functions. *) 122(*****************************************************************************) 123val nil_def = 124 acl2Define "COMMON-LISP::NIL" `nil = sym "COMMON-LISP" "NIL"`; 125 126val t_def = 127 acl2Define "COMMON-LISP::T" `t = sym "COMMON-LISP" "T"`; 128 129val quote_def = 130 acl2Define "COMMON-LISP::QUOTE" `quote = sym "COMMON-LISP" "QUOTE"`; 131 132(*****************************************************************************) 133(* From axioms.lisp *) 134(* *) 135(* ; (equal x x) = T *) 136(* *) 137(* ; x/=y -> (equal x y) = NIL *) 138(* *) 139(* *) 140(* equal *) 141(* *) 142(* ; *1* definition (not helpful): *) 143(* (defun-*1* equal (x y) *) 144(* (equal x y)) *) 145(*****************************************************************************) 146val equal_def = 147 acl2Define "COMMON-LISP::EQUAL" 148 `equal (x:sexp) (y:sexp) = if x = y then t else nil`; 149 150(*****************************************************************************) 151(* stringp *) 152(* *) 153(* ; *1* definition (not helpful): *) 154(* (defun-*1* stringp (x) *) 155(* (stringp x)) *) 156(*****************************************************************************) 157val stringp_def = 158 acl2Define "COMMON-LISP::STRINGP" 159 `(stringp(str x) = t) /\ (stringp _ = nil)`; 160 161(*****************************************************************************) 162(* characterp *) 163(* *) 164(* ; *1* definition (not helpful): *) 165(* (defun-*1* characterp (x) *) 166(* (characterp x)) *) 167(*****************************************************************************) 168val characterp_def = 169 acl2Define "COMMON-LISP::CHARACTERP" 170 `(characterp(chr x) = t) /\ (characterp _ = nil)`; 171 172(*****************************************************************************) 173(* Construct a fraction then a rational from numerator and denominator *) 174(*****************************************************************************) 175val rat_def = Define `rat n d = abs_rat(abs_frac(n,d))`; 176 177(*****************************************************************************) 178(* Construct a complex from four integers: an/ad + (bn/bd)i. *) 179(*****************************************************************************) 180val cpx_def = 181 Define `cpx an ad bn bd = num(com (rat an ad) (rat bn bd))`; 182 183(*****************************************************************************) 184(* Construct a complex from an integer: n |--> n/1 + (0/1)i. *) 185(*****************************************************************************) 186val int_def = Define `int n = cpx n 1 0 1`; 187 188(*****************************************************************************) 189(* Construct a complex from a natural number: n |--> int n. *) 190(*****************************************************************************) 191val nat_def = Define `nat n = int(& n)`; 192 193(*****************************************************************************) 194(* acl2-numberp *) 195(* *) 196(* ; *1* definition (not helpful): *) 197(* (defun-*1* acl2-numberp (x) *) 198(* (numberp x)) *) 199(*****************************************************************************) 200val acl2_numberp_def = 201 acl2Define "ACL2::ACL2-NUMBERP" 202 `(acl2_numberp(num x) = t) /\ (acl2_numberp _ = nil)`; 203 204(*****************************************************************************) 205(* binary-+ *) 206(* *) 207(* ; *1* definition: *) 208(* (defun-*1* binary-+ (x y) *) 209(* (the number *) 210(* (if (numberp x) *) 211(* (if (numberp y) *) 212(* (+ (the number x) (the number y)) *) 213(* (gv binary-+ (x y) x)) *) 214(* (gv binary-+ (x y) *) 215(* (if (numberp y) *) 216(* y *) 217(* 0))))) *) 218(* *) 219(* ; Hand-optimized ACL2: *) 220(* (defun-*1* binary-+ (x y) *) 221(* (+ (if (numberp x) x 0) *) 222(* (if (numberp y) y 0))) *) 223(*****************************************************************************) 224val add_def = 225 acl2Define "ACL2::BINARY-+" 226 `(add (num x) (num y) = num(x+y)) /\ 227 (add (num x) _ = num x) /\ 228 (add _ (num y) = num y) /\ 229 (add _ _ = int 0)`; 230 231(*****************************************************************************) 232(* [Note: space added between "(" and "*" to avoid confusing ML!] *) 233(* *) 234(* binary-* *) 235(* *) 236(* ; *1* definition: *) 237(* (defun-*1* binary-* (x y) *) 238(* (the number *) 239(* (if (numberp x) *) 240(* (if (numberp y) *) 241(* ( * x y) *) 242(* (gv binary-* (x y) 0)) *) 243(* (gv binary-* (x y) 0)))) *) 244(*****************************************************************************) 245val mult_def = 246 acl2Define "ACL2::BINARY-*" 247 `(mult (num x) (num y) = num(x*y)) /\ 248 (mult _ _ = int 0)`; 249 250(*****************************************************************************) 251(* ; *1* definition (not very helpful):: *) 252(* (defun-*1* < (x y) *) 253(* (if (and (rationalp x) *) 254(* (rationalp y)) *) 255(* (< (the rational x) (the rational y)) *) 256(* (gv < (x y) *) 257(* (let ((x1 (if (numberp x) x 0)) *) 258(* (y1 (if (numberp y) y 0))) *) 259(* (or (< (realpart x1) (realpart y1)) *) 260(* (and (= (realpart x1) (realpart y1)) *) 261(* (< (imagpart x1) (imagpart y1)))))))) *) 262(*****************************************************************************) 263val less_def = 264 acl2Define "COMMON-LISP::<" 265 `(less (num(com xr xi)) (num(com yr yi)) = 266 if xr < yr 267 then t 268 else (if xr = yr then (if xi < yi then t else nil) else nil)) 269 /\ 270 (less _ (num(com yr yi)) = 271 if rat_0 < yr 272 then t 273 else (if rat_0 = yr then (if rat_0 < yi then t else nil) else nil)) 274 /\ 275 (less (num(com xr xi)) _ = 276 if xr < rat_0 277 then t 278 else (if xr = rat_0 then (if xi < rat_0 then t else nil) else nil)) 279 /\ 280 (less _ _ = nil)`; 281 282(*****************************************************************************) 283(* unary-- *) 284(* *) 285(* ; *1* definition: *) 286(* (defun-*1* unary-- (x) *) 287(* (the number *) 288(* (if (numberp x) *) 289(* (- x) *) 290(* (gv unary-- (x) 0)))) *) 291(*****************************************************************************) 292val unary_minus_def = 293 acl2Define "ACL2::UNARY--" 294 `(unary_minus(num x) = num(COMPLEX_SUB com_0 x)) /\ 295 (unary_minus _ = int 0)`; 296 297(*****************************************************************************) 298(* unary-/ *) 299(* *) 300(* ; *1* definition: *) 301(* (defun-*1* unary-/ (x) *) 302(* (the number *) 303(* (if (and (numberp x) (not (= x 0))) *) 304(* (/ x) *) 305(* (gv unary-/ (x) 0)))) *) 306(* *) 307(* ; Hand-optimized ACL2: *) 308(* (defun-*1* unary-/ (x) *) 309(* (if (and (numberp x) (not (equal x 0))) *) 310(* (/ x) *) 311(* 0)) *) 312(*****************************************************************************) 313val reciprocal_def = 314 acl2Define "ACL2::UNARY-/" 315 `(reciprocal (num x) = 316 if x = com_0 then int 0 else num(COMPLEX_RECIPROCAL x)) 317 /\ 318 (reciprocal _ = int 0)`; 319 320(*****************************************************************************) 321(* consp *) 322(* *) 323(* ; *1* definition (not helpful): *) 324(* (defun-*1* consp (x) *) 325(* (consp x)) *) 326(* *) 327(*****************************************************************************) 328val consp_def = 329 acl2Define "COMMON-LISP::CONSP" 330 `(consp(cons x y) = t) /\ (consp _ = nil)`; 331 332(*****************************************************************************) 333(* car *) 334(* *) 335(* ; *1* definition: *) 336(* (defun-*1* car (x) *) 337(* (cond *) 338(* ((consp x) *) 339(* (car x)) *) 340(* ((null x) *) 341(* nil) *) 342(* (t (gv car (x) nil)))) *) 343(* *) 344(* ; Hand-optimized ACL2: *) 345(* (defun-*1* car (x) *) 346(* (if (consp x) (car x) nil)) *) 347(*****************************************************************************) 348val car_def = 349 acl2Define "COMMON-LISP::CAR" 350 `(car(cons x _) = x) /\ (car _ = nil)`; 351 352(*****************************************************************************) 353(* cdr *) 354(* *) 355(* ; *1* definition: *) 356(* (defun-*1* cdr (x) *) 357(* (cond *) 358(* ((consp x) *) 359(* (cdr x)) *) 360(* ((null x) *) 361(* nil) *) 362(* (t (gv cdr (x) nil)))) *) 363(* *) 364(* ; Hand-optimized ACL2: *) 365(* (defun-*1* cdr (x) *) 366(* (if (consp x) (cdr x) nil)) *) 367(*****************************************************************************) 368val cdr_def = 369 acl2Define "COMMON-LISP::CDR" 370 `(cdr(cons _ y) = y) /\ (cdr _ = nil)`; 371 372(*****************************************************************************) 373(* realpart *) 374(* *) 375(* ; *1* definition: *) 376(* (defun-*1* realpart (x) *) 377(* (if (numberp x) *) 378(* (realpart x) *) 379(* (gv realpart (x) 0))) *) 380(*****************************************************************************) 381val realpart_def = 382 acl2Define "COMMON-LISP::REALPART" 383 `(realpart(num(com a b)) = num(com a rat_0)) /\ 384 (realpart _ = int 0)`; 385 386(*****************************************************************************) 387(* imagpart *) 388(* *) 389(* ; *1* definition: *) 390(* (defun-*1* imagpart (x) *) 391(* (if (numberp x) *) 392(* (imagpart x) *) 393(* (gv imagpart (x) 0))) *) 394(*****************************************************************************) 395val imagpart_def = 396 acl2Define "COMMON-LISP::IMAGPART" 397 `(imagpart(num(com a b)) = num(com b rat_0)) /\ 398 (imagpart _ = int 0)`; 399 400(*****************************************************************************) 401(* rationalp *) 402(* *) 403(* ; *1* definition (not helpful): *) 404(* (defun-*1* rationalp (x) *) 405(* (rationalp x)) *) 406(*****************************************************************************) 407val rationalp_def = 408 acl2Define "COMMON-LISP::RATIONALP" 409 `(rationalp(num(com a b)) = if b = rat_0 then t else nil) /\ 410 (rationalp _ = nil)`; 411 412(*****************************************************************************) 413(* complex-rationalp *) 414(* *) 415(* ; *1* definition: *) 416(* (defun-*1* complex-rationalp (x) *) 417(* (complexp x)) *) 418(* *) 419(* Complex-rationalp holds only of numbers that are not rational, i.e., *) 420(* have a non-zero imaginary part. Here is the ACL2 documentation for *) 421(* COMPLEX-RATIONALP, followed by the doc for COMPLEX (pointed to by the *) 422(* former, and perhaps also useful for you). *) 423(* *) 424(* *) 425(* COMPLEX-RATIONALP recognizes complex rational numbers *) 426(* *) 427(* *) 428(* Examples: *) 429(* (complex-rationalp 3) ; nil, as 3 is rational, not complex rational*) 430(* (complex-rationalp #c(3 0)) ; nil, since #c(3 0) is the same as 3 *) 431(* (complex-rationalp t) ; nil *) 432(* (complex-rationalp #c(3 1)) ; t, as #c(3 1) is the complex number 3 + i *) 433(*****************************************************************************) 434val complex_rationalp_def = 435 acl2Define "ACL2::COMPLEX-RATIONALP" 436 `(complex_rationalp(num(com a b)) = if b = rat_0 then nil else t) 437 /\ 438 (complex_rationalp _ = nil)`; 439 440(*****************************************************************************) 441(* complex *) 442(* *) 443(* ; *1* definition: *) 444(* (defun-*1* complex (x y) *) 445(* (complex (the rational (if (rationalp x) x (gv complex (x y) 0))) *) 446(* (the rational (if (rationalp y) y (gv complex (x y) 0))))) *) 447(* *) 448(* *) 449(* COMPLEX create an ACL2 number *) 450(* *) 451(* *) 452(* Examples: *) 453(* (complex x 3) ; x + 3i, where i is the principal square root of -1 *) 454(* (complex x y) ; x + yi *) 455(* (complex x 0) ; same as x, for rational numbers x *) 456(* *) 457(* *) 458(* The function complex takes two rational number arguments and returns an *) 459(* ACL2 number. This number will be of type (complex rational) [as defined *) 460(* in the Common Lisp language], except that if the second argument is *) 461(* zero, then complex returns its first argument. The function *) 462(* complex-rationalp is a recognizer for complex rational numbers, i.e. for *) 463(* ACL2 numbers that are not rational numbers. *) 464(* *) 465(* The reader macro #C (which is the same as #c) provides a convenient way *) 466(* for typing in complex numbers. For explicit rational numbers x and y, *) 467(* #C(x y) is read to the same value as (complex x y). *) 468(* *) 469(* The functions realpart and imagpart return the real and imaginary parts *) 470(* (respectively) of a complex (possibly rational) number. So for example, *) 471(* (realpart #C(3 4)) = 3, (imagpart #C(3 4)) = 4, (realpart 3/4) = 3/4, *) 472(* and (imagpart 3/4) = 0. *) 473(* *) 474(* The following built-in axiom may be useful for reasoning about complex *) 475(* numbers. *) 476(* *) 477(* (defaxiom complex-definition *) 478(* (implies (and (real/rationalp x) *) 479(* (real/rationalp y)) *) 480(* (equal (complex x y) *) 481(* (+ x ( * #c(0 1) y)))) *) 482(* :rule-classes nil) *) 483(* *) 484(* *) 485(* A completion axiom that shows what complex returns on arguments *) 486(* violating its guard (which says that both arguments are rational *) 487(* numbers) is the following. *) 488(* *) 489(* (equal (complex x y) *) 490(* (complex (if (rationalp x) x 0) *) 491(* (if (rationalp y) y 0))) *) 492(*****************************************************************************) 493val complex_def = 494 acl2Define "COMMON-LISP::COMPLEX" 495 `(complex (num(com xr xi)) (num(com yr yi)) = 496 num(com (if (xi = rat_0) then xr else rat_0) 497 (if (yi = rat_0) then yr else rat_0))) 498 /\ 499 (complex (num(com xr xi)) _ = 500 num(com (if (xi = rat_0) then xr else rat_0) rat_0)) 501 /\ 502 (complex _ (num(com yr yi)) = 503 num(com rat_0 (if (yi = rat_0) then yr else rat_0))) 504 /\ 505 (complex _ _ = int 0)`; 506 507(*****************************************************************************) 508(* integerp *) 509(* *) 510(* ; *1* definition (not helpful): *) 511(* (defun-*1* integerp (x) *) 512(* (integerp x)) *) 513(*****************************************************************************) 514val integerp_def = 515 acl2Define "COMMON-LISP::INTEGERP" 516 `(integerp(num n) = if IS_INT n then t else nil) /\ 517 (integerp _ = nil)`; 518 519(*****************************************************************************) 520(* numerator *) 521(* *) 522(* ; *1* definition:: *) 523(* (defun-*1* numerator (x) *) 524(* (if (rationalp x) *) 525(* (numerator x) *) 526(* (gv numerator (x) 0))) *) 527(* *) 528(* ; Hand-optimized ACL2: *) 529(* (defun-*1* numerator (x) *) 530(* (if (rationalp x) *) 531(* (numerator x) *) 532(* 0)) *) 533(*****************************************************************************) 534val numerator_def = 535 acl2Define "COMMON-LISP::NUMERATOR" 536 `(numerator(num(com a b)) = 537 if b = rat_0 then int(reduced_nmr a) else int 0) 538 /\ 539 (numerator _ = int 0)`; 540 541(*****************************************************************************) 542(* denominator *) 543(* *) 544(* ; *1* definition:: *) 545(* (defun-*1* denominator (x) *) 546(* (if (rationalp x) *) 547(* (denominator x) *) 548(* (gv denominator (x) 1))) *) 549(* *) 550(* ; Hand-optimized ACL2: *) 551(* (defun-*1* denominator (x) *) 552(* (if (rationalp x) *) 553(* (denominator x) *) 554(* 1)) *) 555(*****************************************************************************) 556val denominator_def = 557 acl2Define "COMMON-LISP::DENOMINATOR" 558 `(denominator(num(com a b)) = 559 if b = rat_0 then int(reduced_dnm a) else int 1) 560 /\ 561 (denominator _ = int 1)`; 562 563(*****************************************************************************) 564(* char-code *) 565(* *) 566(* ; *1* definition *) 567(* (defun-*1* char-code (x) *) 568(* (if (characterp x) *) 569(* (char-code x) *) 570(* (gv char-code (x) 0))): *) 571(*****************************************************************************) 572val char_code_def = 573 acl2Define "COMMON-LISP::CHAR-CODE" 574 `(char_code(chr c) = int (&(ORD c))) /\ 575 (char_code _ = int 0)`; 576 577(*****************************************************************************) 578(* code-char *) 579(* *) 580(* ; *1* definition: *) 581(* (defun-*1* code-char (x) *) 582(* (if (and (integerp x) *) 583(* (>= x 0) *) 584(* (< x 256)) *) 585(* (code-char x) *) 586(* (gv code-char (x) (code-char 0)))) *) 587(*****************************************************************************) 588val code_char_def = 589 acl2Define "COMMON-LISP::CODE-CHAR" 590 `(code_char(num(com a b)) = 591 if IS_INT(com a b) /\ (0 <= reduced_nmr a) /\ (reduced_nmr a < 256) 592 then chr(CHR (Num(reduced_nmr a))) 593 else chr(CHR 0)) 594 /\ 595 (code_char _ = chr(CHR 0))`; 596 597(*****************************************************************************) 598(* From axioms.lisp *) 599(* *) 600(* ; (if NIL y z) = z *) 601(* *) 602(* ; x/=NIL -> (if x y z) = y *) 603(* *) 604(* if *) 605(* *) 606(* ; *1* definition (not helpful): *) 607(* (defun-*1* if (x y z) *) 608(* (error "We just can't stand having a non-lazy IF around. *) 609(* But we attempted ~%~ to call the executable counterpart *) 610(* of IF on argument list ~s." *) 611(* (list x y z))) *) 612(* *) 613(* Can't overload "if" onto ``ACL2_IF`` because of HOL's *) 614(* `if ... then ... else` construct. Using "ite" instead. *) 615(*****************************************************************************) 616val ite_def = 617 acl2Define "COMMON-LISP::IF" 618 `ite x (y:sexp) (z:sexp) = if x = nil then z else y`; 619 620(*****************************************************************************) 621(* If f : 'a -> sexp then list_to_sexp f : num list : 'a list -> sexp. *) 622(* *) 623(* For example: *) 624(* *) 625(* |- list_to_sexp num [1; 2; 3] = *) 626(* cons (num 1) (cons (num 2) (cons (num 3) (sym "COMMON-LISP" "NIL"))) *) 627(*****************************************************************************) 628val list_to_sexp_def = 629 Define 630 `(list_to_sexp f [] = nil) /\ 631 (list_to_sexp f (x::l) = cons (f x) (list_to_sexp f l))`; 632 633(*****************************************************************************) 634(* coerce *) 635(* *) 636(* ; First, we need to translate this ACL2 definition: *) 637(* *) 638(* (defun make-character-list (x) *) 639(* (cond ((atom x) nil) *) 640(* ((characterp (car x)) *) 641(* (cons (car x) (make-character-list (cdr x)))) *) 642(* (t *) 643(* (cons (code-char 0) (make-character-list (cdr x)))))) *) 644(* *) 645(* ; We also require HOL functions coerce_string_to_list and *) 646(* ; coerce_list_to_string (not written here) that coerce a string (e.g., *) 647(* ; "abc") to an SEXP list (e.g., cons 'a' (cons 'b' (cons 'c' nil))) *) 648(* ; and vice-versa, respectively. *) 649(* *) 650(* ; *1* definition (not very helpful): *) 651(* (defun-*1* coerce (x y) *) 652(* (cond *) 653(* ((equal y 'list) *) 654(* (if (stringp x) *) 655(* (coerce x 'list) *) 656(* (gv coerce (x y) nil))) *) 657(* ((character-listp x) *) 658(* (if (equal y 'string) *) 659(* (coerce x 'string) *) 660(* (gv coerce (x y) (coerce x 'string)))) *) 661(* (t *) 662(* (gv coerce (x y) *) 663(* (coerce (make-character-list x) 'string))))) *) 664(*****************************************************************************) 665 666(*****************************************************************************) 667(* (defun make-character-list (x) *) 668(* (cond ((atom x) nil) *) 669(* ((characterp (car x)) *) 670(* (cons (car x) (make-character-list (cdr x)))) *) 671(* (t *) 672(* (cons (code-char 0) (make-character-list (cdr x)))))) *) 673(*****************************************************************************) 674 675val sexp_size_def = 676 (fetch "-" "sexp_size_def" 677 handle _ => 678 Define 679 `(sexp_size (sym a0 a1) = 1n) /\ 680 (sexp_size (str a) = 1) /\ 681 (sexp_size (chr b) = 1) /\ 682 (sexp_size (num c) = 1) /\ 683 (sexp_size (cons x y) = 1 + sexp_size x + sexp_size y)`); 684 685val make_character_list_def = 686 tDefine "make_character_list" 687 `(make_character_list(cons (chr c) y) = 688 (cons (chr c) (make_character_list y))) 689 /\ 690 (make_character_list(cons x y) = 691 (cons (code_char(int 0)) (make_character_list y))) 692 /\ 693 (make_character_list _ = nil)` 694 (WF_REL_TAC `measure sexp_size` THEN 695 RW_TAC arith_ss [sexp_size_def]); 696 697(*****************************************************************************) 698(* "abc" |--> (cons (chr #"a") (cons (chr #"b") (cons (chr #"c") nil))) *) 699(* *) 700(* list_to_sexp maps a function down a HOL list and then conses up an *) 701(* s-expression from the resulting list. For example: *) 702(* *) 703(* list_to_sexp chr [a; b; c] = *) 704(* cons (chr a) (cons (chr b) (cons (chr c) (sym "COMMON-LISP" "NIL"))) *) 705(* *) 706(* EXPLODE explodes a HOL string into a HOL list of characters. *) 707(*****************************************************************************) 708val coerce_string_to_list_def = 709 Define 710 `coerce_string_to_list s = list_to_sexp chr (EXPLODE s)`; 711 712(*****************************************************************************) 713(* (cons (chr #"a") (cons (chr #"b") (cons (chr #"c") nil))) |--> "abc" *) 714(* *) 715(* STRING : char->string->string is HOL's string-cons function. *) 716(*****************************************************************************) 717val coerce_list_to_string_def = 718 tDefine "coerce_list_to_string" 719 `(coerce_list_to_string(cons (chr c) y) = 720 STRING c (coerce_list_to_string y)) 721 /\ 722 (coerce_list_to_string _ = "")` 723 (WF_REL_TAC `measure sexp_size` THEN 724 RW_TAC arith_ss [sexp_size_def]); 725 726val coerce_def = 727 acl2Define "COMMON-LISP::COERCE" 728 `(coerce (str s) y = 729 if y = sym "COMMON-LISP" "LIST" 730 then coerce_string_to_list s 731 else str "") 732 /\ 733 (coerce (cons a x) y = 734 if y = sym "COMMON-LISP" "LIST" 735 then nil 736 else str(coerce_list_to_string(make_character_list(cons a x)))) 737 /\ 738 (coerce _ y = if y = sym "COMMON-LISP" "LIST" then nil else str "")`; 739 740(*****************************************************************************) 741(* The following function represents an ACL2 package system, but is not *) 742(* itself an ACL2 primitive; rather, it is used in the translation (see *) 743(* for example intern-in-package-of-symbol). *) 744(* *) 745(* BASIC_INTERN : string -> string -> SEXP *) 746(* *) 747(* An ACL2 data structure is available to help with the definition of *) 748(* BASIC_INTERN. For example, after evaluation of (defpkg "FOO" '(a *) 749(* b)), the form (known-package-alist state) evaluates to the following *) 750(* (which I have abbreviated, omitting irrelevant or not-useful info). *) 751(* Note that each package is associated with a list of imported *) 752(* symbols. For example, "FOO" imports two symbols, represented in HOL *) 753(* as (sym "ACL2" "A") and (sym "ACL2" "B"). *) 754(* *) 755(* (("FOO" (A B) ...) *) 756(* ("ACL2-USER" (& *ACL2-EXPORTS* ...)) *) 757(* ("ACL2-PC" NIL ...) *) 758(* ("ACL2-INPUT-CHANNEL" NIL NIL NIL) *) 759(* ("ACL2-OUTPUT-CHANNEL" NIL NIL NIL) *) 760(* ("ACL2" (&ALLOW-OTHER-KEYS *PRINT-MISER-WIDTH* ...) NIL NIL) *) 761(* ("COMMON-LISP" NIL NIL NIL) *) 762(* ("KEYWORD" NIL NIL NIL)) *) 763(* *) 764(* Let us turn now to the definition of BASIC_INTERN. *) 765(* *) 766(* If pkg_name is the name of a known package and symbol_name is the *) 767(* name of a symbol imported into that package from some other package, *) 768(* named old_pkg, then: *) 769(* *) 770(* BASIC_INTERN symbol_name pkg_name = (sym old_pkg symbol_name) *) 771(* *) 772(* For example, given the package system shown above, *) 773(* BASIC_INTERN "A" "FOO" = (sym "ACL2" "A"). *) 774(* *) 775(* Otherwise, if pkg_name is the name of a known package (from the ACL2 *) 776(* data structure as shown above), then: *) 777(* *) 778(* BASIC_INTERN symbol_name pkg_name = (sym pkg_name symbol_name) *) 779(*****************************************************************************) 780val BASIC_INTERN_def = 781 Define 782 `BASIC_INTERN sym_name pkg_name = 783 sym (LOOKUP pkg_name ACL2_PACKAGE_ALIST sym_name) sym_name`; 784 785(*****************************************************************************) 786(* symbolp *) 787(* *) 788(* ; *1* definition (not helpful): *) 789(* (defun-*1* symbolp (x) *) 790(* (symbolp x)) *) 791(*****************************************************************************) 792val symbolp_def = 793 acl2Define "COMMON-LISP::SYMBOLP" 794 `(symbolp (sym p n) = 795 if (BASIC_INTERN n p = sym p n) /\ ~(p = "") then t else nil) 796 /\ 797 (symbolp _ = nil)`; 798 799(*****************************************************************************) 800(* bad-atom<= *) 801(* *) 802(* ; For us, bad atoms are objects that look like symbols but whose *) 803(* ; combination of package name and symbol name are impossible for the *) 804(* ; given package system. *) 805(* *) 806(* ; *1* definition (not helpful): *) 807(* (defun-*1* bad-atom<= (x y) *) 808(* (cond ((and (bad-atom x) (bad-atom y)) *) 809(* *) 810(* ; The following should never happen. *) 811(* *) 812(* (error "We have called (the executable counterpart of) *) 813(* bad-atom<= on ~ ~s and ~s, but bad-atom<= *) 814(* has no Common Lisp definition." *) 815(* x y)) *) 816(* (t (gv bad-atom<= (x y) nil)))) *) 817(*****************************************************************************) 818 819(*****************************************************************************) 820(* Theorems about VALID_PACKAGE_TRIPLES. Maybe should be closer to their *) 821(* use, e.g. in hol_defaxioms_proofsScript.sml *) 822(*****************************************************************************) 823 824(*****************************************************************************) 825(* Following theorem may not be needed *) 826(*****************************************************************************) 827val VALID_PKG_TRIPLES = 828 store_thm 829 ("VALID_PKG_TRIPLES", 830 ``VALID_PKG_TRIPLES triples = 831 (triples = []) 832 \/ 833 ((LOOKUP (SND(SND(HD triples))) triples (FST(HD triples)) = 834 (SND(SND(HD triples)))) /\ 835 ~((FST(HD triples)) = "ACL2-PKG-WITNESS") /\ 836 ~((SND(SND(HD triples))) = "") /\ 837 (VALID_PKG_TRIPLES_AUX (TL triples) triples))``, 838 Induct_on `triples` 839 THEN RW_TAC list_ss [VALID_PKG_TRIPLES_def,VALID_PKG_TRIPLES_AUX_def] 840 THEN Cases_on `h` 841 THEN Cases_on `r` 842 THEN RW_TAC list_ss [VALID_PKG_TRIPLES_def,VALID_PKG_TRIPLES_AUX_def]); 843 844val LOOKUP_IDEMPOTENT_LEMMA = 845 prove 846 (``VALID_PKG_TRIPLES_AUX tail triples /\ 847 (LOOKUP pkg_name tail sym_name = orig_pkg_name) /\ 848 ~(pkg_name = orig_pkg_name) 849 ==> 850 (LOOKUP orig_pkg_name triples sym_name = orig_pkg_name)``, 851 Induct_on `tail` 852 THEN RW_TAC list_ss [VALID_PKG_TRIPLES_AUX_def,LOOKUP_def] 853 THEN Cases_on `h` 854 THEN Cases_on `q` 855 THEN Cases_on `r` 856 THEN RW_TAC std_ss [] 857 THEN FULL_SIMP_TAC std_ss [VALID_PKG_TRIPLES_AUX_def,LOOKUP_def] 858 THEN BasicProvers.NORM_TAC std_ss []); 859 860val LOOKUP_IDEMPOTENT = 861 store_thm 862 ("LOOKUP_IDEMPOTENT", 863 ``let orig_pkg_name = LOOKUP pkg_name triples sym_name 864 in 865 (VALID_PKG_TRIPLES triples 866 ==> 867 (LOOKUP orig_pkg_name triples sym_name = orig_pkg_name))``, 868 RW_TAC std_ss [] 869 THEN PROVE_TAC [LOOKUP_IDEMPOTENT_LEMMA,VALID_PKG_TRIPLES_def]); 870 871val LOOKUP_NOT_EMPTY_STRING_LEMMA = 872 prove 873 (``VALID_PKG_TRIPLES_AUX tail triples /\ ~(pkg_name = "") 874 ==> 875 ~(LOOKUP pkg_name tail sym_name = "")``, 876 Induct_on `tail` 877 THEN RW_TAC list_ss [VALID_PKG_TRIPLES_AUX_def,LOOKUP_def] 878 THEN Cases_on `h` 879 THEN Cases_on `q` 880 THEN Cases_on `r` 881 THEN RW_TAC std_ss [] 882 THEN FULL_SIMP_TAC std_ss [VALID_PKG_TRIPLES_AUX_def,LOOKUP_def] 883 THEN PROVE_TAC[]); 884 885val LOOKUP_NOT_EMPTY_STRING = 886 store_thm 887 ("LOOKUP_NOT_EMPTY_STRING", 888 ``VALID_PKG_TRIPLES triples /\ ~(pkg_name = "") 889 ==> 890 ~(LOOKUP pkg_name triples sym_name = "")``, 891 PROVE_TAC[VALID_PKG_TRIPLES_def,LOOKUP_NOT_EMPTY_STRING_LEMMA]); 892 893val LOOKUP_PKG_WITNESS_LEMMA = 894 prove 895 (``VALID_PKG_TRIPLES_AUX tail triples 896 ==> 897 (LOOKUP pkg_name tail "ACL2-PKG-WITNESS" = pkg_name)``, 898 Induct_on `tail` 899 THEN RW_TAC list_ss [VALID_PKG_TRIPLES_AUX_def,LOOKUP_def] 900 THEN Cases_on `h` 901 THEN Cases_on `q` 902 THEN Cases_on `r` 903 THEN RW_TAC std_ss [] 904 THEN FULL_SIMP_TAC std_ss [VALID_PKG_TRIPLES_AUX_def,LOOKUP_def] 905 THEN PROVE_TAC[]); 906 907val LOOKUP_PKG_WITNESS = 908 store_thm 909 ("LOOKUP_PKG_WITNESS", 910 ``VALID_PKG_TRIPLES triples 911 ==> 912 (LOOKUP pkg_name triples "ACL2-PKG-WITNESS" = pkg_name)``, 913 PROVE_TAC[VALID_PKG_TRIPLES_def,LOOKUP_PKG_WITNESS_LEMMA]); 914 915(*****************************************************************************) 916(* Use the lexicographic order to lift an order from elements to lists *) 917(*****************************************************************************) 918val LIST_LEX_ORDER_def = 919 Define 920 `(LIST_LEX_ORDER R [] [] = F) 921 /\ 922 (LIST_LEX_ORDER R (a::al) [] = F) 923 /\ 924 (LIST_LEX_ORDER R [] (b::bl) = T) 925 /\ 926 (LIST_LEX_ORDER R (a::al) (b::bl) = 927 R a b \/ ((a = b) /\ LIST_LEX_ORDER R al bl))`; 928 929val LIST_LEX_ORDER_IRREFLEXIVE = 930 store_thm 931 ("LIST_LEX_ORDER_IRREFLEXIVE", 932 ``(!x. ~(R x x)) ==> !xl. ~(LIST_LEX_ORDER R xl xl)``, 933 STRIP_TAC 934 THEN Induct 935 THEN RW_TAC list_ss [LIST_LEX_ORDER_def]); 936 937val LIST_LEX_ORDER_ANTISYM = 938 store_thm 939 ("LIST_LEX_ORDER_ANTISYM", 940 ``(!x y. ~(R x y /\ R y x)) 941 ==> 942 !xl yl. ~(LIST_LEX_ORDER R xl yl /\ LIST_LEX_ORDER R yl xl)``, 943 STRIP_TAC 944 THEN Induct 945 THEN SIMP_TAC list_ss [LIST_LEX_ORDER_def] 946 THENL 947 [Induct 948 THEN SIMP_TAC list_ss [LIST_LEX_ORDER_def], 949 GEN_TAC 950 THEN Induct 951 THEN RW_TAC list_ss [LIST_LEX_ORDER_def] 952 THEN PROVE_TAC[]]); 953 954val LIST_LEX_ORDER_TRANS = 955 store_thm 956 ("LIST_LEX_ORDER_TRANS", 957 ``(!x y z. R x y /\ R y z ==> R x z) 958 ==> 959 !xl yl zl. LIST_LEX_ORDER R xl yl /\ LIST_LEX_ORDER R yl zl 960 ==> 961 LIST_LEX_ORDER R xl zl``, 962 STRIP_TAC 963 THEN Induct 964 THEN SIMP_TAC list_ss [LIST_LEX_ORDER_def] 965 THENL 966 [Induct 967 THEN SIMP_TAC list_ss [LIST_LEX_ORDER_def] 968 THEN GEN_TAC 969 THEN Induct 970 THEN RW_TAC list_ss [LIST_LEX_ORDER_def], 971 GEN_TAC 972 THEN Induct 973 THEN SIMP_TAC list_ss [LIST_LEX_ORDER_def] 974 THEN GEN_TAC 975 THEN Induct 976 THEN RW_TAC list_ss [LIST_LEX_ORDER_def] 977 THEN PROVE_TAC[]]); 978 979val LIST_LEX_ORDER_TRICHOTOMY = 980 store_thm 981 ("LIST_LEX_ORDER_TRICHOTOMY", 982 ``(!x y. R x y \/ R y x \/ (x = y)) 983 ==> 984 !xl yl. LIST_LEX_ORDER R xl yl \/ LIST_LEX_ORDER R yl xl \/ (xl = yl)``, 985 STRIP_TAC 986 THEN Induct 987 THEN SIMP_TAC list_ss [LIST_LEX_ORDER_def] 988 THENL 989 [Induct 990 THEN SIMP_TAC list_ss [LIST_LEX_ORDER_def], 991 GEN_TAC 992 THEN Induct 993 THEN RW_TAC list_ss [LIST_LEX_ORDER_def] 994 THEN PROVE_TAC[]]); 995 996(*****************************************************************************) 997(* Define an order on strings *) 998(*****************************************************************************) 999val STRING_LESS_def = 1000 Define 1001 `STRING_LESS s1 s2 = 1002 LIST_LEX_ORDER 1003 ($< : num->num->bool) 1004 (MAP ORD (EXPLODE s1)) 1005 (MAP ORD (EXPLODE s2))`; 1006 1007val STRING_LESS_EQ_def = 1008 Define 1009 `STRING_LESS_EQ s1 s2 = STRING_LESS s1 s2 \/ (s1 = s2)`; 1010 1011val STRING_LESS_IRREFLEXIVE = 1012 store_thm 1013 ("STRING_LESS_IRREFLEXIVE", 1014 ``~(STRING_LESS s s)``, 1015 METIS_TAC 1016 [STRING_LESS_def,LIST_LEX_ORDER_IRREFLEXIVE, 1017 DECIDE ``!(m:num). ~(m<m)``]); 1018 1019val STRING_LESS_SYM = 1020 store_thm 1021 ("STRING_LESS_SYM", 1022 ``~(STRING_LESS s1 s2 /\ STRING_LESS s2 s1)``, 1023 METIS_TAC 1024 [STRING_LESS_def,LIST_LEX_ORDER_ANTISYM, 1025 DECIDE ``!(m:num) n. ~(m<n /\ n<m)``]); 1026 1027val STRING_LESS_EQ_SYM = 1028 store_thm 1029 ("STRING_LESS_EQ_SYM", 1030 ``STRING_LESS_EQ s1 s2 /\ STRING_LESS_EQ s2 s1 ==> (s1 = s2)``, 1031 METIS_TAC 1032 [STRING_LESS_EQ_def,STRING_LESS_def,LIST_LEX_ORDER_ANTISYM, 1033 DECIDE ``!(m:num) n. ~(m<n /\ n<m)``]); 1034 1035val MAP_ORD_11 = 1036 store_thm 1037 ("MAP_ORD_11", 1038 ``!l1 l2. (MAP ORD l1 = MAP ORD l2) = (l1 = l2)``, 1039 Induct 1040 THEN SIMP_TAC list_ss [] 1041 THENL 1042 [PROVE_TAC[], 1043 GEN_TAC 1044 THEN Induct 1045 THEN RW_TAC list_ss [stringTheory.ORD_11]]); 1046 1047val STRING_LESS_ANTISYM = 1048 store_thm 1049 ("STRING_LESS_ANTISYM", 1050 ``~STRING_LESS s1 s2 /\ ~STRING_LESS s2 s1 ==> (s1 = s2)``, 1051 METIS_TAC 1052 [STRING_LESS_def, 1053 stringTheory.EXPLODE_11,MAP_ORD_11,LIST_LEX_ORDER_TRICHOTOMY, 1054 DECIDE ``!(m:num) n. m<n \/ n<m \/ (m=n)``]); 1055 1056val STRING_LESS_EQ_ANTISYM = 1057 store_thm 1058 ("STRING_LESS_EQ_ANTISYM", 1059 ``~STRING_LESS_EQ s1 s2 /\ ~STRING_LESS_EQ s2 s1 ==> (s1 = s2)``, 1060 METIS_TAC 1061 [STRING_LESS_EQ_def,STRING_LESS_def, 1062 stringTheory.EXPLODE_11,MAP_ORD_11,LIST_LEX_ORDER_TRICHOTOMY, 1063 DECIDE ``!(m:num) n. m<n \/ n<m \/ (m=n)``]); 1064 1065val STRING_LESS_TRICHOTOMY = 1066 store_thm 1067 ("STRING_LESS_TRICHOTOMY", 1068 ``STRING_LESS s1 s2 \/ STRING_LESS s2 s1 \/ (s1 = s2)``, 1069 METIS_TAC 1070 [STRING_LESS_def, 1071 stringTheory.EXPLODE_11,MAP_ORD_11,LIST_LEX_ORDER_TRICHOTOMY, 1072 DECIDE ``!(m:num) n. m<n \/ n<m \/ (m=n)``]); 1073 1074val STRING_LESS_EQ_TRICHOTOMY = 1075 store_thm 1076 ("STRING_LESS_EQ_TRICHOTOMY", 1077 ``STRING_LESS_EQ s1 s2 \/ STRING_LESS_EQ s2 s1``, 1078 METIS_TAC 1079 [STRING_LESS_EQ_def,STRING_LESS_def, 1080 stringTheory.EXPLODE_11,MAP_ORD_11,LIST_LEX_ORDER_TRICHOTOMY, 1081 DECIDE ``!(m:num) n. m<n \/ n<m \/ (m=n)``]); 1082 1083val STRING_LESS_TRANS = 1084 store_thm 1085 ("STRING_LESS_TRANS", 1086 ``STRING_LESS s1 s2 /\ STRING_LESS s2 s3 ==> STRING_LESS s1 s3``, 1087 RW_TAC list_ss [STRING_LESS_def] 1088 THEN METIS_TAC 1089 [LIST_LEX_ORDER_TRANS,stringTheory.EXPLODE_11,MAP_ORD_11, 1090 DECIDE ``!(m:num) n p. m<n /\ n<p ==> m<p``]); 1091 1092val STRING_LESS_EQ_TRANS = 1093 store_thm 1094 ("STRING_LESS_EQ_TRANS", 1095 ``STRING_LESS_EQ s1 s2 /\ STRING_LESS_EQ s2 s3 ==> STRING_LESS_EQ s1 s3``, 1096 RW_TAC list_ss [STRING_LESS_EQ_def,STRING_LESS_def] 1097 THEN Cases_on `s1 = s2` 1098 THEN RW_TAC std_ss [] 1099 THEN Cases_on `s1 = s3` 1100 THEN RW_TAC std_ss [] 1101 THEN METIS_TAC 1102 [LIST_LEX_ORDER_TRANS,stringTheory.EXPLODE_11,MAP_ORD_11, 1103 DECIDE ``!(m:num) n p. m<n /\ n<p ==> m<p``]); 1104 1105val STRING_LESS_TRANS_NOT = 1106 store_thm 1107 ("STRING_LESS_TRANS_NOT", 1108 ``~STRING_LESS s1 s2 /\ ~STRING_LESS s2 s3 ==> ~STRING_LESS s1 s3``, 1109 METIS_TAC[STRING_LESS_TRANS,STRING_LESS_ANTISYM]); 1110 1111val STRING_LESS_EQ_TRANS_NOT = 1112 store_thm 1113 ("STRING_LESS_EQ_TRANS_NOT", 1114 ``~STRING_LESS_EQ s1 s2 /\ ~STRING_LESS_EQ s2 s3 ==> ~STRING_LESS_EQ s1 s3``, 1115 METIS_TAC[STRING_LESS_EQ_TRANS,STRING_LESS_EQ_ANTISYM]); 1116 1117val SEXP_SYM_LESS_def = 1118 Define 1119 `SEXP_SYM_LESS (sym p1 n1) (sym p2 n2) = 1120 STRING_LESS p1 p2 \/ ((p1 = p2) /\ STRING_LESS n1 n2)`; 1121 1122val SEXP_SYM_LESS_EQ_def = 1123 Define 1124 `SEXP_SYM_LESS_EQ sym1 sym2 = SEXP_SYM_LESS sym1 sym2 \/ (sym1 = sym2)`; 1125 1126(*****************************************************************************) 1127(* In ACL2, bad-atom<= is a non-strict order: *) 1128(* *) 1129(* (defaxiom bad-atom<=-antisymmetric *) 1130(* (implies (and (bad-atom x) *) 1131(* (bad-atom y) *) 1132(* (bad-atom<= x y) *) 1133(* (bad-atom<= y x)) *) 1134(* (equal x y)) *) 1135(* :rule-classes nil) *) 1136(*****************************************************************************) 1137val bad_atom_less_equal_def = 1138 acl2Define "ACL2::BAD-ATOM<=" 1139 `bad_atom_less_equal x y = if SEXP_SYM_LESS_EQ x y then t else nil`; 1140 1141(*****************************************************************************) 1142(* symbol-name *) 1143(* *) 1144(* ; *1* definition: *) 1145(* (defun-*1* symbol-name (x) *) 1146(* (if (symbolp x) *) 1147(* (symbol-name x) *) 1148(* (gv symbol-name (x) ""))) *) 1149(*****************************************************************************) 1150val symbol_name_def = 1151 acl2Define "COMMON-LISP::SYMBOL-NAME" 1152 `(symbol_name (sym p n) = ite (symbolp (sym p n)) (str n) (str "")) 1153 /\ 1154 (symbol_name _ = (str ""))`; 1155 1156(*****************************************************************************) 1157(* symbol-package-name *) 1158(* *) 1159(* ; *1* definition: *) 1160(* (defun-*1* symbol-package-name (x) *) 1161(* (if (symbolp x) *) 1162(* (symbol-package-name x) *) 1163(* (gv symbol-package-name (x) ""))) *) 1164(*****************************************************************************) 1165val symbol_package_name_def = 1166 acl2Define "ACL2::SYMBOL-PACKAGE-NAME" 1167 `(symbol_package_name (sym p n) = 1168 ite (symbolp (sym p n)) (str p) (str "")) 1169 /\ 1170 (symbol_package_name _ = (str ""))`; 1171 1172(*****************************************************************************) 1173(* pkg-witness *) 1174(* *) 1175(* ; *1* definition (not very helpful): *) 1176(* (defun-*1* pkg-witness (pkg) *) 1177(* (if (stringp pkg) *) 1178(* (if (find-non-hidden-package-entry *) 1179(* pkg (known-package-alist *the-live-state* )) *) 1180(* (intern *pkg-witness-name* pkg) *) 1181(* (throw-raw-ev-fncall (list 'pkg-witness-er pkg))) *) 1182(* (gv pkg-witness (pkg) (intern *pkg-witness-name* "ACL2")) *) 1183(* *) 1184(* ; Here, we treat the ACL2 constant *pkg-witness-name* as its value, *) 1185(* ; the string "ACL2-PKG-WITNESS" -- in fact, ACL2 treates constants *) 1186(* ; (defconst events) much as it treats macros, in the sense that they *) 1187(* ; are eliminated when passing to internal terms. *) 1188(* *) 1189(* ; Note that ACL2 refuses to parse (pkg-witness pkg) unless pkg is an *) 1190(* ; explicit string naming a package already known to ACL2. *) 1191(* *) 1192(* ; The original default case, represented by the last argument of the gv *) 1193(* ; call shown above, was nil. But in the course of this work, Matt *) 1194(* ; Kaufmann noticed that this default value was erroroneous, and he then *) 1195(* ; exploited this error to prove a contradiction in ACL2 Versions from 2.8 *) 1196(* ; (where pkg-witness was introduced) up through 3.0.1. That bug has been *) 1197(* ; fixed, as shown in the gv call above, for subsequent versions of ACL2. *) 1198(* *) 1199(* MJCG added catchall case after consulting Matt Kaufmann following failure *) 1200(* to prove DEFAXIOM ACL2::SYMBOLP-PKG-WITNESS *) 1201(*****************************************************************************) 1202(* Old version (some axioms untrue with this) 1203val pkg_witness_def = 1204 acl2Define "ACL2::PKG-WITNESS" 1205 `(pkg_witness (str x) = 1206 let s = BASIC_INTERN "ACL2-PKG-WITNESS" x in ite (symbolp s) s nil) 1207 /\ 1208 (pkg_witness _ = BASIC_INTERN "ACL2-PKG-WITNESS" "ACL2")`; 1209*) 1210 1211val pkg_witness_def = 1212 acl2Define "ACL2::PKG-WITNESS" 1213 `(pkg_witness (str x) = 1214 ite (equal (str x) (str "")) 1215 (BASIC_INTERN "ACL2-PKG-WITNESS" "ACL2") 1216 (let s = BASIC_INTERN "ACL2-PKG-WITNESS" x in ite (symbolp s) s nil)) 1217 /\ 1218 (pkg_witness _ = BASIC_INTERN "ACL2-PKG-WITNESS" "ACL2")`; 1219 1220(*****************************************************************************) 1221(* intern-in-package-of-symbol *) 1222(* *) 1223(* ; *1* definition:: *) 1224(* (defun-*1* intern-in-package-of-symbol (x y) *) 1225(* (if (and (stringp x) *) 1226(* (symbolp y)) *) 1227(* (intern x (symbol-package y)) *) 1228(* (gv intern (x y) nil))) *) 1229(* *) 1230(* ; Hand-optimized ACL2: *) 1231(* (defun-*1* intern-in-package-of-symbol (x y) *) 1232(* (if (and (stringp x) *) 1233(* (symbolp y)) *) 1234(* (intern x (symbol-package y)) *) 1235(* nil)) *) 1236(*****************************************************************************) 1237val intern_in_package_of_symbol_def = 1238 acl2Define "ACL2::INTERN-IN-PACKAGE-OF-SYMBOL" 1239 `(intern_in_package_of_symbol (str x) (sym p n) = 1240 ite (symbolp (sym p n)) (BASIC_INTERN x p) nil) 1241 /\ 1242 (intern_in_package_of_symbol _ _ = nil)`; 1243 1244(*****************************************************************************) 1245(* Auxiliary definitions. *) 1246(*****************************************************************************) 1247 1248(*****************************************************************************) 1249(* |= t, where t:sexp, means t is a theorem of ACL2 *) 1250(*****************************************************************************) 1251val _ = set_fixity "|=" (Prefix 11); (* Give "|=" weak precedence *) 1252 1253val ACL2_TRUE_def = 1254 xDefine "ACL2_TRUE" 1255 `(|= p) = (ite (equal p nil) nil t = t)`; 1256 1257val ACL2_TRUE = 1258 store_thm 1259 ("ACL2_TRUE", 1260 ``(|= p) = ~(p = nil)``, 1261 ACL2_SIMP_TAC [ACL2_TRUE_def] 1262 THEN PROVE_TAC[fetch "-" "sexp_11",T_NIL]); 1263 1264(*****************************************************************************) 1265(* Same as translateTheory.bool_def *) 1266(*****************************************************************************) 1267val bool_to_sexp_def = 1268 Define `(bool_to_sexp T = t) /\ (bool_to_sexp F = nil)`; 1269 1270(*****************************************************************************) 1271(* Add quantifiers to ACL2 logic: go to HOL, quantify, then back to ACL2 *) 1272(*****************************************************************************) 1273 1274val forall_def = 1275 new_binder_definition 1276 ("forall_def", ``$forall = \P. bool_to_sexp !v. |= P v``); 1277 1278val exists_def = 1279 new_binder_definition 1280 ("exists_def", ``$exists = \P. bool_to_sexp ?v. |= P v``); 1281 1282val caar_def = 1283 Define 1284 `caar x = car(car x)`; 1285 1286val cadr_def = 1287 Define 1288 `cadr x = car(cdr x)`; 1289 1290val cdar_def = 1291 Define 1292 `cdar x = cdr(car x)`; 1293 1294val cddr_def = 1295 Define 1296 `cddr x = cdr(cdr x)`; 1297 1298val caaar_def = 1299 Define 1300 `caaar x = car(car(car x))`; 1301 1302val cdaar_def = 1303 Define 1304 `cdaar x = cdr(car(car x))`; 1305 1306val cadar_def = 1307 Define 1308 `cadar x = car(cdr(car x))`; 1309 1310val cddar_def = 1311 Define 1312 `cddar x = cdr(cdr(car x))`; 1313 1314val caadr_def = 1315 Define 1316 `caadr x = car(car(cdr x))`; 1317 1318val cdadr_def = 1319 Define 1320 `cdadr x = cdr(car(cdr x))`; 1321 1322val caddr_def = 1323 Define 1324 `caddr x = car(cdr(cdr x))`; 1325 1326val cdddr_def = 1327 Define 1328 `cdddr x = cdr(cdr(cdr x))`; 1329 1330val caaaar_def = 1331 Define 1332 `caaaar x = car(car(car(car x)))`; 1333 1334val cadaar_def = 1335 Define 1336 `cadaar x = car(cdr(car(car x)))`; 1337 1338val caadar_def = 1339 Define 1340 `caadar x = car(car(cdr(car x)))`; 1341 1342val caddar_def = 1343 Define 1344 `caddar x = car(cdr(cdr(car x)))`; 1345 1346val caaadr_def = 1347 Define 1348 `caaadr x = car(car(car(cdr x)))`; 1349 1350val cadadr_def = 1351 Define 1352 `cadadr x = car(cdr(car(cdr x)))`; 1353 1354val caaddr_def = 1355 Define 1356 `caaddr x = car(car(cdr(cdr x)))`; 1357 1358val cadddr_def = 1359 Define 1360 `cadddr x = car(cdr(cdr(cdr x)))`; 1361 1362val cdaaar_def = 1363 Define 1364 `cdaaar x = cdr(car(car(car x)))`; 1365 1366val cddaar_def = 1367 Define 1368 `cddaar x = cdr(cdr(car(car x)))`; 1369 1370val cdadar_def = 1371 Define 1372 `cdadar x = cdr(car(cdr(car x)))`; 1373 1374val cdddar_def = 1375 Define 1376 `cdddar x = cdr(cdr(cdr(car x)))`; 1377 1378val cdaadr_def = 1379 Define 1380 `cdaadr x = cdr(car(car(cdr x)))`; 1381 1382val cddadr_def = 1383 Define 1384 `cddadr x = cdr(cdr(car(cdr x)))`; 1385 1386val cdaddr_def = 1387 Define 1388 `cdaddr x = cdr(car(cdr(cdr x)))`; 1389 1390val cddddr_def = 1391 Define 1392 `cddddr x = cdr(cdr(cdr(cdr x)))`; 1393 1394val List_def = 1395 Define 1396 `(List[] = nil) 1397 /\ 1398 (List(s::sl) = cons s (List sl))`; 1399 1400val andl_def = 1401 Define 1402 `(andl[] = t) 1403 /\ 1404 (andl[s] = s) 1405 /\ 1406 (andl(x::y::l) = ite x (andl(y::l)) nil)`; 1407 1408val andl_append = 1409 store_thm 1410 ("andl_append", 1411 ``!l1 l2. andl(andl l1 :: l2) = andl(l1 ++ l2)``, 1412 Induct 1413 THEN RW_TAC list_ss [andl_def,ite_def,List_def] 1414 THENL 1415 [Cases_on `l2` 1416 THEN RW_TAC list_ss [andl_def,ite_def,List_def,EVAL ``t=nil``], 1417 Cases_on `h=nil` 1418 THEN RW_TAC list_ss [andl_def,ite_def,List_def,EVAL ``t=nil``] 1419 THENL 1420 [Cases_on `l1` THEN Cases_on `l2` 1421 THEN RW_TAC list_ss [andl_def,ite_def,List_def,EVAL ``t=nil``], 1422 Cases_on `l1` 1423 THEN RW_TAC list_ss [andl_def,ite_def,List_def,EVAL ``t=nil``]]]); 1424 1425val andl_fold = 1426 store_thm 1427 ("andl_fold", 1428 ``(ite x y nil = andl[x;y]) 1429 /\ 1430 (andl[x; andl(y::l)] = andl(x::(y::l))) 1431 /\ 1432 (andl(andl(x::y::l1)::l2) = andl(x::y::(l1++l2)))``, 1433 RW_TAC std_ss [andl_def,ite_def,List_def] 1434 THENL 1435 [Cases_on `l2` 1436 THEN RW_TAC std_ss [andl_def,ite_def,List_def], 1437 RW_TAC list_ss [andl_append]]); 1438 1439val itel_def = 1440 Define 1441 `(itel [] val' = val') 1442 /\ 1443 (itel ((test,val)::sl) val' = ite test val (itel sl val'))`; 1444 1445val itel_fold = 1446 store_thm 1447 ("itel_fold", 1448 ``(ite x y z = itel [(x,y)] z) 1449 /\ 1450 (itel [p] (itel pl v) = itel (p::pl) v)``, 1451 Cases_on `p` 1452 THEN RW_TAC std_ss [itel_def,ite_def]); 1453 1454val itel_append = 1455 store_thm 1456 ("itel_append", 1457 ``itel l1 (itel l2 v) = itel (l1 ++ l2) v``, 1458 Induct_on `l1` 1459 THEN RW_TAC list_ss [itel_def,ite_def] 1460 THEN Cases_on `h` 1461 THEN Cases_on `q=nil` 1462 THEN RW_TAC list_ss [itel_def,ite_def,List_def,EVAL ``t=nil``]); 1463 1464(*****************************************************************************) 1465(* Infrastructure for making recursive definitions *) 1466(* (from KXS): *) 1467(* *) 1468(* *) 1469(* 1. Prove the analogue of COND_CONG (call it ite_CONG): *) 1470(* *) 1471(* |- !P Q x x' y y'. *) 1472(* (P = Q) /\ (Q ==> (x = x')) /\ (~Q ==> (y = y')) ==> *) 1473(* ((if P then x else y) = (if Q then x' else y')) : thm *) 1474(* *) 1475(* 2. Install ite_CONG in the DefnBase: *) 1476(* *) 1477(* DefnBase.write_congs (ite_CONG :: DefnBase.read_congs()); *) 1478(* *) 1479(* 3. Make the definition (with Hol_defn) *) 1480(* *) 1481(* 4. The resulting termination conditions should be trivial to prove. *) 1482(*****************************************************************************) 1483 1484val ite_CONG1 = 1485 store_thm 1486 ("ite_CONG1", 1487 ``!p q x x' y y'. 1488 (p = q) /\ (~(q = nil) ==> (x = x')) /\ ((q = nil) ==> (y = y')) 1489 ==> 1490 (ite p x y = ite q x' y')``, 1491 RW_TAC std_ss [ite_def]); 1492 1493val ite_CONG2 = 1494 store_thm 1495 ("ite_CONG2", 1496 ``!p q x x' y y'. 1497 (p = q) /\ ((|= q) ==> (x = x')) /\ (~(|= q) ==> (y = y')) 1498 ==> 1499 (ite p x y = ite q x' y')``, 1500 RW_TAC std_ss [ite_def,ACL2_TRUE_def,equal_def,EVAL ``t=nil``]); 1501 1502val _ = DefnBase.write_congs (ite_CONG1::ite_CONG2::DefnBase.read_congs()); 1503 1504val itel_CONG1 = 1505 store_thm 1506 ("itel_CONG1", 1507 ``!p q x x' l l' y y'. 1508 (p = q) 1509 /\ 1510 (~(q = nil) ==> (x = x')) 1511 /\ 1512 ((q = nil) ==> (itel l y = itel l' y')) 1513 ==> 1514 (itel ((p,x)::l) y = itel ((q,x')::l') y')``, 1515 RW_TAC std_ss [itel_def,ite_def]); 1516 1517val itel_CONG2 = 1518 store_thm 1519 ("itel_CONG2", 1520 ``!p q x x' l l' y y'. 1521 (p = q) 1522 /\ 1523 ((|= q) ==> (x = x')) 1524 /\ 1525 (~(|= q) ==> (itel l y = itel l' y')) 1526 ==> 1527 (itel ((p,x)::l) y = itel ((q,x')::l') y')``, 1528 RW_TAC std_ss [itel_def,ite_def,ACL2_TRUE_def,equal_def,EVAL ``t=nil``]); 1529 1530val _ = DefnBase.write_congs (itel_CONG1::itel_CONG2::DefnBase.read_congs()); 1531 1532val andl_CONG = 1533 store_thm 1534 ("andl_CONG", 1535 ``!p q x x'. 1536 (p = q) /\ (~(p = nil) ==> (x = x')) ==> (andl[p;x] = andl[q;x'])``, 1537 Cases 1538 THEN RW_TAC std_ss [andl_def,ite_def]); 1539 1540val _ = DefnBase.write_congs (andl_CONG::DefnBase.read_congs()); 1541 1542val sexp_size_car = 1543 store_thm 1544 ("sexp_size_car", 1545 ``!x. ~(consp x = nil) ==> (sexp_size (car x) < sexp_size x)``, 1546 Cases 1547 THEN RW_TAC arith_ss 1548 [car_def,nil_def,consp_def,arithmeticTheory.MAX_DEF, 1549 fetch "-" "sexp_size_def"]); 1550 1551val sexp_size_cdr = 1552 store_thm 1553 ("sexp_size_cdr", 1554 ``!x. ~(consp x = nil) ==> (sexp_size (cdr x) < sexp_size x)``, 1555 Cases 1556 THEN RW_TAC arith_ss 1557 [cdr_def,nil_def,consp_def,arithmeticTheory.MAX_DEF, 1558 fetch "-" "sexp_size_def"]); 1559 1560(*****************************************************************************) 1561(* Definitions and lemmas used used in the Ray-Kaufmann LTL example *) 1562(*****************************************************************************) 1563val let_simp = 1564 store_thm 1565 ("let_simp", 1566 ``(!P1 v y. 1567 (let (x,y) = (v,y) in P1 x y) = (let x = v in P1 x y)) 1568 /\ 1569 (!P2 v y z. 1570 (let (x,y,z) = (v,y,z) in P2 x y z) = (let x = v in P2 x y z)) 1571 /\ 1572 (!P3 v y z w. 1573 (let (x,y,z,w) = (v,y,z,w) in P3 x y z w) = (let x = v in P3 x y z w))``, 1574 RW_TAC std_ss [] 1575 THEN FULL_SIMP_TAC std_ss [markerTheory.Abbrev_def]); 1576 1577val forall_fold = 1578 store_thm 1579 ("forall_fold", 1580 ``bool_to_sexp (!v. |= P v) = forall x. P x``, 1581 RW_TAC std_ss [forall_def]); 1582 1583val exists_fold = 1584 store_thm 1585 ("exists_fold", 1586 ``bool_to_sexp (?v. |= P v) = exists x. P x``, 1587 RW_TAC std_ss [exists_def]); 1588 1589val bool_to_sexp = 1590 store_thm 1591 ("bool_to_sexp", 1592 ``bool_to_sexp b = if b then t else nil``, 1593 Cases_on `b` 1594 THEN RW_TAC std_ss [bool_to_sexp_def]); 1595 1596val forall2_thm = 1597 store_thm 1598 ("forall2_thm", 1599 ``(bool_to_sexp !x y. |= P x y) = 1600 bool_to_sexp (!x. |= bool_to_sexp !y. |= P x y)``, 1601 RW_TAC std_ss [bool_to_sexp,ACL2_TRUE] 1602 THEN METIS_TAC[]); 1603 1604val exists2_thm = 1605 store_thm 1606 ("exists2_thm", 1607 ``(bool_to_sexp ?x y. |= P x y) = 1608 bool_to_sexp (?x. |= bool_to_sexp ?y. |= P x y)``, 1609 RW_TAC std_ss [bool_to_sexp,ACL2_TRUE] 1610 THEN METIS_TAC[]); 1611 1612val t_nil = 1613 store_thm 1614 ("t_nil", 1615 ``~(t = nil) /\ ~(nil = t) /\ (|= t) /\ ~(|= nil) /\ 1616 !x. ((x = nil) = ~(|= x)) /\ (~(x = nil) = (|= x))``, 1617 RW_TAC std_ss [t_def,nil_def,ACL2_TRUE]); 1618 1619val bool_to_sexp = 1620 prove 1621 (``bool_to_sexp b = if b then t else nil``, 1622 Cases_on `b` 1623 THEN RW_TAC std_ss [bool_to_sexp_def,t_nil]); 1624 1625val implies_def = 1626 acl2Define "ACL2::IMPLIES" 1627 `implies p q = ite p (andl [q; t]) t`; 1628 1629val implies_ite = 1630 store_thm 1631 ("implies_ite", 1632 ``implies p q = ite p (ite q t nil) t``, 1633 RW_TAC std_ss [implies_def,ite_def,itel_def,andl_def]); 1634 1635val implies = 1636 store_thm 1637 ("implies", 1638 ``(|= implies p q) = (|= p) ==> (|= q)``, 1639 RW_TAC std_ss [implies_def,ite_def,itel_def,andl_def,t_nil]); 1640 1641val consp_nil = 1642 store_thm 1643 ("consp_nil", 1644 ``(consp nil = nil) /\ ~|= consp nil``, 1645 RW_TAC std_ss [consp_def,nil_def,ACL2_TRUE]); 1646 1647val ite_simp = 1648 store_thm 1649 ("ite_simp", 1650 ``!a b c. 1651 ((|= (if a then b else c)) = (a /\ (|= b)) \/ (~a /\ |= c)) 1652 /\ 1653 (ite nil b c = c) /\ (ite t b c = b)``, 1654 GEN_TAC 1655 THEN Cases_on `a` 1656 THEN RW_TAC std_ss [t_nil,ite_def]); 1657 1658val andl_simp = 1659 store_thm 1660 ("andl_simp", 1661 ``!a b. (|= andl []) /\ ((|= andl (a::b)) = (|= a) /\ (|= andl b))``, 1662 GEN_TAC 1663 THEN Cases 1664 THEN RW_TAC std_ss [andl_def,t_nil,ite_def] 1665 THEN METIS_TAC[]); 1666 1667val not_def = 1668 acl2Define "COMMON-LISP::NOT" 1669 `not p = ite p nil t`; 1670 1671val not_simp = 1672 store_thm 1673 ("not_simp", 1674 ``(|= not a) = ~|= a``, 1675 RW_TAC std_ss [not_def,t_nil,ite_def]); 1676 1677val equal_memberp_imp = 1678 store_thm 1679 ("equal_memberp_imp", 1680 ``!a s1 s2. 1681 (|= equal (memberp a s1) (memberp a s2)) 1682 ==> 1683 ((|= memberp a s1) = (|= memberp a s2))``, 1684 RW_TAC std_ss [equal_def,t_nil]); 1685 1686val equal_imp = 1687 store_thm 1688 ("equal_imp", 1689 ``!a s1 s2. (|= equal s1 s2) ==> ((|= s1) = (|= s2))``, 1690 RW_TAC std_ss [equal_def,t_nil]); 1691 1692(*****************************************************************************) 1693(* HOL version of Matt's ACL2 function imported-symbol-names *) 1694(* used to prove acl2_package_defaxiom: *) 1695(* *) 1696(* (defun imported-symbol-names (pkg-name triples) *) 1697(* (cond ((endp triples) nil) *) 1698(* ((equal (cadr (car triples)) pkg-name) *) 1699(* (cons (car (car triples)) *) 1700(* (imported-symbol-names pkg-name (cdr triples)))) *) 1701(* (t (imported-symbol-names pkg-name (cdr triples))))) *) 1702(*****************************************************************************) 1703val imported_symbol_names_def = 1704 Define 1705 `(imported_symbol_names pkg_name [] = []) 1706 /\ 1707 (imported_symbol_names pkg_name 1708 ((sym_name,known_name,actual_name)::triples) = 1709 if (known_name = pkg_name) 1710 then sym_name :: (imported_symbol_names pkg_name triples) 1711 else imported_symbol_names pkg_name triples)`; 1712 1713val _ = 1714 add_acl2_simps 1715 [fetch "-" "sexp_11",ACL2_TRUE, 1716 caar_def,cadr_def,cdar_def,cddr_def, 1717 caaar_def,cdaar_def,cadar_def,cddar_def,caadr_def,cdadr_def,caddr_def,cdddr_def, 1718 caaaar_def,cadaar_def,caadar_def,caddar_def,caaadr_def,cadadr_def,caaddr_def, 1719 cadddr_def,cdaaar_def,cddaar_def,cdadar_def,cdddar_def,cdaadr_def,cddadr_def, 1720 cdaddr_def,cddddr_def,sexp_size_car,sexp_size_cdr, 1721 List_def,andl_def]; 1722 1723val _ = adjoin_to_theory 1724 {sig_ps = NONE, 1725 struct_ps = 1726 SOME (fn ppstrm => 1727 PP.add_string ppstrm 1728 ("val _ = DefnBase.write_congs" ^ 1729 "(andl_CONG::\ 1730 \ite_CONG1::ite_CONG2::\ 1731 \itel_CONG1::itel_CONG2::\ 1732 \DefnBase.read_congs());\n")) 1733 }; 1734 1735val _ = export_acl2_theory(); 1736 1737