summaryrefslogtreecommitdiff
path: root/books/workshops/2002/kaufmann-sumners/support/records.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'books/workshops/2002/kaufmann-sumners/support/records.lisp')
-rw-r--r--books/workshops/2002/kaufmann-sumners/support/records.lisp306
1 files changed, 306 insertions, 0 deletions
diff --git a/books/workshops/2002/kaufmann-sumners/support/records.lisp b/books/workshops/2002/kaufmann-sumners/support/records.lisp
new file mode 100644
index 0000000..5fdaf9d
--- /dev/null
+++ b/books/workshops/2002/kaufmann-sumners/support/records.lisp
@@ -0,0 +1,306 @@
+; Rob Sumners
+
+(in-package "ACL2")
+
+#|
+
+We define properties of a generic record accessor function and updater
+function. The basic functions are (g a r) and (s a v r) where a is an
+address/key, v is a value, r is a record, and (g a r) returns the value set to
+address a in record r, and (s a v r) returns a new record with address a set to
+value v in record r.
+
+The following main lemmas are "exported" about record (g)et and (s)et:
+
+(defthm g-same-s
+ (equal (g a (s a v r))
+ v))
+
+(defthm g-diff-s
+ (implies (not (equal a b))
+ (equal (g a (s b v r))
+ (g a r))))
+
+(defthm s-same-g
+ (equal (s a (g a r) r)
+ r))
+
+(defthm s-same-s
+ (equal (s a y (s a x r))
+ (s a y r)))
+
+(defthm s-diff-s
+ (implies (not (equal a b))
+ (equal (s b y (s a x r))
+ (s a x (s b y r))))
+ :rule-classes ((:rewrite :loop-stopper ((b a s)))))
+
+We also include some auxiliary lemmas which have proven useful.
+
+(defthm access-of-nil-is-nil
+ (not (g a nil)))
+
+(defthm record-set-cannot-be-nil
+ (implies v (s a v r)))
+
+(defthm record-get-non-nil-cannot-be-nil
+ (implies (g a r) r))
+
+We normalize the record structures (which allows the 'equal-ity based rewrite
+rules) as alists where the keys (cars) are ordered using the total-order added
+to ACL2 and defined in the included book. We define a set of "-aux" functions
+which assume well-formed records -- defined by rcdp -- and then prove the
+desired properties using hypothesis assuming well-formed records.
+
+We then remove these well-formed record hypothesis by defining an invertible
+mapping (acl2->rcd) taking any ACL2 object and returning a well-formed
+record. We then prove the desired properties using the proper translations of
+the -aux functions to the acl2 objects, and subsequently remove the
+well-formed record hypothesis.
+
+|#
+
+(include-book "../../../../misc/total-order")
+
+;; BEGIN records definitions.
+
+(defun rcdp (x)
+ (declare (xargs :guard t))
+ (or (null x)
+ (and (consp x)
+ (consp (car x))
+ (rcdp (cdr x))
+ (cdar x)
+ (or (null (cdr x))
+ (<< (caar x) (caadr x))))))
+
+(defthm rcdp-implies-alistp
+ (implies (rcdp x) (alistp x)))
+
+(defun ifrp (x) ;; ill-formed rcdp
+ (declare (xargs :guard t))
+ (or (not (rcdp x))
+ (and (consp x)
+ (null (cdr x))
+ (consp (car x))
+ (null (caar x))
+ (ifrp (cdar x)))))
+
+(defun acl2->rcd (x) ;; function mapping acl2 objects to well-formed records.
+ (declare (xargs :guard t))
+ (if (ifrp x) (list (cons nil x)) x))
+
+(defun rcd->acl2 (x) ;; inverse of acl2->rcd.
+ (declare (xargs :guard (rcdp x)))
+ (if (ifrp x) (cdar x) x))
+
+(defun g-aux (a x) ;; record g(et) when x is a well-formed record.
+ (declare (xargs :guard (rcdp x)))
+ (cond ((or (endp x)
+ (<< a (caar x)))
+ nil)
+ ((equal a (caar x))
+ (cdar x))
+ (t
+ (g-aux a (cdr x)))))
+
+;; we use the name g-aux in this book, but used rcd-access in the paper for
+;; presentation reasons. Here we simply document their equivalence using the
+;; following macro.
+(defmacro rcd-access (a r)
+ `(g-aux ,a ,r))
+
+(defun g (a x) ;; the generic record g(et) which works on any ACL2 object.
+ (declare (xargs :guard t))
+ (g-aux a (acl2->rcd x)))
+
+(defun acons-if (a v x)
+ (declare (xargs :guard (rcdp x)))
+ (if v (acons a v x) x))
+
+(defun s-aux (a v r) ;; record s(et) when x is a well-formed record.
+ (declare (xargs :guard (rcdp r)))
+ (cond ((or (endp r)
+ (<< a (caar r)))
+ (acons-if a v r))
+ ((equal a (caar r))
+ (acons-if a v (cdr r)))
+ (t
+ (cons (car r) (s-aux a v (cdr r))))))
+
+;; we use the name s-aux in this book, but used rcd-update in the paper for
+;; presentation reasons. Here we simply document their equivalence using the
+;; following macro.
+(defmacro rcd-update (a v r)
+ `(s-aux ,a ,v ,r))
+
+;; we need the following theorems in order to get the guard for s to verify.
+
+(local
+(defthm s-aux-is-bounded
+ (implies (and (rcdp r)
+ (s-aux a v r)
+ (<< e a)
+ (<< e (caar r)))
+ (<< e (caar (s-aux a v r))))))
+
+(local
+(defthm s-aux-preserves-rcdp
+ (implies (rcdp r)
+ (rcdp (s-aux a v r)))))
+
+(defun s (a v x) ;; the generic record s(et) which works on any ACL2 object.
+ (declare (xargs :guard t))
+ (rcd->acl2 (rcd-update a v (acl2->rcd x))))
+
+
+;;;; basic property of records ;;;;
+
+(local
+(defthm rcdp-implies-true-listp
+ (implies (rcdp x)
+ (true-listp x))
+ :rule-classes (:forward-chaining
+ :rewrite)))
+
+
+;;;; initial properties of s-aux and g-aux ;;;;
+
+(local
+(defthm g-aux-same-s-aux
+ (implies (rcdp r)
+ (equal (g-aux a (s-aux a v r))
+ v))))
+
+(local
+(defthm g-aux-diff-s-aux
+ (implies (and (rcdp r)
+ (not (equal a b)))
+ (equal (g-aux a (s-aux b v r))
+ (g-aux a r)))))
+
+(local
+(defthm s-aux-same-g-aux
+ (implies (rcdp r)
+ (equal (s-aux a (g-aux a r) r)
+ r))))
+
+(local
+(defthm s-aux-same-s-aux
+ (implies (rcdp r)
+ (equal (s-aux a y (s-aux a x r))
+ (s-aux a y r)))))
+
+(local
+(defthm s-aux-diff-s-aux
+ (implies (and (rcdp r)
+ (not (equal a b)))
+ (equal (s-aux b y (s-aux a x r))
+ (s-aux a x (s-aux b y r))))
+ :rule-classes ((:rewrite :loop-stopper ((b a s))))))
+
+(local
+(defthm s-aux-non-nil-cannot-be-nil
+ (implies (and v (rcdp r))
+ (s-aux a v r))))
+
+(local
+(defthm g-aux-is-nil-for-<<
+ (implies (and (rcdp r)
+ (<< a (caar r)))
+ (equal (g-aux a r) nil))))
+
+
+;;;; properties of acl2->rcd and rcd->acl2 ;;;;
+
+(local
+(defthm acl2->rcd-rcd->acl2-of-rcdp
+ (implies (rcdp x)
+ (equal (acl2->rcd (rcd->acl2 x))
+ x))))
+
+(local
+(defthm acl2->rcd-returns-rcdp
+ (rcdp (acl2->rcd x))))
+
+(local
+(defthm acl2->rcd-preserves-equality
+ (iff (equal (acl2->rcd x) (acl2->rcd y))
+ (equal x y))))
+
+(local
+(defthm rcd->acl2-acl2->rcd-inverse
+ (equal (rcd->acl2 (acl2->rcd x)) x)))
+
+(local
+(defthm rcd->acl2-of-record-non-nil
+ (implies (and r (rcdp r))
+ (rcd->acl2 r))))
+
+(in-theory (disable acl2->rcd rcd->acl2))
+
+
+;;;; final (exported) properties of record g(et) and s(et) ;;;;
+
+;; NOTE that these theorems basically follow from the "equivalent" properties
+;; for s-aux and g-aux with rcdp hypothesis, and the lemmas about the acl2->rcd
+;; and its inverse rcd->acl2. If the user wanted to add to the following set of
+;; exported theorems, they should add the corresponding lemma about s-aux and
+;; g-aux using rcdp hypothesis and then add the theorem here about the generic
+;; s(et) and g(et) they wish to export from the book.
+
+(defthm g-same-s
+ (equal (g a (s a v r))
+ v))
+
+(defthm g-diff-s
+ (implies (not (equal a b))
+ (equal (g a (s b v r))
+ (g a r))))
+
+;;;; NOTE: The following can be used instead of the above rules to force ACL2
+;;;; to do a case-split. We disable this rule by default since it can lead to
+;;;; an expensive case explosion, but in many cases, this rule may be more
+;;;; effective than two rules above and should be enabled.
+
+(defthm g-of-s-redux
+ (equal (g a (s b v r))
+ (if (equal a b) v (g a r))))
+
+(in-theory (disable g-of-s-redux))
+
+(defthm s-same-g
+ (equal (s a (g a r) r)
+ r))
+
+(defthm s-same-s
+ (equal (s a y (s a x r))
+ (s a y r)))
+
+(defthm s-diff-s
+ (implies (not (equal a b))
+ (equal (s b y (s a x r))
+ (s a x (s b y r))))
+ :rule-classes ((:rewrite :loop-stopper ((b a s)))))
+
+;; the following theorems are less relevant but have been useful in dealing
+;; with a default record of NIL.
+
+(defthm g-of-nil-is-nil
+ (not (g a nil)))
+
+(defthm s-non-nil-cannot-be-nil
+ (implies v (s a v r))
+ :hints (("Goal"
+ :in-theory (disable rcd->acl2-of-record-non-nil)
+ :use (:instance rcd->acl2-of-record-non-nil
+ (r (s-aux a v (acl2->rcd r)))))))
+
+(defthm non-nil-if-g-non-nil
+ (implies (g a r) r)
+ :rule-classes :forward-chaining)
+
+;; We disable s and g, assuming the rules proven in this book are sufficient to
+;; manipulate record terms which are encountered.
+
+(in-theory (disable s g))