~ubuntu-branches/ubuntu/wily/acl2/wily

« back to all changes in this revision

Viewing changes to books/workshops/2009/sumners/support/kas.lisp

  • Committer: Package Import Robot
  • Author(s): Camm Maguire
  • Date: 2015-01-16 10:35:45 UTC
  • mfrom: (3.3.26 sid)
  • Revision ID: package-import@ubuntu.com-20150116103545-prehe9thgo79o8w8
Tags: 7.0-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#| KAS - Kernel Architecture Simplifier |#
 
2
 
 
3
(in-package "ACL2")
 
4
 
 
5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
6
#| Some logical functions needed to define KAS operation                      |#
 
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
8
 
 
9
(program)
 
10
 
 
11
(defun symbol-appendp (x) (or (symbolp x) (stringp x) (natp x)))
 
12
 
 
13
(defun dec-to-string (d)
 
14
  (case d (0 "0") (1 "1") (2 "2") (3 "3") (4 "4") (5 "5") (6 "6") (7 "7") (8 "8") (t "9")))
 
15
 
 
16
(defun nat-to-string (n)
 
17
  (string-append (if (zp (floor n 10)) "" (nat-to-string (floor n 10))) 
 
18
                 (dec-to-string (mod n 10))))
 
19
 
 
20
(defun symbol-append-string (x) 
 
21
  (cond ((symbolp x) (symbol-name x))
 
22
        ((stringp x) x)
 
23
        (t (nat-to-string x))))
 
24
 
 
25
(defun symbol-binary-append (x y)
 
26
  (declare (xargs :guard (and (symbol-appendp x) (symbol-appendp y))))
 
27
  ;; (intern-in-package-of-symbol (string-append (symbol-name x) (symbol-name y)) x))
 
28
  (intern (string-append (symbol-append-string x) (symbol-append-string y)) "ACL2"))
 
29
 
 
30
(defmacro symbol-append (symb1 symb2 &rest symbs)
 
31
  `(symbol-binary-append ,symb1 ,(if (endp symbs) symb2 `(symbol-append ,symb2 ,@symbs))))
 
32
 
 
33
(defun make-hyps-and-args-list (n)
 
34
  (if (zp n) () (cons (symbol-append 'x n) (make-hyps-and-args-list (1- n)))))
 
35
 
 
36
(defun make-hyps-and-fn (n)
 
37
  `(defun ,(symbol-append 'hyps-and- n) ,(make-hyps-and-args-list n)
 
38
     (and ,(symbol-append 'x n) 
 
39
          ,(cons (symbol-append 'hyps-and- (1- n))
 
40
                 (make-hyps-and-args-list (1- n))))))
 
41
 
 
42
(defun make-hyps-and-fns (n r)
 
43
  (if (zp n) r (make-hyps-and-fns (1- n) (cons (make-hyps-and-fn n) r))))
 
44
 
 
45
(logic)
 
46
 
 
47
(defun siv (x) (declare (ignore x)) t)
 
48
(defthm siv-rewrite (equal (siv x) t))
 
49
(in-theory (disable siv (siv)))
 
50
(defun fak (x) x)
 
51
(defun fail (x) x)
 
52
(defmacro sieve (x) `(siv (quote ,x)))
 
53
(defun hyps-and-0 () ())
 
54
(defmacro make-hyps-and-functions (n)
 
55
  (declare (xargs :guard (natp n)))
 
56
  (cons 'progn (make-hyps-and-fns n ())))
 
57
(make-hyps-and-functions 63) ; greater value can cause CCL compiler warnings
 
58
 
 
59
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
60
#| ACL2 interface macros and functions                                        |#
 
61
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
62
 
 
63
(program)
 
64
 
 
65
(defmacro kern-comp ()
 
66
  ; '(value t)
 
67
  ; '(comp-gcl t)
 
68
  ; '(comp t)
 
69
  ; '(comp-gcl :raw)
 
70
  '(comp :raw)
 
71
  )
 
72
 
 
73
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
74
#| definition of stobj+ macros                                                |#
 
75
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
76
 
 
77
; We define a bunch of macros for defining functions which use stobj+'s.
 
78
; Basically, these macros lift the main program from overnotating several
 
79
; common structures encountered in programming with stobjs.
 
80
 
 
81
(defmacro kern-fixnum-size () 61)
 
82
(defmacro my-fixnum (x) `(the (signed-byte ,(kern-fixnum-size)) ,x))
 
83
 
 
84
(defun gen-stobj+-renaming (flds stb)
 
85
  (if (endp flds) ()
 
86
    (let ((name (caar flds))
 
87
          (type (cadar flds)))
 
88
      (append (if (member-eq type '(:fixnum :object))
 
89
                  (list (list name 
 
90
                              (symbol-append 'get- name))
 
91
                        (list (symbol-append 'update- name)
 
92
                              (symbol-append 'set- name))
 
93
                        (list (symbol-append name 'p)
 
94
                              (symbol-append stb '- name 'p)))
 
95
                (list (list (symbol-append name 'i) 
 
96
                            (symbol-append 'get- name))
 
97
                      (list (symbol-append 'update- name 'i)
 
98
                            (symbol-append 'set- name))
 
99
                      (list (symbol-append name 'p)
 
100
                            (symbol-append stb '- name 'p))
 
101
                      (list (symbol-append 'resize- name)
 
102
                            (symbol-append stb '-resize- name))
 
103
                      (list (symbol-append name '-length)
 
104
                            (symbol-append 'length- name))))
 
105
              (gen-stobj+-renaming (cdr flds) stb)))))
 
106
 
 
107
(defun process-stobj+-fields (flds)
 
108
  (if (endp flds) ()
 
109
    (cons (cons (caar flds)
 
110
                (case (cadar flds)
 
111
                  (:fixnum       `(:type (signed-byte ,(kern-fixnum-size))
 
112
                                   :initially 0))
 
113
                  (:fixnum-array `(:type (array (signed-byte ,(kern-fixnum-size)) (0))
 
114
                                   :initially 0
 
115
                                   :resizable t))
 
116
                  (:object       `(:type T
 
117
                                   :initially nil))
 
118
                  (:object-array `(:type (array T (0))
 
119
                                   :initially nil
 
120
                                   :resizable t))
 
121
                  (otherwise     (er hard 'process-stobj+-fields
 
122
                                     "ill-formed stobj+ definition"))))
 
123
          (process-stobj+-fields (cdr flds)))))
 
124
 
 
125
(defun stobj+-resize-funcs (flds stb)
 
126
  (cond ((endp flds) ())
 
127
        ((member-eq (cadar flds) '(:fixnum :object))
 
128
         (stobj+-resize-funcs (cdr flds) stb))
 
129
        (t
 
130
         (cons `(defun ,(symbol-append 'resize- (caar flds)) 
 
131
                  (size ,stb)
 
132
                  (declare (xargs :stobjs ,stb))
 
133
                  (if (eql size (,(symbol-append 'length- (caar flds)) ,stb))
 
134
                      ,stb
 
135
                    (prog2$ (and (,(symbol-append 'get- stb '-resize-array-display)
 
136
                                  ,stb)
 
137
                                 (cw "~x0:~x1~%"
 
138
                                     (quote ,(symbol-append 'resize- (caar flds)))
 
139
                                     size))
 
140
                      (,(symbol-append stb '-resize- (caar flds)) size ,stb))))
 
141
               (stobj+-resize-funcs (cdr flds) stb)))))
 
142
 
 
143
(defun stobj+-clear-arr-funcs (flds stb)
 
144
  (cond ((endp flds) ())
 
145
        ((member-eq (cadar flds) '(:fixnum :object))
 
146
         (stobj+-clear-arr-funcs (cdr flds) stb))
 
147
        (t
 
148
         (let ((clear-arr-fn (symbol-append `clear-arr- (caar flds)))
 
149
               (set-arr-fn (symbol-append 'set- (caar flds)))
 
150
               (clear-obj (if (eq (cadar flds) :fixnum-array) 0 nil)))
 
151
           (cons `(defun ,clear-arr-fn (N ,stb)
 
152
                    (declare (xargs :stobjs ,stb)
 
153
                             (type (signed-byte ,(kern-fixnum-size)) N))
 
154
                    (if (=^ N 0) ,stb
 
155
                      (let ((N (1-^ N)))
 
156
                        (declare (type (signed-byte ,(kern-fixnum-size)) N))
 
157
                        (let ((,stb (,set-arr-fn N ,clear-obj ,stb)))
 
158
                          (,clear-arr-fn N ,stb)))))
 
159
                 (stobj+-clear-arr-funcs (cdr flds) stb))))))
 
160
 
 
161
(defun stobj+-clear-func (flds stb)
 
162
  (if (endp flds) ()
 
163
    (cons (list stb
 
164
                (case (cadar flds)
 
165
                      (:fixnum (list (symbol-append 'set- (caar flds)) 0 stb))
 
166
                      (:object (list (symbol-append 'set- (caar flds)) nil stb))
 
167
                      (t (list (symbol-append 'clear-arr- (caar flds))
 
168
                               (list (symbol-append 'length- (caar flds)) stb)
 
169
                               stb))))
 
170
          (stobj+-clear-func (cdr flds) stb))))
 
171
 
 
172
(defun built-in-stobj+-fields (stobj-name)
 
173
  (list (list (symbol-append stobj-name '-resize-array-display) :object)))
 
174
 
 
175
(defmacro define-stobj+ (stobj-name &rest fields)
 
176
  (let ((fields (append fields (built-in-stobj+-fields stobj-name))))
 
177
    (cons 'progn
 
178
          (append (list `(defstobj ,stobj-name
 
179
                           ,@(process-stobj+-fields fields)
 
180
                           :inline t
 
181
                           :renaming ,(gen-stobj+-renaming fields stobj-name)))
 
182
                  (stobj+-resize-funcs fields stobj-name)
 
183
                  (stobj+-clear-arr-funcs fields stobj-name)
 
184
                  (list `(defun ,(symbol-append 'clear- stobj-name)
 
185
                           (,stobj-name)
 
186
                           (declare (xargs :stobjs ,stobj-name))
 
187
                           (let* ,(stobj+-clear-func fields stobj-name)
 
188
                             ,stobj-name)))))))
 
189
 
 
190
;; now we define some macros for defining record-arrays. These are records stored consecutively
 
191
;; in possibly different arrays which are declared with special types.
 
192
 
 
193
(defun stobj+-record-fields-fn (stb fields array object type ctr)
 
194
  (if (endp fields) ()
 
195
    (let ((field (first fields)))
 
196
      (list* `(defmacro ,(symbol-append object (intern "." "ACL2") field) 
 
197
                (,object)
 
198
                ,(let ((form `(list ',(symbol-append 'get- array)
 
199
                                    ,(if (eql ctr 0)
 
200
                                         `(list ',(symbol-append array '-arr-ndx) ,object)
 
201
                                       `(list '+^
 
202
                                              (list ',(symbol-append array '-arr-ndx) ,object)
 
203
                                              ,ctr))
 
204
                                    ',stb)))
 
205
                   (if (eq type :fixnum)
 
206
                       `(list 'my-fixnum ,form)
 
207
                     form)))
 
208
             `(defmacro ,(symbol-append object '.set- field) 
 
209
                (,object ,field)
 
210
                (list ',(symbol-append 'set- array)
 
211
                      ,(if (eql ctr 0)
 
212
                           `(list ',(symbol-append array '-arr-ndx) ,object)
 
213
                         `(list '+^
 
214
                                (list ',(symbol-append array '-arr-ndx) ,object)
 
215
                                ,ctr))
 
216
                      ,(if (eq type :fixnum)
 
217
                           `(list 'my-fixnum ,field)
 
218
                         field)
 
219
                      ',stb))
 
220
             (stobj+-record-fields-fn stb (rest fields) array object type (1+ ctr))))))
 
221
 
 
222
(defun stobj+-record-fields (fields stb object)
 
223
  (if (endp fields) ()
 
224
    (let* ((fld (first fields))
 
225
           (array (second fld))
 
226
           (rcd-size (len (third fld))))
 
227
      (cons `(defmacro ,(symbol-append (second fld) '-arr-ndx) 
 
228
               (,object)
 
229
               ,(if (>= rcd-size 2)
 
230
                    `(list '*^ (list 'my-fixnum ,object) ,rcd-size)
 
231
                  `(list 'my-fixnum ,object)))
 
232
            (append (stobj+-record-fields-fn stb (third fld) array object (first fld) 0)
 
233
                    (stobj+-record-fields (rest fields) stb object))))))
 
234
 
 
235
(defun resize-rcd-arr-calls (fields stb)
 
236
  (if (endp fields) ()
 
237
    (let ((array (second (first fields)))
 
238
          (rcd-size (length (third (first fields)))))
 
239
      (cons (list stb (list (symbol-append 'resize- array)
 
240
                            `(*^ (+^ ptr extra 1) ,rcd-size)
 
241
                            stb))
 
242
            (resize-rcd-arr-calls (rest fields) stb)))))
 
243
 
 
244
(defun merge-fields-into-list (fields)
 
245
  (if (endp fields) ()
 
246
    (append (third (first fields))
 
247
            (merge-fields-into-list (rest fields)))))
 
248
 
 
249
(defun merge-fields-into-object-arr (fields)
 
250
  (let ((obj-arr (second (assoc :object fields))))
 
251
    (if obj-arr
 
252
        (list (list :object obj-arr (merge-fields-into-list fields)))
 
253
      fields)))
 
254
 
 
255
(defmacro define-stobj+-record-array (stb object merge-into-obj-arr &rest fields)
 
256
  (let ((fields (if merge-into-obj-arr
 
257
                    (merge-fields-into-object-arr fields)
 
258
                  fields)))
 
259
    (let ((array (second (first fields)))
 
260
          (rcd-size (len (third (first fields)))))
 
261
      (list* 'progn
 
262
             `(defabbrev ,(symbol-append 'num-of- object)
 
263
                ()
 
264
                (let ((size (,(symbol-append 'length- array) ,stb)))
 
265
                  (declare (type (signed-byte ,(kern-fixnum-size)) size))
 
266
                  (floor^ size ,rcd-size)))
 
267
             `(defabbrev ,(symbol-append 'ensure- object) 
 
268
                (ptr extra)
 
269
                (declare (type (signed-byte ,(kern-fixnum-size)) ptr extra))
 
270
                (let ((size (,(symbol-append 'length- array) ,stb)))
 
271
                  (declare (type (signed-byte ,(kern-fixnum-size)) size))
 
272
                  (if (<^ (*^ (1+^ ptr) ,rcd-size) size)
 
273
                      ,stb
 
274
                    (let* ,(resize-rcd-arr-calls fields stb)
 
275
                      ,stb))))
 
276
             `(defabbrev ,(symbol-append 'restrict- object)
 
277
                (ptr)
 
278
                (declare (type (signed-byte ,(kern-fixnum-size)) ptr))
 
279
                (let ((size (,(symbol-append 'length- array) ,stb)))
 
280
                  (if (=^ (*^ (1+^ ptr) ,rcd-size) size)
 
281
                      ,stb
 
282
                    (let ((extra 0))
 
283
                      (let* ,(resize-rcd-arr-calls fields stb)
 
284
                        ,stb)))))
 
285
             (stobj+-record-fields fields stb object)))))
 
286
 
 
287
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
288
#| utility functions and macros                                               |#
 
289
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
290
 
 
291
(defun kern-monitor-comp   () nil)   ; enable/disable monitor code at compile-time
 
292
(defun kern-monitor-run    () nil)   ; enable/disable monitor code at run-time
 
293
(defun kern-assert-comp    () t)     ; enable/disable assert code at compile-time
 
294
(defun kern-merge-arrays   () nil)   ; should be NIL for GCL, T for Franz
 
295
 
 
296
; enables for various inline checks for compiled code
 
297
 
 
298
(defun kern-enable-check-<^s () nil)
 
299
(defun kern-enable-check-fixns () nil)
 
300
(defun kern-enable-temp-recording () t)
 
301
 
 
302
; kern-display is a simple macro which is used to add some display code
 
303
; kern-monitor actually performs a test to see if it should display or not and
 
304
; can be disabled at compile
 
305
 
 
306
(defmacro kern-display (&rest x)
 
307
  (declare (xargs :guard (>= (len x) 1)))
 
308
  `(prog2$ (cw ,@(butlast x 1)) ,(car (last x))))
 
309
 
 
310
(defmacro kern-monitor (&rest x)
 
311
  (declare (xargs :guard (>= (len x) 2)))
 
312
  (if (kern-monitor-comp)
 
313
      `(prog2$ (and (kern-monitor-run)
 
314
                    ,(car x)
 
315
                    (cw ,@(butlast (cdr x) 1)))
 
316
               ,(car (last x)))
 
317
    (car (last x))))
 
318
 
 
319
; kern-assert is used to declare an assertion which is checked before
 
320
; evaluating the body term provided.
 
321
 
 
322
(defmacro kern-force-assert (mbt body)
 
323
  (let ((r (if (atom mbt) (list mbt) mbt)))
 
324
    `(prog2$ (and (not (eq ,mbt t))
 
325
                  (er hard (quote (assert ,@r))
 
326
                      "assert non-T value: ~x0"
 
327
                      ,mbt))
 
328
       ,body)))
 
329
 
 
330
(defmacro kern-assert (mbt body)
 
331
  (if (kern-assert-comp)
 
332
      `(kern-force-assert ,mbt ,body)
 
333
    body))
 
334
 
 
335
; The macro define-stobj+-record-array is defined in stobjp.lisp. This is
 
336
; simply a wrapper macro.
 
337
 
 
338
(defmacro define-kern-record-array (record &rest fields)
 
339
  `(define-stobj+-record-array ls$ ,record
 
340
     ,(kern-merge-arrays)
 
341
     ,@fields))
 
342
 
 
343
(defmacro define-user-record-array (record &rest fields)
 
344
  `(define-stobj+-record-array us$ ,record
 
345
     ,(kern-merge-arrays)
 
346
     ,@fields))
 
347
 
 
348
; We often wish to pass back multiple values such that the first is a fixnum.
 
349
; This declares that the first value in the mv is a fixnum which keeps it from
 
350
; being boxed (mainly of use in GCL).
 
351
 
 
352
(defmacro mv^ (x &rest rest)
 
353
  `(mv (my-fixnum ,x) ,@rest))
 
354
 
 
355
; We now define the letk which is our general purpose let-form which
 
356
; automatically includes the necessary fixnum declarations, introduces mv-lets
 
357
; when appropriate, and handles propogation of errors (when appropriate). We
 
358
; use a variable and function name scheme to allow the letk macro determine the
 
359
; "type" of the variable and function calls. Basically in any letk binding, the
 
360
; first return value is always a fixnum unless it is a stobj (which is either
 
361
; 'state or ends in the character #\$). For functions, if a function ends in a
 
362
; #\! character then it may return an "error" which will need to be propagated.
 
363
; The letk macro is essentially written for the kernel functions in this file
 
364
; and really should not be used in any other context. If a more generic let
 
365
; form could be conceived which achieved the uses here, then please make the
 
366
; suggestion to the ACL2 maintainers.
 
367
 
 
368
(defun is-letk-stobj-var (x)
 
369
  (and (symbolp x)
 
370
       (not (keywordp x))
 
371
       (or (eq x 'state)
 
372
           (let ((s (symbol-name x)))
 
373
             (eql (char s (1- (length s))) #\$)))))
 
374
 
 
375
(defun is-letk-object-var (x)
 
376
  (and (symbolp x)
 
377
       (not (keywordp x))
 
378
       (let ((s (symbol-name x)))
 
379
         (eql (char s (1- (length s))) #\.))))
 
380
 
 
381
(defun is-letk-fixnum-var (x)
 
382
  (and (symbolp x)
 
383
       (not (or (booleanp x)
 
384
                (keywordp x)
 
385
                (is-letk-stobj-var x)
 
386
                (is-letk-object-var x)))))
 
387
 
 
388
(defun drop-list-last (x)
 
389
  (if (endp (rest x)) ()
 
390
    (cons (first x)
 
391
          (drop-list-last (rest x)))))
 
392
 
 
393
(defun legal-var-listp (x)
 
394
  (or (null x)
 
395
      (and (consp x)
 
396
           (or (symbolp (car x))
 
397
               (and (consp (car x))
 
398
                    (null (cdar x))
 
399
                    (symbolp (caar x))))
 
400
           (legal-var-listp (cdr x)))))
 
401
 
 
402
(defun letk-binding-entryp (x)
 
403
  (and (true-listp x)
 
404
       (>= (len x) 2)
 
405
       (legal-var-listp (drop-list-last x))
 
406
       (or (atom (car (last x)))
 
407
           (symbolp (caar (last x))))))
 
408
 
 
409
(defun letk-bindingp (x)
 
410
  (or (null x)
 
411
      (and (consp x)
 
412
           (letk-binding-entryp (first x))
 
413
           (letk-bindingp (rest x)))))
 
414
 
 
415
(defmacro letk (bind rslt)
 
416
  (declare (xargs :guard (letk-bindingp bind)))
 
417
  (if (endp bind) rslt
 
418
    (let ((b (first bind)))
 
419
      (if (= (len b) 2)
 
420
          (let* ((lhs (first b))
 
421
                 (is-fixn (is-letk-fixnum-var lhs))
 
422
                 (rhs (if (and is-fixn (kern-enable-check-fixns))
 
423
                          `(the (signed-byte ,(kern-fixnum-size)) ,(second b))
 
424
                        (second b))))
 
425
            `(let ((,lhs ,rhs))
 
426
               ,@(and is-fixn
 
427
                      `((declare (type (signed-byte ,(kern-fixnum-size)) ,lhs))))
 
428
               (letk (,@(rest bind)) ,rslt)))
 
429
        (let* ((lhs (drop-list-last b))
 
430
               (rhs (car (last b)))
 
431
               (is-fixn (is-letk-fixnum-var (first lhs))))
 
432
          `(mv-let ,lhs ,rhs
 
433
             ,@(and is-fixn
 
434
                    `((declare (type (signed-byte ,(kern-fixnum-size)) ,(first lhs)))))
 
435
             ,(let ((body `(letk (,@(rest bind)) ,rslt)))
 
436
                (if (and is-fixn (kern-enable-check-fixns))
 
437
                    `(let ((,(first lhs) (the (signed-byte ,(kern-fixnum-size)) ,(first lhs))))
 
438
                       (declare (type (signed-byte ,(kern-fixnum-size)) ,(first lhs)))
 
439
                       ,body)
 
440
                  body))))))))
 
441
 
 
442
(defun defunk-fixnum-vars (vars)
 
443
  (cond ((endp vars) ())
 
444
        ((is-letk-fixnum-var (first vars))
 
445
         (cons (first vars)
 
446
               (defunk-fixnum-vars (rest vars))))
 
447
        (t (defunk-fixnum-vars (rest vars)))))
 
448
 
 
449
(defun defunk-type-declare (vars)
 
450
  (let ((vars (defunk-fixnum-vars vars)))
 
451
    (and vars `((declare (type (signed-byte ,(kern-fixnum-size)) ,@vars))))))
 
452
 
 
453
(defun defunk-stobj-vars (vars)
 
454
  (cond ((endp vars) ())
 
455
        ((is-letk-stobj-var (first vars))
 
456
         (cons (first vars)
 
457
               (defunk-stobj-vars (rest vars))))
 
458
        (t (defunk-stobj-vars (rest vars)))))
 
459
 
 
460
(defun defunk-stobj-declare (vars)
 
461
  (let ((vars (defunk-stobj-vars vars)))
 
462
    (and vars `((declare (xargs :stobjs ,vars))))))
 
463
 
 
464
(defconst *defunk-sig-vars*
 
465
  '(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))
 
466
 
 
467
(defun defunk-create-sig (args vars)
 
468
  (cond ((endp args) ())
 
469
        ((is-letk-stobj-var (first args))
 
470
         (cons (first args)
 
471
               (defunk-create-sig (rest args) vars)))
 
472
        ((endp vars)
 
473
         (er hard 'defunk-create-sig
 
474
             "ran out of var.s"))
 
475
        (t
 
476
         (cons (first vars)
 
477
               (defunk-create-sig (rest args) (rest vars))))))
 
478
 
 
479
(mutual-recursion
 
480
(defun defunk-mv-sig (term)
 
481
  (and (consp term)
 
482
       (case (first term)
 
483
             (mv^  (defunk-create-sig (rest term) *defunk-sig-vars*))
 
484
             (if   (or (defunk-mv-sig (third term)) (defunk-mv-sig (fourth term))))
 
485
             (letk (defunk-mv-sig (third term)))
 
486
             (cond (defunk-cond-sig (rest term)))
 
487
             (case (defunk-cond-sig (rest (rest term))))
 
488
             ((kern-assert kern-error prog2$) (defunk-mv-sig (third term))))))
 
489
 
 
490
(defun defunk-cond-sig (conds)
 
491
  (and (consp conds)
 
492
       (or (defunk-mv-sig (second (first conds)))
 
493
           (defunk-cond-sig (rest conds)))))
 
494
)
 
495
 
 
496
(defconst *kern-fixnum-ops*
 
497
  '(+^ -^ *^ floor^ logand^ my-fixnum lognot^
 
498
    logior^ logxor^ mod^ expt^ max^ min^ ash^
 
499
    abs^ er0 1+^ 1-^ mask^ dctx-0 kern-make-opcd))
 
500
 
 
501
(mutual-recursion
 
502
(defun defunk-fixnum-body (term)
 
503
  (cond
 
504
   ((is-letk-fixnum-var term) t)
 
505
   ((atom term) nil)
 
506
   (t (case (first term)
 
507
            (if (or (defunk-fixnum-body (third term))
 
508
                    (defunk-fixnum-body (fourth term))))
 
509
            (letk (defunk-fixnum-body (third term)))
 
510
            (cond (defunk-cond-fixnum (rest term)))
 
511
            (case (defunk-cond-fixnum (rest (rest term))))
 
512
            ((kern-assert kern-error prog2$)
 
513
             (defunk-fixnum-body (fourth term)))
 
514
            (t (member-eq (first term) *kern-fixnum-ops*))))))
 
515
 
 
516
(defun defunk-cond-fixnum (conds)
 
517
  (and (consp conds)
 
518
       (or (defunk-fixnum-body (second (first conds)))
 
519
           (defunk-cond-fixnum (rest conds)))))
 
520
)
 
521
 
 
522
(defun defunk-tag-body (body)
 
523
  (if (defunk-fixnum-body body) `(my-fixnum ,body)
 
524
    (let ((sig (defunk-mv-sig body)))
 
525
      (if sig `(the-mv ,sig (signed-byte ,(kern-fixnum-size)) ,body)
 
526
        body))))
 
527
 
 
528
(defun defunk-make-binds (vars)
 
529
  (if (endp vars) ()
 
530
    (cons (list (first vars) (first vars))
 
531
          (defunk-make-binds (rest vars)))))
 
532
 
 
533
(defconst *defunk-body-primitives*
 
534
  '(+   *   1+   =  1-   -   /=  <=  <  >  >=
 
535
    +^  *^  1+^  =^ 1-^  -^  /=^ <=^ <^ >^ >=^
 
536
    mod mod^ floor floor^ expt expt^
 
537
    min min^ max max^
 
538
    logand logand^ logior logior^
 
539
    lognot lognot^ logxor logxor^
 
540
    ash ash^
 
541
    mask^ mv mv^ my-fixnum
 
542
    er er0 prog2$ cw ev-fncall-w
 
543
    fn-count-evg lexorder
 
544
    if not implies and or iff
 
545
    acl2-numberp rationalp integerp consp 
 
546
    characterp symbolp stringp
 
547
    booleanp termp keywordp
 
548
    true-listp symbol-listp
 
549
    cons null atom endp list list* push-lemma
 
550
    car cdr caar cdar cadr cddr cadar
 
551
    first second third fourth fifth
 
552
    sixth seventh eighth ninth tenth
 
553
    rest last butlast nth nthcdr update-nth
 
554
    append length reverse revappend string-append
 
555
    acons assoc assoc-eq assoc-equal
 
556
    strip-cars strip-cdrs
 
557
    numerator denominator realpart imagpart
 
558
    char-code char code-char
 
559
    symbol-name symbol-package-name
 
560
    intern intern-in-package-of-symbol
 
561
    symbol-append bozo
 
562
    equal eql eq
 
563
    member-eq member member-equal
 
564
    ))
 
565
 
 
566
(defconst *defunk-body-prefixes*
 
567
  '(get- set- length- resize- ensure- num-of- restrict-
 
568
    candidate. undo. qobj. rule. oper. node. opcd. memo. loop.))
 
569
 
 
570
(defun str-has-prefix (x y i)
 
571
  (or (>= i (length y))
 
572
      (and (< i (length x))
 
573
           (eql (char x i) (char y i))
 
574
           (str-has-prefix x y (1+ i)))))
 
575
 
 
576
(defun symb-has-prefix (x y)
 
577
  (str-has-prefix (symbol-name x)
 
578
                  (symbol-name y)
 
579
                  0))
 
580
 
 
581
(defun symb-prefixes (x lst)
 
582
  (and (not (endp lst))
 
583
       (or (symb-has-prefix x (first lst))
 
584
           (symb-prefixes x (rest lst)))))
 
585
 
 
586
(defun is-kern-primitive (op)
 
587
  (or (member-eq op *defunk-body-primitives*)
 
588
      (symb-prefixes op *defunk-body-prefixes*)))
 
589
 
 
590
(defun map-kern-op (op)
 
591
  (if (is-kern-primitive op) op (symbol-append 'kern- op)))
 
592
 
 
593
(mutual-recursion
 
594
(defun add-kern-to-calls (term)
 
595
  (cond ((atom term) term)
 
596
        ((eq (first term) 'quote) term)
 
597
        ((eq (first term) 'cond)
 
598
         (cons 'cond 
 
599
               (add-kern-to-conds (rest term))))
 
600
        ((eq (first term) 'case)
 
601
         (list* 'case 
 
602
                (add-kern-to-calls (second term))
 
603
                (add-kern-to-binds (rest (rest term)))))
 
604
        ((eq (first term) 'letk)
 
605
         (list 'letk
 
606
               (add-kern-to-binds (second term))
 
607
               (add-kern-to-calls (third term))))
 
608
        (t
 
609
         (cons (map-kern-op (first term))
 
610
               (add-kern-to-args (rest term))))))
 
611
 
 
612
(defun add-kern-to-args (args)
 
613
  (if (endp args) ()
 
614
    (cons (add-kern-to-calls (first args))
 
615
          (add-kern-to-args (rest args)))))
 
616
 
 
617
(defun add-kern-to-binds (binds)
 
618
  (if (endp binds) ()
 
619
    (cons (append (butlast (first binds) 1)
 
620
                  (add-kern-to-args (last (first binds))))
 
621
          (add-kern-to-binds (rest binds)))))
 
622
 
 
623
(defun add-kern-to-conds (conds)
 
624
  (if (endp conds) ()
 
625
    (cons (add-kern-to-args (first conds))
 
626
          (add-kern-to-conds (rest conds)))))
 
627
)
 
628
 
 
629
(defun mk-defunk (name vars inlined decls body)
 
630
  (kern-assert (and (symbolp name)
 
631
                    (symbol-listp vars))
 
632
   (let* ((name (map-kern-op name))
 
633
          (body (add-kern-to-calls body))
 
634
          (body (if (kern-enable-check-fixns)
 
635
                    `(letk ,(defunk-make-binds (defunk-fixnum-vars vars))
 
636
                       ,body)
 
637
                  body)))
 
638
     (if inlined
 
639
         `(defabbrev ,name ,vars ,@decls
 
640
            ,@(defunk-type-declare vars)
 
641
            ,(defunk-tag-body body))
 
642
       `(defun ,name ,vars ,@decls
 
643
          ,@(defunk-type-declare vars)
 
644
          ,@(defunk-stobj-declare vars)
 
645
          ,(defunk-tag-body body))))))
 
646
 
 
647
(defun parse-defunk-args (args)
 
648
  (let* ((inlined (and (consp args) 
 
649
                       (eq (first args) :inline)))
 
650
         (args (if inlined (rest args) args)))
 
651
    (mv inlined (butlast args 1) (car (last args)))))
 
652
 
 
653
(defmacro defunk (name vars &rest args)
 
654
  (if (endp args)
 
655
      (let ((body (add-kern-to-calls vars)))
 
656
        (list 'defmacro (symbol-append 'kern- name) ()
 
657
              (list 'let (list (list 'x body)) (list 'list ''quote 'x))))
 
658
    (mv-let (inlined decls body) (parse-defunk-args args)
 
659
      (mk-defunk name vars inlined decls body))))
 
660
 
 
661
(defun split-defunks (fns)
 
662
  (if (endp fns) (mv () ())
 
663
    (let ((fn (first fns)))
 
664
      (kern-assert (and (true-listp fn)
 
665
                        (> (length fn) 3)
 
666
                        (eq (first fn) 'defunk))
 
667
       (mv-let (inlined decls body)
 
668
           (parse-defunk-args (rest (rest (rest fn))))
 
669
         (let ((fn (mk-defunk (second fn) (third fn)
 
670
                              inlined decls body)))
 
671
           (mv-let (abbrevs funcs)
 
672
               (split-defunks (rest fns))
 
673
             (if (and (consp fn) (eq (first fn) 'defabbrev))
 
674
                 (mv (cons fn abbrevs) funcs)
 
675
               (mv abbrevs (cons fn funcs))))))))))
 
676
 
 
677
(defmacro mutual-recursionk (&rest fns)
 
678
  (mv-let (abbrevs funcs) (split-defunks fns)
 
679
    (cons 'progn (append abbrevs (list (cons 'mutual-recursion funcs))))))
 
680
 
 
681
;; a node which has been "promoted" or is persistent will have a pointer value
 
682
;; greater than 0.
 
683
 
 
684
;; we exclude 0 = (node-btm) as a special node
 
685
(defunk promoted (x) :inline (>^ x 0))
 
686
(defunk temp-node (x) :inline (<^ x 0))
 
687
 
 
688
(defunk node< (x y) :inline  
 
689
  (assert (and (promoted x)
 
690
               (promoted y))
 
691
   (<^ x y)))
 
692
 
 
693
(defmacro kern-check-<^ (x y ctx)
 
694
  (if (kern-enable-check-<^s)
 
695
      `(my-fixnum 
 
696
        (if (<^ ,x ,y) ,x
 
697
          (er0 hard ,ctx "expected decreasing ~x0 < ~x1" ,x ,y)))
 
698
    x))
 
699
 
 
700
; We now defined several macros which are "fixnum" verions of existing
 
701
; functions and primitives.
 
702
 
 
703
(defmacro -^ (x &rest y)
 
704
  (if (consp y)          `(my-fixnum (-      (my-fixnum ,x) (my-fixnum ,(first y))))
 
705
                         `(my-fixnum (-      (my-fixnum ,x)))))
 
706
(defmacro +^ (x &rest y)
 
707
  (if (endp y)           `(my-fixnum ,x)
 
708
                         `(my-fixnum (+      (my-fixnum ,x) (+^ ,(first y) ,@(rest y))))))
 
709
(defmacro *^ (x &rest y)
 
710
  (if (endp y)           `(my-fixnum ,x)
 
711
                         `(my-fixnum (*      (my-fixnum ,x) (*^ ,(first y) ,@(rest y))))))
 
712
(defmacro 1+^ (x)        `(my-fixnum (1+     (my-fixnum ,x))))
 
713
(defmacro 1-^ (x)        `(my-fixnum (1-     (my-fixnum ,x))))
 
714
(defmacro ash^ (x y)     `(my-fixnum (ash    (my-fixnum ,x) (my-fixnum ,y))))
 
715
(defmacro =^ (x y)                  `(eql    (my-fixnum ,x) (my-fixnum ,y)))
 
716
(defmacro <^ (x y)                  `(<      (my-fixnum ,x) (my-fixnum ,y)))
 
717
(defmacro mod^ (x y)     `(my-fixnum (mod    (my-fixnum ,x) (my-fixnum ,y))))
 
718
(defmacro floor^ (x y)   `(my-fixnum (floor  (my-fixnum ,x) (my-fixnum ,y))))
 
719
(defmacro expt^ (x y)    `(my-fixnum (expt   (my-fixnum ,x) (my-fixnum ,y))))
 
720
(defmacro lognot^ (x)    `(my-fixnum (lognot (my-fixnum ,x))))
 
721
(defmacro logand^ (x &rest y) 
 
722
  `(my-fixnum ,(if (endp y) x `(logand (my-fixnum ,x) (logand^ ,(first y) ,@(rest y))))))
 
723
(defmacro logior^ (x &rest y)
 
724
  `(my-fixnum ,(if (endp y) x `(logior (my-fixnum ,x) (logior^ ,(first y) ,@(rest y))))))
 
725
(defmacro logxor^ (x &rest y)
 
726
  `(my-fixnum ,(if (endp y) x `(logxor (my-fixnum ,x) (logxor^ ,(first y) ,@(rest y))))))
 
727
 
 
728
(defmacro mask^ (x y)    `(my-fixnum (logand ,x ,y)))
 
729
 
 
730
(defmacro /=^ (x y)      `(not (=^ ,x ,y)))
 
731
(defmacro <=^ (x y)      `(<= (my-fixnum ,x) (my-fixnum ,y)))
 
732
(defmacro >^ (x y)       `(<^ ,y ,x))
 
733
(defmacro >=^ (x y)      `(<=^ ,y ,x))
 
734
 
 
735
(defmacro max^ (x &rest r)
 
736
  (if (endp r) x
 
737
    `(letk ((x ,x)
 
738
            (m (max^ ,@r)))
 
739
       (if (>^ x m) x m))))
 
740
 
 
741
(defmacro min^ (x &rest r)
 
742
  (if (endp r) x
 
743
    `(letk ((x ,x)
 
744
            (m (min^ ,@r)))
 
745
       (if (<^ x m) x m))))
 
746
 
 
747
(defmacro er0 (&rest args) `(prog2$ (er ,@args) 0))
 
748
 
 
749
; The following macro is simply a wrapper for getprop. The
 
750
; variable wrld is captured from the current context and is
 
751
; expected to be the current ACL2 world.
 
752
 
 
753
(defmacro kern-getprop (name prop)
 
754
  `(getprop ,name ,prop nil 'current-acl2-world wrld))
 
755
 
 
756
; (defunk zp (x)             :inline (or (not (integerp x)) (<=^ x 0)))
 
757
(defunk zp (x)             :inline (<=^ x 0))
 
758
(defunk absf (x)           :inline (if (<^ x 0) (-^ x) x))
 
759
(defunk is-boolean (x.)    :inline (or (eq x. t) (eq x. nil)))
 
760
(defunk is-natrual (x.)    :inline (and (integerp x.) (>= x. 0)))
 
761
(defunk is-trace-mark (x.) :inline (or (is-boolean x.) (eq x. :all)))
 
762
 
 
763
(defunk spcs (n) (if (zp n) "" (string-append " " (spcs (1- n)))))
 
764
 
 
765
(defunk max-fixnum   (1- (expt 2 60)))
 
766
(defunk min-fixnum   (- (expt 2 60)))
 
767
(defunk maximum-array-size (max-fixnum))
 
768
 
 
769
(defunk fixnump (x) :inline
 
770
  (and (integerp x)
 
771
       (>= x (min-fixnum))
 
772
       (<= x (max-fixnum))))
 
773
 
 
774
(kern-comp)  ;; compile to get macros compiled
 
775
 
 
776
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
777
#| ls$ stobj, structures, and access functions                                |#
 
778
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
779
 
 
780
; We now define the stobj used in the kernel functions.  The stobj is called
 
781
; ls$ which stands for "logic state stobj".
 
782
 
 
783
(define-stobj+ ls$
 
784
  (node-stor        :fixnum-array)
 
785
  (node-hash        :fixnum-array)
 
786
  (alloc-nodes      :fixnum)
 
787
  (num-of-nodes     :fixnum)
 
788
  (quote-stor       :object-array)
 
789
  (quote-hash       :fixnum-array)
 
790
  (next-quote       :fixnum)
 
791
  (node-step        :fixnum)
 
792
  (node-limit       :fixnum)
 
793
  (hash-mask        :fixnum)
 
794
  (trans-stor       :fixnum-array)
 
795
  (trans-hash       :fixnum-array)
 
796
  (alloc-trans      :fixnum)
 
797
  (num-trans-nodes  :fixnum)
 
798
  (memo-stor        :fixnum-array)
 
799
  (loop-stack       :fixnum-array)
 
800
  (loop-stk-top     :fixnum)
 
801
  (op-obj-stor      :object-array)
 
802
  (op-fix-stor      :fixnum-array)
 
803
  (next-op-ndx      :fixnum)
 
804
  (op-hash          :fixnum-array)
 
805
  (undo-stk         :fixnum-array)
 
806
  (undo-chains      :fixnum-array)
 
807
  (undo-top         :fixnum)
 
808
  (undo-free-list   :fixnum)
 
809
  (rule-fix-stor    :fixnum-array)
 
810
  (rule-obj-stor    :object-array)
 
811
  (next-rule-ndx    :fixnum)
 
812
  (curr-ctx-stk     :fixnum-array)
 
813
  (curr-ctx-top     :fixnum)
 
814
  (current-world    :object)
 
815
  (current-ens      :object)
 
816
  (var-chg-stk      :fixnum)
 
817
  (current-age      :fixnum)
 
818
  (bchain-limit     :fixnum)
 
819
  (next-extend-age  :fixnum)
 
820
  (current-dctx     :fixnum)
 
821
  (warned-ctx-depth :object)
 
822
  (current-clock    :fixnum)
 
823
  (output-verbose   :object)
 
824
  (kern-size-param  :object)
 
825
  (flip-t-fns       :object)
 
826
  (flip-nil-fns     :object)
 
827
  (allow-context-reduction :object)
 
828
  (initial-rule-trace-descriptor :object)
 
829
  (initial-node-prune-depth :object)
 
830
  (rew-call-depth   :fixnum)  ;; only used for debugging
 
831
)
 
832
 
 
833
(define-kern-record-array memo
 
834
  (:fixnum memo-stor (opcd rslt dcv arg0 arg1 arg2)))
 
835
 
 
836
(define-kern-record-array undo
 
837
  (:fixnum undo-stk (node rep dcv chain)))
 
838
 
 
839
(define-kern-record-array qobj
 
840
  (:object quote-stor (obj uniq-chain)))
 
841
 
 
842
(define-kern-record-array oper
 
843
  (:object op-obj-stor (name is-var is-if is-equal non-nil rules boolp assume-tbr assume-fbr))
 
844
  (:fixnum op-fix-stor (next-stk bound narg uniq-chain num-nodes num-trans exec)))
 
845
 
 
846
(define-kern-record-array rule
 
847
  (:object rule-obj-stor (rune sieves enabled traced))
 
848
  (:fixnum rule-fix-stor (ctr tryctr lhs rhs op hyps)))
 
849
 
 
850
(define-kern-record-array loop
 
851
  (:fixnum loop-stack (rule node)))
 
852
 
 
853
; We may use more than one memo slot if the num. args for the fn is greater
 
854
; than 3. In order to facilitate this definition, we include the following
 
855
; definition of arg access/update functions
 
856
 
 
857
(defunk opcd-memo-mrkr -1)
 
858
(defunk max-memo-narg   9)
 
859
(defunk num-1memo-args  3)
 
860
 
 
861
(defunk memo.arg (x i) :inline
 
862
  (assert (<^ i (max-memo-narg))
 
863
   (case i
 
864
     (0 (memo.arg0 x))
 
865
     (1 (memo.arg1 x))
 
866
     (2 (memo.arg2 x))
 
867
     (3 (memo.rslt (1+^ x)))
 
868
     (4 (memo.dcv  (1+^ x)))
 
869
     (5 (memo.arg0 (1+^ x)))
 
870
     (6 (memo.arg1 (1+^ x)))
 
871
     (t (memo.arg2 (1+^ x))))))
 
872
 
 
873
(defunk memo.set-arg (x i v) :inline
 
874
  (assert (<^ i (max-memo-narg))
 
875
   (case i
 
876
     (0 (memo.set-arg0 x v))
 
877
     (1 (memo.set-arg1 x v))
 
878
     (2 (memo.set-arg2 x v))
 
879
     (3 (memo.set-rslt (1+^ x) v))
 
880
     (4 (memo.set-dcv  (1+^ x) v))
 
881
     (5 (memo.set-arg0 (1+^ x) v))
 
882
     (6 (memo.set-arg1 (1+^ x) v))
 
883
     (t (memo.set-arg2 (1+^ x) v)))))
 
884
 
 
885
; We include a "wrapper" for oper.uniq which checks if the uniq-ptr retrieved
 
886
; is strictly less than o. This should be an invariant of the construction of
 
887
; nodes, but we add this "wrapper" to help in admitting various functions which
 
888
; traverse nodes. BOZO -- need to check if this affects performance appreciably
 
889
; and note here whether or not it does.
 
890
 
 
891
(defunk oper.uniq (o) :inline
 
892
  (letk ((uniq (oper.uniq-chain o)))
 
893
    (check-<^ uniq o 'oper.uniq)))
 
894
 
 
895
(defunk oper.set-uniq (o uniq) :inline
 
896
  (oper.set-uniq-chain o uniq))
 
897
 
 
898
; We include a "wrapper" for qobj.uniq which checks if the uniq-ptr retrieved
 
899
; is strictly less than q. This should be an invariant of the construction of
 
900
; nodes, but we add this "wrapper" to help in admitting various functions which
 
901
; traverse nodes. BOZO -- need to check if this affects performance appreciably
 
902
; and note here whether or not it does.
 
903
 
 
904
(defunk qobj.uniq (q) :inline
 
905
  (letk ((uniq (qobj.uniq-chain q)))
 
906
    (check-<^ uniq q 'qobj.uniq)))
 
907
 
 
908
(defunk qobj.set-uniq (q uniq) :inline
 
909
  (qobj.set-uniq-chain q uniq))
 
910
 
 
911
 
 
912
;; A node consists of the following fields (each encoded in a fixnum) at an
 
913
;; offset from a base address for the node:
 
914
;;
 
915
;;  offset  0:  <vcnt[14],fcnt[14]>,<in-ctx>,<user-mark>,<op[18],equal[1],if[1],var[1],narg[9]>  <-- count[28],user-mark[1],in-ctx[1],opcd[30]
 
916
;;  offset -1:  rep[60]/age[60]
 
917
;;  offset -2:  dcv[60]
 
918
;;  offset -3:  uniq[60]
 
919
;;  offset -4:  arg1[60]
 
920
;;  offset -5:  ...
 
921
 
 
922
(defunk avg-num-args     3)
 
923
(defunk base-node-alloc  4)
 
924
(defunk base-trans-alloc 1)
 
925
 
 
926
(defunk var-mask     (ash 1 10))
 
927
(defunk non-var-mask (lognot (var-mask)))
 
928
(defunk if-mask      (ash (var-mask) 1))
 
929
(defunk equal-mask   (ash (if-mask) 1))
 
930
(defunk opndx-shft   (ash (equal-mask) 1))
 
931
(defunk narg-mask    (1- (var-mask)))
 
932
(defunk opcd-mask    (1- (ash 1 30)))
 
933
(defunk in-ctx-mask  (ash 1 31))
 
934
(defunk in-ctx-flip  (lognot (in-ctx-mask)))
 
935
(defunk user-mark-mask  (ash 1 32))
 
936
(defunk user-mark-flip  (lognot (user-mark-mask)))
 
937
 
 
938
(defunk size-shft     (ash 1 32))
 
939
(defunk non-size-mask (1- (size-shft)))
 
940
(defunk size-mask     (lognot (non-size-mask)))
 
941
(defunk vcnt-shft     (ash 1 14))
 
942
(defunk fcnt-mask     (1- (vcnt-shft)))
 
943
 
 
944
(defunk max-num-args  (narg-mask))
 
945
(defunk max-num-fns   (- (ash 1 18) 2))
 
946
(defunk max-size-valu (1- (ash 1 28)))
 
947
(defunk size-btm      (max-size-valu))
 
948
(defunk max-fcnt-valu (fcnt-mask))
 
949
(defunk max-vcnt-valu (1- (ash 1 14)))
 
950
 
 
951
 
 
952
(defunk opcd.is-var (o)   :inline (=^ (logand^ o (var-mask))   (var-mask)))
 
953
(defunk opcd.is-if (o)    :inline (=^ (logand^ o (if-mask))    (if-mask)))
 
954
(defunk opcd.is-equal (o) :inline (=^ (logand^ o (equal-mask)) (equal-mask)))
 
955
(defunk opcd.narg (o)     :inline (logand^ o (narg-mask)))
 
956
(defunk opcd.index (o)    :inline (floor^ o (opndx-shft)))
 
957
 
 
958
(defunk make-opcd (narg var. is-if. is-eq. ndx) :inline
 
959
  (logior^ (*^ ndx (opndx-shft))
 
960
           (if is-eq. (equal-mask) 0)
 
961
           (if is-if. (if-mask) 0)
 
962
           (if var. (var-mask) 0)
 
963
           narg))
 
964
 
 
965
(defunk get-size-fcnt  (size)      :inline (logand^ size (fcnt-mask)))
 
966
(defunk get-size-vcnt  (size)      :inline (floor^ size (vcnt-shft)))
 
967
(defunk make-node-size (vcnt fcnt) :inline (logior^ (*^ vcnt (vcnt-shft)) fcnt))
 
968
 
 
969
(defunk node.set-opcd (n szop) :inline  (if (promoted n) (set-node-stor n szop ls$) (set-trans-stor (-^ n) szop ls$)))
 
970
(defunk node.opcd (n) :inline (logand^ (if (promoted n) (my-fixnum (get-node-stor n ls$)) (my-fixnum (get-trans-stor (-^ n) ls$))) (opcd-mask)))
 
971
(defunk node.size (n) :inline (floor^  (if (promoted n) (my-fixnum (get-node-stor n ls$)) (my-fixnum (get-trans-stor (-^ n) ls$))) (size-shft)))
 
972
 
 
973
(defunk node.in-ctx (n) :inline 
 
974
  (assert (promoted n) (=^ (logand^ (get-node-stor n ls$) (in-ctx-mask)) (in-ctx-mask))))
 
975
(defunk node.set-in-ctx (n in-ctx.) :inline 
 
976
  (assert (promoted n) (set-node-stor n (if in-ctx. (logior^ (get-node-stor n ls$) (in-ctx-mask)) 
 
977
                                          (logand^ (get-node-stor n ls$) (in-ctx-flip))) ls$)))
 
978
 
 
979
(defunk node.user-mark (n) :inline 
 
980
  (=^ (logand^ (get-node-stor n ls$) (user-mark-mask)) (user-mark-mask)))
 
981
(defunk node.set-user-mark (n user-mark.) :inline
 
982
  (set-node-stor n (if user-mark. (logior^ (get-node-stor n ls$) (user-mark-mask)) 
 
983
                     (logand^ (get-node-stor n ls$) (user-mark-flip))) ls$))
 
984
 
 
985
(defunk node.rep (n)         :inline (if (promoted n) (my-fixnum (get-node-stor (1-^ n) ls$)) (node-btm)))
 
986
(defunk node.set-rep (n rep) :inline (assert (promoted n) (set-node-stor (1-^ n) rep ls$)))
 
987
 
 
988
(defunk node.dcv (n)         :inline (assert (promoted n) (get-node-stor (-^ n 2) ls$)))
 
989
(defunk node.set-dcv (n dcv) :inline (assert (promoted n) (set-node-stor (-^ n 2) dcv ls$)))
 
990
 
 
991
; We include a "wrapper" for node.uniq which checks if the uniq-ptr retrieved
 
992
; is strictly less than the node id n passed in. This should be an invariant of
 
993
; the construction of nodes, but we add this "wrapper" to help in admitting
 
994
; various functions which traverse nodes. BOZO -- need to check if this affects
 
995
; performance appreciably and note here whether or not it does.
 
996
 
 
997
(defunk node.uniq (n)          :inline (assert (promoted n) (letk ((uniq (get-node-stor (-^ n 3) ls$))) (check-<^ uniq n 'node.uniq))))
 
998
(defunk node.set-uniq (n uniq) :inline (assert (promoted n) (set-node-stor (-^ n 3) uniq ls$)))
 
999
 
 
1000
 
 
1001
; Some special node ids. (node-btm) is a special node which denotes "no
 
1002
; value". NOTE -- it is important that 0 is not a legal node value (for
 
1003
; multiple reasons). So, actual node ids should always begin with node id 1.
 
1004
 
 
1005
(defunk node-btm 0)
 
1006
(defunk args-btm 0)
 
1007
(defunk opcd-btm 0)
 
1008
(defunk qobj-btm 0)
 
1009
(defunk loop-btm 0)
 
1010
 
 
1011
(defunk dctx-0    0)
 
1012
(defunk dctx-btm  -1)
 
1013
(defunk dcv-empty 0)
 
1014
(defunk dcv-btm   -1)
 
1015
 
 
1016
; NOTE -- While the preceding constants may look "symbolic", it is important
 
1017
; that these constants keep the value for which they are declared. 
 
1018
 
 
1019
(defunk opcd-quote (make-opcd 1 nil nil nil 1))
 
1020
(defunk opcd-if    (make-opcd 3 nil t   nil 2))
 
1021
(defunk opcd-equal (make-opcd 2 nil nil t   3))
 
1022
(defunk opcd-cons  (make-opcd 2 nil nil nil 4))
 
1023
(defunk opcd-hide  (make-opcd 1 nil nil nil 5))
 
1024
(defunk opcd-fail  (make-opcd 1 nil nil nil 6))
 
1025
 
 
1026
(defunk node-nil (1+ (base-node-alloc)))
 
1027
(defunk node-t   (+ (node-nil) (base-node-alloc) 1))
 
1028
 
 
1029
; We include a "wrapper" for node.arg which checks if the arg retrieved is
 
1030
; strictly less than the node id n passed in. This should be an invariant of
 
1031
; the construction of nodes, but we add this "wrapper" to help in admitting
 
1032
; various functions which traverse nodes. BOZO -- need to check if this affects
 
1033
; performance appreciably and note here whether or not it does.
 
1034
 
 
1035
(defunk node.arg (n i) :inline
 
1036
  (letk ((promoted. (promoted n))
 
1037
         (alloc (if promoted. (base-node-alloc) (base-trans-alloc)))
 
1038
         (n+ (if promoted. n (-^ n)))
 
1039
         (ptr (-^ n+ (+^ alloc i)))
 
1040
         (arg (if promoted.
 
1041
                  (get-node-stor ptr ls$)
 
1042
                (get-trans-stor ptr ls$))))
 
1043
    (assert (or (temp-node n)
 
1044
                (=^ (node.opcd n) (opcd-quote))
 
1045
                (node< arg n)
 
1046
                (list n i arg 
 
1047
                      (oper.name (opcd.index (node.opcd n)))
 
1048
                      (opcd.narg (node.opcd n))
 
1049
                      (opcd.is-var (node.opcd n))))
 
1050
     arg)))
 
1051
 
 
1052
(defunk node.set-arg (n i arg) :inline
 
1053
  (letk ((promoted. (promoted n))
 
1054
         (alloc (if promoted. (base-node-alloc) (base-trans-alloc)))
 
1055
         (n+ (if promoted. n (-^ n)))
 
1056
         (ptr (-^ n+ (+^ alloc i))))
 
1057
    (assert (or (temp-node n)
 
1058
                (=^ (node.opcd n) (opcd-quote))
 
1059
                (node< arg n)
 
1060
                (list n i arg 
 
1061
                      (oper.name (opcd.index (node.opcd n)))
 
1062
                      (opcd.narg (node.opcd n))
 
1063
                      (node-to-term arg)))
 
1064
     (if promoted.
 
1065
         (set-node-stor ptr arg ls$)
 
1066
       (set-trans-stor ptr arg ls$)))))
 
1067
 
 
1068
;; The function node-to-term is used to generate final results and to provide
 
1069
;; feedback in debugging. We generate an "illegal term" for (node-btm), but we
 
1070
;; want these to show up in the case this function is being used for
 
1071
;; debugging. We filter these "illegal terms" out when doing final result
 
1072
;; printing. This function may also be too "expensive" since it does not
 
1073
;; memoize the term structure created, but in this case, the user is in trouble
 
1074
;; already since the term which results will either be viewed by the user or
 
1075
;; used subsequently by ACL2 and as such, the ability to memoize common
 
1076
;; subterms would be irrelevant (although we could return a lambda expression
 
1077
;; and perhaps this is the more appropriate path to take).
 
1078
 
 
1079
(mutual-recursionk
 
1080
(defunk node-to-term1 (node ls$)
 
1081
  (if (=^ node (node-btm)) :btm
 
1082
    (letk ((opcd (node.opcd node))
 
1083
           (op   (opcd.index opcd)))
 
1084
      (cond ((opcd.is-var opcd)
 
1085
             (oper.name op))
 
1086
            ((=^ opcd (opcd-quote))
 
1087
             (list 'quote (qobj.obj (node.arg node 0))))
 
1088
            (t
 
1089
             (cons (oper.name op) 
 
1090
                   (args-to-terms (opcd.narg opcd) 0 node ls$)))))))
 
1091
 
 
1092
(defunk args-to-terms (n i node ls$)
 
1093
  (if (zp n) ()
 
1094
    (cons (node-to-term1 (node.arg node i) ls$)
 
1095
          (args-to-terms (1-^ n) (1+^ i) node ls$))))
 
1096
)
 
1097
 
 
1098
(defunk node-to-term (node) :inline (node-to-term1 node ls$))
 
1099
 
 
1100
(defunk funcall (op. args.) :inline
 
1101
  (ev-fncall-w op. args. (get-current-world ls$)
 
1102
               nil    ; user-stobj-alist (guess from Matt K. after v4-3)
 
1103
               nil    ; safe-mode
 
1104
               t      ; gc-off
 
1105
               nil    ; hard-error-returns-nilp
 
1106
               nil))  ; aok
 
1107
 
 
1108
(defmacro kern-error (err-string node rslt)
 
1109
  `(prog2$ (kern-print-stats ls$) 
 
1110
           (prog2$ (cw "       Final Term on Error: ~| ~p0 ~|~|" (kern-prune-node-term ,node))
 
1111
                   (prog2$ (er hard 'kernel-simplify ,err-string)
 
1112
                           ,rslt))))
 
1113
 
 
1114
(kern-comp) ;; compile to get macros compiled
 
1115
 
 
1116
 
 
1117
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1118
#| functions defining a stats printing function                               |#
 
1119
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1120
 
 
1121
(defunk merge-histograms (x. y.)
 
1122
  (cond ((endp x.) y.)
 
1123
        ((endp y.) x.)
 
1124
        ((< (cadar x.) (cadar y.))
 
1125
         (cons (car x.)
 
1126
               (merge-histograms (cdr x.) y.)))
 
1127
        (t (cons (car y.)
 
1128
                 (merge-histograms x. (cdr y.))))))
 
1129
 
 
1130
(defunk split-histogram (x. y. n)
 
1131
  (if (or (endp x.) (zp n)) (mv x. y.)
 
1132
    (split-histogram (cdr x.) (cons (car x.) y.) (1-^ n))))
 
1133
 
 
1134
(defunk sort-histogram (x.)
 
1135
  (if (endp (cdr x.)) x.
 
1136
    (letk ((y. z. (split-histogram x. () (floor^ (length x.) 2))))
 
1137
      (merge-histograms (sort-histogram y.)
 
1138
                        (sort-histogram z.)))))
 
1139
 
 
1140
(defunk get-rule-histogram (n r. ls$)
 
1141
  (if (zp n) r.
 
1142
    (letk ((n (1-^ n))
 
1143
           (r. (if (>^ (rule.ctr n) 0)
 
1144
                   (cons (list (rule.rune n)
 
1145
                               (rule.ctr n))
 
1146
                         r.)
 
1147
                 r.)))
 
1148
      (get-rule-histogram n r. ls$))))
 
1149
 
 
1150
(defunk compute-rule-histogram () :inline
 
1151
  (sort-histogram (get-rule-histogram (num-of-rule) () ls$)))
 
1152
 
 
1153
(defunk get-rule-try-histogram (n r. ls$)
 
1154
  (if (zp n) r.
 
1155
    (letk ((n (1-^ n))
 
1156
           (r. (if (>^ (rule.tryctr n) 0)
 
1157
                   (cons (list (rule.rune n)
 
1158
                               (rule.tryctr n))
 
1159
                         r.)
 
1160
                 r.)))
 
1161
      (get-rule-try-histogram n r. ls$))))
 
1162
 
 
1163
(defunk compute-rule-try-histogram () :inline
 
1164
  (sort-histogram (get-rule-try-histogram (num-of-rule) () ls$)))
 
1165
 
 
1166
(defunk get-node-histogram (n r. ls$)
 
1167
  (if (zp n) r.
 
1168
    (letk ((n (1-^ n))
 
1169
           (r. (if (>^ (oper.num-nodes n) 0)
 
1170
                   (cons (list (if (eq (oper.name n) 'quote)
 
1171
                                   :quote
 
1172
                                 (oper.name n))
 
1173
                               (oper.num-nodes n))
 
1174
                         r.)
 
1175
                 r.)))
 
1176
      (get-node-histogram n r. ls$))))
 
1177
 
 
1178
(defunk compute-node-histogram () :inline
 
1179
  (sort-histogram (get-node-histogram (num-of-oper) () ls$)))
 
1180
 
 
1181
(defunk get-trans-histogram (n r. ls$)
 
1182
  (if (zp n) r.
 
1183
    (letk ((n (1-^ n))
 
1184
           (r. (if (>^ (oper.num-trans n) 0)
 
1185
                   (cons (list (if (eq (oper.name n) 'quote)
 
1186
                                   :quote
 
1187
                                 (oper.name n))
 
1188
                               (oper.num-trans n))
 
1189
                         r.)
 
1190
                 r.)))
 
1191
      (get-trans-histogram n r. ls$))))
 
1192
 
 
1193
(defunk compute-trans-histogram () :inline
 
1194
  (sort-histogram (get-trans-histogram (num-of-oper) () ls$)))
 
1195
 
 
1196
(defunk histogram-to-ttree (histogram. ttree.)
 
1197
  (if (endp histogram.) ttree.
 
1198
    (histogram-to-ttree (cdr histogram.)
 
1199
                        (push-lemma (caar histogram.) ttree.))))
 
1200
 
 
1201
(defunk print-loop-stack (n l r. ls$)
 
1202
  (if (or (zp n) (zp l)) r.
 
1203
    (print-loop-stack (1-^ n) (1-^ l)
 
1204
                      (cons (rule.rune (loop.rule l)) r.)
 
1205
                      ls$)))
 
1206
 
 
1207
(defunk compute-rule-stack () :inline
 
1208
  (print-loop-stack 100 (1-^ (get-loop-stk-top ls$)) () ls$))
 
1209
 
 
1210
(mutual-recursionk
 
1211
(defunk prune-print-term1 (x. n)
 
1212
  (cond ((atom x.) x.)
 
1213
        ((eq (first x.) 'quote) x.)
 
1214
        ((zp n) "...")
 
1215
        (t (cons (first x.)
 
1216
                 (prune-print-args (rest x.) (1-^ n))))))
 
1217
 
 
1218
(defunk prune-print-args (a. n)
 
1219
  (if (endp a.) ()
 
1220
    (cons (prune-print-term1 (first a.) n)
 
1221
          (prune-print-args (rest a.) n))))
 
1222
)
 
1223
 
 
1224
(defunk fixfix (n)
 
1225
  (if (and (integerp n) (>= n 0) (< n (max-fixnum))) n 0))
 
1226
 
 
1227
(defunk prune-node-term (x) :inline
 
1228
  (prune-print-term1 (node-to-term x) (fixfix (get-initial-node-prune-depth ls$))))
 
1229
 
 
1230
(defunk print-suffix-stack (n l r. ls$)
 
1231
  (if (or (zp n) (zp l)) r.
 
1232
    (print-suffix-stack (1-^ n) (1-^ l)
 
1233
                        (cons (list (rule.rune (loop.rule l)) 
 
1234
                                    (prune-node-term (loop.node l)))
 
1235
                              r.)
 
1236
                        ls$)))
 
1237
 
 
1238
(defunk compute-suffix-stack () :inline
 
1239
  (print-suffix-stack 10 (1-^ (get-loop-stk-top ls$)) () ls$))
 
1240
 
 
1241
(defunk print-stats (ls$)
 
1242
  (letk ((rule-hist.  (compute-rule-histogram))
 
1243
         (try-hist.   (compute-rule-try-histogram))
 
1244
         (node-hist.  (compute-node-histogram))
 
1245
         (trans-hist. (compute-trans-histogram))
 
1246
         (ttree.      (histogram-to-ttree rule-hist. ()))
 
1247
         (rule-stk.   (compute-rule-stack))
 
1248
         (stk-terms.  (compute-suffix-stack))
 
1249
         (num-promo   (get-num-of-nodes ls$))
 
1250
         (num-trans   (get-num-trans-nodes ls$))
 
1251
         (num-nodes   (+^ num-promo num-trans)))
 
1252
    (or (not (get-output-verbose ls$))
 
1253
        (cw "--- KAS Num. Nodes: ~p0 ~|"                    num-nodes)
 
1254
        (cw "        Num. Promoted Nodes: ~p0 ~|"           num-promo)
 
1255
        (cw "        Num. Current Temp. Nodes: ~p0 ~|"      num-trans)
 
1256
        (cw "        Applied Rule Histogram: ~| ~p0 ~|~%"   rule-hist.)
 
1257
        (cw "        Attempted Rule Histogram: ~| ~p0 ~|~%" try-hist.)
 
1258
        (cw "        Promoted Node Histogram: ~| ~p0 ~|~%"  node-hist.)
 
1259
        (cw "        Temporary Node Histogram: ~| ~p0 ~|~%" trans-hist.)
 
1260
        (and rule-stk.
 
1261
             (cw "        Pending Rule Stack (top 100): ~| ~p0 ~|~%"  rule-stk.))
 
1262
        (and stk-terms.
 
1263
             (cw "        Rule Stack With Terms (top 10): ~| ~p0 ~|~%" stk-terms.))
 
1264
        ttree.)))
 
1265
 
 
1266
 
 
1267
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1268
#| functions defining various hash codes used in the kernel                   |#
 
1269
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1270
 
 
1271
; The following macro defines the bound on the node indexes which are used
 
1272
; throughout the kernel code to efficiently encode terms. This bound is
 
1273
; necessary due to the requirements of the subsequent hashing function for
 
1274
; newly created nodes.
 
1275
 
 
1276
(defunk hash-index-string (index mask string. acc)
 
1277
  (if (zp index) acc
 
1278
    (letk ((index (1-^ index))
 
1279
           (acc (logand^ mask (+^ acc (char-code (char string. index))))))
 
1280
      (hash-index-string index mask string. acc))))
 
1281
 
 
1282
(defunk hash-index-evg (evg. hash-mask)
 
1283
  (mask^ hash-mask
 
1284
   (cond
 
1285
    ((integerp evg.)
 
1286
     evg.)
 
1287
    ((rationalp evg.)
 
1288
     (+ (numerator evg.)
 
1289
        (* 17 (denominator evg.))))
 
1290
    ((acl2-numberp evg.)
 
1291
     (+^ (hash-index-evg (realpart evg.) hash-mask)
 
1292
         (hash-index-evg (imagpart evg.) hash-mask)))
 
1293
    ((characterp evg.)
 
1294
     (+^ (floor^ hash-mask 4) (char-code evg.)))
 
1295
    ((symbolp evg.)
 
1296
     (*^ 19 (hash-index-evg (symbol-name evg.) hash-mask)))
 
1297
    ((stringp evg.)
 
1298
     (hash-index-string (length evg.) hash-mask evg. (floor^ hash-mask 2)))
 
1299
    (t
 
1300
     (assert (consp evg.)
 
1301
             (+^ (hash-index-evg (car evg.) hash-mask)
 
1302
                 (*^ 2 (hash-index-evg (cdr evg.) hash-mask))))))))
 
1303
 
 
1304
;; modify the following number to adjust the various params used in allocating
 
1305
;; the kernel simplifier data structures.
 
1306
 
 
1307
(defunk static-param (expt 2 12))
 
1308
(defunk op-hash-tbl-size (floor (static-param) 8))
 
1309
(defunk op-hash-tbl-mask (1- (op-hash-tbl-size)))
 
1310
 
 
1311
(defunk fn-hash-code (name.) :inline
 
1312
  (letk ((str. (symbol-name name.)))
 
1313
    (hash-index-string (length str.) (op-hash-tbl-mask) str. 0)))
 
1314
 
 
1315
(defunk mult-kern-mask (1- (expt 2 28)))
 
1316
(defunk add-kern-mask  (1- (expt 2 58)))
 
1317
(defunk add-kern-mod   1021) ;; greatest prime < 1024
 
1318
 
 
1319
(defunk hash-step (arg mask acc) :inline
 
1320
  (logand^ (+^ (logand^ (*^ (logand^ acc (mult-kern-mask))
 
1321
                            (logand^ arg (mult-kern-mask)))
 
1322
                        (add-kern-mask))
 
1323
               (logand^ arg (add-kern-mask))
 
1324
               (mod^ acc (add-kern-mod)))
 
1325
           mask))
 
1326
 
 
1327
(defunk hash-args (n i acc mask x ls$)
 
1328
  (if (zp n) acc
 
1329
    (hash-args (1-^ n) (1+^ i)
 
1330
               (hash-step (node.arg x i) mask acc)
 
1331
               mask x ls$)))
 
1332
 
 
1333
(defunk hash-arg-list (args. acc mask ls$)
 
1334
  (if (endp args.) acc
 
1335
    (hash-arg-list (rest args.)
 
1336
                   (hash-step (first args.) mask acc)
 
1337
                   mask ls$)))
 
1338
 
 
1339
(defunk hash-node (node) :inline
 
1340
  (letk ((opcd (node.opcd node))
 
1341
         (narg (opcd.narg opcd))
 
1342
         (mask (get-hash-mask ls$)))
 
1343
    (hash-step opcd mask (hash-args narg 0 1 mask node ls$))))
 
1344
 
 
1345
(defunk hash-signature (sig.) :inline
 
1346
  (letk ((opcd (first sig.))
 
1347
         (args. (rest sig.))
 
1348
         (mask (get-hash-mask ls$)))
 
1349
    (hash-step opcd mask (hash-arg-list args. 1 mask ls$))))
 
1350
 
 
1351
 
 
1352
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1353
#| auxiliary functions supporting main kernel loop and user fn updates        |#
 
1354
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1355
 
 
1356
(defunk lookup-opcd (op name. var. ls$)
 
1357
  (cond ((zp op)
 
1358
         (opcd-btm))
 
1359
        ((and (equal name. (oper.name op))
 
1360
              (eq var. (oper.is-var op)))
 
1361
         (make-opcd (oper.narg op) 
 
1362
                    var.
 
1363
                    (oper.is-if op)
 
1364
                    (oper.is-equal op)
 
1365
                    op))
 
1366
        (t (lookup-opcd (oper.uniq op) name. var. ls$))))
 
1367
 
 
1368
(defunk find-fn-opcd (name.) :inline
 
1369
  (letk ((op (get-op-hash (fn-hash-code name.) ls$)))
 
1370
    (lookup-opcd op name. nil ls$)))
 
1371
 
 
1372
(defunk find-var-opcd (name.) :inline
 
1373
  (letk ((op (get-op-hash (fn-hash-code name.) ls$)))
 
1374
    (lookup-opcd op name. t ls$)))
 
1375
 
 
1376
(defunk oper-stor-incr (floor (static-param) 8))
 
1377
(defunk rule-stor-incr (floor (static-param) 8))
 
1378
 
 
1379
(defunk alloc-rule-ndx (ls$)
 
1380
  (letk ((ndx (get-next-rule-ndx ls$))
 
1381
         (ls$ (ensure-rule ndx (rule-stor-incr)))
 
1382
         (ls$ (set-next-rule-ndx (1+^ ndx) ls$)))
 
1383
    (mv^ ndx ls$)))
 
1384
 
 
1385
(defunk arg-list= (n i x args. ls$)
 
1386
  (cond ((zp n) (endp args.))
 
1387
        ((endp args.) nil)
 
1388
        ((/=^ (node.arg x i) (first args.)) nil)
 
1389
        (t (arg-list= (1-^ n) (1+^ i) x (rest args.) ls$))))
 
1390
 
 
1391
(defunk args= (n i x y ls$)
 
1392
  (cond ((zp n) t)
 
1393
        ((/=^ (node.arg x i) (node.arg y i)) nil)
 
1394
        (t (args= (1-^ n) (1+^ i) x y ls$))))
 
1395
 
 
1396
(defunk node= (x y) :inline
 
1397
  (or (=^ x y)
 
1398
      (and (not (and (promoted x) (promoted y)))
 
1399
           (node=fn x y 0 0 nil ls$))))
 
1400
 
 
1401
(defunk node=fn (x y n i args-p. ls$)
 
1402
  (if args-p.
 
1403
      (or (zp n)
 
1404
          (and (node= (node.arg x i) (node.arg y i))
 
1405
               (node=fn x y (1-^ n) (1+^ i) t ls$)))
 
1406
    (assert (and (/=^ x (node-btm))
 
1407
                 (/=^ y (node-btm)))
 
1408
     (letk ((opcd-x (node.opcd x))
 
1409
            (opcd-y (node.opcd y)))
 
1410
       (and (=^ opcd-x opcd-y)
 
1411
            (letk ((narg (opcd.narg opcd-x)))
 
1412
              (node=fn x y narg 0 t ls$)))))))
 
1413
 
 
1414
(defunk find-uniq-sig (node opcd args. ls$)
 
1415
  (cond ((zp node) (node-btm))
 
1416
        ((and (=^ (node.opcd node) opcd)
 
1417
              (arg-list= (opcd.narg opcd) 0 node args. ls$))
 
1418
         node)
 
1419
        (t (find-uniq-sig (node.uniq node) opcd args. ls$))))
 
1420
 
 
1421
(defunk find-uniq-node (node opcd x ls$)
 
1422
  (cond ((zp node) (node-btm))
 
1423
        ((and (=^ (node.opcd node) opcd)
 
1424
              (args= (opcd.narg opcd) 0 node x ls$))
 
1425
         node)
 
1426
        (t (find-uniq-node (node.uniq node) opcd x ls$))))
 
1427
 
 
1428
(defunk copy-new-args (n y i x ls$)
 
1429
  (if (zp n) ls$
 
1430
    (letk ((ls$ (node.set-arg x i (node.arg y i))))
 
1431
      (copy-new-args (1-^ n) y (1+^ i) x ls$))))
 
1432
 
 
1433
(defunk add-size (x y) :inline
 
1434
  (if (or (=^ x (size-btm))
 
1435
          (=^ y (size-btm)))
 
1436
      (size-btm)
 
1437
    (letk ((fcnt (+^ (get-size-fcnt x)
 
1438
                     (get-size-fcnt y)))
 
1439
           (vcnt (+^ (get-size-vcnt x)
 
1440
                     (get-size-vcnt y))))
 
1441
      (if (not (and (<^ fcnt (max-fcnt-valu))
 
1442
                    (<^ vcnt (max-vcnt-valu))))
 
1443
          (size-btm)
 
1444
        (make-node-size vcnt fcnt)))))
 
1445
 
 
1446
(defunk compute-args-size (i n x rslt ls$)
 
1447
  (if (zp n) rslt
 
1448
    (compute-args-size (1+^ i) (1-^ n) x
 
1449
                       (add-size (node.size (node.arg x i)) rslt)
 
1450
                       ls$)))
 
1451
 
 
1452
(defunk compute-node-size (size opcd narg x) :inline
 
1453
  (cond ((/=^ size (size-btm))  size)
 
1454
        ((=^ opcd (opcd-quote)) (make-node-size 0 1))
 
1455
        ((opcd.is-var opcd)     (make-node-size 1 0))
 
1456
        ((=^ narg 0)            (make-node-size 0 1))
 
1457
        (t      (compute-args-size 0 narg x 0 ls$))))
 
1458
 
 
1459
(defunk all-args-prom (x n i ls$)
 
1460
  (or (zp n)
 
1461
      (and (promoted (node.arg x i))
 
1462
           (all-args-prom x (1-^ n) (1+^ i) ls$))))
 
1463
 
 
1464
(defunk args-promoted (x) :inline
 
1465
  (all-args-prom x (opcd.narg (node.opcd x)) 0 ls$))
 
1466
 
 
1467
(defmacro kern-record-temp-alloc ()
 
1468
  (if (kern-enable-temp-recording)
 
1469
      '(if promote. ls$
 
1470
         (letk ((ndx (opcd.index opcd))
 
1471
                (num-trans (oper.num-trans ndx))
 
1472
                (ls$ (oper.set-num-trans ndx (1+^ num-trans))))
 
1473
           ls$))
 
1474
    'ls$))
 
1475
 
 
1476
(defunk allocate-node (opcd size promote. ls$)
 
1477
  (letk ((temp. (not promote.))
 
1478
         (narg (opcd.narg opcd))
 
1479
         (num-of-nodes (if temp. (get-num-trans-nodes ls$) (get-num-of-nodes ls$)))
 
1480
         (alloc-nodes (if temp. (get-alloc-trans ls$) (get-alloc-nodes ls$)))
 
1481
         (node-step (get-node-step ls$))
 
1482
         (base-alloc (if temp. (base-trans-alloc) (base-node-alloc)))
 
1483
         (min-alloc (+^ alloc-nodes narg base-alloc))
 
1484
         (length (if temp. (length-trans-stor ls$) (length-node-stor ls$)))
 
1485
         (ls$ (if (>=^ min-alloc length)
 
1486
                  (letk ((new-length (+^ min-alloc
 
1487
                                         (*^ node-step
 
1488
                                             (+^ (avg-num-args)
 
1489
                                                 (if temp. (base-trans-alloc)
 
1490
                                                   (base-node-alloc)))))))
 
1491
                    (if temp. (resize-trans-stor new-length ls$) 
 
1492
                      (resize-node-stor new-length ls$)))
 
1493
                ls$))
 
1494
         (node (1-^ min-alloc))
 
1495
         (ls$ (if temp.
 
1496
                  (letk ((ls$ (set-alloc-trans min-alloc ls$))
 
1497
                         (ls$ (set-num-trans-nodes (1+^ num-of-nodes) ls$)))
 
1498
                    ls$)
 
1499
                (letk ((ls$ (set-alloc-nodes min-alloc ls$))
 
1500
                       (ls$ (set-num-of-nodes (1+^ num-of-nodes) ls$)))
 
1501
                  ls$)))
 
1502
         (node (if temp. (-^ node) node))
 
1503
         (ls$ (node.set-opcd node (logand^ (logand^ (logior^ opcd (*^ size (size-shft)))
 
1504
                                                    (in-ctx-flip)) ; clear the in-ctx bit on allocation
 
1505
                                           (user-mark-flip))))  ; clear the user-mark bit on allocation
 
1506
         (ls$ (record-temp-alloc)))
 
1507
    (mv^ node ls$)))
 
1508
 
 
1509
(defunk complete-promoted-init (new chain hash opcd ls$)
 
1510
  (letk ((ls$ (node.set-uniq new chain))
 
1511
         (ls$ (node.set-rep new (node-btm)))
 
1512
         (ls$ (node.set-dcv new (dcv-empty)))
 
1513
         (ls$ (set-node-hash hash new ls$))
 
1514
         (ndx (opcd.index opcd))
 
1515
         (num-nodes (oper.num-nodes ndx))
 
1516
         (ls$ (oper.set-num-nodes ndx (1+^ num-nodes))))
 
1517
    (mv^ new ls$)))
 
1518
 
 
1519
(defunk make-arg-list (n i x ls$)
 
1520
  (if (zp n) ()
 
1521
    (cons (node.arg x i)
 
1522
          (make-arg-list (1-^ n) (1+^ i) x ls$))))
 
1523
 
 
1524
(defunk signature-to-node (sig. ls$)
 
1525
  (find-uniq-sig (get-node-hash (hash-signature sig.) ls$)
 
1526
                 (first sig.) (rest sig.) ls$))
 
1527
 
 
1528
(defunk node-to-signature (node ls$)
 
1529
  (letk ((opcd (node.opcd node))
 
1530
         (narg (opcd.narg opcd)))
 
1531
    (cons opcd (make-arg-list narg 0 node ls$))))
 
1532
 
 
1533
(defunk install-node (x promote. ls$)
 
1534
  (if (eq promote. (promoted x))
 
1535
      (mv^ x ls$)
 
1536
    (letk ((temp. (not promote.))
 
1537
           (opcd  (node.opcd x))
 
1538
           (size  (node.size x))
 
1539
           (narg  (opcd.narg opcd))
 
1540
           (size  (compute-node-size size opcd narg x))
 
1541
           (hash  (if temp. 0 (hash-node x)))
 
1542
           (chain (if temp. 0 (get-node-hash hash ls$)))
 
1543
           (node  (if temp. (node-btm) (find-uniq-node chain opcd x ls$))))
 
1544
      (assert (not (and temp. (opcd.is-var opcd)))
 
1545
       (assert (or temp. (=^ opcd (opcd-quote)) (args-promoted x))
 
1546
        (if (/=^ node (node-btm))
 
1547
            (mv^ node ls$)
 
1548
          (letk ((new ls$ (allocate-node opcd size promote. ls$))
 
1549
                 (ls$ (copy-new-args narg x 0 new ls$)))
 
1550
            (if temp. (mv^ new ls$)
 
1551
              (complete-promoted-init new chain hash opcd ls$)))))))))
 
1552
 
 
1553
(defunk install-node-memo (opcd x hash ls$)
 
1554
  (assert (args-promoted x)
 
1555
   (letk ((narg (opcd.narg opcd))
 
1556
          (size (node.size x))
 
1557
          (size (compute-node-size size opcd narg x))
 
1558
          (chain (get-node-hash hash ls$))
 
1559
          (new ls$ (allocate-node opcd size t ls$))
 
1560
          (ls$ (copy-new-args narg x 0 new ls$))
 
1561
          (x ls$ (complete-promoted-init new chain hash opcd ls$)))
 
1562
     (mv^ x ls$))))
 
1563
 
 
1564
(defunk quote-obj-incr  (floor (static-param) 4))
 
1565
(defunk quote-hash-size (* (quote-obj-incr) 2))
 
1566
(defunk quote-hash-mask (1- (quote-hash-size)))
 
1567
 
 
1568
(defunk find-quote-obj (ptr obj. ls$)
 
1569
  (cond ((zp ptr) (qobj-btm))
 
1570
        ((equal (qobj.obj ptr) obj.) ptr)
 
1571
        (t (find-quote-obj (qobj.uniq ptr) obj. ls$))))
 
1572
 
 
1573
(defunk make-quote (obj. ls$)
 
1574
  (letk ((hash (hash-index-evg obj. (quote-hash-mask)))
 
1575
         (chain (get-quote-hash hash ls$))
 
1576
         (qobj (find-quote-obj chain obj. ls$)))
 
1577
    (if (/=^ qobj (qobj-btm))
 
1578
        (mv^ qobj ls$)
 
1579
      (letk ((x (get-next-quote ls$))
 
1580
             (ls$ (ensure-qobj x (quote-obj-incr)))
 
1581
             (ls$ (qobj.set-obj x obj.))
 
1582
             (ls$ (qobj.set-uniq x chain))
 
1583
             (ls$ (set-quote-hash hash x ls$))
 
1584
             (ls$ (set-next-quote (1+^ x) ls$)))
 
1585
        (mv^ x ls$)))))
 
1586
 
 
1587
(defunk create-quote (obj.) :inline
 
1588
  (letk ((v ls$ (make-quote obj. ls$))
 
1589
         (x ls$ (allocate-node (opcd-quote) (size-btm) nil ls$))
 
1590
         (ls$ (node.set-arg x 0 v)))
 
1591
    (install-node x t ls$)))
 
1592
 
 
1593
(defunk install-quote (obj. ls$)
 
1594
  (cond ((eq obj. t)   (mv^ (node-t) ls$))
 
1595
        ((eq obj. nil) (mv^ (node-nil) ls$))
 
1596
        (t (create-quote obj.))))
 
1597
 
 
1598
(defunk install-var-oper (name. ls$)
 
1599
  (letk ((hash (fn-hash-code name.))
 
1600
         (chain (get-op-hash hash ls$))
 
1601
         (opcd (lookup-opcd chain name. t ls$))
 
1602
         (ndx (if (/=^ opcd (opcd-btm))
 
1603
                  (opcd.index opcd)
 
1604
                (get-next-op-ndx ls$)))
 
1605
         (ls$ (if (/=^ opcd (opcd-btm)) 
 
1606
                  ls$
 
1607
                (letk ((ls$ (ensure-oper ndx (oper-stor-incr)))
 
1608
                       (ls$ (oper.set-uniq ndx chain)) 
 
1609
                       (ls$ (set-op-hash hash ndx ls$))
 
1610
                       (ls$ (set-next-op-ndx (1+^ ndx) ls$))
 
1611
                       (ls$ (oper.set-next-stk ndx (opcd-btm)))
 
1612
                       (ls$ (oper.set-bound ndx (node-btm))))
 
1613
                  ls$)))
 
1614
         (ls$ (oper.set-name ndx name.))
 
1615
         (ls$ (oper.set-is-var ndx t))
 
1616
         (ls$ (oper.set-rules ndx ()))
 
1617
         (ls$ (oper.set-narg ndx 0))
 
1618
         (ls$ (oper.set-num-nodes ndx 0))
 
1619
         (ls$ (oper.set-num-trans ndx 0))
 
1620
         (ls$ (oper.set-exec ndx (node-btm)))
 
1621
         (ls$ (oper.set-boolp ndx nil))
 
1622
         (ls$ (oper.set-assume-tbr ndx nil))
 
1623
         (ls$ (oper.set-assume-fbr ndx nil))
 
1624
         (ls$ (oper.set-is-if ndx nil))
 
1625
         (ls$ (oper.set-is-equal ndx nil))
 
1626
         (ls$ (oper.set-non-nil ndx nil)))
 
1627
    (mv^ ndx ls$)))
 
1628
 
 
1629
(defunk get-var-opcode (name. ls$)
 
1630
  (letk ((opcd (find-var-opcd name.)))
 
1631
    (if (/=^ opcd (opcd-btm))
 
1632
        (mv^ opcd ls$)
 
1633
      (letk ((op ls$ (install-var-oper name. ls$)))
 
1634
        (mv^ (make-opcd 0 t nil nil op) ls$)))))
 
1635
 
 
1636
(defunk install-var (name. ls$)
 
1637
  (letk ((opcd ls$ (get-var-opcode name. ls$))
 
1638
         (x ls$ (allocate-node opcd (size-btm) nil ls$))
 
1639
         (x ls$ (install-node x t ls$)))
 
1640
    (mv^ x ls$)))
 
1641
 
 
1642
(mutual-recursionk
 
1643
(defunk term-to-node (term. ls$)
 
1644
  (cond
 
1645
   ((atom term.)
 
1646
    (assert (symbolp term.)
 
1647
     (install-var term. ls$)))
 
1648
   ((eq (first term.) 'quote)
 
1649
    (install-quote (second term.) ls$))
 
1650
   ((and (consp (first term.))
 
1651
         (eq (first (first term.)) 'lambda))
 
1652
    (mv^ (er0 hard 'term-to-node
 
1653
              "should not encounter lambdas in mapping term to node")
 
1654
         ls$))
 
1655
   (t
 
1656
    (letk ((opcd (find-fn-opcd (first term.)))
 
1657
           (narg (opcd.narg opcd)))
 
1658
      (if (or (=^ opcd (opcd-btm))
 
1659
              (/=^ narg (length (rest term.))))
 
1660
          (mv^ (er0 hard 'term-to-node
 
1661
                    "could not locate appropriate opcode for term ~x0 ~x1"
 
1662
                    (first term.) opcd)
 
1663
               ls$)
 
1664
        (letk ((x ls$ (allocate-node opcd (size-btm) nil ls$))
 
1665
               (ls$ (rest-to-args (rest term.) 0 x ls$)))
 
1666
          (install-node x t ls$)))))))
 
1667
 
 
1668
(defunk rest-to-args (args. i x ls$)
 
1669
  (if (endp args.) ls$
 
1670
    (letk ((arg ls$ (term-to-node (first args.) ls$))
 
1671
           (ls$ (node.set-arg x i arg)))
 
1672
      (rest-to-args (rest args.) (1+^ i) x ls$))))
 
1673
)
 
1674
 
 
1675
 
 
1676
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1677
#| functions implementing undo-stk and depth ctx (dctx)                       |#
 
1678
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1679
 
 
1680
(defunk undo-btm                 0)
 
1681
(defunk undo-stk-increment   12286)
 
1682
(defunk undo-chains-increment 1048)
 
1683
 
 
1684
(defunk dctx-max-rep (- (fixnum-size) 2))
 
1685
(defunk dcv-max-rep (1- (ash 1 (1+ (dctx-max-rep)))))
 
1686
 
 
1687
(defunk alloc-undo-ptr (ls$)
 
1688
  (letk ((free (get-undo-free-list ls$)))
 
1689
    (if (/=^ free (undo-btm))
 
1690
        (letk ((ls$ (set-undo-free-list (undo.chain free) ls$)))
 
1691
          (mv^ free ls$))
 
1692
      (letk ((top (get-undo-top ls$))
 
1693
             (ls$ (ensure-undo top (undo-stk-increment)))
 
1694
             (ls$ (set-undo-top (1+^ top) ls$)))
 
1695
        (mv^ top ls$)))))
 
1696
 
 
1697
(defunk memo-args= (x m n i ls$)
 
1698
  (or (zp n)
 
1699
      (and (=^ (node.arg x i) (memo.arg m i))
 
1700
           (memo-args= x m (1-^ n) (1+^ i) ls$))))
 
1701
 
 
1702
(defunk find-max-dctx (dcv dcx)
 
1703
  (cond ((zp dcx) (dctx-0))
 
1704
        ((/=^ (logand^ (ash^ 1 dcx) dcv) 0) dcx)
 
1705
        (t (find-max-dctx dcv (1-^ dcx)))))
 
1706
 
 
1707
(defunk max-in-dcv (dcv) :inline
 
1708
  (if (=^ dcv (dcv-empty)) (dctx-0) (find-max-dctx dcv (dctx-max-rep))))
 
1709
 
 
1710
(defunk create-new-undo (x dcv old-r old-d ls$)
 
1711
  (if (=^ dcv (dcv-empty)) ls$
 
1712
    (letk ((dcx (max-in-dcv dcv))
 
1713
           (chain (get-undo-chains dcx ls$))
 
1714
           (uptr ls$ (alloc-undo-ptr ls$))
 
1715
           (ls$ (undo.set-node uptr x))
 
1716
           (ls$ (undo.set-rep uptr old-r))
 
1717
           (ls$ (undo.set-dcv uptr old-d))
 
1718
           (ls$ (undo.set-chain uptr chain))
 
1719
           (ls$ (set-undo-chains dcx uptr ls$)))
 
1720
      ls$)))
 
1721
 
 
1722
(defunk create-update-rep (node new-r dcv ls$)
 
1723
  (if (>=^ dcv (dcv-max-rep)) ls$
 
1724
    (letk ((old-r (node.rep node))
 
1725
           (old-d (node.dcv node))
 
1726
           (ls$ (create-new-undo node dcv old-r old-d ls$))
 
1727
           (ls$ (node.set-rep node new-r))
 
1728
           (ls$ (node.set-dcv node dcv)))
 
1729
      ls$)))
 
1730
 
 
1731
;; The following is the ratio from entries in the unique node hash-table and
 
1732
;; the memo-table. Since we reuse the hashing function, we have to divide down
 
1733
;; the hash address in order to get the memo table address.
 
1734
 
 
1735
(defunk hash-memo-divisor 4)
 
1736
 
 
1737
(defunk check-memos (x ls$)
 
1738
  (if (promoted x)
 
1739
      (mv^ x ls$)
 
1740
    (letk ((opcd (node.opcd x))
 
1741
           (narg (opcd.narg opcd)))
 
1742
      (if (or (>^ narg (max-memo-narg))
 
1743
              (not (args-promoted x)))
 
1744
          (mv^ x ls$)
 
1745
        (letk ((h (hash-node x))
 
1746
               (node (find-uniq-node (get-node-hash h ls$) opcd x ls$)))
 
1747
          (if (/=^ node (node-btm))
 
1748
              (mv^ node ls$)
 
1749
            (letk ((m (floor^ h (hash-memo-divisor)))
 
1750
                   (m-opcd (memo.opcd m))
 
1751
                   (match. (and (=^ opcd m-opcd)
 
1752
                                (or (<=^ narg (num-1memo-args))
 
1753
                                    (=^ (memo.opcd (1+^ m))
 
1754
                                        (opcd-memo-mrkr)))
 
1755
                                (memo-args= x m narg 0 ls$))))
 
1756
              (if (not match.)
 
1757
                  (mv^ x ls$)
 
1758
                (letk ((node ls$ (install-node-memo opcd x h ls$))
 
1759
                       (ls$ (if (/=^ (node.rep node) (node-btm)) ls$
 
1760
                              (create-update-rep node (memo.rslt m) (memo.dcv m) ls$))))
 
1761
                  (mv^ node ls$))))))))))
 
1762
 
 
1763
(defunk memo-copy-args (m x n i ls$)
 
1764
  (if (zp n) ls$
 
1765
    (letk ((ls$ (memo.set-arg m i (node.arg x i))))
 
1766
      (memo-copy-args m x (1-^ n) (1+^ i) ls$))))
 
1767
 
 
1768
(defunk create-memo-if-needed (x rep dcv ls$)
 
1769
  (assert (and (temp-node x) (>^ rep 0))
 
1770
   (letk ((opcd (node.opcd x))
 
1771
          (narg (opcd.narg opcd)))
 
1772
     (if (or (>^ narg (max-memo-narg))
 
1773
             (not (args-promoted x))
 
1774
             (>=^ dcv (dcv-max-rep)))
 
1775
         ls$
 
1776
       (letk ((m (floor^ (hash-node x) (hash-memo-divisor)))
 
1777
              (ls$ (memo.set-opcd m opcd))
 
1778
              (ls$ (memo.set-rslt m rep))
 
1779
              (ls$ (memo.set-dcv  m dcv))
 
1780
              (ls$ (memo-copy-args m x narg 0 ls$))
 
1781
              (ls$ (if (<=^ narg (num-1memo-args)) ls$ 
 
1782
                     (memo.set-opcd (1+^ m) (opcd-memo-mrkr))))
 
1783
              (ls$ (create-new-undo (-^ m) dcv (node-btm) (dcv-btm) ls$)))
 
1784
         ls$)))))
 
1785
 
 
1786
(defunk update-rep (node rep dcv id ls$)
 
1787
  (declare (ignore id))
 
1788
  (assert (or (and (>=^ dcv (dcv-btm))
 
1789
                   (/=^ node (node-btm))
 
1790
                   (/=^ (node.opcd node) (opcd-quote)))
 
1791
              (list dcv node rep (node.opcd node)))
 
1792
   (cond ((=^ rep (node-btm))
 
1793
          (assert (promoted node)
 
1794
           (node.set-rep node (node-btm))))
 
1795
         ((temp-node node)
 
1796
          (create-memo-if-needed node rep dcv ls$))
 
1797
         ((=^ rep node) ls$)
 
1798
         ((=^ dcv (dcv-btm))
 
1799
          (letk ((ls$ (node.set-rep node rep))
 
1800
                 (ls$ (node.set-dcv node (dcv-empty))))
 
1801
            ls$))
 
1802
         ((=^ (node.rep node) rep) ls$)
 
1803
         (t (create-update-rep node rep dcv ls$)))))
 
1804
 
 
1805
(defunk pop-undo-stk-fn (uptr depth ls$)
 
1806
  (cond ((zp depth)
 
1807
         (prog2$ (er0 hard 'pop-undo-stk-fn
 
1808
                      "An internal error in the KAS algorithm has been detected. ~
 
1809
                       Please notify current maintainer of KAS")
 
1810
           ls$))
 
1811
        ((zp uptr) ls$)
 
1812
        (t
 
1813
         (letk ((node (undo.node uptr))
 
1814
                (chain (undo.chain uptr))
 
1815
                (ls$ (cond ((=^ node (node-btm))
 
1816
                            (letk ((dcv (undo.dcv uptr)))
 
1817
                              (if (=^ dcv (dcv-btm))
 
1818
                                  (node.set-in-ctx (undo.rep uptr) nil)
 
1819
                                (set-curr-ctx-stk dcv (undo.rep uptr) ls$))))
 
1820
                           ((promoted node)
 
1821
                            (letk ((ls$ (node.set-rep node (undo.rep uptr)))
 
1822
                                   (ls$ (node.set-dcv node (undo.dcv uptr))))
 
1823
                              ls$))
 
1824
                           (t (memo.set-opcd (-^ node) (opcd-btm))))) ;; clear the memo
 
1825
                (free (get-undo-free-list ls$))
 
1826
                (ls$ (undo.set-chain uptr free))
 
1827
                (ls$ (set-undo-free-list uptr ls$)))
 
1828
           (pop-undo-stk-fn chain (1-^ depth) ls$)))))
 
1829
 
 
1830
(defunk pop-undo-stk (dcx) :inline
 
1831
  (letk ((undo (get-undo-chains dcx ls$))
 
1832
         (ls$ (set-undo-chains dcx (undo-btm) ls$))
 
1833
         (ls$ (pop-undo-stk-fn undo (1+^ (get-undo-top ls$)) ls$)))
 
1834
    ls$))
 
1835
 
 
1836
(defunk create-new-dctx (ls$)
 
1837
  (letk ((dcx (get-current-dctx ls$))
 
1838
         (dcx (1+^ dcx))
 
1839
         (ls$ (if (<=^ (ash^ 1 dcx) (dcv-max-rep)) ls$
 
1840
                (prog2$ (and (not (get-warned-ctx-depth ls$))
 
1841
                             (cw "NOTE: context depth exceeded maximum ctx. limit. performance will be hindered."))
 
1842
                        (set-warned-ctx-depth t ls$))))
 
1843
         (ls$ (if (<^ dcx (length-undo-chains ls$))
 
1844
                  ls$
 
1845
                (resize-undo-chains
 
1846
                 (+^ dcx (undo-chains-increment)) ls$)))
 
1847
         (ls$ (set-undo-chains dcx (node-btm) ls$))
 
1848
         (ls$ (set-current-dctx dcx ls$)))
 
1849
    (mv^ dcx ls$)))
 
1850
 
 
1851
(defunk restore-previous-state (dcx- dcx+ age ls$)
 
1852
  (letk ((ls$ (pop-undo-stk dcx+))
 
1853
         (ls$ (set-current-dctx dcx- ls$))
 
1854
         (ls$ (set-current-age age ls$)))
 
1855
    ls$))
 
1856
 
 
1857
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1858
#| heuristic for generating case splits implemented as a sieve                |#
 
1859
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
1860
 
 
1861
(defunk non-nilp (x) :inline
 
1862
  (or (=^ x (node-t))
 
1863
      (letk ((opcd (node.opcd x)))
 
1864
        (or (and (/=^ x (node-nil))
 
1865
                 (=^ opcd (opcd-quote)))
 
1866
            (oper.non-nil (opcd.index opcd))))))
 
1867
 
 
1868
(defunk is-boolp (x) :inline
 
1869
  (or (=^ x (node-t))
 
1870
      (=^ x (node-nil))
 
1871
      (oper.boolp (opcd.index (node.opcd x)))))
 
1872
 
 
1873
;; The following is the user stobj which can be used to store whatever
 
1874
;; data the user wants to maintain during the simplification process.
 
1875
(define-stobj+ us$
 
1876
  (dynamic-user-state-obj :object)
 
1877
  (candidate-stor         :fixnum-array)
 
1878
  (candidate-hash         :fixnum-array)
 
1879
  (candidate-mask         :fixnum)
 
1880
  (candidate-step         :fixnum)
 
1881
  (next-candidate         :fixnum)
 
1882
  (candidate-stk          :fixnum-array)
 
1883
  (candidate-top          :fixnum)
 
1884
  (opcd-bv                :fixnum)
 
1885
)
 
1886
 
 
1887
(define-user-record-array candidate
 
1888
  (:fixnum candidate-stor (node weight tst chain)))
 
1889
 
 
1890
(defunk candidate-tbl-init  (sp) (floor (expt 2 sp) 64))
 
1891
(defunk candidate-tbl-step  (sp) (candidate-tbl-init sp))
 
1892
(defunk candidate-hash-size (sp) (* (candidate-tbl-init sp) 2))
 
1893
(defunk candidate-hash-mask (sp) (- (candidate-hash-size sp) 1))
 
1894
 
 
1895
(defunk init-candidate-hash (n us$)
 
1896
  (if (zp n) us$
 
1897
    (letk ((n (1-^ n))
 
1898
           (us$ (set-candidate-hash n (node-btm) us$)))
 
1899
      (init-candidate-hash n us$))))
 
1900
 
 
1901
(defunk user-init (ls$ us$)
 
1902
  (letk ((sp (get-kern-size-param ls$))
 
1903
         (us$ (set-opcd-bv (opcd-btm) us$))
 
1904
         (us$ (set-dynamic-user-state-obj nil us$))
 
1905
         (us$ (resize-candidate-hash (candidate-hash-size sp) us$))
 
1906
         (us$ (init-candidate-hash (candidate-hash-size sp) us$))
 
1907
         (us$ (set-candidate-mask (candidate-hash-mask sp) us$))
 
1908
         (us$ (ensure-candidate (candidate-tbl-init sp) 0))
 
1909
         (us$ (set-candidate-step (candidate-tbl-step sp) us$))
 
1910
         (us$ (set-next-candidate (1+^ (node-btm)) us$))
 
1911
         (us$ (resize-candidate-stk (candidate-hash-size sp) us$))
 
1912
         (us$ (set-candidate-top 0 us$)))
 
1913
    us$))
 
1914
 
 
1915
; We implement a heuristic for introducing case-splits. The basic idea is to
 
1916
; case-split on the most frequently referenced term which appears in the test
 
1917
; of an if (or is equated in the test of an if).
 
1918
;
 
1919
; 1. Introduce entry for each candidate node
 
1920
; 2. Weighted count of all references to candidate nodes
 
1921
; 3. determination of heaviest candidate in weighting
 
1922
;    -- and clear the hash-table at the same time.
 
1923
 
 
1924
(defunk hash-candidate (node) :inline 
 
1925
  (logand^ node (get-candidate-mask us$)))
 
1926
 
 
1927
(defunk find-candidate-in-chain (cand node us$)
 
1928
  (cond ((zp cand) (node-btm))
 
1929
        ((=^ (candidate.node cand) node) cand)
 
1930
        (t (find-candidate-in-chain (candidate.chain cand) node us$))))
 
1931
 
 
1932
(defunk add-candidate-node (node tst us$)
 
1933
  (letk ((hash (hash-candidate node))
 
1934
         (chain (get-candidate-hash hash us$))
 
1935
         (cand (find-candidate-in-chain chain node us$)))
 
1936
    (if (/=^ cand (node-btm)) us$
 
1937
      (letk ((cand (get-next-candidate us$))
 
1938
             (us$ (ensure-candidate cand (get-candidate-step us$)))
 
1939
             (us$ (candidate.set-node   cand node))
 
1940
             (us$ (candidate.set-weight cand 0))
 
1941
             (us$ (candidate.set-tst    cand tst))
 
1942
             (us$ (candidate.set-chain  cand chain))
 
1943
             (us$ (set-candidate-hash hash cand us$))
 
1944
             (us$ (set-next-candidate (1+^ cand) us$)))
 
1945
        (if (/=^ chain (node-btm)) us$
 
1946
          (letk ((top (get-candidate-top us$))
 
1947
                 (us$ (set-candidate-stk top hash us$))
 
1948
                 (us$ (set-candidate-top (1+^ top) us$)))
 
1949
            us$))))))
 
1950
 
 
1951
(mutual-recursionk
 
1952
(defunk if-subterm (x ls$)
 
1953
  (letk ((opcd (node.opcd x)))
 
1954
    (cond
 
1955
     ((=^ opcd (opcd-quote)) nil)
 
1956
     ((opcd.is-var opcd) nil)
 
1957
     ((opcd.is-if opcd) t)
 
1958
     (t (if-subterm-args (opcd.narg opcd) 0 x ls$)))))
 
1959
 
 
1960
(defunk if-subterm-args (n i x ls$)
 
1961
  (and (not (zp n))
 
1962
       (or (if-subterm (node.arg x i) ls$)
 
1963
           (if-subterm-args (1-^ n) (1+^ i) x ls$))))
 
1964
)
 
1965
 
 
1966
(defunk add-candidate-nodes (opcd x ls$ us$)
 
1967
  (if (not (opcd.is-if opcd)) us$
 
1968
    (letk ((tst (node.arg x 0)))
 
1969
      (if (or (not (is-boolp tst)) (if-subterm tst ls$)) us$
 
1970
        (letk ((us$ (add-candidate-node tst tst us$)))
 
1971
          (if (/=^ (node.opcd tst) (opcd-equal)) us$
 
1972
            (add-candidate-node (node.arg tst 0) tst us$)))))))
 
1973
 
 
1974
(mutual-recursionk
 
1975
(defunk add-candidates-for-node (x ls$ us$)
 
1976
  (letk ((opcd (node.opcd x)))
 
1977
    (if (or (=^ opcd (opcd-quote)) (opcd.is-var opcd)) us$
 
1978
      (letk ((us$ (add-candidate-nodes opcd x ls$ us$)))
 
1979
        (add-candidates-for-args (opcd.narg opcd) 0 x ls$ us$)))))
 
1980
 
 
1981
(defunk add-candidates-for-args (n i x ls$ us$)
 
1982
  (if (zp n) us$
 
1983
    (letk ((us$ (add-candidates-for-node (node.arg x i) ls$ us$)))
 
1984
      (add-candidates-for-args (1-^ n) (1+^ i) x ls$ us$))))
 
1985
)
 
1986
 
 
1987
(defunk case-split-candidates (x ls$ us$)
 
1988
  (letk ((opcd (node.opcd x)))
 
1989
    (cond
 
1990
     ((or (=^ opcd (opcd-quote)) 
 
1991
          (opcd.is-var opcd)) 
 
1992
      us$)
 
1993
     ((and (opcd.is-if opcd)
 
1994
           (not (if-subterm (node.arg x 0) ls$)))
 
1995
      (letk ((us$ (case-split-candidates (node.arg x 1) ls$ us$)))
 
1996
        (case-split-candidates (node.arg x 2) ls$ us$)))
 
1997
     ((=^ (opcd.narg opcd) 1)
 
1998
      (case-split-candidates (node.arg x 0) ls$ us$))
 
1999
     (t
 
2000
      (add-candidates-for-node x ls$ us$)))))
 
2001
 
 
2002
 
 
2003
;; An upper bound on the weight for any candidate. We use this as
 
2004
;; a cap on nodes which may get too much weight due to reconvergent
 
2005
;; nodes (in those cases, we are probably already in trouble), and
 
2006
;; we need a mechanism to ensure that we maintain fixnums.
 
2007
(defunk max-candidate-weight (expt 2 20))
 
2008
 
 
2009
(defunk adjust-candidate-weight (x weight us$)
 
2010
  (letk ((hash (hash-candidate x))
 
2011
         (chain (get-candidate-hash hash us$))
 
2012
         (cand (find-candidate-in-chain chain x us$)))
 
2013
    (if (=^ cand (node-btm)) us$
 
2014
      (letk ((curr (candidate.weight cand))
 
2015
             (new (if (and (<^ curr (max-candidate-weight))
 
2016
                           (<^ weight (max-candidate-weight))
 
2017
                           (<^ (+^ curr weight) (max-candidate-weight)))
 
2018
                      (+^ curr weight)
 
2019
                    (max-candidate-weight)))
 
2020
             (us$ (candidate.set-weight cand new)))
 
2021
        us$))))
 
2022
 
 
2023
(defunk decrement-weight (weight decr) :inline
 
2024
  (if (>^ weight decr) (-^ weight decr) 1))
 
2025
 
 
2026
(mutual-recursionk
 
2027
(defunk weigh-case-splits (x weight ls$ us$)
 
2028
  (letk ((opcd (node.opcd x)))
 
2029
    (cond
 
2030
     ((or (=^ opcd (opcd-quote))
 
2031
          (opcd.is-var opcd))
 
2032
      us$)
 
2033
     ((opcd.is-if opcd)
 
2034
      (letk ((br-w (decrement-weight weight 2))
 
2035
             (us$ (weigh-case-splits (node.arg x 1) br-w ls$ us$))
 
2036
             (us$ (weigh-case-splits (node.arg x 2) br-w ls$ us$)))
 
2037
        (weigh-case-splits (node.arg x 0) (decrement-weight weight 1) ls$ us$)))
 
2038
     (t
 
2039
      (letk ((us$ (adjust-candidate-weight x weight us$)))
 
2040
        (weigh-case-split-args (opcd.narg opcd) 0 x weight ls$ us$))))))
 
2041
 
 
2042
(defunk weigh-case-split-args (n i x w ls$ us$)
 
2043
  (if (zp n) us$
 
2044
    (letk ((us$ (weigh-case-splits (node.arg x i) w ls$ us$)))
 
2045
      (weigh-case-split-args (1-^ n) (1+^ i) x w ls$ us$))))
 
2046
)
 
2047
 
 
2048
(defunk find-better-candidate (cand max us$)
 
2049
  (cond ((zp cand) max)
 
2050
        ((=^ max (node-btm)) cand)
 
2051
        ((>^ (candidate.weight cand) (candidate.weight max))
 
2052
         (find-better-candidate (candidate.chain cand) cand us$))
 
2053
        (t (find-better-candidate (candidate.chain cand) max us$))))
 
2054
 
 
2055
(defunk find-and-clear-split (ptr max us$)
 
2056
  (if (zp ptr) (mv^ max us$)
 
2057
    (letk ((ptr (1-^ ptr))
 
2058
           (hash (get-candidate-stk ptr us$))
 
2059
           (cand (get-candidate-hash hash us$))
 
2060
           (max (find-better-candidate cand max us$))
 
2061
           (us$ (set-candidate-hash hash (node-btm) us$)))
 
2062
      (find-and-clear-split ptr max us$))))
 
2063
 
 
2064
(defunk determine-case-split (us$)
 
2065
  (letk ((top (get-candidate-top us$))
 
2066
         (cand us$ (find-and-clear-split top (node-btm) us$)))
 
2067
    (if (=^ cand (node-btm))
 
2068
        (mv^ (node-btm) us$)
 
2069
      (letk ((split (candidate.tst cand))
 
2070
             (us$ (set-candidate-top 0 us$))
 
2071
             (us$ (set-next-candidate (1+^ (node-btm)) us$)))
 
2072
        (mv^ split us$)))))
 
2073
 
 
2074
(defunk valid-case-split (x) :inline
 
2075
  (and (/=^ x (node-btm))
 
2076
       (promoted x)
 
2077
       (letk ((opcd (node.opcd x)))
 
2078
         (and (/=^ opcd (opcd-quote))
 
2079
              (not (opcd.is-var opcd))))))
 
2080
 
 
2081
;; initial weight which is distributed differently through if args
 
2082
;; and added to the weights accumulating in the candidate table.
 
2083
(defunk initial-case-split-weight 32)
 
2084
 
 
2085
(defunk generate-case-split (sieve. x ls$ us$)
 
2086
  (letk ((n (second sieve.))
 
2087
         (opcd (node.opcd n)))
 
2088
    (if (not (opcd.is-var opcd))
 
2089
        (mv () us$)
 
2090
      (letk ((var (opcd.index opcd))
 
2091
             (us$ (case-split-candidates x ls$ us$))
 
2092
             (us$ (weigh-case-splits x (initial-case-split-weight) ls$ us$))
 
2093
             (split us$ (determine-case-split us$)))
 
2094
        (mv (and (valid-case-split split)
 
2095
                 (list (list :set-var-bound var
 
2096
                             (node-to-signature split ls$))))
 
2097
            us$)))))
 
2098
 
 
2099
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
2100
#| user function stobj (us$) and user function call                           |#
 
2101
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
2102
 
 
2103
; The user-fn responds with an answer and a list of "update"s to the kernel
 
2104
; logic state stobj ls$. The reason we use this interface is to restrict (in a
 
2105
; clear logical sense) what "effects" the user-fn can have on ls$ (which stores
 
2106
; all of the information relevant to the soundness of the kernel
 
2107
; simplifier). The following updates are currently supported/allowed:
 
2108
;
 
2109
; (:set-var-bound     <var>  <node>)        <var>   is nfix index, <node> is nfix index
 
2110
; (:set-rule-sieves   <rule> <sieves>)
 
2111
; (:set-rule-enabled  <rule> <flag>)        <rule>  is nfix index, <flag> is boolean
 
2112
; (:set-rule-always   <rule> <flag>)        <rule>  is nfix index, <flag> is boolean
 
2113
; (:set-rule-ctr      <rule> <ctr>)
 
2114
; (:set-node-step     <step>)               <step>  is nfix
 
2115
; (:set-node-limit    <limit>)              <limit> is nfix
 
2116
; (:change-rule-order <rule> <pos>)         <rule>  is nfix index, <pos>  is natural
 
2117
; (:set-rule-traced   <rule> <mark>)
 
2118
; (:set-user-mark     <node> <mark>)
 
2119
;
 
2120
;;;; nfix is a natural fixnum
 
2121
 
2122
; The function process-update does not place any assumptions on the 
 
2123
; update structure from the user-fn, so some checks are required.
 
2124
 
 
2125
(defunk first-oper-ndx 1)
 
2126
(defunk first-rule-ndx 1)
 
2127
 
 
2128
(defunk drop-rule (rules. ndx)
 
2129
  (cond ((endp rules.) ())
 
2130
        ((=^ (car rules.) ndx) (cdr rules.))
 
2131
        (t (cons (car rules.)
 
2132
                 (drop-rule (cdr rules.) ndx)))))
 
2133
 
 
2134
(defunk place-rule (rules. ndx pos)
 
2135
  (if (or (zp pos) (endp rules.))
 
2136
      (cons ndx rules.)
 
2137
    (cons (car rules.)
 
2138
          (place-rule (cdr rules.) ndx (1-^ pos)))))
 
2139
 
 
2140
(defunk move-rule (rules. ndx pos)
 
2141
  (place-rule (drop-rule rules. ndx) ndx pos))
 
2142
 
 
2143
(defunk is-legal-rule (rule. ls$)
 
2144
  (and (fixnump rule.)
 
2145
       (>=^ rule. (first-rule-ndx))
 
2146
       (<^ rule. (get-next-rule-ndx ls$))))
 
2147
 
 
2148
(defunk is-legal-oper (op. ls$)
 
2149
  (and (fixnump op.)
 
2150
       (>=^ op. (first-oper-ndx))
 
2151
       (<^ op. (get-next-op-ndx ls$))))
 
2152
 
 
2153
(defunk is-legal-sig-args (sig.)
 
2154
  (or (null sig.)
 
2155
      (and (consp sig.)
 
2156
           (fixnump (first sig.))
 
2157
           (is-legal-sig-args (rest sig.)))))
 
2158
 
 
2159
(defunk is-legal-sig (sig.)
 
2160
  (and (consp sig.)
 
2161
       (fixnump (first sig.))
 
2162
       (is-legal-sig-args (rest sig.))))
 
2163
 
 
2164
(defunk legal-sieves (sieves.)
 
2165
  (or (null sieves.)
 
2166
      (and (consp sieves.)
 
2167
           (consp (first sieves.))
 
2168
           (keywordp (first (first sieves.)))
 
2169
           (true-listp (rest (first sieves.)))
 
2170
           (legal-sieves (rest sieves.)))))
 
2171
 
 
2172
(defunk install-arg-as-node (arg. ls$)
 
2173
  (if (termp arg. (get-current-world ls$))
 
2174
      (term-to-node arg. ls$)
 
2175
    (term-to-node (list 'quote arg.) ls$)))
 
2176
 
 
2177
(defunk install-sieve-args (args. ls$)
 
2178
  (if (endp args.)
 
2179
      (mv () ls$)
 
2180
    (letk ((node ls$ (install-arg-as-node (first args.) ls$))
 
2181
           (rst. ls$ (install-sieve-args (rest args.) ls$)))
 
2182
      (mv (cons node rst.) ls$))))
 
2183
 
 
2184
(defunk install-sieves (sieves. ls$)
 
2185
  (if (endp sieves.)
 
2186
      (mv () ls$)
 
2187
    (letk ((args. ls$ (install-sieve-args (rest (first sieves.)) ls$))
 
2188
           (rst. ls$ (install-sieves (rest sieves.) ls$)))
 
2189
      (mv (acons (first (first sieves.)) args. rst.) ls$))))
 
2190
 
 
2191
(defunk er-process-update-arg (msg.) :inline
 
2192
  (er hard 'process-update
 
2193
      "ill-formed user-fn update. message: ~x0 update: ~x1"
 
2194
      msg. upd.))
 
2195
 
 
2196
(defunk er-process-update (msg.) :inline
 
2197
  (prog2$ (er-process-update-arg msg.) ls$))
 
2198
 
 
2199
(defunk pu-bool (x.) :inline
 
2200
  (if (is-boolean x.) x. (er-process-update-arg "expected boolean value")))
 
2201
 
 
2202
(defunk pu-nat (x. lo. hi.) :inline
 
2203
  (if (and (fixnump x.)
 
2204
           (or (null lo.) (>= x. lo.))
 
2205
           (or (null hi.) (<= x. hi.)))
 
2206
      x.
 
2207
    (er-process-update-arg "expected natural number")))
 
2208
 
 
2209
(defunk find-rule-id (rules. rune. ls$)
 
2210
  (cond ((endp rules.) nil)
 
2211
        ((equal (rule.rune (first rules.)) rune.)
 
2212
         (first rules.))
 
2213
        (t (find-rule-id (rest rules.) rune. ls$))))
 
2214
 
 
2215
(defunk pu-rule (x.) :inline
 
2216
  (if (is-legal-rule x. ls$) x.
 
2217
    (if (atom x.)
 
2218
        (er-process-update-arg "expected legal rule or rune")
 
2219
      (letk ((op. (car x.))
 
2220
             (rune. (cdr x.))
 
2221
             (opcd (find-fn-opcd op.)))
 
2222
        (if (=^ opcd (opcd-btm))
 
2223
            (er-process-update-arg "could not find rune base op.")
 
2224
          (letk ((rule. (find-rule-id (oper.rules op.) rune. ls$)))
 
2225
            (if (not rule.)
 
2226
                (er-process-update-arg "could not find rule for rune")
 
2227
              rule.)))))))
 
2228
 
 
2229
(defunk pu-free-var (x.) :inline
 
2230
  (if (not (is-legal-oper x. ls$))
 
2231
      (er-process-update-arg "expected legal free var. name")
 
2232
    (if (/=^ (oper.bound x.) (node-btm))
 
2233
        (er-process-update-arg "expected free var. to be unbound")
 
2234
      x.)))
 
2235
 
 
2236
(defunk pu-signature-node (x.) :inline
 
2237
  (if (not (is-legal-sig x.))
 
2238
      (er-process-update-arg "expected legal node signature")
 
2239
    (letk ((n. (signature-to-node x. ls$)))
 
2240
      (if (= n. (node-btm))
 
2241
          (er-process-update-arg "expected signature to define existing promoted node")
 
2242
        n.))))
 
2243
 
 
2244
(defunk pu-sieves (x.) :inline
 
2245
  (if (legal-sieves x.) x. 
 
2246
    (er-process-update-arg "expected well-formed list of sieves")))
 
2247
 
 
2248
(defunk pu-trace-mark (x.) :inline
 
2249
  (if (is-trace-mark x.) x. 
 
2250
    (er-process-update-arg "expected t/nil, :all, or symbol-list for trace mark")))
 
2251
 
 
2252
(defunk set-var-bound (var node) :inline
 
2253
  (letk ((ls$ (oper.set-bound var node))
 
2254
         (ls$ (oper.set-next-stk var (get-var-chg-stk ls$)))
 
2255
         (ls$ (set-var-chg-stk var ls$)))
 
2256
    ls$))
 
2257
 
 
2258
(defunk process-update (upd. ls$)
 
2259
  (if (not (true-listp upd.))
 
2260
      (er-process-update "expected update to be a true list")
 
2261
    (letk ((cmd. (first upd.))
 
2262
           (a1. (second upd.))
 
2263
           (a2. (third upd.)))
 
2264
      (case cmd.
 
2265
            (:set-var-bound
 
2266
             (set-var-bound (pu-free-var a1.) (pu-signature-node a2.)))
 
2267
            (:set-rule-sieves
 
2268
             (letk ((sieves. ls$ (install-sieves (pu-sieves a2.) ls$)))
 
2269
               (rule.set-sieves (pu-rule a1.) sieves.)))
 
2270
            (:set-rule-enabled
 
2271
             (rule.set-enabled (pu-rule a1.) (pu-bool a2.)))
 
2272
            (:set-rule-ctr
 
2273
             (rule.set-ctr (pu-rule a1.) (pu-nat a2. 0 nil)))
 
2274
            (:set-node-step
 
2275
             (set-node-step (pu-nat a1. 1 (maximum-array-size)) ls$))
 
2276
            (:set-node-limit
 
2277
             (set-node-limit (pu-nat a1. 1 (maximum-array-size)) ls$))
 
2278
            (:change-rule-order
 
2279
             (letk ((rule (pu-rule a1.))
 
2280
                    (op (rule.op rule))
 
2281
                    (pos. (pu-nat a2. 0 nil)))
 
2282
               (oper.set-rules op (move-rule (oper.rules op) rule pos.))))
 
2283
            (:set-rule-traced
 
2284
             (rule.set-traced (pu-rule a1.) (pu-trace-mark a2.)))
 
2285
            (:set-user-mark
 
2286
             (node.set-user-mark (pu-signature-node a1.) (pu-bool a2.)))
 
2287
            (t (er-process-update "illegal command encountered in update"))))))
 
2288
 
 
2289
(defunk process-updates (updates. ls$)
 
2290
  (if (atom updates.) ls$
 
2291
    (letk ((ls$ (process-update (first updates.) ls$)))
 
2292
      (process-updates (rest updates.) ls$))))
 
2293
 
 
2294
(defunk maximum-p-fn-count (1- (expt 2 19)))
 
2295
 
 
2296
(mutual-recursionk
 
2297
(defunk node-aux-cnt (x typ. ls$)
 
2298
  (letk ((opcd (node.opcd x)))
 
2299
    (cond ((=^ opcd (opcd-quote))
 
2300
           (if (not (eq typ. :quote-fns)) 0
 
2301
             (mask^ (fn-count-evg (qobj.obj (node.arg x 0)))
 
2302
                    (maximum-p-fn-count))))
 
2303
          ((opcd.is-var opcd) (if (eq typ. :vars) 1 0))
 
2304
          (t (+^ (if (eq typ. :fns) 1 0)
 
2305
                 (args-aux-cnt x (opcd.narg opcd) 0 typ. 0 ls$))))))
 
2306
 
 
2307
(defunk args-aux-cnt (x n i typ. r ls$)
 
2308
  (if (zp n) r
 
2309
    (letk ((r (+^ r (node-aux-cnt (node.arg x i) typ. ls$))))
 
2310
      (args-aux-cnt x (1-^ n) (1+^ i) typ. r ls$))))
 
2311
)
 
2312
 
 
2313
(defunk node-var-cnt (x) :inline
 
2314
  (node-aux-cnt x :vars ls$))
 
2315
 
 
2316
(defunk node-fn-cnt (x) :inline
 
2317
  (node-aux-cnt x :fns ls$))
 
2318
 
 
2319
(defunk node-q-fn-cnt (x) :inline
 
2320
  (node-aux-cnt x :quote-fns ls$))
 
2321
 
 
2322
(mutual-recursionk
 
2323
(defunk lex-order (x y ls$)
 
2324
  (letk ((opcd-x (node.opcd x))
 
2325
         (opcd-y (node.opcd y)))
 
2326
    (or (<^ opcd-x opcd-y)
 
2327
        (and (=^ opcd-x opcd-y)
 
2328
             (if (=^ opcd-x (opcd-quote))
 
2329
                 (letk ((x-o. (qobj.obj (node.arg x 0)))
 
2330
                        (y-o. (qobj.obj (node.arg y 0))))
 
2331
                   (and (not (equal x-o. y-o.))
 
2332
                        (lexorder x-o. y-o.)))
 
2333
               (args-order (opcd.narg opcd-x) 0 x y ls$))))))
 
2334
 
 
2335
(defunk args-order (n i x y ls$)
 
2336
  (cond ((zp n) nil)
 
2337
        ((lex-order (node.arg x i) (node.arg y i) ls$) t)
 
2338
        ((not (node= (node.arg x i) (node.arg y i))) nil)
 
2339
        (t (args-order (1-^ n) (1+^ i) x y ls$))))
 
2340
)
 
2341
 
 
2342
(defunk term-order (x y ls$)
 
2343
  (and (/=^ x (node-btm))
 
2344
       (/=^ y (node-btm))
 
2345
       (letk ((x-size (node.size x))
 
2346
              (y-size (node.size y)))
 
2347
         (if (and (/=^ x-size (size-btm))
 
2348
                  (/=^ y-size (size-btm))
 
2349
                  (/=^ x-size y-size))
 
2350
             (<^ x-size y-size)
 
2351
           (letk ((x-cnt (node-var-cnt x))
 
2352
                  (y-cnt (node-var-cnt y)))
 
2353
             (or (<^ x-cnt y-cnt)
 
2354
                 (and (=^ x-cnt y-cnt)
 
2355
                      (letk ((x-cnt (node-fn-cnt x))
 
2356
                             (y-cnt (node-fn-cnt y)))
 
2357
                        (or (<^ x-cnt y-cnt)
 
2358
                            (and (=^ x-cnt y-cnt)
 
2359
                                 (letk ((x-cnt (node-q-fn-cnt x))
 
2360
                                        (y-cnt (node-q-fn-cnt y)))
 
2361
                                   (or (<^ x-cnt y-cnt)
 
2362
                                       (and (=^ x-cnt y-cnt)
 
2363
                                            (lex-order x y ls$))))))))))))))
 
2364
 
 
2365
(defunk bdd< (x y op-bv) :inline
 
2366
  (and (/=^ x (node-btm))
 
2367
       (/=^ y (node-btm))
 
2368
       (letk ((op-x (node.opcd x)))
 
2369
         (and (=^ op-x op-bv)
 
2370
              (letk ((op-y (node.opcd y)))
 
2371
                (cond ((=^ op-y op-bv)
 
2372
                       (node< x y))
 
2373
                      ((opcd.is-if op-y)
 
2374
                       (letk ((y (node.arg y 0))
 
2375
                              (op-y (node.opcd y)))
 
2376
                         (and (=^ op-y op-bv)
 
2377
                              (node< x y))))
 
2378
                      (t t)))))))
 
2379
 
 
2380
(defunk bdd-order-p (x y ls$ us$)
 
2381
  (letk ((op-bv1 (get-opcd-bv us$))
 
2382
         (op-bv2 (if (=^ op-bv1 (opcd-btm)) (find-fn-opcd 'bv) op-bv1)))
 
2383
    (if (=^ op-bv2 (opcd-btm))
 
2384
        (mv (er hard 'bdd-order-p "could not locate opcd for operator bv") us$)
 
2385
      (letk ((us$ (if (=^ op-bv1 (opcd-btm)) (set-opcd-bv op-bv2 us$) us$)))
 
2386
        (mv (bdd< x y op-bv2) us$)))))
 
2387
 
 
2388
(defunk bound-node (x) :inline
 
2389
  (letk ((opcd (node.opcd x)))
 
2390
    (if (opcd.is-var opcd)
 
2391
        (oper.bound (opcd.index opcd))
 
2392
      (node-btm))))
 
2393
 
 
2394
(defunk create-sieve-arg (x ls$)
 
2395
  (letk ((rep (node.rep x))
 
2396
         (bound (bound-node x)))
 
2397
    (cond ((/=^ bound (node-btm)) (node-to-term bound))
 
2398
          ((>^ rep 0)             (node-to-term rep))
 
2399
          (t                      (node-to-term x)))))
 
2400
 
 
2401
(defunk create-sieve-args (args. ls$)
 
2402
  (if (endp args.) ()
 
2403
    (cons (create-sieve-arg (first args.) ls$)
 
2404
          (create-sieve-args (rest args.) ls$))))
 
2405
 
 
2406
(defunk process-fast-sieve (sieve.) :inline
 
2407
  (case (first sieve.)
 
2408
        (:quotep (=^ (node.opcd (bound-node (second sieve.)))
 
2409
                     (opcd-quote)))
 
2410
        (:non-nilp (non-nilp (bound-node (second sieve.))))
 
2411
        (:boolp (is-boolp (bound-node (second sieve.))))
 
2412
        (:termordp (term-order (bound-node (second sieve.))
 
2413
                               (bound-node (third sieve.))
 
2414
                               ls$))
 
2415
        (:nodeordp (node< (bound-node (second sieve.))
 
2416
                          (bound-node (third sieve.))))
 
2417
        (t :no-rslt)))
 
2418
 
 
2419
(defunk process-slow-sieve (sieve. x ls$ us$)
 
2420
  (case (first sieve.)
 
2421
        (:bddordp (bdd-order-p (bound-node (second sieve.))
 
2422
                               (bound-node (third sieve.))
 
2423
                               ls$ us$))
 
2424
        (:case-split (generate-case-split sieve. x ls$ us$))
 
2425
        (t (mv () us$))))
 
2426
 
 
2427
(defunk process-user-sieve (sieve. r ls$ us$)
 
2428
  (if (not (eq (first sieve.) :funcall))
 
2429
      (mv nil () us$)
 
2430
    (letk ((rune. (rule.rune r))
 
2431
           (args. (create-sieve-args (rest sieve.) ls$)))
 
2432
      (if (not (and (consp (first args.))
 
2433
                    (eq (first (first args.)) 'quote)
 
2434
                    (symbolp (second (first args.)))))
 
2435
          (mv (er hard 'process-sieve
 
2436
                  "In applying ~x0: first argument to :funcall sieve should be quoted name of function: ~x1"
 
2437
                  rune. (first args.))
 
2438
              () us$)
 
2439
        (letk ((op. (second (first args.)))
 
2440
               (args. (rest args.))
 
2441
               (st. (get-dynamic-user-state-obj us$))
 
2442
               (wrld. (get-current-world ls$))
 
2443
               (erp. val. (funcall op. (list args. st. wrld.))))
 
2444
          (cond (erp.
 
2445
                 (mv (er hard 'process-sieve
 
2446
                         "In applying ~x0: encountered error in evaluating sieve: ~x1"
 
2447
                         rune. sieve.)
 
2448
                     () us$))
 
2449
                ((is-boolean val.)
 
2450
                 (mv val. () us$))
 
2451
                ((and (consp val.)
 
2452
                      (true-listp val.)
 
2453
                      (= (length val.) 3))
 
2454
                 (letk ((us$ (set-dynamic-user-state-obj (third val.) us$)))
 
2455
                       (mv (first val.) (second val.) us$)))
 
2456
                (t
 
2457
                 (mv (er hard 'process-sieve
 
2458
                         "In applying ~x0: expected result from ~x1 must either be boolean or a triple"
 
2459
                         rune. op.)
 
2460
                     () us$))))))))
 
2461
 
 
2462
(defunk process-sieve (sieve. x r ls$ us$)
 
2463
  (letk ((rslt. (process-fast-sieve sieve.)))
 
2464
    (if (is-boolean rslt.) (mv rslt. () us$)
 
2465
      (letk ((upds. us$ (process-slow-sieve sieve. x ls$ us$)))
 
2466
        (if upds. (mv t (and (consp upds.) upds.) us$)
 
2467
          (process-user-sieve sieve. r ls$ us$))))))
 
2468
 
 
2469
(defunk process-each-sieve (sieves. x r ls$ us$)
 
2470
  (if (endp sieves.)
 
2471
      (mv t ls$ us$)
 
2472
    (letk ((ok. upds. us$ (process-sieve (first sieves.) x r ls$ us$))
 
2473
           (ls$ (process-updates upds. ls$)))
 
2474
      (if (not ok.)
 
2475
          (mv nil ls$ us$)
 
2476
        (process-each-sieve (rest sieves.) x r ls$ us$)))))
 
2477
 
 
2478
(defunk process-sieves (x r) :inline
 
2479
  (process-each-sieve (rule.sieves r) x r ls$ us$))
 
2480
 
 
2481
 
 
2482
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
2483
#| kernel unification and rewrite rule application functions                  |#
 
2484
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
2485
 
 
2486
(defunk pop-var-chg-stk-fn (stk ls$)
 
2487
  (if (=^ stk (opcd-btm))
 
2488
      (set-var-chg-stk (opcd-btm) ls$)
 
2489
    (letk ((nxt (oper.next-stk stk))
 
2490
           (ls$ (oper.set-bound stk (node-btm))))
 
2491
      (pop-var-chg-stk-fn nxt ls$))))
 
2492
 
 
2493
(defunk pop-var-chg-stk () :inline
 
2494
  (letk ((stk (get-var-chg-stk ls$)))
 
2495
    (if (=^ stk (opcd-btm)) ls$
 
2496
      (pop-var-chg-stk-fn stk ls$))))
 
2497
 
 
2498
(defunk trace-rule-app (traced. rune. x) :inline
 
2499
  (if (not traced.) ls$
 
2500
    (prog2$ (cw ">>>~p0~%" rune.)
 
2501
      (if (eq traced. t) ls$
 
2502
        (prog2$ (cw "~p0~%" (prune-node-term x)) ls$)))))
 
2503
 
 
2504
(mutual-recursionk
 
2505
(defunk subst-node (y ls$)
 
2506
  (assert (/=^ y (node-btm))
 
2507
   (letk ((opcd-y (node.opcd y)))
 
2508
     (cond 
 
2509
      ((=^ opcd-y (opcd-quote))
 
2510
       (mv^ y ls$))
 
2511
      ((opcd.is-var opcd-y)
 
2512
       (letk ((node (oper.bound (opcd.index opcd-y)))
 
2513
              (node (if (=^ node (node-btm)) y node)))
 
2514
         (assert (or (promoted node)
 
2515
                     (list y node (node-to-term y) (node-to-term node)))
 
2516
           (mv^ node ls$))))
 
2517
      (t
 
2518
       (letk ((x ls$ (allocate-node opcd-y (size-btm) nil ls$))
 
2519
              (ls$ (subst-args (opcd.narg opcd-y) y 0 x ls$)))
 
2520
         (mv^ x ls$)))))))
 
2521
 
 
2522
(defunk subst-args (narg y i x ls$)
 
2523
  (if (zp narg) ls$
 
2524
    (letk ((a ls$ (subst-node (node.arg y i) ls$))
 
2525
           (ls$ (node.set-arg x i a)))
 
2526
      (subst-args (1-^ narg) y (1+^ i) x ls$))))
 
2527
)
 
2528
 
 
2529
(defunk 1way-unify-var (x opcd-y ls$)
 
2530
  (letk ((op-y (opcd.index opcd-y))
 
2531
         (bound (oper.bound op-y)))
 
2532
    (if (=^ bound (node-btm))
 
2533
        (letk ((ls$ (set-var-bound op-y x))) (mv t ls$))
 
2534
      (mv (node= bound x) ls$))))
 
2535
 
 
2536
(defunk 1way-unify-obj (x. opcd-y y ls$)
 
2537
  (cond
 
2538
   ((=^ opcd-y (opcd-cons))
 
2539
    (if (atom x.) (mv nil ls$)
 
2540
      (letk ((y0 (node.arg y 0))
 
2541
             (y1 (node.arg y 1))
 
2542
             (op0 (node.opcd y0))
 
2543
             (op1 (node.opcd y1))
 
2544
             (match. ls$ (1way-unify-obj (car x.) op0 y0 ls$)))
 
2545
        (if (not match.) (mv nil ls$)
 
2546
          (1way-unify-obj (cdr x.) op1 y1 ls$)))))
 
2547
   ((opcd.is-var opcd-y)
 
2548
    (letk ((x ls$ (create-quote x.)))
 
2549
      (1way-unify-var x opcd-y ls$)))
 
2550
   (t (mv nil ls$))))
 
2551
 
 
2552
; The following function performs one-way unification of x with y (i.e. match x
 
2553
; with y where all variables in x are treated as ground).
 
2554
 
 
2555
(defunk 1way-unify (x y n i args-p. ls$)
 
2556
  (if args-p.
 
2557
      (if (zp n) (mv t ls$)
 
2558
        (letk ((match. ls$ (1way-unify (node.arg x i)
 
2559
                                       (node.arg y i)
 
2560
                                       0 0 nil ls$)))
 
2561
          (if (not match.) (mv nil ls$)
 
2562
            (1way-unify x y (1-^ n) (1+^ i) t ls$))))
 
2563
    (assert (and (/=^ x (node-btm)) (/=^ y (node-btm)))
 
2564
     (letk ((opcd-y (node.opcd y))
 
2565
            (opcd-x (node.opcd x)))
 
2566
       (cond 
 
2567
        ((opcd.is-var opcd-y)
 
2568
         (1way-unify-var x opcd-y ls$))
 
2569
        ((=^ opcd-y (opcd-quote))
 
2570
         (mv (=^ x y) ls$))
 
2571
        ((=^ opcd-x (opcd-quote))
 
2572
         (1way-unify-obj (qobj.obj (node.arg x 0)) opcd-y y ls$))
 
2573
        ((/=^ opcd-x opcd-y)
 
2574
         (mv nil ls$))
 
2575
        (t
 
2576
         (1way-unify x y (opcd.narg opcd-x) 0 t ls$)))))))
 
2577
 
 
2578
(defunk unify-args (x y narg) :inline
 
2579
  (1way-unify x y narg 0 t ls$))
 
2580
 
 
2581
(defunk maximum-rule-ctr (- (expt 2 28) 2))
 
2582
 
 
2583
(defunk incr-rule-ctr (r) :inline
 
2584
  (letk ((ctr (rule.ctr r))
 
2585
         (ctr (if (<^ ctr (maximum-rule-ctr)) (1+^ ctr) ctr)))
 
2586
    (rule.set-ctr r ctr)))
 
2587
 
 
2588
(defunk incr-rule-tryctr (r) :inline
 
2589
  (letk ((ctr (rule.tryctr r))
 
2590
         (ctr (if (<^ ctr (maximum-rule-ctr)) (1+^ ctr) ctr)))
 
2591
    (rule.set-tryctr r ctr)))
 
2592
 
 
2593
(defunk loop-stk-incr () (floor (static-param) 8))
 
2594
 
 
2595
(defunk push-loop-stack (r x ls$)
 
2596
  (letk ((l (get-loop-stk-top ls$))
 
2597
         (ls$ (ensure-loop l (loop-stk-incr)))
 
2598
         (ls$ (loop.set-rule l r))
 
2599
         (ls$ (loop.set-node l x))
 
2600
         (ls$ (set-loop-stk-top (1+^ l) ls$)))
 
2601
    ls$))
 
2602
 
 
2603
(defunk oper-rule-match (x r ls$ us$)
 
2604
  (if (not (rule.enabled r))
 
2605
      (mv nil ls$ us$)
 
2606
    (letk ((match. ls$ us$ (process-sieves x r)))
 
2607
      (if (not match.)
 
2608
          (mv nil ls$ us$)
 
2609
        (letk ((ls$ (incr-rule-ctr r)))
 
2610
          (mv t ls$ us$))))))
 
2611
 
 
2612
(defunk rule-matches (x r narg ls$ us$)
 
2613
  (letk ((ls$ (incr-rule-tryctr r))
 
2614
         (match. ls$ (unify-args x (rule.lhs r) narg)))
 
2615
    (if (not match.)
 
2616
        (mv nil ls$ us$)
 
2617
      (letk ((match. ls$ us$ (process-sieves x r)))
 
2618
        (if (not match.)
 
2619
            (mv nil ls$ us$)
 
2620
          (letk ((ls$ (incr-rule-ctr r)))
 
2621
            (mv t ls$ us$)))))))
 
2622
 
 
2623
(defunk args-are-quotes (n i x ls$)
 
2624
  (or (zp n)
 
2625
      (and (=^ (node.opcd (node.arg x i)) (opcd-quote))
 
2626
           (args-are-quotes (1-^ n) (1+^ i) x ls$))))
 
2627
 
 
2628
(defunk args-quote-objs (n i x ls$)
 
2629
  (if (zp n) ()
 
2630
    (cons (qobj.obj (node.arg (node.arg x i) 0))
 
2631
          (args-quote-objs (1-^ n) (1+^ i) x ls$))))
 
2632
 
 
2633
(defunk apply-exec (op x ls$)
 
2634
  (letk ((args. (args-quote-objs (oper.narg op) 0 x ls$))
 
2635
         (erp. val. (funcall (oper.name op) args.)))
 
2636
    (if erp. (mv^ x ls$)
 
2637
      (letk ((ls$ (incr-rule-ctr (oper.exec op)))
 
2638
             (y ls$ (install-quote val. ls$)))
 
2639
        (mv^ y ls$)))))
 
2640
 
 
2641
(defunk exec-counterpart (opcd x ls$ us$)
 
2642
  (letk ((op (opcd.index opcd))
 
2643
         (narg (opcd.narg opcd))
 
2644
         (exec (oper.exec op)))
 
2645
    (if (not (args-are-quotes narg 0 x ls$))
 
2646
        (mv^ x (dcv-empty) nil ls$ us$)
 
2647
      (letk ((go. ls$ us$ (oper-rule-match x exec ls$ us$)))
 
2648
        (if (not go.)
 
2649
            (mv^ x (dcv-empty) nil ls$ us$)
 
2650
          (letk ((rslt ls$ (apply-exec op x ls$)))
 
2651
            (mv^ rslt (dcv-empty) nil ls$ us$)))))))
 
2652
 
 
2653
(defunk node/= (x y) :inline
 
2654
  (and (/=^ x y)
 
2655
       (or (and (=^ (node.opcd x) (opcd-quote))
 
2656
                (=^ (node.opcd y) (opcd-quote)))
 
2657
           (and (=^ x (node-nil)) (non-nilp y))
 
2658
           (and (=^ y (node-nil)) (non-nilp x)))))
 
2659
 
 
2660
(defunk built-in-rewrites (opcd x) :inline
 
2661
  (cond ((opcd.is-equal opcd)
 
2662
         (letk ((lhs (node.arg x 0))
 
2663
                (rhs (node.arg x 1)))
 
2664
           (cond ((node= lhs rhs) (node-t))
 
2665
                 ((node/= lhs rhs) (node-nil))
 
2666
                 (t x))))
 
2667
        ((opcd.is-if opcd)
 
2668
         (letk ((tst (node.arg x 0))
 
2669
                (tbr (node.arg x 1))
 
2670
                (fbr (node.arg x 2)))
 
2671
           (cond ((=^ tst (node-nil)) fbr)
 
2672
                 ((non-nilp tst) tbr)
 
2673
                 ((node= tbr fbr) tbr)
 
2674
                 (t x))))
 
2675
        (t x)))
 
2676
 
 
2677
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
2678
#| main kernel rewrite loop functions (rewrite-node is entry point)           |#
 
2679
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
2680
 
 
2681
(defunk depth-exceeded () :inline
 
2682
  (zp (get-current-clock ls$)))
 
2683
 
 
2684
(defunk space-exceeded () :inline
 
2685
  (>^ (+^ (get-num-trans-nodes ls$) (get-num-of-nodes ls$))
 
2686
      (get-node-limit ls$)))
 
2687
 
 
2688
; compute-if-direction can return one of the following:
 
2689
;  nil      -- if-test has rewritten to nil, only rewrite false branch
 
2690
;  t        -- if-test has rewritten to non-nil, only rewrite true branch
 
2691
; :both     -- assume context on both branches
 
2692
; :only-t   -- assume context only on true branch
 
2693
; :only-nil -- assume context only on false branch
 
2694
; :neither  -- do not assume context on either branch
 
2695
 
 
2696
(defunk compute-if-direction (tst+) :inline
 
2697
  (cond ((=^ tst+ (node-nil)) nil)
 
2698
        ((non-nilp tst+) t)
 
2699
        (t (letk ((op (opcd.index (node.opcd tst+))))
 
2700
             (if (oper.assume-tbr op)
 
2701
                 (if (oper.assume-fbr op) :both :only-t)
 
2702
               (if (oper.assume-fbr op) :only-nil :neither))))))
 
2703
 
 
2704
(defunk drop-dctx-dcv (dcx dcv) :inline
 
2705
  (if (>=^ dcx (dctx-max-rep)) dcv (logand^ dcv (lognot^ (ash^ 1 dcx)))))
 
2706
 
 
2707
(mutual-recursionk
 
2708
(defunk promote-node (x ls$)
 
2709
  (if (promoted x) (mv^ x ls$)
 
2710
    (letk ((ls$ (promote-args (opcd.narg (node.opcd x)) 0 x ls$)))
 
2711
      (install-node x t ls$))))
 
2712
 
 
2713
(defunk promote-args (n i x ls$)
 
2714
  (if (zp n) ls$
 
2715
    (letk ((a ls$ (promote-node (node.arg x i) ls$))
 
2716
           (ls$ (node.set-arg x i a)))
 
2717
      (promote-args (1-^ n) (1+^ i) x ls$))))
 
2718
)
 
2719
 
 
2720
(defunk well-formed-context-equation (tst) :inline
 
2721
  (and (opcd.is-equal (node.opcd tst))
 
2722
       (not (=^ (node.opcd (node.arg tst 0)) (opcd-quote)))))
 
2723
 
 
2724
(defunk create-equal-tst-for-case (tst cas. ls$)
 
2725
  (letk ((opcd (node.opcd tst)))
 
2726
    (assert (/=^ opcd (opcd-quote))
 
2727
      (if (and cas. (or (opcd.is-equal opcd)
 
2728
                        (not (oper.boolp (opcd.index opcd)))))
 
2729
          (mv^ tst ls$)
 
2730
        (letk ((x ls$ (allocate-node (opcd-equal) (size-btm) nil ls$))
 
2731
               (ls$ (node.set-arg x 0 tst))
 
2732
               (rhs (if cas. (node-t) (node-nil)))
 
2733
               (ls$ (node.set-arg x 1 rhs)))
 
2734
          (promote-node x ls$))))))
 
2735
 
 
2736
(defunk push-new-context (tst ls$)
 
2737
  (letk ((top (get-curr-ctx-top ls$)))
 
2738
    (if (>=^ top (length-curr-ctx-stk ls$))
 
2739
        (error "Maximum number of context stack nodes exceeded. ~
 
2740
                The user may wish to adjust the maximum node bound for KAS."
 
2741
               tst (mv^ top ls$))
 
2742
      (letk ((ls$ (set-curr-ctx-stk top tst ls$))
 
2743
             (ls$ (set-curr-ctx-top (1+^ top) ls$)))
 
2744
        (mv^ top ls$)))))
 
2745
 
 
2746
(defunk pop-new-context (ls$)
 
2747
  (set-curr-ctx-top (1-^ (get-curr-ctx-top ls$)) ls$))
 
2748
 
 
2749
(mutual-recursionk
 
2750
(defunk is-subterm (x y ls$)
 
2751
  (or (node= x y)
 
2752
      (letk ((opcd (node.opcd y)))
 
2753
        (and (/=^ opcd (opcd-quote))
 
2754
             (not (opcd.is-var opcd))
 
2755
             (is-subterm-args x y (opcd.narg opcd) 0 ls$)))))
 
2756
 
 
2757
(defunk is-subterm-args (x y n i ls$)
 
2758
  (and (not (zp n))
 
2759
       (or (is-subterm x (node.arg y i) ls$)
 
2760
           (is-subterm-args x y (1-^ n) (1+^ i) ls$))))
 
2761
)
 
2762
 
 
2763
(mutual-recursionk
 
2764
(defunk mark-node-in-ctx (x dcv ls$)
 
2765
  (letk ((opcd (node.opcd x)))
 
2766
    (if (=^ opcd (opcd-quote)) ls$
 
2767
      (letk ((ls$ (if (node.in-ctx x) ls$
 
2768
                    (letk ((ls$ (create-new-undo (node-btm) dcv x (dcv-btm) ls$))
 
2769
                           (ls$ (node.set-in-ctx x t)))
 
2770
                      ls$))))
 
2771
        (mark-args-in-ctx (opcd.narg opcd) 0 x dcv ls$)))))
 
2772
 
 
2773
(defunk mark-args-in-ctx (n i x dcv ls$)
 
2774
  (if (zp n) ls$
 
2775
    (letk ((ls$ (mark-node-in-ctx (node.arg x i) dcv ls$)))
 
2776
      (mark-args-in-ctx (1-^ n) (1+^ i) x dcv ls$))))
 
2777
)
 
2778
 
 
2779
(defunk mark-subnodes-in-ctx (x dcv ls$)
 
2780
  (letk ((opcd (node.opcd x)))
 
2781
    (if (=^ opcd (opcd-quote)) ls$
 
2782
      (mark-args-in-ctx (opcd.narg opcd) 0 x dcv ls$))))
 
2783
 
 
2784
(mutual-recursionk
 
2785
(defunk rewrite-hyps-args (n i h dcv ls$ us$)
 
2786
  (if (zp n) (mv t dcv ls$ us$)
 
2787
    (letk ((a dcv+ ls$ us$ (rewrite-node (node.arg h i) ls$ us$)))
 
2788
      (if (not (non-nilp a)) (mv nil (dcv-empty) ls$ us$)
 
2789
        (rewrite-hyps-args (1-^ n) (1+^ i) h (logior^ dcv dcv+) ls$ us$)))))
 
2790
 
 
2791
(defunk rewrite-hyps (h ls$ us$)
 
2792
  (if (=^ h (node-t)) (mv t (dcv-empty) ls$ us$)
 
2793
    (letk ((bc (get-bchain-limit ls$)))
 
2794
      (if (zp bc) (mv nil (dcv-empty) ls$ us$)
 
2795
        (letk ((ls$ (set-bchain-limit (1-^ bc) ls$))
 
2796
               (op (node.opcd h))
 
2797
               (pass. dcv ls$ us$ (rewrite-hyps-args (opcd.narg op) 0 h (dcv-empty) ls$ us$))
 
2798
               (ls$ (set-bchain-limit bc ls$)))
 
2799
          (mv pass. dcv ls$ us$))))))
 
2800
 
 
2801
(defunk apply-rule (r x narg ls$ us$)
 
2802
  (if (not (rule.enabled r))
 
2803
      (mv^ x (dcv-empty) nil ls$ us$)
 
2804
    (letk ((match. ls$ us$ (rule-matches x r narg ls$ us$)))
 
2805
      (if (not match.)
 
2806
          (letk ((ls$ (pop-var-chg-stk)))
 
2807
            (mv^ x (dcv-empty) nil ls$ us$))
 
2808
        (letk ((ls$ (push-loop-stack r x ls$))
 
2809
               (h+ ls$ (subst-node (rule.hyps r) ls$))
 
2810
               (y ls$ (subst-node (rule.rhs r) ls$))
 
2811
               (ls$ (pop-var-chg-stk))
 
2812
               (pass. dcv ls$ us$ (rewrite-hyps h+ ls$ us$)))
 
2813
          (if (not pass.)
 
2814
              (mv^ x (dcv-empty) t ls$ us$)
 
2815
            (letk ((ls$ (trace-rule-app (rule.traced r) (rule.rune r) x)))
 
2816
              (mv^ y dcv nil ls$ us$))))))))
 
2817
 
 
2818
(defunk apply-rules (rules. x narg cond-failed. ls$ us$)
 
2819
  (if (endp rules.)
 
2820
      (mv^ x (dcv-empty) cond-failed. ls$ us$)
 
2821
    (letk ((y dcv c-f. ls$ us$ (apply-rule (first rules.) x narg ls$ us$))
 
2822
           (cond-failed. (or c-f. cond-failed.)))
 
2823
      (if (/=^ y x) 
 
2824
          (mv^ y dcv cond-failed. ls$ us$)
 
2825
        (apply-rules (rest rules.) x narg cond-failed. ls$ us$)))))
 
2826
 
 
2827
(defunk apply-rewrite (opcd x) :inline
 
2828
  (apply-rules (oper.rules (opcd.index opcd)) x (opcd.narg opcd) nil ls$ us$))
 
2829
 
 
2830
(defunk rewrite-step (opcd x ls$ us$)
 
2831
  (letk ((y (built-in-rewrites opcd x)))
 
2832
    (if (/=^ y x) (mv^ y (dcv-empty) nil ls$ us$)
 
2833
      (letk ((y dcv c-f. ls$ us$ (apply-rewrite opcd x)))
 
2834
        (if (/=^ y x) (mv^ y dcv c-f. ls$ us$)
 
2835
          (exec-counterpart opcd x ls$ us$))))))
 
2836
 
 
2837
(defunk decr-and-rewrite (x ls$ us$)
 
2838
  (letk ((clk (get-current-clock ls$))
 
2839
         (ls$ (set-current-clock (1-^ clk) ls$))
 
2840
         (x+ dcv ls$ us$ (rewrite-node x ls$ us$))
 
2841
         (ls$ (set-current-clock clk ls$)))
 
2842
    (mv^ x+ dcv ls$ us$)))
 
2843
 
 
2844
(defunk extend-context (tst dcv ndx ls$ us$)
 
2845
  (if (not (well-formed-context-equation tst))
 
2846
      (mv t ls$ us$)
 
2847
    (letk ((nxt (get-next-extend-age ls$))
 
2848
           (ls$ (set-current-age nxt ls$))
 
2849
           (ls$ (set-next-extend-age (1+^ nxt) ls$))
 
2850
           (lhs (node.arg tst 0))
 
2851
           (rhs (node.arg tst 1))
 
2852
           (ls$ (update-rep lhs rhs dcv 1 ls$)))
 
2853
      (if (not (get-allow-context-reduction ls$)) (mv t ls$ us$)
 
2854
        (letk ((ls$ (mark-subnodes-in-ctx lhs dcv ls$))
 
2855
               (ls$ (mark-node-in-ctx rhs dcv ls$)))
 
2856
          (if (not (node.in-ctx lhs)) (mv t ls$ us$)
 
2857
            (rewrite-context (get-curr-ctx-top ls$) lhs ndx ls$ us$)))))))
 
2858
 
 
2859
(defunk rewrite-context (i lhs ndx ls$ us$)
 
2860
  (if (=^ i 0) (mv t ls$ us$)
 
2861
    (letk ((i (1-^ i)))
 
2862
      (if (=^ i ndx) (rewrite-context i lhs ndx ls$ us$)
 
2863
        (letk ((top (get-curr-ctx-stk i ls$)))      
 
2864
          (if (not (and (well-formed-context-equation top)
 
2865
                        (is-subterm lhs top ls$)))
 
2866
              (rewrite-context i lhs ndx ls$ us$)
 
2867
            (letk ((top-lhs (node.arg top 0))
 
2868
                   (tmp (node.rep top-lhs)) 
 
2869
                   (ls$ (node.set-rep top-lhs (node-btm)))
 
2870
                   (top+ dcv ls$ us$ (decr-and-rewrite top ls$ us$))
 
2871
                   (ls$ (node.set-rep top-lhs tmp)))
 
2872
              (cond ((=^ top+ (node-nil))
 
2873
                     (mv nil ls$ us$))
 
2874
                    ((node= top+ top) 
 
2875
                     (rewrite-context i lhs ndx ls$ us$))
 
2876
                    (t
 
2877
                     (letk ((ls$ (set-curr-ctx-stk i top+ ls$))
 
2878
                            (ls$ (create-new-undo (node-btm) dcv top i ls$))
 
2879
                            (vald. ls$ us$ (extend-context top+ dcv i ls$ us$)))
 
2880
                       (if (not vald.) (mv nil ls$ us$)
 
2881
                         (rewrite-context i lhs ndx ls$ us$))))))))))))
 
2882
 
 
2883
(defunk rewrite-case (cas. brn tst+ dir. ls$ us$)
 
2884
  (cond 
 
2885
   ((and (not (eq dir. cas.))
 
2886
         (is-boolean dir.))
 
2887
    (mv^ brn (dcv-empty) ls$ us$))  ; DO NOT REWRITE branch
 
2888
   ((or (eq dir. cas.)
 
2889
        (eq dir. :neither)
 
2890
        (if cas. (eq dir. :only-nil) (eq dir. :only-t)))
 
2891
    (rewrite-node brn ls$ us$))     ; REWRITE branch with no test assumption
 
2892
   (t
 
2893
    (letk ((dcx- (get-current-dctx ls$))
 
2894
           (age (get-current-age ls$))
 
2895
           (dcx+ ls$ (create-new-dctx ls$))
 
2896
           (tst= ls$ (create-equal-tst-for-case tst+ cas. ls$)) 
 
2897
           (ndx ls$ (push-new-context tst= ls$))
 
2898
           (vald. ls$ us$ (extend-context tst= (ash^ 1 dcx+) ndx ls$ us$)))
 
2899
      (if (not vald.)
 
2900
          (letk ((ls$ (pop-new-context ls$))
 
2901
                 (ls$ (restore-previous-state dcx- dcx+ age ls$)))
 
2902
            (mv^ (node-btm) (dcv-empty) ls$ us$))
 
2903
        (letk ((node dcv ls$ us$ (rewrite-node brn ls$ us$))
 
2904
               (ls$ (pop-new-context ls$))
 
2905
               (ls$ (restore-previous-state dcx- dcx+ age ls$))
 
2906
               (dcv (drop-dctx-dcv dcx+ dcv)))
 
2907
          (assert (<=^ (max-in-dcv dcv) dcx-)
 
2908
            (mv^ node dcv ls$ us$))))))))
 
2909
 
 
2910
(defunk rewrite-args-if (x ls$ us$)
 
2911
  (letk ((tst (node.arg x 0))
 
2912
         (tbr (node.arg x 1))
 
2913
         (fbr (node.arg x 2))
 
2914
         (tst+ tst-dcv ls$ us$ (rewrite-node tst ls$ us$))
 
2915
         (dir. (compute-if-direction tst+))
 
2916
         (tbr+ tbr-dcv ls$ us$ (rewrite-case t tbr tst+ dir. ls$ us$))
 
2917
         (fbr+ fbr-dcv ls$ us$ (rewrite-case nil fbr tst+ dir. ls$ us$))
 
2918
         (no-tbr. (=^ tbr+ (node-btm)))
 
2919
         (no-fbr. (=^ fbr+ (node-btm)))
 
2920
         (tst+ (if no-tbr. (node-nil) (if no-fbr. (node-t) tst+)))
 
2921
         (tbr+ (if no-tbr. tbr tbr+))
 
2922
         (fbr+ (if no-fbr. fbr fbr+))
 
2923
         (ls$ (node.set-arg x 0 tst+))
 
2924
         (ls$ (node.set-arg x 1 tbr+))
 
2925
         (ls$ (node.set-arg x 2 fbr+))
 
2926
         (chgd. (or (/=^ tst+ tst) (/=^ tbr+ tbr) (/=^ fbr+ fbr))))
 
2927
    (mv chgd. (logior^ tst-dcv tbr-dcv fbr-dcv) ls$ us$)))
 
2928
 
 
2929
(defunk rewrite-args-op (n i x chgd. dcv ls$ us$)
 
2930
  (if (zp n) (mv chgd. dcv ls$ us$)
 
2931
    (letk ((a (node.arg x i))
 
2932
           (a+ dcv+ ls$ us$ (rewrite-node a ls$ us$))
 
2933
           (ls$ (node.set-arg x i a+))
 
2934
           (chgd. (or (/=^ a+ a) chgd.))
 
2935
           (dcv (logior^ dcv dcv+)))
 
2936
      (rewrite-args-op (1-^ n) (1+^ i) x chgd. dcv ls$ us$))))
 
2937
 
 
2938
(defunk rewrite-args-hide () :inline
 
2939
  (mv nil (dcv-empty) ls$ us$))
 
2940
 
 
2941
(defunk rewrite-args (opcd x ls$ us$)
 
2942
  (assert (temp-node x)
 
2943
   (cond ((opcd.is-if opcd)     (rewrite-args-if x ls$ us$))
 
2944
         ((=^ opcd (opcd-hide)) (rewrite-args-hide))
 
2945
         (t                     (rewrite-args-op (opcd.narg opcd) 0 x nil (dcv-empty) ls$ us$)))))
 
2946
 
 
2947
(defunk rewrite-node+ (x- opcd rep age ls$ us$)
 
2948
  (if (>^ rep 0)
 
2949
      (assert (and (promoted x-) (/=^ x- rep))
 
2950
       (letk ((x+ dcv ls$ us$ (decr-and-rewrite rep ls$ us$))
 
2951
              (dcv (logior^ (node.dcv x-) dcv))
 
2952
              (ls$ (update-rep x- x+ dcv 2 ls$)))
 
2953
         (mv^ x+ dcv ls$ us$)))
 
2954
    ;; /\ If we have a rep node, then rewrite the rep node and return the result, otherwise....
 
2955
    (letk ((x ls$ (install-node x- nil ls$))
 
2956
           (chgd. dcv1 ls$ us$ (rewrite-args opcd x ls$ us$)))
 
2957
      (if (and (/=^ rep (node-btm)) (not chgd.))
 
2958
          (assert (and (promoted x-) (/=^ x- rep))
 
2959
           (letk ((ls$ (update-rep x- (-^ age) (dcv-btm) 3 ls$)))
 
2960
             (mv^ x- (dcv-empty) ls$ us$)))
 
2961
        ;; /\ Rewrite the args and if the args have not changed and we were not marked to rewrite, then return original, otherwise... 
 
2962
        (letk ((x+ dcv2 cond-failed. ls$ us$ (rewrite-step opcd x ls$ us$)))
 
2963
          (if (/=^ x+ x)
 
2964
              (letk ((x+ dcv3 ls$ us$ (decr-and-rewrite x+ ls$ us$))
 
2965
                     (dcv (logior^ dcv1 dcv2 dcv3))
 
2966
                     (ls$ (update-rep x- x+ dcv 4 ls$))
 
2967
                     (ls$ (update-rep x x+ dcv 5 ls$)))
 
2968
                (mv^ x+ dcv ls$ us$))
 
2969
            ;; /\ Apply rewrite rules and return rewrite of result if a rule fired, otherwise...
 
2970
            (letk ((x ls$ (promote-node x ls$))
 
2971
                   (rep (node.rep x)))
 
2972
              (if (>^ rep 0)
 
2973
                  (assert (/=^ x rep)
 
2974
                   (letk ((x+ dcv2 ls$ us$ (decr-and-rewrite rep ls$ us$))
 
2975
                          (dcv (logior^ dcv1 dcv2 (node.dcv x)))
 
2976
                          (ls$ (update-rep x- x+ dcv 6 ls$))
 
2977
                          (ls$ (update-rep x x+ dcv 7 ls$)))
 
2978
                     (mv^ x+ dcv ls$ us$)))
 
2979
                ;; /\ promote the node (it is in normal form) and then see if the node has a rep node which can then rewrite and return the result, otherwise...
 
2980
                ;; \/ look to see if we had a conditional rule fail due to hypothesis and mark rep accordingly and return promoted node.
 
2981
                (letk ((ls$ (update-rep x- x dcv1 8 ls$))
 
2982
                       (x-rep (if cond-failed. (node-btm) (-^ age)))
 
2983
                       (ls$ (update-rep x x-rep (dcv-btm) 9 ls$)))
 
2984
                  (mv^ x dcv1 ls$ us$))))))))))
 
2985
 
 
2986
(defunk rewrite-node (x ls$ us$)
 
2987
  (letk ((x ls$ (check-memos x ls$))
 
2988
         (opcd (node.opcd x))
 
2989
         (rep (node.rep x))
 
2990
         (age (get-current-age ls$)))
 
2991
    (cond
 
2992
     ((depth-exceeded)
 
2993
      (error "Maximum number of iterations in term rewriting was reached. ~
 
2994
              The user may wish to adjust the rewrite depth for KAS."
 
2995
             x (mv^ x (dcv-empty) ls$ us$)))
 
2996
     ((space-exceeded)
 
2997
      (error "Maximum number of allocated nodes was reached during KAS rewriting. ~
 
2998
              The user may wish to adjust the maximum node bound for KAS."
 
2999
             x (mv^ x (dcv-empty) ls$ us$)))
 
3000
     ((or (=^ opcd (opcd-quote))  ;; quoted objects are always in normal-form
 
3001
          (and (opcd.is-var opcd) ;; var.s which are not equated, are in normal-form
 
3002
               (not (>^ rep 0)))
 
3003
          (>=^ (-^ rep) age))      ;; node tagged in normal-form in current ctx
 
3004
      (assert (promoted x)
 
3005
       (mv^ x (dcv-empty) ls$ us$)))
 
3006
     (t
 
3007
      (assert (/=^ rep x) ;; this isn't critical, but we don't expect this to happen
 
3008
       (letk ((save-depth (get-rew-call-depth  ls$))
 
3009
              (save-alloc (get-alloc-trans     ls$))
 
3010
              (save-num   (get-num-trans-nodes ls$))
 
3011
              (save-ltop  (get-loop-stk-top    ls$))
 
3012
              (ls$ (set-rew-call-depth (1+^ save-depth) ls$))
 
3013
              (x+ dcv ls$ us$ (rewrite-node+ x opcd rep age ls$ us$))
 
3014
              (ls$ (set-num-trans-nodes save-num   ls$))
 
3015
              (ls$ (set-alloc-trans     save-alloc ls$))
 
3016
              (ls$ (set-rew-call-depth  save-depth ls$))
 
3017
              (ls$ (set-loop-stk-top    save-ltop  ls$)))
 
3018
         (assert (promoted x+)
 
3019
          (assert (=^ (get-current-age ls$) age)
 
3020
           (mv x+ dcv ls$ us$)))))))))
 
3021
)
 
3022
 
 
3023
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
3024
#| stobj initialization and wrapper call for rewrite-node                     |#
 
3025
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
3026
 
 
3027
(defabbrev rlrcd.sieves    (rule) (first rule))
 
3028
(defabbrev rlrcd.lhs       (rule) (second rule))
 
3029
(defabbrev rlrcd.rhs       (rule) (third rule))
 
3030
(defabbrev rlrcd.rune      (rule) (fourth rule))
 
3031
(defabbrev rlrcd.enabled   (rule) (fifth rule))
 
3032
(defabbrev rlrcd.traced    (rule) (sixth rule))
 
3033
(defabbrev rlrcd.hyps      (rule) (seventh rule))
 
3034
 
 
3035
(defabbrev make-rlrcd (sieves lhs rhs rune enabled traced hyps)
 
3036
  (list sieves lhs rhs rune enabled traced hyps))
 
3037
 
 
3038
(defabbrev oprcd.name            (opr) (first (first opr)))
 
3039
(defabbrev oprcd.is-var          (opr) (second (first opr)))
 
3040
(defabbrev oprcd.rules           (opr) (third (first opr)))
 
3041
(defabbrev oprcd.narg            (opr) (fourth (first opr)))
 
3042
(defabbrev oprcd.boolp           (opr) (first (second opr)))
 
3043
(defabbrev oprcd.is-if           (opr) (second (second opr)))
 
3044
(defabbrev oprcd.is-equal        (opr) (third (second opr)))
 
3045
(defabbrev oprcd.non-nil         (opr) (fourth (second opr)))
 
3046
(defabbrev oprcd.exec-enabled    (opr) (fifth (second opr)))
 
3047
 
 
3048
(defun make-oprcd (name is-var rules narg
 
3049
                   boolp is-if is-equal non-nil
 
3050
                   exec-enabled)
 
3051
  (list (list name is-var rules narg)
 
3052
        (list boolp is-if is-equal non-nil
 
3053
              exec-enabled)))
 
3054
 
 
3055
(defun kern-chk-rule-traced (rune typ name descr)
 
3056
  (if (atom descr) descr
 
3057
    (let ((elem (first descr)))
 
3058
      (cond ((atom elem) elem)
 
3059
            ((or (equal rune (first elem))
 
3060
                 (and (member-eq typ '(:rewrite :definition))
 
3061
                      (equal name (first elem))))
 
3062
             (second elem))
 
3063
            (t (kern-chk-rule-traced rune typ name (rest descr)))))))
 
3064
 
 
3065
(defun kern-is-rule-traced (rune ls$)
 
3066
  (declare (xargs :stobjs ls$))
 
3067
  (kern-assert
 
3068
   (and (consp rune) (eql (len rune) 2))
 
3069
   (let ((traced
 
3070
          (kern-chk-rule-traced rune (first rune) (second rune)
 
3071
                                (get-initial-rule-trace-descriptor ls$))))
 
3072
     (if (kern-is-trace-mark traced) traced
 
3073
       (er hard 'kern-is-rule-traced "illegal trace mark: ~x0" traced)))))
 
3074
 
 
3075
(defmacro defunf (fn args body)
 
3076
  `(defun ,fn ,args
 
3077
     (declare (xargs :stobjs ls$)
 
3078
              (type (signed-byte ,(kern-fixnum-size)) ,(first args)))
 
3079
     ,body))
 
3080
     
 
3081
(defunf kern-install-auto-rule (ndx opr typ ls$)
 
3082
  (let* ((rune (list typ (oprcd.name opr)))
 
3083
         (enabled (case typ
 
3084
                    (:executable-counterpart (oprcd.exec-enabled opr))))
 
3085
         (traced (kern-is-rule-traced rune ls$)))
 
3086
    (letk ((r ls$ (kern-alloc-rule-ndx ls$))
 
3087
           (ls$ (case typ
 
3088
                  (:executable-counterpart (oper.set-exec ndx r))
 
3089
                  (t ls$)))
 
3090
           (ls$ (rule.set-op       r ndx))
 
3091
           (ls$ (rule.set-sieves   r ()))
 
3092
           (ls$ (rule.set-rune     r rune))
 
3093
           (ls$ (rule.set-lhs      r (kern-node-btm)))
 
3094
           (ls$ (rule.set-rhs      r (kern-node-btm)))
 
3095
           (ls$ (rule.set-hyps     r (kern-node-btm)))
 
3096
           (ls$ (rule.set-ctr      r 0))
 
3097
           (ls$ (rule.set-tryctr   r 0))
 
3098
           (ls$ (rule.set-enabled  r enabled))
 
3099
           (ls$ (rule.set-traced   r traced)))
 
3100
      ls$)))
 
3101
 
 
3102
(defunf kern-install-oper-type (ndx opr typ ls$)
 
3103
  (let* ((rune (case typ
 
3104
                     (:boolp (oprcd.boolp opr))
 
3105
                     (:is-if (oprcd.is-if opr))
 
3106
                     (:is-equal (oprcd.is-equal opr))
 
3107
                     (:non-nil (oprcd.non-nil opr))
 
3108
                     (t (er hard 'kern-install-oper-type "illegal typ"))))
 
3109
         (flag (if rune t nil))
 
3110
         (ls$ (case typ
 
3111
                    (:boolp (oper.set-boolp ndx flag))
 
3112
                    (:is-if (oper.set-is-if ndx flag))
 
3113
                    (:is-equal (oper.set-is-equal ndx flag))
 
3114
                    (:non-nil (oper.set-non-nil ndx flag))
 
3115
                    (t ls$)))
 
3116
         (ls$ (if (not (eq typ :boolp)) ls$
 
3117
                (letk ((ls$ (oper.set-assume-tbr ndx flag))
 
3118
                       (ls$ (oper.set-assume-fbr ndx flag)))
 
3119
                  ls$)))
 
3120
         (ls$ (if (consp rune)
 
3121
                  (letk ((r ls$ (kern-alloc-rule-ndx ls$))
 
3122
                         (ls$ (rule.set-op       r ndx))
 
3123
                         (ls$ (rule.set-sieves   r ()))
 
3124
                         (ls$ (rule.set-rune     r rune))
 
3125
                         (ls$ (rule.set-lhs      r (kern-node-btm)))
 
3126
                         (ls$ (rule.set-rhs      r (kern-node-btm)))
 
3127
                         (ls$ (rule.set-hyps     r (kern-node-btm)))
 
3128
                         (ls$ (rule.set-ctr      r 1)))
 
3129
                    ls$)
 
3130
                ls$)))
 
3131
    ls$))
 
3132
 
 
3133
(defun kern-install-oper-base (name is-var opr ls$)
 
3134
  (declare (xargs :stobjs ls$))
 
3135
  (letk ((hash (kern-fn-hash-code name))
 
3136
         (chain (get-op-hash hash ls$))
 
3137
         (opcd (kern-lookup-opcd chain name is-var ls$))
 
3138
         (ndx (if (/=^ opcd (kern-opcd-btm))
 
3139
                  (opcd.index opcd)
 
3140
                (get-next-op-ndx ls$)))
 
3141
         (ls$ (if (/=^ opcd (kern-opcd-btm)) 
 
3142
                  ls$
 
3143
                (letk ((ls$ (ensure-oper ndx (kern-oper-stor-incr)))
 
3144
                       (ls$ (oper.set-uniq ndx chain)) 
 
3145
                       (ls$ (set-op-hash hash ndx ls$))
 
3146
                       (ls$ (set-next-op-ndx (1+^ ndx) ls$)))
 
3147
                  ls$)))
 
3148
         (ls$ (oper.set-name ndx name))
 
3149
         (ls$ (oper.set-is-var ndx is-var))
 
3150
         (ls$ (oper.set-rules ndx ()))
 
3151
         (ls$ (oper.set-num-nodes ndx 0))
 
3152
         (ls$ (oper.set-num-trans ndx 0))
 
3153
         (ls$ (oper.set-narg ndx (oprcd.narg opr)))
 
3154
         (ls$ (oper.set-next-stk ndx (kern-opcd-btm)))
 
3155
         (ls$ (oper.set-bound ndx (kern-node-btm)))
 
3156
         (ls$ (oper.set-assume-tbr ndx nil))
 
3157
         (ls$ (oper.set-assume-fbr ndx nil))
 
3158
         (ls$ (if (eq name 'quote) ls$
 
3159
                (kern-install-auto-rule ndx opr :executable-counterpart ls$)))
 
3160
         (ls$ (kern-install-oper-type ndx opr :boolp ls$))
 
3161
         (ls$ (kern-install-oper-type ndx opr :is-if ls$))
 
3162
         (ls$ (kern-install-oper-type ndx opr :is-equal ls$))
 
3163
         (ls$ (kern-install-oper-type ndx opr :non-nil ls$))
 
3164
         (ls$ (if (member name (get-flip-t-fns ls$))
 
3165
                  (oper.set-assume-tbr ndx (not (oper.assume-tbr ndx)))
 
3166
                ls$))
 
3167
         (ls$ (if (member name (get-flip-nil-fns ls$))
 
3168
                  (oper.set-assume-fbr ndx (not (oper.assume-fbr ndx)))
 
3169
                ls$)))
 
3170
    ls$))
 
3171
 
 
3172
(defun kern-create-alist (vars vals)
 
3173
  (if (endp vars) ()
 
3174
    (acons (first vars) (first vals)
 
3175
           (kern-create-alist (rest vars) (rest vals)))))
 
3176
 
 
3177
(mutual-recursion
 
3178
(defun kern-expand-lambdas-fn (term alist)
 
3179
  (cond ((atom term)
 
3180
         (if (assoc term alist)
 
3181
             (cdr (assoc term alist))
 
3182
           term))
 
3183
        ((eq (first term) 'quote)
 
3184
         term)
 
3185
        ((atom (first term))
 
3186
         (cons (first term)
 
3187
               (kern-expand-lambdas-args (rest term) alist)))
 
3188
        (t
 
3189
         (kern-expand-lambdas-fn 
 
3190
          (third (first term))
 
3191
          (kern-create-alist 
 
3192
           (second (first term))
 
3193
           (kern-expand-lambdas-args (rest term) alist))))))
 
3194
 
 
3195
(defun kern-expand-lambdas-args (args alist)
 
3196
  (if (endp args) ()
 
3197
    (cons (kern-expand-lambdas-fn (first args) alist)
 
3198
          (kern-expand-lambdas-args (rest args) alist))))
 
3199
)
 
3200
 
 
3201
(defabbrev kern-expand-lambdas (term)
 
3202
  (kern-expand-lambdas-fn term ()))
 
3203
 
 
3204
(defun kern-expand-lambda-terms (terms)
 
3205
  (if (endp terms) ()
 
3206
    (cons (kern-expand-lambdas (first terms))
 
3207
          (kern-expand-lambda-terms (rest terms)))))
 
3208
 
 
3209
(defun kern-install-rules (rlrcds op ls$)
 
3210
  (declare (xargs :stobjs ls$))
 
3211
  (if (endp rlrcds)
 
3212
      (oper.set-rules op ())
 
3213
    (letk ((r. (first rlrcds))
 
3214
           (lhs. (kern-expand-lambdas (rlrcd.lhs r.)))
 
3215
           (rhs. (kern-expand-lambdas (rlrcd.rhs r.)))
 
3216
           (hyps. (kern-expand-lambdas (rlrcd.hyps r.)))
 
3217
           (sieves. ls$ (kern-install-sieves (rlrcd.sieves r.) ls$))
 
3218
           (ndx ls$ (kern-alloc-rule-ndx ls$))
 
3219
           (lhs ls$ (kern-term-to-node lhs. ls$))
 
3220
           (rhs ls$ (kern-term-to-node rhs. ls$))
 
3221
           (hyps ls$ (kern-term-to-node hyps. ls$))
 
3222
           (ls$ (rule.set-rune      ndx (rlrcd.rune r.)))
 
3223
           (ls$ (rule.set-sieves    ndx sieves.))
 
3224
           (ls$ (rule.set-ctr       ndx 0))
 
3225
           (ls$ (rule.set-lhs       ndx lhs))
 
3226
           (ls$ (rule.set-rhs       ndx rhs))
 
3227
           (ls$ (rule.set-hyps      ndx hyps))
 
3228
           (ls$ (rule.set-op        ndx op))
 
3229
           (ls$ (rule.set-enabled   ndx (rlrcd.enabled r.)))
 
3230
           (ls$ (rule.set-traced    ndx (rlrcd.traced r.)))
 
3231
           (ls$ (kern-install-rules (rest rlrcds) op ls$)))
 
3232
      (oper.set-rules op (cons ndx (oper.rules op))))))
 
3233
 
 
3234
(defun kern-install-base-opers (oprcds ls$)
 
3235
  (declare (xargs :stobjs ls$))
 
3236
  (if (endp oprcds) ls$
 
3237
    (letk ((ls$ (kern-install-oper-base (oprcd.name (first oprcds))
 
3238
                                        (oprcd.is-var (first oprcds))
 
3239
                                        (first oprcds) ls$)))
 
3240
      (kern-install-base-opers (rest oprcds) ls$))))
 
3241
 
 
3242
(defun kern-install-rlrcds (oprcds ls$)
 
3243
  (declare (xargs :stobjs ls$))
 
3244
  (if (endp oprcds) ls$
 
3245
    (letk ((opcd (kern-find-fn-opcd (oprcd.name (first oprcds))))
 
3246
           (ndx (kern-assert (/=^ opcd (kern-opcd-btm))
 
3247
                             (opcd.index opcd)))
 
3248
           (ls$ (kern-install-rules (oprcd.rules (first oprcds)) ndx ls$)))
 
3249
      (kern-install-rlrcds (rest oprcds) ls$))))
 
3250
 
 
3251
(defun kern-install-oprcds (oprcds ls$)
 
3252
  (declare (xargs :stobjs ls$))
 
3253
  (letk ((ls$ (kern-install-base-opers oprcds ls$)))
 
3254
    (kern-install-rlrcds oprcds ls$)))
 
3255
 
 
3256
(defun kern-remove-equal-list (e x)
 
3257
  (cond ((endp x) ())
 
3258
        ((equal e (first x))
 
3259
         (kern-remove-equal-list e (rest x)))
 
3260
        (t (cons (first x)
 
3261
                 (kern-remove-equal-list e (rest x))))))
 
3262
 
 
3263
(mutual-recursion
 
3264
(defun kern-unfak-term (term)
 
3265
  (cond ((atom term) term)
 
3266
        ((eq (first term) 'quote) term)
 
3267
        ((eq (first term) 'fak)
 
3268
         (kern-unfak-term (second term)))
 
3269
        (t (cons (first term)
 
3270
                 (kern-unfak-terms (rest term))))))
 
3271
 
 
3272
(defun kern-unfak-terms (args)
 
3273
  (if (endp args) ()
 
3274
    (cons (kern-unfak-term (first args))
 
3275
          (kern-unfak-terms (rest args)))))
 
3276
)
 
3277
 
 
3278
(defun kern-translate-hyps (hyps)
 
3279
  (cons (symbol-append 'hyps-and- (length hyps)) hyps))
 
3280
 
 
3281
(defun kern-prune-sieves (hyps)
 
3282
  (cond ((endp hyps) ())
 
3283
        ((and (consp (first hyps))
 
3284
              (eq (caar hyps) 'siv))
 
3285
         (kern-prune-sieves (rest hyps)))
 
3286
        (t (cons (first hyps) (kern-prune-sieves (rest hyps))))))
 
3287
 
 
3288
(defun kern-extract-sieves (hyps)
 
3289
  (cond ((endp hyps) ())
 
3290
        ((and (consp (first hyps))
 
3291
              (eq (caar hyps) 'siv))
 
3292
         (cons (if (quotep (cadar hyps)) (cadr (cadar hyps)) (cadar hyps))
 
3293
               (kern-extract-sieves (rest hyps))))
 
3294
        (t (kern-extract-sieves (rest hyps)))))
 
3295
 
 
3296
(defun kern-find-new-rules (lemmas recp ens all-fns rules new-fns ls$)
 
3297
  (declare (xargs :stobjs ls$))
 
3298
  (if (endp lemmas)
 
3299
      (mv new-fns (reverse rules))
 
3300
    (let* ((lemma (first lemmas))
 
3301
           (rhs (kern-unfak-term (access rewrite-rule lemma :rhs)))
 
3302
           (lhs (kern-unfak-term (access rewrite-rule lemma :lhs)))
 
3303
           (rune (access rewrite-rule lemma :rune))
 
3304
           (subclass (access rewrite-rule lemma :subclass))
 
3305
           (hyps (and (not (eq subclass 'abbreviation))
 
3306
                      (kern-unfak-terms (access rewrite-rule lemma :hyps))))
 
3307
           (heuristic-info (access rewrite-rule lemma :heuristic-info)))
 
3308
      (if (and (eq (access rewrite-rule lemma :equiv) 'equal)
 
3309
               (member-eq subclass '(definition abbreviation backchain))
 
3310
               (implies (eq subclass 'backchain) (null heuristic-info)))
 
3311
          (let* ((enabled   (enabled-numep (access rewrite-rule lemma :nume) ens))
 
3312
                 (traced    (kern-is-rule-traced rune ls$))
 
3313
                 (is-def    (eq subclass 'definition))
 
3314
                 (enabled   (and enabled (not (and is-def recp))))
 
3315
                 (sieves    (kern-extract-sieves hyps))
 
3316
                 (hyps      (kern-prune-sieves hyps))
 
3317
                 (hyps      (kern-translate-hyps hyps))
 
3318
                 (new-rule  (make-rlrcd sieves lhs rhs rune enabled traced hyps))
 
3319
                 (rule-fns  (union-eq (all-fnnames lhs) (union-eq (all-fnnames rhs) (all-fnnames hyps)))))
 
3320
            (kern-find-new-rules (rest lemmas) recp ens all-fns (cons new-rule rules)
 
3321
                                 (union-eq (set-difference-eq rule-fns all-fns) new-fns) ls$))
 
3322
        (kern-find-new-rules (rest lemmas) recp ens all-fns rules new-fns ls$)))))
 
3323
 
 
3324
(defun kern-filter-fak-thms (lemmas fn)
 
3325
  (cond ((endp lemmas) ())
 
3326
        ((eq (first (access rewrite-rule (first lemmas) :lhs)) fn)
 
3327
         (cons (first lemmas)
 
3328
               (kern-filter-fak-thms (rest lemmas) fn)))
 
3329
        (t (kern-filter-fak-thms (rest lemmas) fn))))
 
3330
 
 
3331
(defun kern-rules-alist-fn (fns all-fns rules-alist fak-thms ens wrld ls$)
 
3332
  (declare (xargs :stobjs ls$))
 
3333
  (if (endp fns)
 
3334
      (reverse rules-alist)
 
3335
    (let ((fn (first fns)))
 
3336
      (mv-let (new-fns rules)
 
3337
          (kern-find-new-rules (append (kern-getprop fn 'lemmas)
 
3338
                                       (kern-filter-fak-thms fak-thms fn))
 
3339
                               (kern-getprop fn 'recursivep)
 
3340
                               ens (cons fn all-fns) () () ls$)
 
3341
        (kern-rules-alist-fn (append (rest fns) new-fns)
 
3342
                             (append new-fns all-fns)
 
3343
                             (cons (cons fn rules) rules-alist)
 
3344
                             fak-thms ens wrld ls$)))))
 
3345
 
 
3346
(defun kern-trans-fak-thms (lemmas)
 
3347
  (if (endp lemmas) ()
 
3348
    (let* ((lemma (first lemmas))
 
3349
           (lhs (kern-unfak-term (access rewrite-rule lemma :lhs)))
 
3350
           (equiv (access rewrite-rule lemma :equiv)))
 
3351
      (if (not (and (eq equiv 'equal)
 
3352
                    (consp lhs)
 
3353
                    (not (quotep lhs))))
 
3354
          (kern-trans-fak-thms (rest lemmas))
 
3355
        (cons (make rewrite-rule
 
3356
                    :rune (access rewrite-rule lemma :rune)
 
3357
                    :nume (access rewrite-rule lemma :nume)
 
3358
                    :hyps (access rewrite-rule lemma :hyps)
 
3359
                    :equiv 'equal
 
3360
                    :lhs lhs
 
3361
                    :rhs (access rewrite-rule lemma :rhs)
 
3362
                    :subclass (access rewrite-rule lemma :subclass)
 
3363
                    :heuristic-info (access rewrite-rule lemma :heuristic-info)
 
3364
                    :backchain-limit-lst (access rewrite-rule lemma :backchain-limit-lst)
 
3365
                    :match-free (access rewrite-rule lemma :match-free))
 
3366
              (kern-trans-fak-thms (rest lemmas)))))))
 
3367
 
 
3368
(defun kern-rules-alist (fns ens wrld ls$)
 
3369
  (declare (xargs :stobjs ls$))
 
3370
  (kern-rules-alist-fn fns fns () (kern-trans-fak-thms (kern-getprop 'fak 'lemmas)) ens wrld ls$))
 
3371
 
 
3372
(defun kern-find-nume (pairs rune)
 
3373
  (cond ((endp pairs) nil)
 
3374
        ((equal rune (cdar pairs))
 
3375
         (caar pairs))
 
3376
        (t (kern-find-nume (cdr pairs) rune))))
 
3377
 
 
3378
(defun kern-type-pre-subsetp (tp ens ts)
 
3379
  (and (enabled-numep (access type-prescription tp :nume) ens)
 
3380
       (ts-subsetp (access type-prescription tp :basic-ts) ts)
 
3381
       (null (access type-prescription tp :hyps))
 
3382
       (null (access type-prescription tp :vars))))
 
3383
 
 
3384
;; NOTE: In the following function, we have decided to ignore the enabled
 
3385
;; status of the definition rule we use to determine the match. The problem is
 
3386
;; that the user may want a function to be matched to equal or if, but disable
 
3387
;; the definition rule. One level of indirection in the function definition
 
3388
;; will fail this check and allow the user to define functions which are equal,
 
3389
;; if, but are not understood by the simplifier as such.
 
3390
;; 
 
3391
;;   (enabled-numep (access rewrite-rule lemma :nume) ens)
 
3392
 
 
3393
(defun kern-match-defn-body (lemma ens lhs fn num-formals)
 
3394
  (declare (ignore ens))
 
3395
  (and (equal (length lhs) (1+ num-formals))
 
3396
       (member (access rewrite-rule lemma :subclass)
 
3397
               '(abbreviation definition))
 
3398
       (null (access rewrite-rule lemma :hyps))
 
3399
       (let ((rune (access rewrite-rule lemma :rune)))
 
3400
         (and (consp rune) (eq (first rune) :definition)))
 
3401
       (eq (access rewrite-rule lemma :equiv) 'equal)
 
3402
       (equal (access rewrite-rule lemma :lhs) lhs)
 
3403
       (equal (access rewrite-rule lemma :rhs)
 
3404
              (cons fn (rest lhs)))))
 
3405
 
 
3406
(defun kern-find-boolp (lst ens)
 
3407
  (if (endp lst) nil
 
3408
    (let ((tp (first lst)))
 
3409
      (if (kern-type-pre-subsetp tp ens *ts-boolean*)
 
3410
          (access type-prescription tp :rune)
 
3411
        (kern-find-boolp (rest lst) ens)))))
 
3412
 
 
3413
(defun kern-find-non-nil (lst ens)
 
3414
  (if (endp lst) nil
 
3415
    (let ((tp (first lst)))
 
3416
      (if (kern-type-pre-subsetp tp ens *ts-non-nil*)
 
3417
          (access type-prescription tp :rune)
 
3418
        (kern-find-non-nil (rest lst) ens)))))
 
3419
 
 
3420
(defun kern-find-is-if (lst ens lhs)
 
3421
  (if (endp lst) nil
 
3422
    (let ((r (first lst)))
 
3423
      (if (kern-match-defn-body r ens lhs 'if 3)
 
3424
          (access rewrite-rule r :rune)
 
3425
        (kern-find-is-if (rest lst) ens lhs)))))
 
3426
 
 
3427
(defun kern-find-is-equal (lst ens lhs)
 
3428
  (if (endp lst) nil
 
3429
    (let ((r (first lst)))
 
3430
      (if (kern-match-defn-body r ens lhs 'equal 2)
 
3431
          (access rewrite-rule r :rune)
 
3432
        (kern-find-is-equal (rest lst) ens lhs)))))
 
3433
 
 
3434
(defun kern-create-oprcds (alist ens wrld)
 
3435
  (if (endp alist) ()
 
3436
    (let* ((fn (caar alist))
 
3437
           (rules (cdar alist))
 
3438
           (exec (list :executale-counterpart fn))
 
3439
           (formals (kern-getprop fn 'formals))
 
3440
           (lhs (cons fn formals))
 
3441
           (nume (kern-find-nume (kern-getprop fn 'runic-mapping-pairs) exec))
 
3442
           (enabled-exec (if nume (enabled-numep nume ens) t))
 
3443
           (num-formals (if (eq fn 'quote) 1 (length formals)))
 
3444
           (type-pres (kern-getprop fn 'type-prescriptions))
 
3445
           (lemmas (kern-getprop fn 'lemmas))
 
3446
           (boolp    (or (eq fn 'equal) (kern-find-boolp type-pres ens)))
 
3447
           (non-nil  (or (eq fn 'cons)  (kern-find-non-nil type-pres ens)))
 
3448
           (is-if    (or (eq fn 'if)    (kern-find-is-if lemmas ens lhs)))
 
3449
           (is-equal (or (eq fn 'equal) (kern-find-is-equal lemmas ens lhs)))
 
3450
           (exec-enabled (if enabled-exec t nil)))
 
3451
      (cons (make-oprcd fn nil rules num-formals
 
3452
                        boolp is-if is-equal non-nil exec-enabled)
 
3453
            (kern-create-oprcds (cdr alist) ens wrld)))))
 
3454
 
 
3455
(defunf kern-init-node-hash (n ls$)
 
3456
  (if (kern-zp n) ls$
 
3457
    (letk ((n (1-^ n))
 
3458
           (ls$ (set-node-hash n (kern-node-btm) ls$)))
 
3459
      (kern-init-node-hash n ls$))))
 
3460
 
 
3461
(defunf kern-init-quote-hash (n ls$)
 
3462
  (if (kern-zp n) ls$
 
3463
    (letk ((n (1-^ n))
 
3464
           (ls$ (set-quote-hash n (kern-node-btm) ls$)))
 
3465
      (kern-init-quote-hash n ls$))))
 
3466
 
 
3467
(defunf kern-init-op-hash (n ls$)
 
3468
  (if (kern-zp n) ls$
 
3469
    (letk ((n (1-^ n))
 
3470
           (ls$ (set-op-hash n (kern-opcd-btm) ls$)))
 
3471
      (kern-init-op-hash n ls$))))
 
3472
 
 
3473
(defunf kern-init-memo-tbl (m ls$)
 
3474
  (if (kern-zp m) ls$
 
3475
    (letk ((m (1-^ m))
 
3476
           (ls$ (memo.set-opcd m (kern-opcd-btm))))
 
3477
      (kern-init-memo-tbl m ls$))))
 
3478
 
 
3479
(defun kern-install-and-check-quotes (alst ls$)
 
3480
  (declare (xargs :stobjs ls$))
 
3481
  (if (endp alst) ls$
 
3482
    (letk ((node ls$ (kern-create-quote (caar alst))))
 
3483
      (kern-force-assert (equal node (cdar alst))
 
3484
       (kern-install-and-check-quotes (cdr alst) ls$)))))
 
3485
 
 
3486
(defun kern-base-quote-alist ()
 
3487
  (list (cons nil (kern-node-nil))
 
3488
        (cons t   (kern-node-t))))
 
3489
 
 
3490
(defun kern-install-base-quotes (ls$)
 
3491
  (declare (xargs :stobjs ls$))
 
3492
  (kern-install-and-check-quotes (kern-base-quote-alist) ls$))
 
3493
 
 
3494
(defun kern-find-max-narg1 (oprcds max)
 
3495
  (cond ((endp oprcds)
 
3496
         (or max (er hard 'kern-logic-init "illegal empty list of oprcds")))
 
3497
        ((or (null max)
 
3498
             (> (oprcd.narg (first oprcds))
 
3499
                (oprcd.narg max)))
 
3500
         (kern-find-max-narg1 (rest oprcds) (first oprcds)))
 
3501
        (t (kern-find-max-narg1 (rest oprcds) max))))
 
3502
 
 
3503
(defun kern-find-max-narg (oprcds)
 
3504
  (kern-find-max-narg1 oprcds nil))
 
3505
 
 
3506
(defun kern-check-opcode-alist (alst ls$)
 
3507
  (declare (xargs :stobjs ls$))
 
3508
  (if (endp alst) ls$
 
3509
    (letk ((opcd (kern-find-fn-opcd (caar alst))))
 
3510
      (if (not (equal opcd (cdar alst)))
 
3511
          (prog2$ (er hard 'kern-check-opcode-alist
 
3512
                      "built-in opcd failure: ~x0"
 
3513
                      (list opcd (caar alst) (cdar alst)))
 
3514
            ls$)
 
3515
       (kern-check-opcode-alist (cdr alst) ls$)))))
 
3516
 
 
3517
(defun kern-initial-fns () '(quote if equal cons hide fail))
 
3518
 
 
3519
(defun kern-base-opcd-alist ()
 
3520
  (list (cons 'quote (kern-opcd-quote))
 
3521
        (cons 'if    (kern-opcd-if))
 
3522
        (cons 'equal (kern-opcd-equal))
 
3523
        (cons 'cons  (kern-opcd-cons))
 
3524
        (cons 'hide  (kern-opcd-hide))
 
3525
        (cons 'fail  (kern-opcd-fail))))
 
3526
 
 
3527
(defun kern-check-base-opcodes (ls$)
 
3528
  (declare (xargs :stobjs ls$))
 
3529
  (kern-check-opcode-alist (kern-base-opcd-alist) ls$))
 
3530
 
 
3531
(defunf kern-clear-node-counts (n ls$)
 
3532
  (if (kern-zp n) ls$
 
3533
    (letk ((n (1-^ n))
 
3534
           (ls$ (oper.set-num-nodes n 0))
 
3535
           (ls$ (oper.set-num-trans n 0)))
 
3536
      (kern-clear-node-counts n ls$))))
 
3537
 
 
3538
(defun user-node-limit (sp) (expt 2 sp))
 
3539
(defun user-node-alloc (sp) (floor (user-node-limit sp) 8))
 
3540
(defun user-node-step (sp) (user-node-alloc sp))
 
3541
(defun qobj-tbl-initial (sp) (floor (user-node-alloc sp) 4))
 
3542
(defun oper-tbl-initial (sp) (floor (user-node-alloc sp) 8))
 
3543
(defun rule-tbl-initial (sp) (* 2 (oper-tbl-initial sp)))
 
3544
(defun undo-stk-initial (sp) (* 2 (oper-tbl-initial sp)))
 
3545
(defun node-hash-size (sp) (* (user-node-alloc sp) 2))
 
3546
(defun node-hash-mask (sp) (1- (node-hash-size sp)))
 
3547
;; The 1+ in the next definition is needed because an entry may take two slots
 
3548
;; and we need an extra slot for padding the last entry in the memo-table.
 
3549
(defun node-memo-size (sp) (1+ (floor (node-hash-size sp)
 
3550
                                      (kern-hash-memo-divisor))))
 
3551
(defun node-memo-hash (sp) (- (node-memo-size sp) 2))
 
3552
(defun start-clock-value (sp) (floor (user-node-alloc sp) 2))
 
3553
(defun node-trans-size (sp) (* (floor (user-node-alloc sp) 2)
 
3554
                               (+ (kern-base-trans-alloc)
 
3555
                                  (kern-avg-num-args))))
 
3556
(defun node-stor-size (sp) (* (user-node-alloc sp)
 
3557
                              (+ (kern-base-node-alloc)
 
3558
                                 (kern-avg-num-args))))
 
3559
(defun initial-loop-size (sp) (floor (user-node-alloc sp) 8))
 
3560
(defun curr-ctx-stk-size (sp) (* sp sp 10))
 
3561
(defun first-quote-ndx () (1+ (kern-qobj-btm)))
 
3562
(defun first-oper-ndx () (1+ (kern-opcd-btm)))
 
3563
(defun first-node-ndx () (1+ (kern-node-btm)))
 
3564
(defun first-trans-ndx () (1+ (kern-node-btm)))
 
3565
 
 
3566
(defun kern-logic-init (term wrld ens ls$)
 
3567
  (declare (xargs :stobjs ls$))
 
3568
  (let* ((fns (all-fnnames term))
 
3569
         (fns (set-difference-eq fns (kern-initial-fns)))
 
3570
         (fns (append (kern-initial-fns) fns))
 
3571
         (alist (kern-rules-alist fns ens wrld ls$))
 
3572
         (oprcds (kern-create-oprcds alist ens wrld)))
 
3573
    (cond ((>= (length oprcds) (kern-max-num-fns))
 
3574
           (prog2$ (er0 hard 'kern-logic-init
 
3575
                        "The kernel simplifier has a hard limit of ~x0 for the number of ~
 
3576
                         functions which can be installed for a given term. The number of ~
 
3577
                         functions required for this call is ~x1 which exceeds th limit."
 
3578
                        (kern-max-num-fns)
 
3579
                        (length oprcds))
 
3580
             ls$))
 
3581
          ((>= (oprcd.narg (kern-find-max-narg oprcds)) (kern-max-num-args))
 
3582
           (prog2$ (er0 hard 'kern-logic-init
 
3583
                        "The kernel simplifier has a hard limit of ~x0 for the number of ~
 
3584
                         arguments for any given function. The number of arguments for the ~
 
3585
                         function ~x1 is ~x2 which exceeds the limit."
 
3586
                        (kern-max-num-args)
 
3587
                        (oprcd.name (kern-find-max-narg oprcds))
 
3588
                        (oprcd.narg (kern-find-max-narg oprcds)))
 
3589
             ls$))
 
3590
          (t     
 
3591
           (letk ((sp (get-kern-size-param ls$))
 
3592
                  (ls$ (resize-node-stor (node-stor-size sp) ls$))
 
3593
                  (ls$ (resize-node-hash (node-hash-size sp) ls$))
 
3594
                  (ls$ (kern-init-node-hash (node-hash-size sp) ls$))
 
3595
                  (ls$ (set-alloc-nodes (first-node-ndx) ls$))
 
3596
                  (ls$ (set-num-of-nodes 0 ls$))
 
3597
                  (ls$ (ensure-qobj (qobj-tbl-initial sp) 0))
 
3598
                  (ls$ (resize-quote-hash (kern-quote-hash-size) ls$))
 
3599
                  (ls$ (kern-init-quote-hash (kern-quote-hash-size) ls$))
 
3600
                  (ls$ (set-next-quote (first-quote-ndx) ls$))
 
3601
                  (ls$ (set-node-step (user-node-step sp) ls$))
 
3602
                  (ls$ (set-node-limit (user-node-limit sp) ls$))
 
3603
                  (ls$ (set-hash-mask (node-hash-mask sp) ls$))
 
3604
                  (ls$ (resize-trans-stor (node-trans-size sp) ls$))
 
3605
                  (ls$ (set-alloc-trans (first-trans-ndx) ls$))
 
3606
                  (ls$ (set-num-trans-nodes 0 ls$))
 
3607
                  (ls$ (ensure-memo (node-memo-size sp) 0))
 
3608
                  (ls$ (kern-init-memo-tbl (node-memo-size sp) ls$))
 
3609
                  (ls$ (ensure-loop (initial-loop-size sp) 0))
 
3610
                  (ls$ (set-loop-stk-top (1+ (kern-loop-btm)) ls$))
 
3611
                  (ls$ (ensure-oper (oper-tbl-initial sp) 0))
 
3612
                  (ls$ (set-next-op-ndx (first-oper-ndx) ls$))
 
3613
                  (ls$ (resize-op-hash (kern-op-hash-tbl-size) ls$))
 
3614
                  (ls$ (kern-init-op-hash (kern-op-hash-tbl-size) ls$))
 
3615
                  (ls$ (ensure-undo (undo-stk-initial sp) 0))
 
3616
                  (ls$ (set-undo-top 1 ls$))
 
3617
                  (ls$ (set-undo-free-list (kern-undo-btm) ls$))
 
3618
                  (ls$ (ensure-rule (rule-tbl-initial sp) 0))
 
3619
                  (ls$ (set-next-rule-ndx (kern-first-rule-ndx) ls$))
 
3620
                  (ls$ (set-current-world wrld ls$))
 
3621
                  (ls$ (set-current-ens ens ls$))
 
3622
                  (ls$ (set-var-chg-stk (kern-node-btm) ls$))
 
3623
                  (ls$ (set-current-age 1 ls$))
 
3624
                  (ls$ (set-bchain-limit 2 ls$))
 
3625
                  (ls$ (set-next-extend-age 2 ls$))
 
3626
                  (ls$ (set-current-dctx (kern-dctx-0) ls$))
 
3627
                  (ls$ (set-current-clock (start-clock-value sp) ls$))
 
3628
                  (ls$ (set-warned-ctx-depth nil ls$))
 
3629
                  (ls$ (kern-install-base-quotes ls$))
 
3630
                  (ls$ (kern-install-oprcds oprcds ls$))
 
3631
                  (ls$ (kern-check-base-opcodes ls$))
 
3632
                  (ls$ (set-rew-call-depth 0 ls$))
 
3633
                  (ls$ (set-curr-ctx-top 0 ls$))
 
3634
                  (ls$ (resize-curr-ctx-stk (curr-ctx-stk-size sp) ls$))
 
3635
                  (ls$ (kern-clear-node-counts (num-of-oper) ls$)))
 
3636
             ls$)))))
 
3637
 
 
3638
(mutual-recursionk
 
3639
(defunk has-fail-subterm (x ls$)
 
3640
  (letk ((opcd (node.opcd x)))
 
3641
    (or (=^ opcd (opcd-fail))
 
3642
        (and (/=^ opcd (opcd-quote))
 
3643
             (not (opcd.is-var opcd))
 
3644
             (args-has-fail-subterm x (opcd.narg opcd) 0 ls$)))))
 
3645
 
 
3646
(defunk args-has-fail-subterm (x n i ls$)
 
3647
  (and (not (zp n))
 
3648
       (or (has-fail-subterm (node.arg x i) ls$)
 
3649
           (args-has-fail-subterm x (1-^ n) (1+^ i) ls$))))
 
3650
)
 
3651
 
 
3652
(defun kern-create-result (node term ls$ state)
 
3653
  (declare (xargs :stobjs (ls$ state)))
 
3654
  (if (=^ node (kern-node-btm))
 
3655
      (let ((state (fms "An internal error in kernel-simplify: returned (node-btm). ~
 
3656
                         Please notify current maintainer of kern-simp."
 
3657
                        () (standard-co state) state nil)))
 
3658
        (mv t term () state))
 
3659
    (let ((ttree (kern-print-stats ls$)))
 
3660
      (if (kern-has-fail-subterm node ls$)
 
3661
          (mv nil term ttree state)
 
3662
        (mv nil (kern-node-to-term node) ttree state)))))
 
3663
 
 
3664
(defun kern-simplify-term (term wrld ens ls$ us$)
 
3665
  (declare (xargs :stobjs (ls$ us$)))
 
3666
  (letk ((term. (kern-unfak-term term))
 
3667
         (ls$ (kern-logic-init term. wrld ens ls$))
 
3668
         (us$ (kern-user-init ls$ us$))
 
3669
         (node ls$ (kern-term-to-node term. ls$))
 
3670
         (node+ dcv ls$ us$ (kern-rewrite-node node ls$ us$)))
 
3671
        (kern-force-assert (or (=^ dcv (kern-dcv-empty)) (list dcv))
 
3672
                           (mv node+ ls$ us$))))
 
3673
 
 
3674
(defun parse-kernel-simplify-hint (hint)
 
3675
  (if (and (consp hint)
 
3676
           (eq (first hint) 'k-s-hint)
 
3677
           (quote-listp (rest hint)))
 
3678
      (mv (second (second hint))
 
3679
          (second (third hint))
 
3680
          (second (fourth hint))
 
3681
          (second (fifth hint))
 
3682
          (second (sixth hint))
 
3683
          (second (seventh hint))
 
3684
          (second (eighth hint))
 
3685
          (second (ninth hint)))
 
3686
    (mv nil nil nil nil nil nil 4 t)))
 
3687
 
 
3688
(defun min-size-param () 13) ;; this one ensures lower-bound for several parameters
 
3689
(defun max-size-param () 36) ;; this one is limited by the number of bits in a node
 
3690
 
 
3691
(defun kern-init-top-params (hint ls$)
 
3692
  (declare (xargs :stobjs ls$))
 
3693
  (mv-let (size-param quiet alloc-display flip-t flip-nil rule-trace prune-depth context-reduce)
 
3694
      (parse-kernel-simplify-hint hint)
 
3695
    (let* ((size-param (min (max (nfix size-param) (min-size-param)) (max-size-param)))
 
3696
           (ls$ (set-kern-size-param size-param ls$))
 
3697
           (ls$ (set-output-verbose (not quiet) ls$))
 
3698
           (ls$ (set-ls$-resize-array-display alloc-display ls$))
 
3699
           (ls$ (set-initial-rule-trace-descriptor rule-trace ls$))
 
3700
           (ls$ (set-initial-node-prune-depth prune-depth ls$))
 
3701
           (ls$ (set-allow-context-reduction context-reduce ls$))
 
3702
           (ls$ (set-flip-t-fns (and (true-listp flip-t) flip-t) ls$))
 
3703
           (ls$ (set-flip-nil-fns (and (true-listp flip-nil) flip-nil) ls$)))
 
3704
      ls$)))
 
3705
 
 
3706
(defun kern-clause-to-term (cl)
 
3707
  (cond ((endp cl) *T*)
 
3708
        ((endp (rest cl)) (first cl))
 
3709
        (t (list 'if (first cl) *T* (kern-clause-to-term (rest cl))))))
 
3710
 
 
3711
(defun kern-simplify-main (cl hint ls$ us$ state)
 
3712
  (declare (xargs :stobjs (ls$ us$ state)))
 
3713
  (let* ((ls$ (kern-init-top-params hint ls$))
 
3714
         (cl (kern-expand-lambda-terms cl))
 
3715
         (term (kern-clause-to-term cl)))
 
3716
    (mv-let (node ls$ us$)
 
3717
        (kern-simplify-term term (w state) (ens state) ls$ us$)
 
3718
      (mv-let (erp term ttree state)
 
3719
          (kern-create-result node term ls$ state)
 
3720
        (mv erp term ttree state ls$ us$)))))
 
3721
 
 
3722
(defun kernel-simplify (cl hint state)
 
3723
  (declare (xargs :stobjs state))
 
3724
  (with-local-stobj ls$
 
3725
    (mv-let (erp term ttree state ls$)
 
3726
        (with-local-stobj us$
 
3727
          (mv-let (erp term ttree state ls$ us$)
 
3728
              (kern-simplify-main cl hint ls$ us$ state)
 
3729
            (mv erp term ttree state ls$)))
 
3730
      (declare (ignore ttree))
 
3731
      (let ((cl-list (list (list term))))
 
3732
        (mv erp cl-list state)))))
 
3733
 
 
3734
(kern-comp)
 
3735
 
 
3736
(logic)
 
3737
 
 
3738
;; the "hint" for the kernel-simplify processor is expected to be a call of the following 
 
3739
;; function where the arguments to the call should be quoted constants which are used to 
 
3740
;; provide optional parameters to simplifier:
 
3741
 
 
3742
(defun k-s-hint (size-param quiet alloc-display flip-t flip-nil rule-trace prune-depth context-reduce)
 
3743
  (list 'k-s-hint 
 
3744
        (list 'quote size-param) 
 
3745
        (list 'quote quiet)
 
3746
        (list 'quote alloc-display)
 
3747
        (list 'quote flip-t)
 
3748
        (list 'quote flip-nil)
 
3749
        (list 'quote rule-trace)
 
3750
        (list 'quote prune-depth)
 
3751
        (list 'quote context-reduce)))
 
3752
 
 
3753
(defmacro defthmk-generic (name form &rest aux)
 
3754
  `(defthm ,name ,form
 
3755
     :hints (("Goal"
 
3756
              :do-not-induct t
 
3757
              :do-not '(preprocess simplify eliminate-destructors fertilize generalize eliminate-irrelevance)
 
3758
              :clause-processor (:function kernel-simplify :hint (k-s-hint 20 nil nil nil nil nil 4 nil))))
 
3759
     ,@aux))
 
3760
 
 
3761
(define-trusted-clause-processor kernel-simplify nil :ttag kernel-simplify-ttag)
 
3762