File: case-raw.lsp

package info (click to toggle)
acl2 8.5dfsg-5
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 991,452 kB
  • sloc: lisp: 15,567,759; javascript: 22,820; cpp: 13,929; ansic: 12,092; perl: 7,150; java: 4,405; xml: 3,884; makefile: 3,507; sh: 3,187; ruby: 2,633; ml: 763; python: 746; yacc: 723; awk: 295; csh: 186; php: 171; lex: 154; tcl: 49; asm: 23; haskell: 17
file content (85 lines) | stat: -rw-r--r-- 3,160 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
; case-raw.lsp
; Copyright (C) 2013, Regents of the University of Texas

; This version of ACL2 is a descendent of ACL2 Version 1.9, Copyright
; (C) 1997 Computational Logic, Inc.  See the documentation topic NOTE-2-0.

; This program is free software; you can redistribute it and/or modify
; it under the terms of the LICENSE file distributed with ACL2.

; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; LICENSE for more details.

; This file was originally part of the HONS version of ACL2.  The original
; version of ACL2(h) was contributed by Bob Boyer and Warren A. Hunt, Jr.  The
; design of this system of Hash CONS, function memoization, and fast
; association lists (applicative hash tables) was initially implemented by
; Boyer and Hunt.

(in-package "ACL2")

; A SOMETIMES FASTER VERSION OF THE COMMON LISP CASE FUNCTION

#+Clozure
(let ((ccl::*warn-if-redefine-kernel* nil))

#+Clozure
(defmacro case (key &body forms)

  ; A modification of the CCL DEFMACRO for CASE.

  "CASE Keyform {({(Key*) | Key} Form*)}* Evaluates the Forms in the
  first clause with a Key EQL to the value of Keyform. If a singleton
  key is T then the clause is a default clause."

  (multiple-value-bind (less-than-or-equal n greater-than)
    (splitable-case forms)
    (cond
     (less-than-or-equal
      (let ((key-var (gensym)))
        `(let ((,key-var ,key))
           (cond ((not (typep ,key-var 'fixnum)) nil)
                 ((< (the fixnum ,key-var) ,n)
                  (fixnum-case ,key-var ,@less-than-or-equal))
                 (t (fixnum-case ,key-var ,@greater-than))))))
     (t (let ((key-var (gensym)))
          `(let ((,key-var ,key))
             (declare (ignorable ,key-var))
             (cond ,@(ccl::case-aux forms key-var nil nil)))))))))

#+Clozure
(defmacro fixnum-case (key &body forms)
  ; For use only when key is a symbol known to hold a fixum.
  (multiple-value-bind (less-than-or-equal n greater-than)
    (splitable-case forms)
    (cond (less-than-or-equal
           `(cond ((< (the fixnum ,key) ,n)
                   (fixnum-case ,key ,@less-than-or-equal))
                  (t (fixnum-case ,key ,@greater-than))))
          (t (let ((key-var (gensym)))
               `(let ((,key-var (the fixnum ,key)))
                  (declare (ignorable ,key-var) (fixnum ,key-var))
                  (cond ,@(ccl::case-aux forms key-var nil nil))))))))

#+Clozure
(defun splitable-case (forms)
  (let ((l (length forms)))
    (cond
     ((and (> l 8)
           (loop for x in forms
                 always (and (consp x) (typep (car x) 'fixnum))))
      (let* ((c (sort (copy-list forms) #'< :key #'car))
             (h (floor l 2))
             (s (car (nth h c))))
        (loop for tail on c
              when (and (cdr tail) (eql (car tail) (cadr tail)))
              do (error "CASE: duplicate-keys: ~a." (car tail)))
        (values
         (loop for x in forms when (< (car x) s) collect x)
         s
         (loop for x in forms when (>= (car x) s) collect x)))))))