1
1
; array1.lisp -- a book about one-dimensional arrays
2
2
; Copyright (C) 1997 Computational Logic, Inc.
4
; This book is free software; you can redistribute it and/or modify
5
; it under the terms of the GNU General Public License as published by
6
; the Free Software Foundation; either version 2 of the License, or
7
; (at your option) any later version.
9
; This book is distributed in the hope that it will be useful,
10
; but WITHOUT ANY WARRANTY; without even the implied warranty of
11
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
; GNU General Public License for more details.
14
; You should have received a copy of the GNU General Public License
15
; along with this book; if not, write to the Free Software
16
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3
; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
18
5
; Written by: Bishop Brock
19
6
; Computational Logic, Inc.
20
7
; 1717 West Sixth Street, Suite 290
21
8
; Austin, TX 78703-4776 U.S.A.
23
;;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27
;;; Characterization of 1-dimensional arrays.
29
;;; This book requires nothing more than the ACL2 boot-strap theory for
30
;;; its certification.
33
;;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
35
;;; Note: This book was originally developed in a version of ACL2 where
36
;;; guards were part of the logic. It is technically possible to weaken
37
;;; the hypotheses of many of the lemmas, but time has not permitted us to
10
; Note: This book was originally developed in a version of ACL2 where guards
11
; were part of the logic. It is technically possible to weaken the hypotheses
12
; of many of the lemmas, but time has not permitted us to do this.
14
; Modified by Jared Davis, September 2014, to port documentation to xdoc.
40
16
(in-package "ACL2")
41
(include-book "doc-section")
44
:doc ":doc-section data-structures
46
A book of lemmas that characterize 1-dimensional arrays.
49
Because many of the functions characterized by this book are non-recursive,
50
one should always DISABLE the theory ARRAY1-FUNCTIONS after including this
51
book, or the lemmas will not be applicable.
54
The lemmas exported by this book should completely characterize
55
1-dimensional arrays for most purposes. Given the lemmas exported by this
56
book, it should not be necessary to ENABLE any of the 1-dimensional array
57
functions except under special circumstances.
59
This book defines a function RESET-ARRAY1 that clears an array, effectively
60
resetting each element of the array to the default value. This book also
61
includes a macro, DEFARRAY1TYPE, which defines recognizers and supporting
62
lemmas for 1-dimensional arrays whose elements are all of a fixed type.~/")
66
A theory of all ENABLEd rules exported by the \"array1\" book.
68
Note that in order for these rules to be applicable you will first need to
69
DISABLE the theory ARRAY1-FUNCTIONS. The following rules are found in this
17
(include-book "xdoc/top" :dir :system)
20
:parents (data-structures)
21
:short "A book of lemmas that characterize 1-dimensional arrays."
22
:long "<p>Because many of the functions characterized by this book are
23
non-recursive, one should always @(see DISABLE) the theory
24
@('ARRAY1-FUNCTIONS') after including this book, or the lemmas will not be
27
<p>The lemmas exported by this book should completely characterize
28
1-dimensional arrays for most purposes. Given the lemmas exported by this
29
book, it should not be necessary to @(see ENABLE) any of the 1-dimensional
30
array functions except under special circumstances.</p>
32
<p>This book defines a function @(see RESET-ARRAY1) that clears an array,
33
effectively resetting each element of the array to the default value. This
34
book also includes a macro, @(see DEFARRAY1TYPE), which defines recognizers and
35
supporting lemmas for 1-dimensional arrays whose elements are all of a fixed
74
39
;;;****************************************************************************
76
41
;;; These are general lemmas about ALISTs and ALIST functions. None of
77
42
;;; these lemmas are exported by this book. Perhaps someday they will
78
;;; appear in an ALIST book.
43
;;; appear in an ALIST book.
80
45
;;;****************************************************************************
85
(defthm eqlable-alistp-implies-alistp
89
:rule-classes (:rewrite :forward-chaining)))
94
(defthm assoc-properties
96
(and (eqlable-alistp l)
98
(and (consp (assoc x l))
99
(equal (car (assoc x l)) x)))))
102
(defthm eqlablep-car-assoc
104
(and (eqlable-alistp l)
106
(eqlablep (car (assoc x l))))))
111
(defthm assoc-eq-properties
115
(and (consp (assoc-eq x l))
116
(equal (car (assoc-eq x l)) x)))))
118
;;; BOUNDED-INTEGER-ALISTP
121
(defthm bounded-integer-alistp-eqlable-alistp
123
(bounded-integer-alistp l n)
125
:rule-classes (:rewrite :forward-chaining)))
128
(defthm bounded-integer-alistp-car-assoc-properties
130
(and (bounded-integer-alistp l n)
132
(not (equal (car (assoc i l)) :header)))
133
(and (integerp (car (assoc i l)))
134
(>= (car (assoc i l)) 0)
135
(< (car (assoc i l)) n)))))
47
(local (defthm eqlable-alistp-implies-alistp
48
(implies (eqlable-alistp l)
50
:rule-classes (:rewrite :forward-chaining)))
52
(local (defthm assoc-properties
53
(implies (and (eqlable-alistp l)
55
(and (consp (assoc x l))
56
(equal (car (assoc x l)) x)))))
58
(local (defthm eqlablep-car-assoc
59
(implies (and (eqlable-alistp l)
61
(eqlablep (car (assoc x l))))))
63
(local (defthm assoc-eq-properties
64
(implies (and (alistp l)
66
(and (consp (assoc-eq x l))
67
(equal (car (assoc-eq x l)) x)))))
69
(local (defthm bounded-integer-alistp-eqlable-alistp
70
(implies (bounded-integer-alistp l n)
72
:rule-classes (:rewrite :forward-chaining)))
74
(local (defthm bounded-integer-alistp-car-assoc-properties
75
(implies (and (bounded-integer-alistp l n)
77
(not (equal (car (assoc i l)) :header)))
78
(and (integerp (car (assoc i l)))
79
(>= (car (assoc i l)) 0)
80
(< (car (assoc i l)) n)))))
138
83
;;;****************************************************************************
140
85
;;; Local array1 events.
175
120
(car (cadr (assoc-keyword :dimensions (cdr (assoc-eq :header l))))))))
176
121
:rule-classes :forward-chaining))
179
(defthm array1p-header-exists
182
(assoc-eq :header l))))
123
(local (defthm array1p-header-exists
124
(implies (array1p name l)
125
(assoc-eq :header l))))
184
127
; ARRAY1P-CONS (in a slightly different format) is part of the
185
128
; BOOT-STRAP-THEORY of ACL2.
188
(defthm our-array1p-cons
190
(and (array1p name l)
193
(< n (car (dimensions name l))))
194
(array1p name (cons (cons n x) l)))))
130
(local (defthm our-array1p-cons
131
(implies (and (array1p name l)
134
(< n (car (dimensions name l))))
135
(array1p name (cons (cons n x) l)))))
196
137
(local (in-theory (disable array1p)))
198
139
;;; Now, we prove everthing we need to know about COMPRESS11, and then use
199
140
;;; these lemmas to characterize COMPRESS1.
202
(defthm eqlable-alistp-compress11
204
(and (array1p name l)
208
(eqlable-alistp (compress11 name l i n default)))))
211
(defthm bounded-integer-alistp-compress11
213
(and (array1p name l)
218
(bounded-integer-alistp (compress11 name l i n default) n))))
221
(defthm compress11-assoc-property-0
223
(and (array1p name l)
229
(assoc j (compress11 name l i n default)))
230
(equal (assoc j (compress11 name l i n default))
234
(defthm compress11-assoc-property-1
236
(and (array1p name l)
237
(not (assoc j (compress11 name l i n default))) ;Free vars!
245
(equal (cdr (assoc j l))
249
(defthm compress11-assoc-property-2
251
(and (array1p name l)
257
(not (assoc j (compress11 name l i n default))))))
142
(local (defthm eqlable-alistp-compress11
143
(implies (and (array1p name l)
147
(eqlable-alistp (compress11 name l i n default)))))
149
(local (defthm bounded-integer-alistp-compress11
150
(implies (and (array1p name l)
155
(bounded-integer-alistp (compress11 name l i n default) n))))
157
(local (defthm compress11-assoc-property-0
158
(implies (and (array1p name l)
164
(assoc j (compress11 name l i n default)))
165
(equal (assoc j (compress11 name l i n default))
168
(local (defthm compress11-assoc-property-1
169
(implies (and (array1p name l)
170
(not (assoc j (compress11 name l i n default))) ;Free vars!
178
(equal (cdr (assoc j l))
181
(local (defthm compress11-assoc-property-2
182
(implies (and (array1p name l)
188
(not (assoc j (compress11 name l i n default))))))
259
190
; Start events added by Matt K. for Version 3.1, 7/1/06, to support proof of
260
191
; compress1-assoc-property-0 in light of addition of reverse-sorted and
261
192
; unsorted ACL2 arrays.
264
(defthm assoc-revappend-1
265
(implies (not (member key (strip-cars alist1)))
266
(equal (assoc key (revappend alist1 alist2))
267
(assoc key alist2)))))
270
(defthm assoc-revappend
271
(implies (and (force (no-duplicatesp (strip-cars alist1)))
272
(force (alistp alist1)))
273
(equal (assoc key (revappend alist1 alist2))
274
(or (assoc key alist1)
275
(assoc key alist2))))))
278
(defun ordered-alistp (x)
286
(t (and (consp (car x))
288
(< (caar x) (caadr x))
289
(ordered-alistp (cdr x)))))))
292
(defthm no-duplicatesp-strip-cars-ordered-alistp-1
293
(implies (and (< key (caar x))
299
(defthm no-duplicatesp-strip-cars-ordered-alistp
300
(implies (ordered-alistp x)
301
(no-duplicatesp (strip-cars x)))))
304
(defthm consp-assoc-rewrite
307
(consp (assoc key alist)))))
311
(implies (assoc key alist)
312
(equal (car (assoc key alist))
316
(defthm <-caar-compress11
317
(implies (and (< i j)
318
(consp (compress11 name l j n default)))
319
(< i (caar (compress11 name l j n default))))))
322
(defthm ordered-alistp-compress11
323
(implies (and (integerp i)
325
(ordered-alistp (compress11 name l i n default)))))
328
(defthm not-member-strip-cars-compress11
332
(strip-cars (compress11 name l j n default)))))))
335
(defthm no-duplicatesp-strip-cars-compress11
336
(no-duplicatesp (strip-cars (compress11 name l i n default)))))
194
(local (defthm assoc-revappend-1
195
(implies (not (member key (strip-cars alist1)))
196
(equal (assoc key (revappend alist1 alist2))
197
(assoc key alist2)))))
199
(local (defthm assoc-revappend
200
(implies (and (force (no-duplicatesp (strip-cars alist1)))
201
(force (alistp alist1)))
202
(equal (assoc key (revappend alist1 alist2))
203
(or (assoc key alist1)
204
(assoc key alist2))))))
206
(local (defun ordered-alistp (x)
213
(t (and (consp (car x))
215
(< (caar x) (caadr x))
216
(ordered-alistp (cdr x)))))))
218
(local (defthm no-duplicatesp-strip-cars-ordered-alistp-1
219
(implies (and (< key (caar x))
224
(local (defthm no-duplicatesp-strip-cars-ordered-alistp
225
(implies (ordered-alistp x)
226
(no-duplicatesp (strip-cars x)))))
228
(local (defthm consp-assoc-rewrite
231
(consp (assoc key alist)))))
233
(local (defthm car-assoc
234
(implies (assoc key alist)
235
(equal (car (assoc key alist))
238
(local (defthm <-caar-compress11
239
(implies (and (< i j)
240
(consp (compress11 name l j n default)))
241
(< i (caar (compress11 name l j n default))))))
243
(local (defthm ordered-alistp-compress11
244
(implies (and (integerp i)
246
(ordered-alistp (compress11 name l i n default)))))
248
(local (defthm not-member-strip-cars-compress11
251
(strip-cars (compress11 name l j n default)))))))
253
(local (defthm no-duplicatesp-strip-cars-compress11
254
(no-duplicatesp (strip-cars (compress11 name l i n default)))))
338
256
; End events added by Matt K. for Version 3.1, 7/1/06, to support proof of
339
257
; compress1-assoc-property-0 in light of addition of reverse-sorted and
340
258
; unsorted ACL2 arrays.
343
(defthm compress1-assoc-property-0
345
(and (array1p name l)
348
(< n (car (dimensions name l)))
350
(assoc n (compress1 name l)))
351
(equal (cdr (assoc n (compress1 name l)))
352
(cdr (assoc n l))))))
355
(defthm compress1-assoc-property-1
357
(and (array1p name l)
360
(< n (car (dimensions name l)))
362
(not (assoc n (compress1 name l))))
363
(equal (cdr (assoc n l))
364
(cadr (assoc-keyword :default (cdr (assoc-eq :header l))))))))
367
(defthm compress1-assoc-property-2
369
(and (array1p name l)
372
(< n (car (dimensions name l)))
374
(not (assoc n (compress1 name l))))))
377
(defthm header-compress1-crock
380
(equal (assoc-eq :header (compress1 name l))
381
(assoc-eq :header l)))))
260
(local (defthm compress1-assoc-property-0
261
(implies (and (array1p name l)
264
(< n (car (dimensions name l)))
266
(assoc n (compress1 name l)))
267
(equal (cdr (assoc n (compress1 name l)))
268
(cdr (assoc n l))))))
270
(local (defthm compress1-assoc-property-1
271
(implies (and (array1p name l)
274
(< n (car (dimensions name l)))
276
(not (assoc n (compress1 name l))))
277
(equal (cdr (assoc n l))
278
(cadr (assoc-keyword :default (cdr (assoc-eq :header l))))))))
280
(local (defthm compress1-assoc-property-2
282
(and (array1p name l)
285
(< n (car (dimensions name l)))
287
(not (assoc n (compress1 name l))))))
289
(local (defthm header-compress1-crock
290
(implies (array1p name l)
291
(equal (assoc-eq :header (compress1 name l))
292
(assoc-eq :header l)))))
295
(defsection-progn array1-lemmas
297
:short "A @(see theory) of all @(see enable)d rules exported by the @(see
300
:long "<p>Note that in order for these rules to be applicable you will first
301
need to @(see DISABLE) the theory @(see ARRAY1-FUNCTIONS).</p>"
384
303
;;;****************************************************************************
386
305
;;; Exported Events.
394
313
; support proof of compress1-assoc-property-0 in light of addition of
395
314
; reverse-sorted and unsorted ACL2 arrays.
398
(defthm alistp-revappend
400
(equal (alistp (revappend x y))
404
(defthm bounded-integer-alistp-revappend
405
(implies (bounded-integer-alistp x n)
406
(equal (bounded-integer-alistp (revappend x y) n)
407
(bounded-integer-alistp y n)))))
409
(defthm array1p-compress1
412
(array1p name (compress1 name l)))
415
:in-theory (enable array1p)
416
:use array1p-header-exists))
417
:doc ":doc-section array1-lemmas
418
Rewrite: (ARRAY1P name (COMPRESS1 name l)).
421
(defthm array1p-compress1-properties
425
(equal (header name (compress1 name l))
427
(equal (dimensions name (compress1 name l))
429
(equal (maximum-length name (compress1 name l))
430
(maximum-length name l))
431
(equal (default name (compress1 name l))
433
:doc ":doc-section array1-lemmas
435
(HEADER name (COMPRESS1 name l)) = (HEADER name l).
436
(DIMENSIONS name (COMPRESS1 name l)) = (DIMENSIONS name l).
437
(MAXIMUM-LENGTH name (COMPRESS1 name l)) = (MAXIMUM-LENGTH name l).
438
(DEFAULT name (COMPRESS1 name l)) = (DEFAULT name l).
441
; COMPRESS1 is now fully characterized, so we DISABLE it and start proving
442
; the interesting theorems.
444
(local (in-theory (disable compress1)))
446
(defthm array1p-aset1
448
(and (array1p name l)
451
(< n (car (dimensions name l))))
452
(array1p name (aset1 name l n val)))
453
:doc ":doc-section array1-lemmas
454
Rewrite: (ARRAY1P name (ASET1 name l n val)).
457
(defthm array1p-aset1-properties
459
(and (array1p name l)
462
(< n (car (dimensions name l))))
464
(equal (header name (aset1 name l n val))
466
(equal (dimensions name (aset1 name l n val))
468
(equal (maximum-length name (aset1 name l n val))
469
(maximum-length name l))
470
(equal (default name (aset1 name l n val))
472
:doc ":doc-section array1-lemmas
474
(HEADER name (ASET1 name l n val)) = (HEADER name l).
475
(DIMENSIONS name (ASET1 name l n val)) = (DIMENSIONS name l).
476
(MAXIMUM-LENGTH name (ASET1 name l n val)) = (MAXIMUM-LENGTH name l).
477
(DEFAULT name (ASET1 name l n val)) = (DEFAULT name l).
480
(defthm aref1-compress1
482
(and (array1p name l)
485
(< n (car (dimensions name l))))
486
(equal (aref1 name (compress1 name l) n)
488
:doc ":doc-section array1-lemmas
489
Rewrite: (AREF1 name (COMPRESS1 name l) n) = (AREF name l n).
492
(defthm array1p-acons-properties
496
(equal (header name (cons (cons n val) l))
498
(equal (dimensions name (cons (cons n val) l))
500
(equal (maximum-length name (cons (cons n val) l))
501
(maximum-length name l))
502
(equal (default name (cons (cons n val) l))
504
:doc ":doc-section array1-lemmas
506
(HEADER name (CONS n val) l) = (HEADER l) , for integers n.
507
(DIMENSIONS name (CONS n val) l) = (DIMENSIONS l) , for integers n.
508
(MAXIMUM-LENGTH name (CONS n val) l) = (MAXIMUM-LENGTH l), for integers n.
509
(DEFAULT name (CONS n val) l) = (DEFAULT l) , for integers n.
512
(defthm array1p-consp-header
515
(consp (header name l)))
516
:rule-classes :type-prescription
517
:doc ":doc-section array1-lemmas
518
Type-Prescription: (CONSP (HEADER name l)).
521
(defthm array1p-car-header
524
(equal (car (header name l))
526
:doc ":doc-section array1-lemmas
527
Rewrite: (CAR (HEADER name l)) = :HEADER.
317
(defthm alistp-revappend
319
(equal (alistp (revappend x y))
323
(defthm bounded-integer-alistp-revappend
324
(implies (bounded-integer-alistp x n)
325
(equal (bounded-integer-alistp (revappend x y) n)
326
(bounded-integer-alistp y n)))))
328
(defthm array1p-compress1
329
(implies (array1p name l)
330
(array1p name (compress1 name l)))
332
:in-theory (enable array1p)
333
:use array1p-header-exists)))
335
(defthm array1p-compress1-properties
336
(implies (array1p name l)
338
(equal (header name (compress1 name l))
340
(equal (dimensions name (compress1 name l))
342
(equal (maximum-length name (compress1 name l))
343
(maximum-length name l))
344
(equal (default name (compress1 name l))
347
; COMPRESS1 is now fully characterized, so we DISABLE it and start proving
348
; the interesting theorems.
350
(local (in-theory (disable compress1)))
352
(defthm array1p-aset1
353
(implies (and (array1p name l)
356
(< n (car (dimensions name l))))
357
(array1p name (aset1 name l n val))))
359
(defthm array1p-aset1-properties
360
(implies (and (array1p name l)
363
(< n (car (dimensions name l))))
364
(and (equal (header name (aset1 name l n val))
366
(equal (dimensions name (aset1 name l n val))
368
(equal (maximum-length name (aset1 name l n val))
369
(maximum-length name l))
370
(equal (default name (aset1 name l n val))
373
(defthm aref1-compress1
374
(implies (and (array1p name l)
377
(< n (car (dimensions name l))))
378
(equal (aref1 name (compress1 name l) n)
381
(defthm array1p-acons-properties
382
(implies (integerp n)
383
(and (equal (header name (cons (cons n val) l))
385
(equal (dimensions name (cons (cons n val) l))
387
(equal (maximum-length name (cons (cons n val) l))
388
(maximum-length name l))
389
(equal (default name (cons (cons n val) l))
392
(defthm array1p-consp-header
393
(implies (array1p name l)
394
(consp (header name l)))
395
:rule-classes :type-prescription)
397
(defthm array1p-car-header
398
(implies (array1p name l)
399
(equal (car (header name l))
530
402
; These two theorems for the AREF1-ASET1 cases are used to prove a
531
403
; combined result, and then exported DISABLEd.
533
(defthm aref1-aset1-equal
535
(and (array1p name l)
538
(< n (car (dimensions name l))))
539
(equal (aref1 name (aset1 name l n val) n)
541
:doc ":doc-section array1-lemmas
542
Rewrite: (AREF1 name (ASET1 name l n val) n) = val.~/
543
Note that this rule is exported DISABLEd by default in favor of
547
(defthm aref1-aset1-not-equal
549
(and (array1p name l)
552
(< n1 (car (dimensions name l)))
555
(< n2 (car (dimensions name l)))
557
(equal (aref1 name (aset1 name l n1 val) n2)
559
:doc ":doc-section array1-lemmas
560
Rewrite: (AREF1 name (ASET1 name l n1 val) n2) = (AREF1 name l n2),
562
Note that this rule is exported DISABLEd by default in favor of
568
(and (array1p name l)
571
(< n1 (car (dimensions name l)))
574
(< n2 (car (dimensions name l))))
575
(equal (aref1 name (aset1 name l n1 val) n2)
581
:in-theory (disable aref1 aset1)))
582
:doc ":doc-section array1-lemmas
583
Rewrite: (AREF1 name (ASET1 name l n1 val) n2) =
584
(IF (EQUAL n1 n2) val (AREF1 name l n2)).
586
Note that this lemma forces the decision of the equality of n1 and n2. If
587
this causes problems, then DISABLE this lemma and
588
(ENABLE AREF1-ASET1-EQUAL AREF1-ASET1-NOT-EQUAL).~/~/")
590
(in-theory (disable aref1-aset1-equal aref1-aset1-not-equal))
405
(defthm aref1-aset1-equal
406
;; Note that this rule is exported DISABLEd by default in favor of
408
(implies (and (array1p name l)
411
(< n (car (dimensions name l))))
412
(equal (aref1 name (aset1 name l n val) n)
415
(defthm aref1-aset1-not-equal
416
;; Note that this rule is exported DISABLEd by default in favor of
418
(implies (and (array1p name l)
421
(< n1 (car (dimensions name l)))
424
(< n2 (car (dimensions name l)))
426
(equal (aref1 name (aset1 name l n1 val) n2)
430
;; Note that this lemma forces the decision of the equality of n1 and n2. If
431
;; this causes problems, then DISABLE this lemma and (ENABLE
432
;; AREF1-ASET1-EQUAL AREF1-ASET1-NOT-EQUAL)
433
(implies (and (array1p name l)
436
(< n1 (car (dimensions name l)))
439
(< n2 (car (dimensions name l))))
440
(equal (aref1 name (aset1 name l n1 val) n2)
444
:hints (("Goal" :in-theory (disable aref1 aset1))))
446
(in-theory (disable aref1-aset1-equal aref1-aset1-not-equal))
592
448
;;; The final form of the :FORWARD-CHAINING lemma for ARRAY1P.
594
(defthm array1p-forward-modular
599
(keyword-value-listp (cdr (header name l)))
600
(true-listp (dimensions name l))
601
(equal (length (dimensions name l)) 1)
602
(integerp (car (dimensions name l)))
603
(integerp (maximum-length name l))
604
(< 0 (car (dimensions name l)))
605
(<= (car (dimensions name l)) (maximum-length name l))
606
(<= (maximum-length name l) *maximum-positive-32-bit-integer*)
607
(bounded-integer-alistp l (car (dimensions name l)))))
608
:rule-classes :forward-chaining
611
:in-theory (disable length)))
612
:doc ":doc-section array1-lemmas
613
Forward Chaining: A forward definition of (ARRAY1P name l), in terms of
614
HEADER, DIMENSIONS, and MAXIMUM-LENGTH.
616
Note that ACL2 also defines a lemma ARRAY1P-FORWARD, but that lemma
617
is in terms of the expansions of HEADER, DIMENSIONS, and MAXIMUM-LENGTH.
619
One should normaly DISABLE ARRAY1P in favor of this :FORWARD-CHAINING rule.
620
If allowed to open, ARRAY1P can cause severe performance degradation due to
621
its large size and many recursive functions. This lemma is designed to be
622
used with the ARRAY1-FUNCTIONS theory DISABLEd.~/")
450
(defthm array1p-forward-modular
451
;; Forward Chaining: A forward definition of (ARRAY1P name l), in terms of
452
;; HEADER, DIMENSIONS, and MAXIMUM-LENGTH.
454
;; Note that ACL2 also defines a lemma ARRAY1P-FORWARD, but that lemma
455
;; is in terms of the expansions of HEADER, DIMENSIONS, and MAXIMUM-LENGTH.
457
;; One should normaly DISABLE ARRAY1P in favor of this :FORWARD-CHAINING rule.
458
;; If allowed to open, ARRAY1P can cause severe performance degradation due to
459
;; its large size and many recursive functions. This lemma is designed to be
460
;; used with the ARRAY1-FUNCTIONS theory DISABLEd.
461
(implies (array1p name l)
464
(keyword-value-listp (cdr (header name l)))
465
(true-listp (dimensions name l))
466
(equal (length (dimensions name l)) 1)
467
(integerp (car (dimensions name l)))
468
(integerp (maximum-length name l))
469
(< 0 (car (dimensions name l)))
470
(<= (car (dimensions name l)) (maximum-length name l))
471
(<= (maximum-length name l) *maximum-positive-32-bit-integer*)
472
(bounded-integer-alistp l (car (dimensions name l)))))
473
:rule-classes :forward-chaining
474
:hints (("Goal" :in-theory (disable length))))
625
477
;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
627
479
;;; RESET-ARRAY1 name l
631
483
; The proofs for RESET-ARRAY1 require a few LOCAL facts.
637
(equal (car (header name l))
641
(defthm array1p-list-header
644
(array1p name (list (header name l))))
647
:in-theory (enable array1p)))))
650
(defthm header-list-header
653
(equal (header name (list (header name l)))
657
(defthm dimensions-list-header
660
(equal (dimensions name (list (header name l)))
661
(dimensions name l)))))
664
(defthm default-cons-header
667
(equal (default name (cons (header name l) x))
671
(defthm symbol-alistp-list-header
674
(symbol-alistp (list (header name l))))))
677
(defthm symbol-alistp-not-assoc-integer
679
(and (symbol-alistp l)
684
(defthm symbol-alistp-not-compress11
686
(and (symbol-alistp l)
689
(not (compress11 name l i n default)))))
487
(implies (array1p name l)
488
(equal (car (header name l))
492
(defthm array1p-list-header
493
(implies (array1p name l)
494
(array1p name (list (header name l))))
495
:hints (("Goal" :in-theory (enable array1p)))))
498
(defthm header-list-header
499
(implies (array1p name l)
500
(equal (header name (list (header name l)))
504
(defthm dimensions-list-header
505
(implies (array1p name l)
506
(equal (dimensions name (list (header name l)))
507
(dimensions name l)))))
510
(defthm default-cons-header
511
(implies (array1p name l)
512
(equal (default name (cons (header name l) x))
516
(defthm symbol-alistp-list-header
517
(implies (array1p name l)
518
(symbol-alistp (list (header name l))))))
521
(defthm symbol-alistp-not-assoc-integer
522
(implies (and (symbol-alistp l)
527
(defthm symbol-alistp-not-compress11
528
(implies (and (symbol-alistp l)
531
(not (compress11 name l i n default))))))
691
534
; HEADER, DEFAULT, and DIMENSIONS are characterized, so we DISABLE them.
693
536
(local (in-theory (disable header default dimensions)))
695
(defun reset-array1 (name l)
697
Clear an 1-dimensional array.
699
The function (RESET-ARRAY1 name l) returns a 1-dimensional array whose
700
alist is simply the HEADER of l. This has the effect of resetting the
701
array, i.e., reading the new array at any address will return the default
702
value. The implementation is simply to redefine the array as the HEADER of
703
the old array. Thus all of the HEADER information is carried over to the
706
Note that an alternate definition is available as the lemma RESET-ARRAY1*.
709
(declare (xargs :guard (array1p name l)))
711
(compress1 name (list (header name l))))
713
(defthm reset-array1*
716
(equal (reset-array1 name l)
717
(list (header name l))))
720
:in-theory (enable compress1 compress11)))
721
:doc ":doc-section reset-array1
722
Rewrite: (RESET-ARRAY1 name l) = (LIST (HEADER name l)).
724
This definition of RESET-ARRAY1 is logically equivalent to the actual
725
definition. The actual definition, which includes a COMPRESS1 call, has the
726
run-time side-effect of re-installing the new array. The COMPRESS1 is
727
logically redundant, however.
729
This lemma is exported DISABLED, however this is the preferred definition
730
to use to reason about RESET-ARRAY1. ~/ ")
538
(defsection reset-array1
540
:short "Clear an 1-dimensional array."
541
:long "<p>The function (RESET-ARRAY1 name l) returns a 1-dimensional array
542
whose alist is simply the HEADER of l. This has the effect of resetting the
543
array, i.e., reading the new array at any address will return the default
544
value. The implementation is simply to redefine the array as the HEADER of the
545
old array. Thus all of the HEADER information is carried over to the new
548
<p>Note that an alternate definition is available as the lemma
551
(defun reset-array1 (name l)
552
(declare (xargs :guard (array1p name l)))
553
(compress1 name (list (header name l)))))
555
(defsection reset-array1*
556
:parents (reset-array1)
557
:short "Rewrite: (RESET-ARRAY1 name l) = (LIST (HEADER name l))."
558
:long "<p>This definition of RESET-ARRAY1 is logically equivalent to the
559
actual definition. The actual definition, which includes a COMPRESS1 call, has
560
the run-time side-effect of re-installing the new array. The COMPRESS1 is
561
logically redundant, however.</p>
563
<p>This lemma is exported DISABLED, however this is the preferred definition to
564
use to reason about RESET-ARRAY1.</p>"
566
(defthm reset-array1*
567
(implies (array1p name l)
568
(equal (reset-array1 name l)
569
(list (header name l))))
570
:hints (("Goal" :in-theory (enable compress1 compress11)))))
732
572
; We can now reason with the simple definition RESET-ARRAY1*.
734
574
(local (in-theory (disable reset-array1)))
736
(defthm array1p-reset-array1
739
(array1p name (reset-array1 name l)))
740
:doc ":doc-section array1-lemmas
741
Rewrite: (ARRAY1P name (RESET-ARRAY1 name l)).
744
(defthm array1p-reset-array1-properties
748
(equal (header name (reset-array1 name l))
750
(equal (dimensions name (reset-array1 name l))
752
(equal (maximum-length name (reset-array1 name l))
753
(maximum-length name l))
754
(equal (default name (reset-array1 name l))
756
:doc ":doc-section array1-lemmas
758
(HEADER name (RESET-ARRAY1 name l)) = (HEADER name l).
759
(DIMENSIONS name (RESET-ARRAY1 name l)) = (DIMENSIONS name l).
760
(MAXIMUM-LENGTH name (RESET-ARRAY1 name l)) = (MAXIMUM-LENGTH name l).
761
(DEFAULT name (RESET-ARRAY1 name l)) = (DEFAULT name l).
764
(defthm aref1-reset-array1
766
(and (array1p name l)
768
(equal (aref1 name (reset-array1 name l) index)
576
(defsection-progn reset-array1-lemmas
577
:extension reset-array1
579
(defthm array1p-reset-array1
580
(implies (array1p name l)
581
(array1p name (reset-array1 name l))))
583
(defthm array1p-reset-array1-properties
584
(implies (array1p name l)
585
(and (equal (header name (reset-array1 name l))
587
(equal (dimensions name (reset-array1 name l))
589
(equal (maximum-length name (reset-array1 name l))
590
(maximum-length name l))
591
(equal (default name (reset-array1 name l))
594
(defthm aref1-reset-array1
595
(implies (and (array1p name l)
597
(equal (aref1 name (reset-array1 name l) index)
771
600
(in-theory (disable reset-array1*))
774
603
;;;****************************************************************************
778
607
;;;****************************************************************************
780
(deftheory array1-functions
781
'(array1p aset1 aref1 compress1 header dimensions maximum-length
782
default reset-array1)
783
:doc ":doc-section array1
784
A theory of all functions specific to 1-dimensional arrays.
786
This theory must be DISABLEd in order for the lemmas exported by the
787
\"array1\" book to be applicable.~/~/")
789
(deftheory array1-lemmas
609
(defsection array1-functions
611
:short "A theory of all functions specific to 1-dimensional arrays."
612
:long "<p>This theory must be DISABLEd in order for the lemmas exported by
613
the \"array1\" book to be applicable.</p>"
615
(deftheory array1-functions
616
'(array1p aset1 aref1 compress1 header dimensions maximum-length
617
default reset-array1)))
619
(deftheory array1-lemmas
790
620
'(array1p-compress1
791
621
array1p-compress1-properties
792
622
array1p-aset1 array1p-aset1-properties
796
626
array1p-reset-array1 array1p-reset-array1-properties
797
627
aref1-reset-array1))
799
(deftheory array1-disabled-lemmas
800
'(aref1-aset1-equal aref1-aset1-not-equal reset-array1*)
801
:doc ":doc-section array1
803
A theory of all rules exported DISABLEd by the \"array1\" book.
806
Note that in order for these rules to be applicable you will first need to
807
(DISABLE ARRAY1-FUNCTIONS). Look at the :DOC for each lemma for an
808
explanation of why the lemma is exported DISABLEd. The following rules are
809
found in this theory:~/~/
811
:cite aref1-aset1-equal
812
:cite aref1-aset1-not-equal
813
:cite reset-array1*")
629
(defsection array1-disabled-lemmas
630
:short "A theory of all rules exported DISABLEd by the \"array1\" book."
631
:long "<p>Note that in order for these rules to be applicable you will first
632
need to disable @(see array1-functions). Look at the :DOC for each lemma for
633
an explanation of why the lemma is exported DISABLEd.</p>"
635
(deftheory array1-disabled-lemmas
636
'(aref1-aset1-equal aref1-aset1-not-equal reset-array1*)))
816
639
;;;****************************************************************************
818
641
;;; DEFARRAY1TYPE
820
643
;;;****************************************************************************
645
(defsection defarray1type
647
:short "Characterize 1-dimensional arrays with a fixed element type."
648
:long "<p>Example form:</p>
651
(DEFARRAY1TYPE INTEGERP-ARRAY1P INTEGERP)
654
<p>The above example defines a recognizer, INTEGERP-ARRAYP, for 1-dimensional
655
arrays whose elements are all INTEGERP.</p>
660
(DEF1ARRAYTYPE recognizer predicate
662
(aref1-lemma-rule-classes ':REWRITE)
663
(aset1-lemma-rule-classes ':REWRITE))
666
<p>DEFARRAY1TYPE defines a recognizer for 1-dimensional arrays whose elements
667
are all of a single type. The recognizer argument is a symbol that is used as
668
the name of the recognizer. The predicate argument should be a 1-argument,
669
unguarded Boolean function that recognizes objects of the desired type. The
670
predicate may either be a symbol (the name of the predicate), or a LAMBDA
673
<p>If :SIZE is specified it should be a variable-free term that will evaluate
674
to a positive integer. If specified, then the recognizer will only recognize
675
1-dimensional arrays of the given type and of a fixed size.</p>
677
<p>If :DOC is specified it should be a string, and it will be inserted as the
678
documentation string in the recognizer.</p>
680
<p>DEFARRAY1TYPE defines a recognizer:</p>
682
@({ (recognizer NAME L) })
684
<p>and proves 4 useful theorems about it. If the :SIZE is not specified then
685
the three theorems will be:</p>
688
1. (IMPLIES (recognizer NAME L)
691
2. (IMPLIES (AND (recognizer NAME L)
693
(predicate (AREF1 NAME L N)))
695
3. (IMPLIES (AND (recognizer NAME L)
696
(< N (CAR (DIMENSIONS NAME L)))
700
(recognizer NAME (ASET1 NAME L N VAL)))
702
4. (IMPLIES (recognizer NAME l)
703
(recognizer NAME (RESET-ARRAY1 name l)))
706
<p>If :SIZE is specified then the first and third theorems become:</p>
709
1. (IMPLIES (recognizer NAME L)
710
(AND (ARRAY1P NAME L)
711
(EQUAL (CAR (DIMENSIONS name l))
714
3. (IMPLIES (AND (recognizer NAME L)
719
(recognizer NAME (ASET1 NAME L N VAL)))
722
<p>The first theorem is stored as both :REWRITE and :FORWARD-CHAINING rules.
723
The :RULE-CLASSES of the second and third lemmas default to :REWRITE, but are
724
selectable by the user by means of the :AREF1-LEMMA-RULE-CLASSES and
725
:ASET1-LEMMA-RULE-CLASSSES arguments to DEFARRAY1TYPE (respectively). If
726
using :RULE-CLASSES other than :REWRITE the user should bear in mind the
727
documented restrictions on the applicability of :TYPE-PRESCRIPTION and
728
:FORWARD-CHAINING rules. The fourth rule is always a :REWRITE rule.</p>
730
<p>Note the the recognizer is a very strong recognizer that specifies that the
731
array alist is a BOUNDED-INTEGER-ALISTP whose elements all satisfy the type
732
predicate. The recognizer also specifies that the default element of the array
733
satisfies the predicate as well.</p>
735
<p>WARNING: The recognizer is defined in terms of a recursive recognizer, named
736
@('<recognizer>-FN'). THE RECURSIVE RECOGNIZER SHOULD BE COMPILED BEFORE YOU
737
TRY TO EXECUTE IT, OR IT MAY CAUSE A STACK OVERFLOW. Also note that the
738
recognizer will be DISABLEd after execution of this macro. The user must
739
insure that the recognizer remains DISABLEd, otherwise the above lemmas will
740
never be applied.</p>
742
<p>DEFARRAY1TYPE proves the generated lemmas in a minimal, ENCAPSULATEd theory
743
that should guarantee that the proofs always succeed. If one should encounter
744
a case where a proof fails (as opposed to a translation or other syntax
745
failure), please notify the author.</p>")
822
747
(defmacro defarray1type
823
748
(recognizer predicate &key
825
750
(aref1-lemma-rule-classes ':REWRITE)
826
751
(aset1-lemma-rule-classes ':REWRITE))
830
Characterize 1-dimensional arrays with a fixed element type.
835
(DEFARRAY1TYPE INTEGERP-ARRAY1P INTEGERP)
837
The above example defines a recognizer, INTEGERP-ARRAYP, for 1-dimensional
838
arrays whose elements are all INTEGERP.~/
842
(DEF1ARRAYTYPE recognizer predicate
844
(aref1-lemma-rule-classes ':REWRITE)
845
(aset1-lemma-rule-classes ':REWRITE))
847
DEFARRAY1TYPE defines a recognizer for 1-dimensional arrays whose elements
848
are all of a single type. The recognizer argument is a symbol that is used
849
as the name of the recognizer. The predicate argument should be a
850
1-argument, unguarded Boolean function that recognizes objects of the
851
desired type. The predicate may either be a symbol (the name of the
852
predicate), or a LAMBDA expression.
854
If :SIZE is specified it should be a variable-free term that will evaluate
855
to a positive integer. If specified, then the recognizer will only
856
recognize 1-dimensional arrays of the given type and of a fixed size.
858
If :DOC is specified it should be a string, and it will be inserted as the
859
documentation string in the recognizer.
861
DEFARRAY1TYPE defines a recognizer:
865
and proves 4 useful theorems about it. If the :SIZE is not specified then
866
the three theorems will be:
873
(AND (recognizer NAME L)
875
(predicate (AREF1 NAME L N)))
878
(AND (recognizer NAME L)
879
(< N (CAR (DIMENSIONS NAME L)))
883
(recognizer NAME (ASET1 NAME L N VAL)))
887
(recognizer NAME (RESET-ARRAY1 name l)))
889
If :SIZE is specified then the first and third theorems become:
893
(AND (ARRAY1P NAME L)
894
(EQUAL (CAR (DIMENSIONS name l))
898
(AND (recognizer NAME L)
903
(recognizer NAME (ASET1 NAME L N VAL)))
905
The first theorem is stored as both :REWRITE and :FORWARD-CHAINING rules.
906
The :RULE-CLASSES of the second and third lemmas default to :REWRITE, but
907
are selectable by the user by means of the :AREF1-LEMMA-RULE-CLASSES and
908
:ASET1-LEMMA-RULE-CLASSSES arguments to DEFARRAY1TYPE (respectively). If
909
using :RULE-CLASSES other than :REWRITE the user should bear in mind the
910
documented restrictions on the applicability of :TYPE-PRESCRIPTION and
911
:FORWARD-CHAINING rules. The fourth rule is always a :REWRITE rule.
913
Note the the recognizer is a very strong recognizer that specifies that the
914
array alist is a BOUNDED-INTEGER-ALISTP whose elements all satisfy the type
915
predicate. The recognizer also specifies that the default element of the
916
array satisfies the predicate as well.
918
WARNING: The recognizer is defined in terms of a recursive recoignizer,
919
named <recognizer>-FN. THE RECURSIVE RECOGNIZER SHOULD BE COMPILED BEFORE
920
YOU TRY TO EXECUTE IT, OR IT MAY CAUSE A STACK OVERFLOW. Also note that
921
the recognizer will be DISABLEd after execution of this macro. The user
922
must insure that the recognizer remains DISABLEd, otherwise the above
923
lemmas will never be applied.
925
DEFARRAY1TYPE proves the generated lemmas in a minimal, ENCAPSULATEd theory
926
that should guarantee that the proofs always succeed. If one should
927
encounter a case where a proof fails (as opposed to a translation or other
928
syntax failure), please notify the author.~/"
930
753
(declare (xargs :guard (and (symbolp recognizer)
931
754
(pseudo-termp predicate)
932
755
(implies doc (stringp doc)))))
999
822
(DEFTHM DEFARRAY1TYPE-ASSOC-PROPERTIES
1001
(AND (,recognizer-fn L N)
1004
(AND (CONSP (ASSOC I L))
1005
(INTEGERP (CAR (ASSOC I L)))
1006
(>= (CAR (ASSOC I L)) 0)
1007
(< (CAR (ASSOC I L)) N)
1008
(,predicate (CDR (ASSOC I L)))))))
823
(IMPLIES (AND (,recognizer-fn L N)
826
(AND (CONSP (ASSOC I L))
827
(INTEGERP (CAR (ASSOC I L)))
828
(>= (CAR (ASSOC I L)) 0)
829
(< (CAR (ASSOC I L)) N)
830
(,predicate (CDR (ASSOC I L)))))))
1011
833
(DEFTHM DEFARRAY1TYPE-CONS-HEADER
1014
(EQUAL (,recognizer-fn (CONS (HEADER NAME L) X) MAX)
1015
(,recognizer-fn X MAX)))))
834
(IMPLIES (ARRAY1P NAME L)
835
(EQUAL (,recognizer-fn (CONS (HEADER NAME L) X) MAX)
836
(,recognizer-fn X MAX)))))
1018
839
(DEFTHM DEFARRAY1TYPE-COMPRESS11
1020
(AND (,recognizer-fn L N)
1023
(,recognizer-fn (COMPRESS11 NAME L I N DEFAULT)
840
(IMPLIES (AND (,recognizer-fn L N)
843
(,recognizer-fn (COMPRESS11 NAME L I N DEFAULT)
1027
847
(DEFTHM DEFARRAY1TYPE-ASET1
1029
(AND (ARRAY1P NAME L)
1030
(EQUAL SIZE (CAR (DIMENSIONS NAME L)))
1031
(,recognizer-fn L SIZE)
1032
(,predicate (DEFAULT NAME L))
1037
(,recognizer-fn (ASET1 NAME L N VAL) SIZE))
1040
:IN-THEORY (ENABLE COMPRESS1 ASET1)))))
848
(IMPLIES (AND (ARRAY1P NAME L)
849
(EQUAL SIZE (CAR (DIMENSIONS NAME L)))
850
(,recognizer-fn L SIZE)
851
(,predicate (DEFAULT NAME L))
856
(,recognizer-fn (ASET1 NAME L N VAL) SIZE))
857
:HINTS (("GOAL" :IN-THEORY (ENABLE COMPRESS1 ASET1)))))
1043
860
(DEFTHM DEFARRAY1TYPE-RESET-ARRAY1
1046
(,recognizer-fn (RESET-ARRAY1 NAME L) N))
1049
:IN-THEORY (ENABLE RESET-ARRAY1*)))))
861
(IMPLIES (ARRAY1P NAME L)
862
(,recognizer-fn (RESET-ARRAY1 NAME L) N))
863
:HINTS (("Goal" :IN-THEORY (ENABLE RESET-ARRAY1*)))))
1051
865
;; The recognizer lemma.
1053
867
(DEFTHM ,recognizer-lemma
1055
(,recognizer NAME L)
1056
(AND (ARRAY1P NAME L)
1057
,@(if size (list `(EQUAL (CAR (DIMENSIONS NAME L)) ,size))
868
(IMPLIES (,recognizer NAME L)
869
(AND (ARRAY1P NAME L)
870
,@(if size (list `(EQUAL (CAR (DIMENSIONS NAME L)) ,size))
1059
872
:RULE-CLASSES (:REWRITE :FORWARD-CHAINING))
1061
874
;; AREF1 returns objects of the proper type.
1063
876
(DEFTHM ,aref1-lemma
1065
(AND (,recognizer NAME L)
1067
(,predicate (AREF1 NAME L N)))
877
(IMPLIES (AND (,recognizer NAME L)
879
(,predicate (AREF1 NAME L N)))
1068
880
:RULE-CLASSES ,aref1-lemma-rule-classes
1071
:IN-THEORY (ENABLE AREF1))))
881
:HINTS (("Goal" :IN-THEORY (ENABLE AREF1))))
1073
883
;; ASET1 returns arrays of the proper type.
1075
885
(DEFTHM ,aset1-lemma
1077
(AND (,recognizer NAME L)
1082
(,recognizer NAME (ASET1 NAME L N VAL)))
886
(IMPLIES (AND (,recognizer NAME L)
891
(,recognizer NAME (ASET1 NAME L N VAL)))
1083
892
:RULE-CLASSES ,aset1-lemma-rule-classes)
1085
894
;; RESET-ARRAY1 returns arrays of the proper type.
1087
896
(defthm ,reset-array1-lemma
1089
(,recognizer name l)
1090
(,recognizer name (reset-array1 name l))))
897
(implies (,recognizer name l)
898
(,recognizer name (reset-array1 name l))))
1092
900
;; DISABLE the recognizer.
1094
902
(IN-THEORY (DISABLE ,recognizer)))))
b'\\ No newline at end of file'