File: fast-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 (106 lines) | stat: -rw-r--r-- 4,357 bytes parent folder | download | duplicates (3)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
; NREV - A "safe" implementation of something like nreverse
; Copyright (C) 2014 Centaur Technology
;
; Contact:
;   Centaur Technology Formal Verification Group
;   7600-C N. Capital of Texas Highway, Suite 300, Austin, TX 78731, USA.
;   http://www.centtech.com/
;
; License: (An MIT/X11-style license)
;
;   Permission is hereby granted, free of charge, to any person obtaining a
;   copy of this software and associated documentation files (the "Software"),
;   to deal in the Software without restriction, including without limitation
;   the rights to use, copy, modify, merge, publish, distribute, sublicense,
;   and/or sell copies of the Software, and to permit persons to whom the
;   Software is furnished to do so, subject to the following conditions:
;
;   The above copyright notice and this permission notice shall be included in
;   all copies or substantial portions of the Software.
;
;   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;   DEALINGS IN THE SOFTWARE.
;
; Original authors: Jared Davis <jared@centtech.com>
;                   Sol Swords <sswords@centtech.com>

(in-package "NREV")

; Basic implementation:
;
;  ACC is NIL == We have the empty list.
;
;  ACC is (CONS HEAD TAIL) otherwise, where:
;
;     HEAD points at the list which has been constructed IN ORDER and hence
;          does not need to be reversed
;
;     TAIL points at its tail, so we can rplacd things in as needed.

(defun nrev$c-copy (nrev$c)
  (let* ((acc  (nrev$c-acc nrev$c))
         (head (car acc)))
    ;; We must make a deep copy of the elements, because otherwise our next
    ;; PUSH would extend a list that someone else has gotten hold of.
    (loop for e in head collect e)))

(defun nrev-replace-common-suffix (orig new)
  ;; Semantics: This may destructively modify NEW, but not ORIG, and it returns
  ;; a list equal to NEW, but perhaps using some suffix of ORIG.

  ;; We'll scan the two lists for the longest common suffix.  First-same will
  ;; be the longest suffix of orig that is the same as a suffix of new, and
  ;; last-diff will be the cons previous to that suffix in new.  We check the
  ;; lists starting from the cars.  At each iteration our variables are set as
  ;; though the rest of the two lists are the same.  So initially, last-diff is
  ;; a dummy cons whose cdr is all of new, and first-same is orig.
  (let* ((head-handle (cons nil new))
         (last-diff head-handle)
         (first-same orig)
         (orig-suffix orig)
         (new-suffix new))
    (declare (dynamic-extent head-handle))
    (loop while (and (consp new-suffix)
                     (consp orig-suffix))
          do
          (unless (eql (car orig-suffix)
                       (car new-suffix))
            (setq last-diff new-suffix)
            (setq first-same (cdr orig-suffix)))
          (setq orig-suffix (cdr orig-suffix))
          (setq new-suffix (cdr new-suffix)))
    (if (eql orig-suffix new-suffix)
        (progn
          ;; Replace the common suffix with the tail from orig.
          (setf (cdr last-diff) first-same)
          (cdr head-handle))
      ;; If the final cdrs differ (or if the lists are different lengths),
      ;; there are no common conses to be used; just return new unchanged.
      new)))

(defun nrev$c-finish (nrev$c)
  (let* ((acc    (nrev$c-acc nrev$c))
         (hint   (nrev$c-hint nrev$c))
         (head   (car acc))
         (nrev$c (update-nrev$c-acc nil nrev$c)))
    (if hint
        (mv (nrev-replace-common-suffix hint head)
            nrev$c)
      ;; No need to deep copy; nobody else has a handle to our conses.
      (mv head nrev$c))))

(defun nrev$c-push (a nrev$c)
  (let* ((acc      (nrev$c-acc nrev$c))
         (new-cons (cons a nil)))
    (if (atom acc)
        (update-nrev$c-acc (cons new-cons new-cons) nrev$c)
      (let* ((tail (cdr acc)))
        (acl2::memoize-flush nrev$c)
        (rplacd tail new-cons)
        (rplacd acc new-cons)
        nrev$c))))