#ci
(module acl2-prims-scheme mzscheme
(require (lib "contract.ss")
(prefix srfi: (lib "1.ss" "srfi"))
(file "../constants.scm")
(file "../nil-macros.scm"))
(require-for-syntax "../checking-proc.scm")
(require-for-template mzscheme)
(define-syntax (define/c stx)
(syntax-case stx (rename case-lambda)
[(_ [rename local-id provided-id] contract-expr value-expr)
#'(begin (define local-id value-expr)
(provide/contract [rename local-id provided-id contract-expr]))]
[(_ id contract-expr (case-lambda clause ...))
(identifier? #'id)
#'(begin (provide [rename macro id])
(define id (case-lambda clause ...))
(define-syntax macro
(lambda (syn)
(syntax-case syn ()
[(_id x (... ...))
#'((contract contract-expr id '|Dracula Language| '|Dracula program|)
x (... ...))]
[_else
(raise-syntax-error
#f "Functions may only appear in operator position" syn)]))))]
[(_ id contract-expr value-expr)
(identifier? #'id)
#'(begin (define id value-expr)
(provide/contract [id contract-expr]))]
[(_ ([rename local-id provided-id] formals ...) contract-expr body bodies ...)
(with-syntax ([(formals* ...) (generate-temporaries #'(formals ...))])
#'(begin (define (local-id formals ...) (begin body bodies ...))
(define-syntax macro-id
(checking-proc local-id contract-expr '|Dracula Language| '|Dracula program|
(formals* ...))
(lambda (syn)
(syntax-case syn ()
[(_id formals* ...)
(syntax/loc syn
((contract contract-expr local-id
'|Dracula Language| '|Dracula program|)
formals* ...))]
[(_id x (... ...)) (raise-syntax-error #f "arity" syn)]
[_else (raise-syntax-error #f "1st order" syn)])))
(provide [rename macro-id provided-id])))]
[(_ (id formals ...) contract-expr body bodies ...)
(with-syntax ([(formals* ...) (generate-temporaries #'(formals ...))])
#'(begin (define (id formals ...) (begin body bodies ...))
(define-syntax macro-id
(checking-proc id contract-expr '|Dracula Language| '|Dracula program|
(formals* ...))
(lambda (syn)
(syntax-case syn ()
[(_id formals* ...)
(syntax/loc syn
((contract contract-expr id '|Dracula Language| '|Dracula program|)
formals* ...))]
[(_id x (... ...)) (raise-syntax-error #f "arity" syn)]
[_else (raise-syntax-error #f "1st order" syn)])))
(provide [rename macro-id id])))]))
(define-syntax bool->CL
(syntax-rules ()
[(_ x) (if x T nil)]))
(define real/rational? rational?)
(define (acl2-symbol? x) (or (symbol? x) (null? x)))
(define symbolp/c (flat-named-contract "symbolp" acl2-symbol?))
(define nil/c (flat-named-contract "nil" null?))
(define (acl2-number? x) (number? x))
(define acl2-number/c (flat-named-contract "acl2-numberp" acl2-number?))
(define (non-zero-acl2-number? x) (and (acl2-number? x) (not (zero? x))))
(define (non-zero-real/rational? x) (and (real/rational? x) (not (zero? x))))
(define (eqlable? x)
(or (acl2-number? x) (acl2-symbol? x) (char? x)))
(define/c (eqlablep x) (any/c . -> . any) (bool->CL (eqlable? x)))
(define eqlablep/c (flat-named-contract "eqlablep" eqlable?))
(define/c (eq x y)
(([x any/c] [y (if (acl2-symbol? x) any/c symbolp/c)]) . ->r . any)
(bool->CL (eq? x y)))
(define/c (eql x y)
(([x any/c] [y (if (eqlable? x) any/c eqlablep/c)]) . ->r . any)
(bool->CL (eqv? x y)))
(define/c (equal x y)
(any/c any/c . -> . any)
(bool->CL (equal? x y)))
(define (not-nil x) (null? (eql x nil)))
(define-syntax (acl2:* stx)
(syntax-case stx (acl2:*)
[(_ args ...) #'(* args ...)]
[acl2:* (raise-syntax-error #f "Functions are allowed only in operator position" stx)]))
(provide [rename acl2:* *])
(define-syntax (acl2:+ stx)
(syntax-case stx (acl2:+)
[(_ args ...) #'(+ args ...)]
[acl2:+ (raise-syntax-error #f "Functions are allowed only in operator position" stx)]))
(provide [rename acl2:+ +])
(define acl2:-
(case-> (acl2-number/c . -> . any)
(acl2-number/c acl2-number/c . -> . any))
(case-lambda
[(x) (- x)]
[(x y) (- x y)]
[args (raise-mismatch-error
'- "Expected only one or two arguments, but given "
(length args))]))
(define-syntax (macro- stx)
(syntax-case stx ()
[(_ x) #'(acl2:- x)]
[(_ x y) #'(acl2:- x y)]
[(_ x ...) (raise-syntax-error
#f
(format "Expects only one or two arguments, but given ~a"
(length (syntax->list #'(x ...))))
stx)]
[_else (raise-syntax-error #f "Functions are allowed only in operator position" stx)]))
(provide [rename macro- -])
(provide not-nil)
(define/c (symbolp x) (any/c . -> . any)
(bool->CL (or (symbol? x) (null? x))))
(provide/contract
[list (() (listof any/c) . ->* . any)]
[list* ((any/c) (listof any/c) . ->* . any)])
(define-syntax (a:list stx)
(syntax-case stx (a:list)
[(_ x ...) #'(list x ...)]
[a:list (raise-syntax-error #f "Functions can only be used in operator position" stx)]))
(define-syntax (a:list* stx)
(syntax-case stx (a:list*)
[(_ x ...) #'(list* x ...)]
[a:list* (raise-syntax-error #f "Functions can only be used in operator position" stx)]))
(provide [rename a:list list]
[rename a:list* list*])
(define/c ([rename a:cons cons] x y) [any/c any/c . -> . any] (cons x y))
(define/c make-list
(case-> [natural-number/c . -> . any]
[natural-number/c (symbols ':initial-element) any/c . -> . any])
(case-lambda
[(size) (srfi:make-list size nil)]
[(size :initial-element fill) (srfi:make-list size fill)]))
(define/c (endp x) ((or/c nil/c pair?) . -> . any) (eq x nil))
(define/c ([rename a:null null] x) (any/c . -> . any) (eq x nil))
(define/c (consp x) (any/c . -> . any) (bool->CL (pair? x)))
(define (true-list? x) (or (null? x) (eq? x 'nil)
(and (pair? x) (true-list? (cdr x)))))
(define/c (true-listp x)
(any/c . -> . any)
(bool->CL (true-list? x)))
(define/c ([rename a:car car] x) [(or/c nil/c (cons/c any/c any/c)) . -> . any]
(if (pair? x) (car x) '()))
(define/c ([rename a:cdr cdr] x) [(or/c nil/c (cons/c any/c any/c)) . -> . any]
(if (pair? x) (cdr x) '()))
(define/c (len x) (any/c . -> . any)
(let loop ([x x] [answer 0])
(if (pair? x) (loop (cdr x) (add1 answer)) answer)))
(define-syntax (acl2:append stx)
(syntax-case stx (acl2:append)
[(_ x ...) #'(append x ...)]
[acl2:append (raise-syntax-error #f "Functions are only allowed on operator position" stx)]))
(provide [rename acl2:append append])
(define/c concatenate (case-> [(symbols 'string 'list) . -> . any]
[((symbols 'string 'list)) (or/c (listof string?) (listof (listof any/c))) . ->* . any])
(case-lambda
[(result-type) (if (eq? result-type 'list) '() "")]
[(result-type . args) (apply (if (eq? result-type 'list) append string-append) args)]))
(define/c (revappend lst acc) [(listof any/c) any/c . -> . any]
(if (null? lst)
acc
(revappend (cdr lst) (cons (car lst) acc))))
(define/c ([rename acl2-reverse reverse] lst-or-str)
[(or/c string? (listof any/c)) . -> . any]
(if (string? lst-or-str)
(list->string (revappend (string->list lst-or-str) '()))
(revappend lst-or-str '())))
(define/c (intersectp-eq x y)
((listof acl2-symbol?) (listof acl2-symbol?) . -> . any)
(cond [(nil? x) nil]
[(memq (car x) y) t]
[else (intersectp-eq (cdr x) y)]))
(define/c (intersectp-equal x y)
((listof any/c) (listof any/c) . -> . any)
(cond [(nil? x) nil]
[(member (car x) y) t]
[else (intersectp-equal (cdr x) y)]))
(define/c (lognot x)
[integer? . -> . any]
(bitwise-not x))
(define/c logand
(case-> (-> any)
(integer? . -> . any)
(integer? integer? . -> . any)
(integer? integer? integer? . -> . any)
((listof integer?) . -> . any))
(case-lambda
[() -1]
[(x) x]
[(x y) (bitwise-and x y)]
[(x y z) (bitwise-and x y z)]
[args (apply bitwise-and args)]))
(define/c logior
(case-> (-> any)
(integer? . -> . any)
(integer? integer? . -> . any)
(integer? integer? integer? . -> . any)
((listof integer?) . -> . any))
(case-lambda
[() 0]
[(x) x]
[(x y) (bitwise-ior x y)]
[(x y z) (bitwise-ior x y z)]
[args (apply bitwise-ior args)]))
(define/c (logorc1 i j)
[integer? integer? . -> . any]
(logior (lognot i) j))
(define/c (logorc2 i j)
[integer? integer? . -> . any]
(logior i (lognot j)))
(define (binary-logeqv x y) (logand (logorc1 x y) (logorc1 y x)))
(define/c logeqv
(case-> [-> any]
[integer? . -> . any]
[() (listof integer?) . ->* . any])
(case-lambda [() -1]
[(x) x]
[args (srfi:fold binary-logeqv (car args) (cdr args))]))
(define/c logxor
(case-> [-> any]
[() (listof integer?) . ->* . any])
(case-lambda [() 0]
[args (apply bitwise-xor args)]))
(define/c ([rename a:expt expt] x y) [acl2-number? integer? . -> . any]
(expt x y))
(define/c (characterp x) [any/c . -> . any]
(bool->CL (char? x)))
(define/c (alpha-char-p x) [char? . -> . any]
(bool->CL (char-alphabetic? x)))
(define/c (char-equal c1 c2) [char? char? . -> . any]
(bool->CL (char-ci=? c1 c2)))
(define/c (char< c1 c2) [char? char? . -> . any]
(bool->CL (char<? c1 c2)))
(define/c (char<= c1 c2) [char? char? . -> . any]
(bool->CL (char<=? c1 c2)))
(define/c (char>= c1 c2) [char? char? . -> . any]
(bool->CL (char>=? c1 c2)))
(define/c (char> c1 c2) [char? char? . -> . any]
(bool->CL (char>? c1 c2)))
(define/c (char-code c) [char? . -> . any] (char->integer c))
(define/c (code-char i) [integer? . -> . any] (integer->char i))
(define/c digit-char-p
(case-> (char? . -> . any)
(char? (integer-in 2 36) . -> . any))
(case-lambda
[(x) (or (string->number (string x)) nil)]
[(x base) (or (string->number (string x) base) nil)]))
(define/c make-character-list [any/c . -> . any]
(lambda (chars)
(let loop ([chars chars]
[result '()])
(cond [(pair? chars) (loop (cdr chars) (cons (if (char? (car chars))
(car chars)
(code-char 0))
result))]
[else (reverse! result)]))))
(define/c (stringp x) [any/c . -> . any] (bool->CL (string? x)))
(define *standard-chars*
'(#\Newline #\Space #\! #\" #\# #\$
#\% #\& #\' #\( #\) #\* #\+ #\, #\- #\.
#\/ #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8
#\9 #\: #\; #\< #\= #\> #\? #\@ #\A #\B
#\C #\D #\E #\F #\G #\H #\I #\J #\K #\L
#\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V
#\W #\X #\Y #\Z #\[ #\\ #\] #\^ #\_ #\`
#\a #\b #\c #\d #\e #\f #\g #\h #\i #\j
#\k #\l #\m #\n #\o #\p #\q #\r #\s #\t
#\u #\v #\w #\x #\y #\z #\{ #\| #\} #\~))
(define/c (standard-char-p c) [char? . -> . any]
(if (memq c *standard-chars*) T nil))
(define (standard-string? s)
(and (string? s) (andmap (lambda (x) (memq x *standard-chars*)) (string->list s))))
(define/c (standard-char-listp x) [any/c . -> . any]
(bool->CL (let loop ([x x])
(if (pair? x)
(and (memq (car x) *standard-chars*)
(loop (cdr x)))
(null? x)))))
(define/c (string-equal s1 s2) [standard-string? standard-string? . -> . any]
(guard (and (stringp s1) (stringp s2)
(standard-char-listp (coerce s1 'list))
(standard-char-listp (coerce s2 'list))))
(bool->CL (string-ci=? s1 s2)))
(define/c (string< s1 s2) [string? string? . -> . any]
(let loop ([posn 0]
[s1 (string->list s1)]
[s2 (string->list s2)])
(cond [(null? s1) (if (null? s2) nil posn)]
[(null? s2) nil]
[(char<? (car s1) (car s2)) posn]
[(char=? (car s1) (car s2)) (loop (add1 posn) (cdr s1) (cdr s2))]
[else nil])))
(define/c (string<= s1 s2) [string? string? . -> . any]
(if (string=? s1 s2) (string-length s1) (string< s1 s2)))
(define/c (string>= s1 s2) [string? string? . -> . any]
(if (string=? s1 s2) (string-length s1) (string> s1 s2)))
(define/c (string> s1 s2) [string? string? . -> . any]
(string< s2 s1))
(define/c (nth n l) (natural-number/c (listof any/c) . -> . any)
(if (>= n (length l)) nil (list-ref l n)))
(define/c (coerce x result-type)
(guard (cond [(equal result-type 'list) (stringp x)]
[(equal result-type 'string) (character-listp x)])
else (coerce (make-character-list x) 'string))
(([x (case result-type
[(list) string?]
[(string) (listof char?)]
[else any/c])] [result-type (symbols 'list 'string)])
. ->r . any)
(case result-type
[(list) (string->list x)]
[(string) (list->string x)]))
(define/c (explode-nonnegative-integer n radix rest)
[natural-number/c (or/c (=/c 2) (=/c 8) (=/c 10) (=/c 16)) any/c . -> . any]
(append (string->list (number->string n radix)) rest))
(define/c (acl2-numberp x) [any/c . -> . any]
(bool->CL (acl2-number? x)))
(define/c (natp x) [any/c . -> . any]
(bool->CL (and (integer? x) (<= 0 x))))
(define (complex-rational? val)
(and (complex? val)
(let ([real (real-part val)]
[imag (imag-part val)])
(and (rational? real)
(rational? imag)
(not (zero? imag))))))
(define/c (complex-rationalp x) [any/c . -> . any] (bool->CL (complex-rational? x)))
(define/c (zp x) [natural-number/c . -> . any] (bool->CL (zero? x)))
(define/c (evenp x) [integer? . -> . any] (bool->CL (even? x)))
(define/c (oddp x) [integer? . -> . any] (bool->CL (odd? x)))
(define/c (minusp x) [real/rational? . -> . any] (bool->CL (negative? x)))
(define/c (plusp x) [real/rational? . -> . any] (bool->CL (positive? x)))
(define/c (posp x) [integer? . -> . any] (bool->CL (positive? x)))
(define/c (integerp x) (any/c . -> . any) (bool->CL (integer? x)))
(define/c (rationalp x) (any/c . -> . any) (bool->CL (rational? x)))
(define/c (real/rationalp x) (any/c . -> . any) (rationalp x))
(define/c (integer-range-p low high int) (integer? integer? any/c . -> . any)
(bool->CL (and (integer? int)
(<= low int)
(< int high))))
(define/c ([rename a:min min] x y) [real/rational? real/rational? . -> . any]
(min x y))
(define/c ([rename a:max max] x y) [real/rational? real/rational? . -> . any]
(max x y))
(define/c (unary-/ x) (non-zero-acl2-number? . -> . any) (/ x))
(define acl2:/
(case-> (non-zero-acl2-number? . -> . any)
(acl2-number? non-zero-acl2-number? . -> . any))
(case-lambda
[(x) (/ x)]
[(num den) (/ num den)]))
(define-syntax (macro/ stx)
(syntax-case stx ()
[(_ x) #'(/ x)]
[(_ num den) #'(/ num den)]
[(_ x ...) (raise-syntax-error
#f
(format "Expected one or two arguments, but got ~a"
(length (syntax->list #'(x ...))))
stx)]
[_else (raise-syntax-error #f "Functions are allowed only in operator position" stx)]))
(provide [rename macro/ /])
(define/c (nonnegative-integer-quotient num den)
(natural-number/c (and/c natural-number/c (>/c 0)) . -> . any)
(quotient num den))
(define/c ([rename acl2:= =] x y) (acl2-number? acl2-number? . -> . any)
(bool->CL (= x y)))
(define/c ([rename acl2:< <] x y) [real/rational? real/rational? . -> . any] (bool->CL (< x y)))
(define/c ([rename acl2:<= <=] x y) [real/rational? real/rational? . -> . any] (bool->CL (<= x y)))
(define/c ([rename acl2:>= >=] x y) [real/rational? real/rational? . -> . any] (bool->CL (>= x y)))
(define/c ([rename acl2:> >] x y) [real/rational? real/rational? . -> . any] (bool->CL (> x y)))
(define/c (fix x) [any/c . -> . any] (if (number? x) x 0))
(define/c ([rename acl2:floor floor] num den) [real/rational? non-zero-real/rational? . -> . any]
(floor (/ num den)))
(define/c (mod i j) [real/rational? non-zero-real/rational? . -> . any]
(- i (* (acl2:floor i j) j)))
(provide/contract (rename acl2:not not [any/c . -> . any]))
(define/c ([rename acl2:not not] x) [any/c . -> . any]
(if (null? x) T nil))
(define (alist? x)
(or (null? x)
(and (pair? x) (pair? (car x)) (alist? (cdr x)))))
(define/c (alistp x) [any/c . -> . any] (bool->CL (alist? x)))
(define (both pred? x y) (and (pred? x) (pred? y)))
(define (complex/lex<= c1 c2)
(let ([x1 (fix c1)]
[y1 (fix c2)])
(or (< (real-part x1) (real-part y1))
(and (= (real-part x1) (real-part y1))
(< (imag-part x1) (imag-part y1))))))
(define (atom? x) (not (pair? x)))
(define/c (alphorder a b) [atom? atom? . -> . any]
(cond [(both rational? a b) (acl2:<= a b)]
[(both complex-rational? a b) (complex/lex<= a b)]
[(both char? a b) (bool->CL (char<=? a b))]
[(both string? a b) (bool->CL (string<=? a b))]
[(both symbol? a b) (bool->CL (string-ci<=? (symbol->string a) (symbol->string b)))]
[(both null? a b) T]
[(rational? a) T]
[(rational? b) nil]
[(complex-rational? a) T]
[(complex-rational? b) nil]
[(char? a) T]
[(char? b) nil]
[(string? a) T]
[(string? b) nil]
[(symbol? a) T]
[(null? a) T]
[else nil]))
(define-syntax (def-c*r stx)
(syntax-case stx ()
[(_ c*r ...)
(with-syntax ([(acl2:c*r ...) (generate-temporaries #'(c*r ...))])
#'(begin (define (acl2:c*r x) (if (eq? x nil) nil (c*r x))) ...
(provide (rename acl2:c*r c*r)) ...))]))
(def-c*r caar cadr cdar cddr)
(def-c*r caaar caadr cadar caddr cdaar cdadr cddar cdddr)
(def-c*r caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr)
(define/c ([rename a:second second] x) [(or/c nil/c pair?) . -> . any] (a:cadr x))
(define/c ([rename a:caar caar] x) [(or/c nil/c pair?) . -> . any] (a:car (a:car x)))
(define/c ([rename a:cadr cadr] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cdr x)))
(define/c ([rename a:cdar cdar] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:car x)))
(define/c ([rename a:cddr cddr] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cdr x)))
(define/c ([rename a:third third] x) [(or/c nil/c pair?) . -> . any] (caddr x))
(define/c ([rename a:caaar caaar] x) [(or/c nil/c pair?) . -> . any] (a:car (a:caar x)))
(define/c ([rename a:caadr caadr] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cadr x)))
(define/c ([rename a:cadar cadar] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cdar x)))
(define/c ([rename a:caddr caddr] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cddr x)))
(define/c ([rename a:cdaar cdaar] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:caar x)))
(define/c ([rename a:cdadr cdadr] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cadr x)))
(define/c ([rename a:cddar cddar] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cdar x)))
(define/c ([rename a:cdddr cdddr] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cddr x)))
(define/c ([rename a:fourth fourth] x) [(or/c nil/c pair?) . -> . any] (cadddr x))
(define/c ([rename a:caaaar caaaar] x) [(or/c nil/c pair?) . -> . any] (a:car (a:caaar x)))
(define/c ([rename a:caaadr caaadr] x) [(or/c nil/c pair?) . -> . any] (a:car (a:caadr x)))
(define/c ([rename a:caadar caadar] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cadar x)))
(define/c ([rename a:caaddr caaddr] x) [(or/c nil/c pair?) . -> . any] (a:car (a:caddr x)))
(define/c ([rename a:cadaar cadaar] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cdaar x)))
(define/c ([rename a:cadadr cadadr] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cdadr x)))
(define/c ([rename a:caddar caddar] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cddar x)))
(define/c ([rename a:cadddr cadddr] x) [(or/c nil/c pair?) . -> . any] (a:car (a:cdddr x)))
(define/c ([rename a:cdaaar cdaaar] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:caaar x)))
(define/c ([rename a:cdaadr cdaadr] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:caadr x)))
(define/c ([rename a:cdadar cdadar] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cadar x)))
(define/c ([rename a:cdaddr cdaddr] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:caddr x)))
(define/c ([rename a:cddaar cddaar] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cdaar x)))
(define/c ([rename a:cddadr cddadr] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cdadr x)))
(define/c ([rename a:cdddar cdddar] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cddar x)))
(define/c ([rename a:cddddr cddddr] x) [(or/c nil/c pair?) . -> . any] (a:cdr (a:cdddr x)))
)