summaryrefslogtreecommitdiff
path: root/books/workshops/2000/manolios/pipeline/trivial/sawada-model
diff options
context:
space:
mode:
authorCamm Maguire <camm@debian.org>2017-05-08 12:58:52 -0400
committerCamm Maguire <camm@debian.org>2017-05-08 12:58:52 -0400
commit092176848cbfd27b96c323cc30c54dff4c4a6872 (patch)
tree91b91b4db76805fd2a09de0745b22080a9ebd335 /books/workshops/2000/manolios/pipeline/trivial/sawada-model
Import acl2_7.4dfsg.orig.tar.gz
[dgit import orig acl2_7.4dfsg.orig.tar.gz]
Diffstat (limited to 'books/workshops/2000/manolios/pipeline/trivial/sawada-model')
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/README43
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux-def.lisp56
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux.lisp738
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.acl24
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.lisp963
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-lemmas.lisp846
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/ihs.lisp155
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/model.lisp374
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/proof.lisp938
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/table-def.lisp487
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/trivia.lisp99
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.acl24
-rw-r--r--books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.lisp104
13 files changed, 4811 insertions, 0 deletions
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/README b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/README
new file mode 100644
index 0000000..efc9c72
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/README
@@ -0,0 +1,43 @@
+The Verification Proof Script for the Three-Stage Pipelined Machine
+
+Author: Jun Sawada (sawada@cs.utexas.edu)
+
+1. Files in this Directory
+
+This directory contains the ACL2 books that define and verify the
+three-stage pipelined machine discussed in the book.
+There are three types of files: a makefile, files with the ".lisp"
+extension, and files with the ".acl2" extension. The makefile is used
+for the Unix make command. The files with ".lisp" extension are ACL2
+books which includes the ACL2 functions and theorems. The files with
+".acl2" extension are used during the certification process.
+
+
+Following is the list of files with the ".lisp" extension:
+
+b-ops-aux-def.lisp: Auxiliary definitions to the IHS library.
+b-ops-aux.lisp: Auxiliary theorems to the IHS library.
+basic-def.lisp: The definitions of basic machine components.
+basic-lemmas.lisp: Basic theorems about the pipelined machine.
+ihs.lisp: Loads the IHS library and set the proper theory.
+model.lisp: The definition of the three-stage pipelined machine.
+proof.lisp: Proof of the commutative diagram.
+table-def.lisp: The definition of the intermediate abstraction MAETT.
+trivia.lisp: Some trivial lemmas.
+utils.lisp: Definitions of utility functions.
+
+
+How to re-certify the ACL2 book:
+
+1. You may have to modify the paths to the ACL2 public libraries. At
+this moment, the ACL2 does not provide a uniform method to load ACL2
+public libraries whose absolute path names may vary. For example, the
+IHS libraries are typically found in the "ihs" directory of the "book"
+directory of the root directory for the ACL2 source code, but the ACL2
+root directory is decided when it is installed. If the load path to
+the public libraries are not set properly, the certification process
+fails. You may have to change all the paths one-by-one.
+
+
+2 Run "make".
+
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux-def.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux-def.lisp
new file mode 100644
index 0000000..5f8a4ce
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux-def.lisp
@@ -0,0 +1,56 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; b-ops-aux-def.lisp
+; This file contains definitions of auxiliary definition of bit operations.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(in-package "ACL2")
+
+;; [Jared] changed this book to just be an include of the identical book
+(include-book "workshops/1999/pipeline/b-ops-aux-def" :dir :system)
+
+;; (include-book "trivia")
+;; (include-book "ihs")
+
+;; (deflabel begin-b-ops-aux-def)
+
+;; ;; Bs-and takes arbitrary number of bits. It returns 1 if all
+;; ;; arguments are 1's, otherwise return 0.
+;; (defmacro bs-and (x y &rest rst)
+;; (xxxjoin 'b-and (cons x (cons y rst))))
+
+;; ;; Bs-and takes arbitrary number of bits. It returns 1 if any
+;; ;; argument is 1, otherwise return 0.
+;; (defmacro bs-ior (x y &rest rst)
+;; (xxxjoin 'b-ior (cons x (cons y rst))))
+
+;; ;; b1p returns T if x is 1, nil if x is 0.
+;; (defun b1p (x)
+;; (declare (xargs :guard (bitp x)))
+;; (not (zbp x)))
+
+;; ;; Bit if operation.
+;; (defmacro b-if (test a1 ax)
+;; `(if (b1p ,test) ,a1 ,ax))
+
+;; ;; N-bit bit vector comparator. If the least significant n-bit of
+;; ;; vectors x and y are equal, bv-eqv returns 1.
+;; (defun bv-eqv (n x y)
+;; (declare (xargs :guard (and (integerp x) (integerp y)
+;; (integerp n) (<= 0 n))))
+;; (if (equal (loghead n x) (loghead n y)) 1 0))
+
+;; (defthm bitp-bv-eqv
+;; (bitp (bv-eqv n x y)))
+
+;; (defthm bit-p-unsigned-byte-p-1
+;; (implies (bitp x)
+;; (unsigned-byte-p 1 x))
+;; :hints (("Goal" :in-theory (enable unsigned-byte-p bitp))))
+
+;; ;; Note on disabled and enabled functions
+;; ;; All bit operations except for b-if are disabled. We'd like to
+;; ;; deal with bit operations without opening them. However, enabling
+;; ;; b-if allows the prover to examine cases automatically.
+
+;; (in-theory (disable b1p))
+;; (in-theory (disable bv-eqv))
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux.lisp
new file mode 100644
index 0000000..4854fdc
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/b-ops-aux.lisp
@@ -0,0 +1,738 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; b-ops-aux.lisp:
+;; This file contains auxiliary lemmas to assist the IHS library
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(in-package "ACL2")
+
+;; [Jared] changed this book to just be an include of the identical book
+(include-book "workshops/1999/pipeline/b-ops-aux" :dir :system)
+
+;; (include-book "b-ops-aux-def")
+
+;; (deflabel begin-b-ops-aux)
+
+;; ;; Type of b-if
+;; (defthm bitp-b-if
+;; (implies (and (bitp y) (bitp z))
+;; (bitp (b-if x y z)))
+;; :hints (("goal" :in-theory (enable bitp))))
+
+;; (defthm integerp-b-if
+;; (implies (and (integerp y) (integerp z))
+;; (integerp (b-if x y z)))
+;; :hints (("goal" :in-theory (enable bitp))))
+
+;; (defthm b-not-b-not
+;; (equal (b-not (b-not i)) (bfix i))
+;; :hints (("goal" :in-theory (enable b-not bfix zbp))))
+
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ;; Here are several basic lemmas about bit operations.
+
+;; ;; If bit vector X is longer than (p+s), bits between the p'th and (p+s)'th
+;; ;; bits of the concatenation of x and y is equal to that of x.
+;; (defthm rdb-logapp-1
+;; (implies (and (integerp x) (integerp y) (integerp i) (<= 0 i)
+;; (integerp s) (<= 0 s) (integerp p) (<= 0 p)
+;; (<= (+ s p) i))
+;; (equal (rdb (cons s p) (logapp i x y))
+;; (rdb (cons s p) x)))
+;; :hints (("Goal" :in-theory (enable logapp* rdb bsp-size bsp-position))))
+
+;; ;; If bit vector X is shorter than p, bits from the p'th LSB to (p+s)'th
+;; ;; LSB of the concatenation of x and y is equal to that of y.
+;; (defthm rdb-logapp-2
+;; (implies (and (integerp x) (integerp y)
+;; (integerp s) (<= 0 s) (integerp p) (<= 0 p)
+;; (integerp i) (<= 0 i)
+;; (<= i p))
+;; (equal (rdb (cons s p) (logapp i x y))
+;; (rdb (cons s (- p i)) y)))
+;; :hints (("Goal" :in-theory (enable logapp* rdb bsp-size bsp-position))))
+
+
+;; (defthm loghead-0
+;; (equal (loghead x 0) 0)
+;; :hints (("Goal" :in-theory (enable loghead))))
+
+;; (defthm loghead-1
+;; (equal (loghead 1 vector) (logcar vector))
+;; :hints (("Goal" :in-theory (enable logcar loghead))))
+
+;; (defthm logcar-bitp
+;; (implies (bitp x)
+;; (equal (logcar x) x))
+;; :hints (("Goal" :in-theory (enable bitp logcar))))
+
+;; (defthm logbit-0-bitp
+;; (implies (bitp x)
+;; (equal (logbit 0 x) x))
+;; :hints (("Goal" :in-theory (enable bitp logbit))))
+
+;; (defthm loghead-bitp
+;; (implies (bitp x)
+;; (equal (loghead 1 x) x))
+;; :hints (("Goal" :in-theory (enable rdb))))
+
+
+;; (defthm logcons-0
+;; (implies (bitp x)
+;; (equal (logcons x 0) x))
+;; :hints (("Goal" :in-theory (enable logcons))))
+
+;; (defthm rdb-bitp
+;; (implies (bitp x)
+;; (equal (rdb (cons 1 0) x) x))
+;; :hints (("Goal" :in-theory (enable rdb))))
+
+;; (defthm rdb-0
+;; (equal (rdb (cons 0 n) x) 0)
+;; :hints (("Goal" :in-theory (enable rdb bsp-size))))
+
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ;; Here begins a basic theory about lobops
+;; ; Recursive definition of Logbit*.
+;; (defthm logbit*
+;; (implies (and (integerp pos)
+;; (>= pos 0)
+;; (integerp i))
+;; (equal (logbit pos i)
+;; (if (equal pos 0)
+;; (logcar i)
+;; (logbit (1- pos) (logcdr i)))))
+;; :rule-classes :definition
+;; :hints (("Goal" :in-theory (e/d (logbit logbitp*) (logbitp)))))
+
+;; (in-theory (disable logbit*))
+
+;; (local
+;; (defun logtail-induct (pos i)
+;; (if (zp pos)
+;; i
+;; (logtail-induct (1- pos) (logcdr i)))))
+
+
+;; (defthm logcar-logtail
+;; (implies (and (integerp n) (<= 0 n)
+;; (integerp x))
+;; (equal (logcar (logtail n x))
+;; (logbit n x)))
+;; :hints (("Goal" :in-theory (e/d (logtail* logbit logbitp*)
+;; (logbitp))
+;; :induct (logtail-induct n x))))
+
+;; (defthm logcdr-logtail
+;; (implies (and (integerp n) (<= 0 n)
+;; (integerp x))
+;; (equal (logcdr (logtail n x))
+;; (logtail (1+ n) x)))
+;; :hints (("Goal" :in-theory (enable logtail*)
+;; :induct (logtail-induct n x))))
+
+;; ;; The following two lemmas are for expansion before BDD
+;; (deflabel begin-bv-expand)
+;; (defthm rdb-expand
+;; (implies (and (syntaxp (and (quoted-constant-p s) (quoted-constant-p n)))
+;; (integerp s) (< 0 s)
+;; (integerp n) (<= 0 n)
+;; (integerp x))
+;; (equal (rdb (cons s n) x)
+;; (logcons (logbit n x) (rdb (cons (1- s) (1+ n)) x))))
+;; :hints (("Goal" :in-theory (enable rdb bsp-position bsp-size loghead*
+;; logtail*))))
+
+
+;; ;; logops supplement for logxxx operations. There are bunch of
+;; ;; definition rules logior* and so on, but they are definition rules.
+;; ;; We rewrite rules to forcibly open up the expressions before applying
+;; ;; BDD techniques. We redefine the same lemma as a rewrite rule.
+;; (defthm open-logior-right-const
+;; (implies (and (bitp i1)
+;; (integerp i2)
+;; (integerp j))
+;; (equal (logior (logcons i1 i2) j)
+;; (logcons (b-ior i1 (logcar j)) (logior i2 (logcdr j)))))
+;; :hints (("Goal" :in-theory (enable logior*))))
+
+
+;; (defthm open-logior-left-const
+;; (implies (and (bitp j1)
+;; (integerp j2)
+;; (integerp i))
+;; (equal (logior i (logcons j1 j2))
+;; (logcons (b-ior (logcar i) j1) (logior (logcdr i) j2))))
+;; :hints (("Goal" :in-theory (enable logior*))))
+
+;; (defthm open-logior
+;; (implies (and (bitp i1)
+;; (bitp j1)
+;; (integerp i2)
+;; (integerp j2))
+;; (equal (logior (logcons i1 i2) (logcons j1 j2))
+;; (logcons (b-ior i1 j1) (logior i2 j2))))
+;; :hints (("Goal" :in-theory (enable logior*))))
+
+;; (defthm open-logxor-right-const
+;; (implies (and (bitp i1)
+;; (integerp i2)
+;; (integerp j))
+;; (equal (logxor (logcons i1 i2) j)
+;; (logcons (b-xor i1 (logcar j)) (logxor i2 (logcdr j)))))
+;; :hints (("Goal" :in-theory (enable logxor*))))
+
+
+;; (defthm open-logxor-left-const
+;; (implies (and (bitp j1)
+;; (integerp j2)
+;; (integerp i))
+;; (equal (logxor i (logcons j1 j2))
+;; (logcons (b-xor (logcar i) j1) (logxor (logcdr i) j2))))
+;; :hints (("Goal" :in-theory (enable logxor*))))
+
+;; (defthm open-logxor
+;; (implies (and (bitp i1)
+;; (bitp j1)
+;; (integerp i2)
+;; (integerp j2))
+;; (equal (logxor (logcons i1 i2) (logcons j1 j2))
+;; (logcons (b-xor i1 j1) (logxor i2 j2))))
+;; :hints (("Goal" :in-theory (enable logxor*))))
+
+
+
+
+;; (defthm open-logand-right-const
+;; (implies (and (bitp i1)
+;; (integerp i2)
+;; (integerp j))
+;; (equal (logand (logcons i1 i2) j)
+;; (logcons (b-and i1 (logcar j)) (logand i2 (logcdr j)))))
+;; :hints (("Goal" :in-theory (enable logand*))))
+
+
+;; (defthm open-logand-left-const
+;; (implies (and (bitp j1)
+;; (integerp j2)
+;; (integerp i))
+;; (equal (logand i (logcons j1 j2))
+;; (logcons (b-and (logcar i) j1) (logand (logcdr i) j2))))
+;; :hints (("Goal" :in-theory (enable logand*))))
+
+;; (defthm open-logand
+;; (implies (and (bitp i1)
+;; (bitp j1)
+;; (integerp i2)
+;; (integerp j2))
+;; (equal (logand (logcons i1 i2) (logcons j1 j2))
+;; (logcons (b-and i1 j1) (logand i2 j2))))
+;; :hints (("Goal" :in-theory (enable logand*))))
+
+;; (defthm open-lognot
+;; (implies (and (bitp i1)
+;; (integerp i2))
+;; (equal (lognot (logcons i1 i2))
+;; (logcons (b-not i1) (lognot i2))))
+;; :hints (("Goal" :in-theory (enable lognot*))))
+
+;; (defthm fold-logcdr-vector
+;; (implies (and (integerp x)
+;; (syntaxp (or (not (consp x))
+;; (not (equal (car x) 'logcons$inline)))))
+;; (equal (logcdr x) (logtail 1 x)))
+;; :hints (("goal" :in-theory (enable logtail*))))
+;; (in-theory (disable fold-logcdr-vector))
+
+;; (defthm fold-logcar-vector
+;; (implies (and (integerp x)
+;; (syntaxp (or (not (consp x))
+;; (not (equal (car x) 'logcons$inline)))))
+;; (equal (logcar x) (logbit 0 x)))
+;; :hints (("goal" :in-theory (enable logbit logbitp*))))
+;; (in-theory (disable fold-logcar-vector))
+;; (deflabel end-bv-expand)
+
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ;; Bv-eqv rules
+;; (defthm bv-eqv*
+;; (implies (and (integerp x)
+;; (integerp y)
+;; (integerp n)
+;; (>= n 0))
+;; (equal (bv-eqv n x y)
+;; (if (zp n)
+;; 1
+;; (b-and (b-eqv (logcar x) (logcar y))
+;; (bv-eqv (1- n) (logcdr x) (logcdr y))))))
+;; :hints (("goal" :in-theory (enable bv-eqv loghead*)))
+;; :rule-classes :definition)
+
+;; (in-theory (disable bv-eqv*))
+
+;; ;; Following lemma is useful in converting a formula with 'bv-eqv' to one
+;; ;; with 'equal'.
+;; ;; This can cause BDD simplification to fail, especially if when the words
+;; ;; need to be open up.
+;; (defthm bv-eqv-iff-equal
+;; (implies (and (unsigned-byte-p n x) (unsigned-byte-p n y))
+;; (equal (b1p (bv-eqv n x y))
+;; (equal x y)))
+;; :hints (("Goal" :in-theory (enable bv-eqv b1p))))
+
+;; (defthm bv-eqv-0
+;; (equal (bv-eqv 0 x y) 1)
+;; :Hints (("Goal" :in-theory (enable bv-eqv))))
+
+;; (defthm bv-x-x
+;; (equal (bv-eqv n x x) 1)
+;; :hints (("goal" :in-theory (enable bv-eqv))))
+
+;; (defthm bv-eqv-assoc
+;; (equal (bv-eqv n x y) (bv-eqv n y x))
+;; :hints (("Goal" :in-theory (enable bv-eqv))))
+
+;; (defthm bv-eqv-bits
+;; (implies (and (bitp x) (bitp y) (integerp n) (> n 0))
+;; (equal (bv-eqv n x y) (b-eqv x y)))
+;; :hints (("Goal" :in-theory (enable bv-eqv* bitp bv-eqv-iff-equal))))
+
+;; (defthm bv-eqv-expand
+;; (implies (and (integerp x) (integerp y)
+;; (integerp n) (> n 0)
+;; (syntaxp (quoted-constant-p n)))
+;; (equal (bv-eqv n x y)
+;; (b-and (b-eqv (logcar x) (logcar y))
+;; (bv-eqv (1- n) (logcdr x) (logcdr y)))))
+;; :hints (("Goal" :in-theory (enable bv-eqv*))))
+
+;; ;; Following lemma is a schematic lemma which will be used in BDD proof.
+;; ;; We noticed that several lemmas is a tautology under the property that
+;; ;; (bv-eqv x y) and (bv-eqv x z) are not simultaneously asserted, if y and
+;; ;; z are not equal. We instantiate the following lemma and add it to BDD
+;; ;; proof as a hint.
+;; (defthm bv-eqv-transitivity
+;; (implies (and (unsigned-byte-p n x)
+;; (unsigned-byte-p n y)
+;; (unsigned-byte-p n z)
+;; (b1p (b-and (bv-eqv n x z) (bv-eqv n y z))))
+;; (equal x y))
+;; :hints (("Goal" :in-theory (enable bv-eqv )))
+;; :rule-classes nil)
+
+;; ;; Bv-expander is the theory to be enabled to expand bit vectors before
+;; ;; applying bdd's.
+;; (deftheory bv-expander
+;; '(rdb-expand
+;; open-lognot
+;; open-logand open-logand-right-const open-logand-left-const
+;; open-logior open-logior-right-const open-logior-left-const
+;; open-logxor open-logxor-right-const open-logxor-left-const
+;; fold-logcar-vector fold-logcdr-vector
+;; bv-eqv-bits
+;; bv-eqv-0
+;; bv-eqv-expand))
+
+;; (in-theory (disable bv-expander))
+
+;; (local (in-theory (enable b1p)))
+
+;; ;; Bit-boolean-converter converting expressions of form (equal x 1) to
+;; ;; expressions using bitp, lest BDD package assigns different boolean values
+;; ;; to (b1p x) and (equal x 1). It also converts (equal x 0) to (not (b1p x)).
+;; (defthm equal-to-1-to-b1p
+;; (implies (bitp x)
+;; (equal (equal x 1)
+;; (b1p x)))
+;; :Hints (("Goal" :In-theory (enable bitp))))
+
+;; (defthm equal-to-0-to-not-b1p
+;; (implies (bitp x)
+;; (equal (equal x 0)
+;; (not (b1p x))))
+;; :Hints (("Goal" :In-theory (enable bitp))))
+
+;; (defthm equal-to-b1p-b-eqv
+;; (implies (and (bitp x) (bitp y))
+;; (equal (equal x y) (b1p (b-eqv x y))))
+;; :hints (("Goal" :in-theory (enable b-eqv b1p zbp bitp))))
+
+;; (deftheory equal-b1p-converter
+;; '(equal-to-1-to-b1p equal-to-0-to-not-b1p))
+
+;; (in-theory (disable equal-b1p-converter))
+;; (in-theory (disable equal-to-b1p-b-eqv))
+
+;; ;; From here, we define bit-to-boolean converter, especially for BDD
+;; ;; operation.
+;; (deflabel begin-lift-b-ops)
+
+;; (defthm zbp-b-and
+;; (equal (zbp (b-and x y))
+;; (or (zbp x) (zbp y)))
+;; :Hints (("Goal" :in-theory (enable b-and))))
+
+;; (defthm zbp-b-ior
+;; (equal (zbp (b-ior x y))
+;; (and (zbp x) (zbp y)))
+;; :Hints (("Goal" :in-theory (enable b-ior))))
+
+;; (defthm zbp-b-xor
+;; (equal (zbp (b-xor x y))
+;; (or (and (zbp x) (zbp y))
+;; (and (not (zbp x)) (not (zbp y)))))
+;; :Hints (("Goal" :in-theory (enable b-xor))))
+
+;; (defthm zbp-b-not
+;; (equal (zbp (b-not x))
+;; (not (zbp x)))
+;; :Hints (("Goal" :in-theory (enable b-not))))
+
+;; (defthm zbp-b-eqv
+;; (equal (zbp (b-eqv x y))
+;; (not (iff (zbp x) (zbp y))))
+;; :Hints (("Goal" :in-theory (enable b-eqv))))
+
+
+
+;; (defthm b1p-b-and
+;; (equal (b1p (b-and x y))
+;; (and (b1p x) (b1p y)))
+;; :Hints (("Goal" :in-theory (enable b-and))))
+
+;; (defthm b1p-b-ior
+;; (equal (b1p (b-ior x y))
+;; (or (b1p x) (b1p y)))
+;; :Hints (("Goal" :in-theory (enable b-ior))))
+
+;; (defthm b1p-b-xor
+;; (equal (b1p (b-xor x y))
+;; (or (and (b1p x) (not (b1p y)))
+;; (and (not (b1p x)) (b1p y))))
+;; :Hints (("Goal" :in-theory (enable b-xor))))
+
+;; (defthm b1p-b-not
+;; (equal (b1p (b-not x))
+;; (not (b1p x)))
+;; :Hints (("Goal" :in-theory (enable b-not))))
+
+;; (defthm b1p-b-eqv
+;; (equal (b1p (b-eqv x y))
+;; (iff (b1p x) (b1p y)))
+;; :Hints (("Goal" :in-theory (enable b-eqv))))
+
+;; (defthm b1p-nand (equal (b1p (b-nand x y)) (not (and (b1p x) (b1p y))))
+;; :hints (("Goal" :in-theory (enable b-nand))))
+
+;; (defthm b1p-nor (equal (b1p (b-nor x y)) (not (or (b1p x) (b1p y))))
+;; :hints (("Goal" :in-theory (enable b-nor))))
+
+;; (defthm b1p-andc1 (equal (b1p (b-andc1 x y)) (and (not (b1p x)) (b1p y)))
+;; :hints (("Goal" :in-theory (enable b-andc1))))
+
+;; (defthm b1p-andc2 (equal (b1p (b-andc2 x y)) (and (b1p x) (not (b1p y))))
+;; :hints (("Goal" :in-theory (enable b-andc2))))
+
+;; (defthm b1p-orc1 (equal (b1p (b-orc1 x y)) (or (not (b1p x)) (b1p y)))
+;; :hints (("Goal" :in-theory (enable b-orc1))))
+
+;; (defthm b1p-orc2 (equal (b1p (b-orc2 x y)) (or (b1p x) (not (b1p y))))
+;; :hints (("Goal" :in-theory (enable b-orc2))))
+
+;; (defthm zbp-to-b1p
+;; (equal (zbp x) (not (b1p x)))
+;; :hints (("Goal" :in-theory (enable b1p))))
+
+;; (deflabel end-lift-b-ops)
+
+;; (deftheory lift-b-ops
+;; (set-difference-theories (universal-theory 'end-lift-b-ops)
+;; (universal-theory 'begin-lift-b-ops)))
+
+;; (in-theory (disable lift-b-ops))
+
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ; New Simplifier
+;; ; This simplifier simplifies bit terms into 1 and 0's using information
+;; ; represented by b1p.
+;; ; Origianl Simplify-Bit-Functions can simplify expressions with bit-functions
+;; ; if its arguments are 0 or 1's. For instance, it can reduce expressions
+;; ; with a rule like:
+;; ; (EQUAL (B-AND 1 X) (BFIX X))
+;; ; In the new simplifier reduces the expressions if hypothesis satisfies
+;; ; certain conditions, like
+;; ; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; ; (equal (b-and x y) 0))
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (deflabel begin-b1p-bit-rewriter)
+
+;; (defthm b1p-bit-forward
+;; (implies (and (b1p b) (force (bitp b))) (equal b 1))
+;; :hints (("goal" :in-theory (enable b1p bitp zbp)))
+;; :rule-classes :forward-chaining)
+
+;; (defthm not-b1p-bit-forward
+;; (implies (and (not (b1p b)) (force (bitp b))) (equal b 0))
+;; :hints (("goal" :in-theory (enable b1p bitp zbp)))
+;; :rule-classes :forward-chaining)
+
+;; (defthm simplify-bit-functions-2
+;; (and (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-and x y) 0))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-and x y) 0))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-and x y) y))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-and x y) x))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-ior x y) y))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-ior x y) x))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-ior x y) 1))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-ior x y) 1))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-xor x y) y))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-xor x y) x))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-xor x y) (b-not y)))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-xor x y) (b-not x)))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-eqv x y) (b-not y)))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-eqv x y) (b-not x)))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-eqv x y) y))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-eqv x y) x))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-nand x y) 1))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-nand x y) 1))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-nand x y) (b-not y)))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-nand x y) (b-not x)))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-nor x y) (b-not y)))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-nor x y) (b-not x)))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-nor x y) 0))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-nor x y) 0))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-andc1 x y) y))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-andc1 x y) 0))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-andc1 x y) 0))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-andc1 x y) (b-not x)))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-andc2 x y) 0))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-andc2 x y) x))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-andc2 x y) (b-not y)))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-andc2 x y) 0))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-orc1 x y) 1))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-orc1 x y) (b-not x)))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-orc1 x y) y))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-orc1 x y) 1))
+
+;; (implies (and (bitp x) (bitp y) (not (b1p x)))
+;; (equal (b-orc2 x y) (b-not y)))
+;; (implies (and (bitp x) (bitp y) (not (b1p y)))
+;; (equal (b-orc2 x y) 1))
+;; (implies (and (bitp x) (bitp y) (b1p x))
+;; (equal (b-orc2 x y) 1))
+;; (implies (and (bitp x) (bitp y) (b1p y))
+;; (equal (b-orc2 x y) x)))
+;; :hints (("Goal" :in-theory (enable b1p zbp b-and bitp))))
+
+;; (deflabel end-b1p-bit-rewriter)
+
+;; (deftheory b1p-bit-rewriter
+;; (set-difference-theories (universal-theory 'end-b1p-bit-rewriter)
+;; (universal-theory 'begin-b1p-bit-rewriter)))
+
+;; (in-theory (disable b1p-bit-rewriter))
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ; BDD helps
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (deftheory pre-bdd-disables
+;; '(bv-eqv-iff-equal simplify-bit-functions))
+
+;; (deftheory bdd-disables
+;; '(bv-eqv-iff-equal simplify-bit-functions))
+
+;; (theory-invariant (incompatible (:rewrite bv-eqv-iff-equal)
+;; (:rewrite rdb-expand)))
+
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ; range of unsigned-byte-p
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ; theories about the range of unsigned-byte-p
+;; (defthm plus-unsigned-byte-p-lt-2-*-expt-2-width
+;; (implies (and (unsigned-byte-p width val1)
+;; (unsigned-byte-p width val2))
+;; (< (+ val1 val2) (* 2 (expt 2 width))))
+;; :hints (("goal" :in-theory (enable unsigned-byte-p))))
+
+;; (defun logbit-induction (pos val)
+;; (if (zp pos)
+;; val
+;; (logbit-induction (1- pos) (logcdr val))))
+
+;; ; If a value are in the range 0 <= val < 2^width
+;; ; then the width'th bit of val is not set.
+;; (defthm logbit-0-if-val-lt-expt-2-width
+;; (implies (and (integerp width) (<= 0 width)
+;; (integerp val)
+;; (<= 0 val) (< val (expt 2 width)))
+;; (equal (logbit width val) 0))
+;; :hints (("goal" :in-theory (e/d (logbit* expt logcar logcdr)
+;; (exponents-add))
+;; :induct (logbit-induction width val)))
+;; :rule-classes nil)
+
+
+;; (encapsulate nil
+;; (local
+;; (defthm logbit-1-if-val-gt-expt-2-width-help1
+;; (IMPLIES (AND (INTEGERP WIDTH)
+;; (< 0 WIDTH)
+;; (INTEGERP VAL)
+;; (<= (* 2 (EXPT 2 (+ -1 WIDTH))) VAL)
+;; (< (/ VAL 2) (* 2 (EXPT 2 (+ -1 WIDTH)))))
+;; (> (* 2 (EXPT 2 (+ -1 WIDTH)))
+;; (FLOOR VAL 2)))
+;; :rule-classes nil))
+
+;; (local
+;; (defthm logbit-1-if-val-gt-expt-2-width-help2
+;; (implies (and (integerp val)
+;; (integerp width) (< 0 width)
+;; (< VAL (* 2 2 (EXPT 2 (+ -1 WIDTH)))))
+;; (< (/ VAL 2) (* 2 (EXPT 2 (+ -1 WIDTH)))))
+;; :hints (("goal" :in-theory (e/d (expt) (exponents-add))))
+;; :rule-classes nil))
+
+;; (local
+;; (defthm logbit-1-if-val-gt-expt-2-width-help
+;; (IMPLIES (AND (INTEGERP WIDTH)
+;; (INTEGERP VAL)
+;; (< 0 WIDTH)
+;; (<= (* 2 (EXPT 2 (+ -1 WIDTH))) (FLOOR VAL 2)))
+;; (<= (* 2 2 (EXPT 2 (+ -1 WIDTH))) VAL))
+;; :hints (("goal" :in-theory (e/d (exponents-add) (expt))
+;; :use ((:instance logbit-1-if-val-gt-expt-2-width-help1)
+;; (:instance logbit-1-if-val-gt-expt-2-width-help2))))))
+
+
+;; ; If a value are in the range 2^width <= val < 2^width * 2,
+;; ; then the width'th bit of val is set.
+;; (defthm logbit-1-if-val-gt-expt-2-width
+;; (implies (and (integerp width) (<= 0 width)
+;; (integerp val)
+;; (<= (expt 2 width) val)
+;; (< val (* 2 (expt 2 width))))
+;; (equal (logbit width val) 1))
+;; :hints (("goal" :in-theory (e/d (logbit* expt logcar logcdr)
+;; (exponents-add))
+;; :induct (logbit-induction width val)))
+;; :rule-classes nil)
+;; )
+
+;; ; Suppose val1 and val2 are unsigned-byte-p whose width is w.
+;; ; If w'th bit of the sum (+ val1 val2) is not set,
+;; ; (+ val1 val2) < 2^w.
+;; (defthm plus-unsigned-byte-lt-expt-2-width-if-logbit
+;; (implies (and (unsigned-byte-p width val1)
+;; (unsigned-byte-p width val2)
+;; (not (b1p (logbit width (+ val1 val2)))))
+;; (< (+ val1 val2) (expt 2 width)))
+;; :hints (("goal" :in-theory (enable unsigned-byte-p)
+;; :use (:instance logbit-1-if-val-gt-expt-2-width
+;; (val (+ val1 val2))))))
+
+
+
+;; ; Suppose val1 and val2 are unsigned-byte-p whose width is w.
+;; ; If w'th bit of the sum (+ val1 val2) is set, then
+;; ; 2^w < (+ val1 val2).
+;; (defthm plus-unsigned-byte-gt-expt-2-width-if-logbit
+;; (implies (and (unsigned-byte-p width val1)
+;; (unsigned-byte-p width val2)
+;; (b1p (logbit width (+ val1 val2))))
+;; (<= (expt 2 width) (+ val1 val2)))
+;; :hints (("goal" :in-theory (enable unsigned-byte-p)
+;; :use (:instance logbit-0-if-val-lt-expt-2-width
+;; (val (+ val1 val2))))))
+
+;; ; Suppose val1 and val2 are unsigned-byte-p whose width is w.
+;; ; If the sum of val1 and val2 does not carry out to w'th bit,
+;; ; (loghead w (+ val1 val2)) = (+ val1 val2)
+;; (defthm loghead-unsigned-byte-+-if-not-carry
+;; (implies (and (integerp width)
+;; (<= 0 width)
+;; (unsigned-byte-p width val1)
+;; (unsigned-byte-p width val2)
+;; (not (b1p (logbit width (+ val1 val2)))))
+;; (equal (loghead width (+ val1 val2)) (+ val1 val2)))
+;; :hints (("goal" :in-theory (enable loghead)
+;; :do-not-induct t)))
+
+;; (encapsulate nil
+;; (local
+;; (defthm j*k-ge-2*k-if-j-gt-1
+;; (implies (and (integerp j)
+;; (< 1 j)
+;; (integerp k)
+;; (< 0 k))
+;; (<= (* 2 k) (* j k)))
+;; :hints (("Goal" :in-theory (enable <-*-right-cancel)))
+;; :rule-classes :linear))
+
+;; ; A trivia theorem.
+;; ; If y < x < 2*y, then (x mod y) = x - y
+;; (defthm mod-x-y-=-minux-x-y
+;; (implies (and (integerp x) (integerp y) (< 0 y)
+;; (<= y x) (< x (* 2 y)))
+;; (equal (mod x y) (- x y)))
+;; :Hints (("goal" :in-theory (disable (:generalize floor-bounds)))
+;; ("subgoal 1" :cases ((<= j 1)))))
+;; )
+
+;; (in-theory (disable mod-x-y-=-minux-x-y))
+
+;; ; Suppose val1 and val2 are unsigned-byte-p whose width is w.
+;; ; If the sum of val1 and val2 does not carry out to w'th bit,
+;; ; (loghead w (+ val1 val2)) = (+ val1 val2)
+;; (defthm loghead-unsigned-byte-+-if-carry
+;; (implies (and (integerp width)
+;; (<= 0 width)
+;; (unsigned-byte-p width val1)
+;; (unsigned-byte-p width val2)
+;; (b1p (logbit width (+ val1 val2))))
+;; (equal (loghead width (+ val1 val2))
+;; (- (+ val1 val2) (expt 2 width))))
+;; :hints (("goal" :in-theory (enable loghead mod-x-y-=-minux-x-y)
+;; :do-not-induct t)))
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.acl2 b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.acl2
new file mode 100644
index 0000000..923cb2f
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.acl2
@@ -0,0 +1,4 @@
+(in-package "ACL2")
+(include-book "data-structures/portcullis" :dir :system)
+(certify-book "basic-def" ? t)
+
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.lisp
new file mode 100644
index 0000000..347ddf7
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-def.lisp
@@ -0,0 +1,963 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Basic-def.lisp:
+; Copyright reserved by SRC
+; Author Jun Sawada, University of Texas at Austin
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; This file includes various underlying definition for ISA and
+;; MA designs.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(in-package "ACL2")
+
+(include-book "../../../../../../data-structures/array1")
+(include-book "../../../../../../data-structures/deflist")
+(include-book "../../../../../../data-structures/list-defthms")
+(include-book "../../../../../../data-structures/structures")
+(include-book "ihs")
+
+(include-book "trivia")
+(include-book "b-ops-aux")
+
+(deflabel begin-basic-def)
+
+(defconst *addr-size* 16)
+(defconst *page-offset-size* 10)
+
+(defconst *rname-size* 4)
+(defconst *immediate-size* 8)
+(defconst *opcode-size* 4)
+(defconst *word-size* 16)
+(defconst *max-word-value* (expt 2 *word-size*))
+(defconst *num-regs* (expt 2 *rname-size*))
+(defconst *num-mem-words* (expt 2 *addr-size*))
+(defconst *num-page-words* (expt 2 *page-offset-size*))
+(defconst *num-pages* (expt 2 (- *addr-size* *page-offset-size*)))
+(defbytetype word *word-size* :unsigned)
+(defbytetype addr *addr-size* :unsigned)
+(defbytetype rname *rname-size* :unsigned)
+(defbytetype immediate *immediate-size* :unsigned)
+(defbytetype opcd *opcode-size* :unsigned)
+
+(defthm word-p-type
+ (implies (word-p word)
+ (and (integerp word)
+ (>= word 0)
+ (< word *max-word-value*)))
+ :hints (("Goal" :in-theory (enable word-p)))
+ :rule-classes :forward-chaining)
+
+(defthm rname-p-type
+ (implies (rname-p rname)
+ (and (integerp rname)
+ (>= rname 0)
+ (< rname *num-regs*)))
+ :hints (("Goal" :in-theory (enable rname-p)))
+ :rule-classes :forward-chaining)
+
+(defthm addr-p-type
+ (implies (addr-p ad)
+ (and (integerp ad)
+ (>= ad 0)
+ (< ad *num-mem-words*)))
+ :hints (("Goal" :in-theory (enable addr-p)))
+ :rule-classes :forward-chaining)
+
+(defthm addr-word-double-casting
+ (equal (addr (word i)) (addr i))
+ :hints (("goal" :in-theory (enable addr word))))
+
+(defthm word-addr-double-casting
+ (equal (word (addr i)) (word i))
+ :hints (("goal" :in-theory (enable addr word))))
+
+
+(defthm word-addr-p
+ (implies (addr-p x) (equal (word x) x))
+ :hints (("goal" :in-theory (enable addr-p word))))
+
+(defthm addr-word-p
+ (implies (word-p x) (equal (addr x) x))
+ :hints (("goal" :in-theory (enable addr word-p))))
+
+(in-theory (disable word-addr-p addr-word-p))
+
+(defthm word-p-logand
+ (implies (and (word-p val1) (word-p val2))
+ (word-p (logand val1 val2)))
+ :hints (("Goal" :in-theory (enable word-p))))
+
+(defthm word-p-logxor
+ (implies (and (word-p val1) (word-p val2))
+ (word-p (logxor val1 val2)))
+ :hints (("Goal" :in-theory (enable word-p))))
+
+(defthm word-p-logior
+ (implies (and (word-p val1) (word-p val2))
+ (word-p (logior val1 val2)))
+ :hints (("Goal" :in-theory (enable word-p))))
+
+(defthm word-p-bv-eqv-iff-equal
+ (implies (and (word-p wd0) (word-p wd1))
+ (equal (b1p (bv-eqv *word-size* wd0 wd1)) (equal wd0 wd1)))
+ :hints (("Goal" :in-theory (enable word-p))))
+
+(defthm addr-p-bv-eqv-iff-equal
+ (implies (and (addr-p wd0) (addr-p wd1))
+ (equal (b1p (bv-eqv *addr-size* wd0 wd1)) (equal wd0 wd1)))
+ :hints (("Goal" :in-theory (enable addr-p))))
+
+(defthm rname-p-bv-eqv-iff-equal
+ (implies (and (rname-p wd0) (rname-p wd1))
+ (equal (b1p (bv-eqv *rname-size* wd0 wd1)) (equal wd0 wd1)))
+ :hints (("Goal" :in-theory (enable rname-p))))
+
+(defthm immediate-p-bv-eqv-iff-equal
+ (implies (and (immediate-p wd0) (immediate-p wd1))
+ (equal (b1p (bv-eqv *immediate-size* wd0 wd1)) (equal wd0 wd1)))
+ :hints (("Goal" :in-theory (enable immediate-p))))
+
+(defthm opcd-p-bv-eqv-iff-equal
+ (implies (and (opcd-p wd0) (opcd-p wd1))
+ (equal (b1p (bv-eqv *opcode-size* wd0 wd1)) (equal wd0 wd1)))
+ :hints (("Goal" :in-theory (enable opcd-p))))
+
+
+(deflist word-listp (l)
+ (declare (xargs :guard t))
+ word-p)
+
+(defun fixlen-word-listp (n lst)
+ "test if list is a array of n words."
+ (declare (xargs :guard (and (integerp n) (<= 0 n))))
+ (and (word-listp lst) (equal (len lst) n)))
+
+(defthm fixlen-word-true-listp
+ (implies (fixlen-word-listp n x)
+ (true-listp x))
+ :rule-classes :forward-chaining)
+
+(in-theory (disable fixlen-word-listp))
+
+; Register file is a fixed lenghth true list of words.
+(defun regs-p (regs)
+ (declare (xargs :guard t))
+ (fixlen-word-listp *num-regs* regs))
+
+(defthm regs-p-true-listp
+ (implies (regs-p x)
+ (true-listp x))
+ :rule-classes :forward-chaining)
+
+
+(defun read-reg (num regs)
+ (declare (xargs :guard (and (rname-p num) (regs-p regs))))
+ (nth num regs))
+
+(defun write-reg (val num regs)
+ (declare (xargs :guard (and (word-p val) (rname-p num) (regs-p regs))))
+ (update-nth num val regs))
+
+(defthm regs-p-write-reg
+ (implies (and (word-p word)
+ (rname-p rname)
+ (regs-p regs))
+ (regs-p (write-reg word rname regs)))
+ :hints (("Goal" :in-theory (enable regs-p fixlen-word-listp
+ rname-p UNSIGNED-BYTE-P
+ len-update-nth))))
+
+(local
+(defthm nth-content-word-listp
+ (implies (and (integerp n)
+ (<= 0 n)
+ (word-listp lst)
+ (< n (len lst)))
+ (and (integerp (nth n lst))
+ (acl2-numberp (nth n lst))))
+ :hints (("Goal" :use ((:instance word-listp-nth (n0 n) (l lst)))
+ :in-theory (disable word-listp-nth)))))
+
+
+(defthm numberp-read-reg
+ (implies (and (regs-p regs)
+ (rname-p rname))
+ (and (integerp (read-reg rname regs))
+ (acl2-numberp (read-reg rname regs))))
+ :hints (("Goal" :in-theory (enable rname-p regs-p fixlen-word-listp)))
+ :rule-classes
+ ((:type-prescription) (:rewrite)))
+
+(defthm word-p-read-reg
+ (implies (and (regs-p regs)
+ (rname-p rname))
+ (word-p (read-reg rname regs)))
+ :hints (("Goal" :in-theory (enable rname-p regs-p fixlen-word-listp)))
+ :rule-classes
+ ((:rewrite)
+ (:type-prescription :corollary
+ (implies (and (regs-p regs) (rname-p rname))
+ (integerp (read-reg rname regs)))
+ :hints (("goal" :in-theory (enable word-p unsigned-byte-p))))))
+
+(defthm read-reg-write-reg
+ (implies (and (rname-p rn1)
+ (rname-p rn2)
+ (regs-p regs))
+ (equal (read-reg rn1 (write-reg val rn2 regs))
+ (if (equal rn1 rn2) val (read-reg rn1 regs))))
+ :hints (("Goal" :in-theory (enable read-reg write-reg regs-p
+ nth-update-nth))))
+
+(in-theory (disable regs-p write-reg read-reg))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Here we define the memory system.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defconst *no-access* 0)
+(defconst *read-only* 1)
+(defconst *read-write* 2)
+
+;; Definition of Address Transformer
+;; page-num Address --> Page number
+;; page-offset Address --> Page Offset
+(defun page-num (addr)
+ (declare (xargs :guard (addr-p addr)))
+ (floor addr *num-page-words*))
+
+(defun page-offset (addr)
+ (declare (xargs :guard (addr-p addr)))
+ (mod addr *num-page-words*))
+
+(defthm page-num-type
+ (implies (addr-p addr)
+ (and (integerp (page-num addr))
+ (<= 0 (page-num addr))))
+ :rule-classes :type-prescription)
+
+(defthm page-num-bound
+ (implies (addr-p addr)
+ (< (page-num addr) *num-pages*))
+ :hints (("Goal" :in-theory (enable addr-p unsigned-byte-p)))
+ :rule-classes :linear)
+
+(defthm page-offset-type
+ (implies (addr-p addr)
+ (and (integerp (page-offset addr))
+ (<= 0 (page-offset addr))))
+ :rule-classes :type-prescription)
+
+(defthm page-offset-bound
+ (implies (addr-p addr)
+ (< (page-offset addr) *num-page-words*))
+ :rule-classes :linear)
+
+(in-theory (disable page-num page-offset))
+;; End of Address Transformer
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of Memory Object
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Check if page is an array representing a page.
+; Addr does not affect the value, but if the correct page tag is given,
+; execution is faster.
+(defun word-array-p (array)
+ (declare (xargs :guard (alistp array)
+ :verify-guards nil))
+ (cond ((endp array) t)
+ ((equal (caar array) ':header) (word-array-p (cdr array)))
+ (t (and (word-p (cdar array))
+ (word-array-p (cdr array))))))
+
+(verify-guards word-array-p
+ :hints (("Goal" :in-theory (enable alistp))))
+
+(defun page-array-p (tag page-array)
+ (declare (xargs :guard t))
+ (and (array1p tag page-array)
+ (equal (car (dimensions tag page-array)) *num-page-words*)
+ (word-p (default tag page-array))
+ (word-array-p page-array)))
+
+(defstructure page
+ (tag (:assert (symbolp tag) :rewrite))
+ (mode (:assert (integerp mode) :rewrite))
+ (array (:assert (page-array-p tag array) :rewrite))
+ (:options :guards))
+
+(defun mem-array-p (array)
+ (declare (xargs :guard (alistp array)
+ :verify-guards nil))
+ (cond ((endp array) t)
+ ((equal (caar array) ':header) (mem-array-p (cdr array)))
+ (t (and (let ((page (cdar array)))
+ (if (integerp page)
+ (or (equal page *no-access*) (equal page *read-only*)
+ (equal page *read-write*))
+ (page-p page)))
+ (mem-array-p (cdr array))))))
+
+(verify-guards mem-array-p :hints (("Goal" :in-theory (enable alistp))))
+
+(defun mem-p (mem)
+ (declare (xargs :guard t))
+ (and (array1p 'mem mem)
+ (equal (car (dimensions 'mem mem)) *num-pages*)
+ (equal (default 'mem mem) *no-access*)
+ (mem-array-p mem)))
+
+(in-theory (disable word-array-p page-array-p mem-array-p mem-p))
+
+(defthm page-p-type
+ (implies (page-p p)
+ (consp p))
+ :hints (("Goal" :in-theory (enable page-p)))
+ :rule-classes :compound-recognizer)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of Read-mem
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defmacro get-page (n mem)
+ `(aref1 'mem ,mem ,n))
+
+(defmacro set-page (page n mem)
+ `(aset1 'mem ,mem ,n ,page))
+
+(defun read-page (offset page)
+ (declare (xargs :guard (and (page-p page)
+ (integerp offset) (<= 0 offset)
+ (< offset *num-page-words*))
+ :verify-guards nil))
+ (aref1 (page-tag page) (page-array page) offset))
+
+
+(defun read-mem (addr mem)
+ (declare (xargs :guard (and (addr-p addr) (mem-p mem))
+ :verify-guards nil))
+ (let ((page (get-page (page-num addr) mem)))
+ (if (integerp page)
+ 0
+ (read-page (page-offset addr) page))))
+
+;(verify-guards get-page
+; :hints (("Goal" :in-theory (enable mem-p))))
+
+(verify-guards read-page
+ :hints (("Goal" :in-theory (enable page-p page-array-p))))
+
+(encapsulate nil
+(local
+ (defthm page-p-assoc-mem-array
+ (implies (and (mem-array-p mem)
+ (integerp pn)
+ (assoc pn mem)
+ (not (integerp (cdr (assoc pn mem)))))
+ (page-p (cdr (assoc pn mem))))
+ :hints (("Goal" :in-theory (enable assoc mem-array-p)))))
+
+(local
+ (defthm integerp-default-in-mem-array
+ (implies (mem-p mem)
+ (integerp (default 'mem mem)))
+ :hints (("Goal" :in-theory (enable mem-p)))))
+
+(defthm page-p-get-page
+ (implies (and (mem-p mem)
+ (integerp pn)
+ (not (integerp (get-page pn mem))))
+ (page-p (get-page pn mem)))
+ :hints (("Goal" :in-theory (enable aref1 mem-p))))
+)
+
+(local
+ (defthm word-p-assoc-word-array
+ (implies (and (word-array-p wa)
+ (integerp pn)
+ (assoc pn wa))
+ (word-p (cdr (assoc pn wa))))
+ :hints (("Goal" :in-theory (enable word-array-p assoc)))))
+
+(encapsulate nil
+(defthm word-p-read-page
+ (implies (and (page-p page)
+ (integerp offset))
+ (word-p (read-page offset page)))
+ :hints (("Goal" :in-theory (enable page-p aref1 page-array-p))))
+)
+
+(in-theory (disable read-page read-mem))
+(verify-guards read-mem
+ :hints (("goal" :in-theory (enable mem-p))))
+
+(defthm word-p-read-mem
+ (implies (and (mem-p mem)
+ (addr-p addr))
+ (word-p (read-mem addr mem)))
+ :hints (("Goal" :in-theory (enable read-mem)))
+ :rule-classes
+ ((:rewrite)
+ (:type-prescription :corollary
+ (implies (and (mem-p mem) (addr-p addr))
+ (and (integerp (read-mem addr mem))
+ (>= (read-mem addr mem) 0))))
+ (:rewrite :corollary
+ (implies (and (mem-p mem) (addr-p addr))
+ (acl2-numberp (read-mem addr mem))))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of Write-Mem
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Page tag is calculated for fast array access.
+; The tag for the <n>'th page is given by page<n>.
+(defun gen-page-tag (page-num)
+ (declare (xargs :guard (and (integerp page-num)
+ (>= page-num 0))
+ :verify-guards nil))
+ (pack-intern 'mem
+ (coerce (append (coerce (symbol-name 'page) 'list)
+ (explode-nonnegative-integer page-num 10 nil))
+ 'string)))
+
+(encapsulate nil
+(local
+ (defthm character-listp-explode-nonnegative-integer-help
+ (implies (and (integerp n) (>= n 0)
+ (character-listp x))
+ (character-listp (explode-nonnegative-integer n print-base x)))
+ :hints (("goal" :in-theory (enable explode-nonnegative-integer
+ character-listp)))))
+
+(local
+ (defthm character-listp-explode-nonnegative-integer
+ (implies (and (integerp n) (>= n 0))
+ (character-listp (explode-nonnegative-integer n print-base nil)))))
+
+; Renamed by Matt K. after Version 4.3, since a similar :type-prescription
+; lemma is now provided by the ACL2 system. Perhaps it could be deleted now.
+(local
+ (defthm true-listp-explode-nonnegative-integer-rewrite
+ (implies (true-listp x)
+ (true-listp (explode-nonnegative-integer n print-base x)))))
+
+(verify-guards gen-page-tag
+ :hints (("goal" :in-theory (enable U::coerce-string-designator-list
+ U::STRING-DESIGNATOR-LISTP
+ character-listp
+ binary-append))))
+)
+
+(defun init-page (page-num mode)
+ (declare (xargs :guard (and (integerp page-num) (<= 0 page-num)
+ (integerp mode))
+ :verify-guards nil))
+ (let ((name (gen-page-tag page-num)))
+ (page name
+ mode
+ (compress1 name `((:header :name ,name
+ :dimensions (,*num-page-words*)
+ :default 0
+ :maximum-length 4096))))))
+
+(verify-guards init-page
+ :hints (("Goal" :in-theory (enable array1p alistp
+ keyword-value-listp
+ assoc-eq
+ assoc-keyword
+ bounded-integer-alistp))))
+
+(defun write-page (val offset page)
+ (declare (xargs :guard (and (word-p val)
+ (integerp offset) (<= 0 offset)
+ (< offset *num-page-words*)
+ (page-p page))
+ :verify-guards nil))
+ (update-page page
+ :array (aset1 (page-tag page) (page-array page) offset val)))
+
+(defun write-mem (val addr mem)
+ (declare (xargs :guard (and (word-p val) (addr-p addr) (mem-p mem))
+ :verify-guards nil))
+ (let ((page (get-page (page-num addr) mem)))
+ (if (integerp page)
+ (let ((p (init-page (page-num addr) page)))
+ (set-page (write-page val (page-offset addr) p)
+ (page-num addr)
+ mem))
+ (set-page (write-page val (page-offset addr) page)
+ (page-num addr)
+ mem))))
+
+(verify-guards write-page
+ :hints (("Goal" :in-theory (enable page-p page-array-p))))
+
+(in-theory (disable write-mem init-page gen-page-tag write-page))
+
+
+(defthm page-p-init-page
+ (implies (integerp mode)
+ (page-p (init-page pn mode)))
+ :hints (("goal" :in-theory (enable page-p init-page page-array-p
+ default dimensions
+ header array1p word-array-p))))
+
+(verify-guards write-mem
+ :hints (("Goal" :in-theory (enable mem-p ))))
+
+(local
+(defthm word-array-p-compress11
+ (implies (and (array1p tag array)
+ (word-array-p array)
+ (integerp i))
+ (word-array-p (compress11 tag array i dim default)))
+ :hints (("Goal" :in-theory (enable word-array-p)))))
+
+
+; Added by Matt K. for Version 3.1, 7/1/06, to support proof of
+; compress1-assoc-property-0 in light of addition of reverse-sorted and
+; unsorted ACL2 arrays:
+(local
+ (defthm word-array-p-revappend
+ (equal (word-array-p (revappend x y))
+ (and (word-array-p x)
+ (word-array-p y)))
+ :hints (("Goal" :in-theory (enable word-array-p)
+ :induct (revappend x y)))))
+
+(defthm word-array-p-compress1
+ (implies (and (array1p tag array)
+ (word-array-p array))
+ (word-array-p (compress1 tag array)))
+ :hints (("Goal" :in-theory (enable compress1 word-array-p))))
+
+(defthm word-array-p-aset1
+ (implies (and (array1p tag page-array)
+ (word-array-p page-array)
+ (integerp index)
+ (>= index 0)
+ (> (car (dimensions tag page-array)) index)
+ (word-p val))
+ (word-array-p (aset1 tag page-array index val)))
+ :hints (("goal" :in-theory (enable aset1 word-array-p ARRAY1P-CONS))))
+
+(defthm page-array-p-aref1
+ (implies (and (page-array-p tag page-array)
+ (word-p val)
+ (integerp offset)
+ (>= offset 0)
+ (> *num-page-words* offset))
+ (page-array-p tag (aset1 tag page-array offset val)))
+ :hints (("Goal" :in-theory (enable page-array-p))))
+
+
+(defthm page-p-write-page
+ (implies (and (word-p val)
+ (integerp offset)
+ (>= offset 0)
+ (> *num-page-words* offset)
+ (page-p page))
+ (page-p (write-page val offset page)))
+ :hints (("Goal" :in-theory (enable write-page))))
+
+(local
+ (defthm valid-integer-assoc-mem-array
+ (implies (and (mem-array-p ma)
+ (integerp pn)
+ (assoc pn ma)
+ (integerp (cdr (assoc pn ma)))
+ (not (equal (cdr (assoc pn ma)) 0))
+ (not (equal (cdr (assoc pn ma)) 1)))
+ (equal (cdr (assoc pn ma)) 2))
+ :hints (("Goal" :in-theory (enable mem-array-p assoc)))))
+
+(local
+ (defthm page-p-assoc-mem-array
+ (implies (and (mem-array-p ma)
+ (integerp pn)
+ (assoc pn ma)
+ (not (integerp (cdr (assoc pn ma)))))
+ (page-p (cdr (assoc pn ma))))
+ :hints (("Goal" :in-theory (enable mem-array-p assoc)))))
+
+
+(local
+(defthm mem-array-p-compress11
+ (implies (and (array1p tag array)
+ (mem-array-p array)
+ (integerp i))
+ (mem-array-p (compress11 tag array i dim default)))
+ :hints (("Goal" :in-theory (enable mem-array-p compress1)))))
+
+; Added by Matt K. for Version 3.1, 7/1/06, to support proof of
+; compress1-assoc-property-0 in light of addition of reverse-sorted and
+; unsorted ACL2 arrays:
+(local
+ (defthm mem-array-p-revappend
+ (equal (mem-array-p (revappend x y))
+ (and (mem-array-p x)
+ (mem-array-p y)))
+ :hints (("Goal" :in-theory (enable mem-array-p)
+ :induct (revappend x y)))))
+
+(defthm mem-array-p-compress1
+ (implies (and (array1p tag array)
+ (mem-array-p array))
+ (mem-array-p (compress1 tag array)))
+ :hints (("Goal" :in-theory (enable mem-array-p compress1))))
+
+
+
+(defthm mem-array-p-aset1
+ (implies (and (array1p tag mem-array)
+ (mem-array-p mem-array)
+ (or (page-p page)
+ (equal page *no-access*)
+ (equal page *read-only*)
+ (equal page *read-write*))
+ (integerp pn)
+ (>= pn 0)
+ (> (car (dimensions tag mem-array)) pn))
+ (mem-array-p (aset1 tag mem-array pn page)))
+ :hints (("Goal" :in-theory (enable mem-array-p aset1))))
+
+
+(defthm mem-p-write-mem
+ (implies (and (word-p val)
+ (addr-p addr)
+ (mem-p mem))
+ (mem-p (write-mem val addr mem)))
+ :hints (("goal" :in-theory (enable mem-p write-mem))))
+
+(defthm page-num-offset-extionsionality
+ (implies (and (addr-p addr1)
+ (addr-p addr2)
+ (equal (page-num addr1) (page-num addr2))
+ (equal (page-offset addr1) (page-offset addr2)))
+ (equal addr1 addr2))
+ :hints (("Goal" :in-theory (enable addr-p page-num page-offset)))
+ :rule-classes
+ ((:rewrite :corollary
+ (implies (and (addr-p addr1)
+ (addr-p addr2)
+ (equal (page-num addr1) (page-num addr2))
+ (not (equal addr1 addr2)))
+ (equal (equal (page-offset addr1) (page-offset addr2))
+ nil)))))
+
+(defthm read-page-init-page
+ (implies (integerp offset)
+ (equal (read-page offset (init-page pn mode)) 0))
+ :hints (("Goal" :in-theory (enable init-page read-page aref1
+ default header))))
+
+
+(defthm read-page-write-page
+ (implies (and (page-p page)
+ (integerp offset1)
+ (>= offset1 0)
+ (> *num-page-words* offset1)
+ (integerp offset2)
+ (>= offset2 0)
+ (> *num-page-words* offset2))
+ (equal (read-page offset1 (write-page val offset2 page))
+ (if (equal offset1 offset2)
+ val
+ (read-page offset1 page))))
+ :hints (("Goal" :in-theory (enable page-p read-page write-page
+ page-array-p))))
+
+
+(defthm read-mem-write-mem
+ (implies (and (addr-p ad1)
+ (addr-p ad2)
+ (mem-p mem))
+ (equal (read-mem ad1 (write-mem val ad2 mem))
+ (if (equal ad1 ad2) val (read-mem ad1 mem))))
+ :hints (("Goal" :in-theory (enable read-mem write-mem
+ mem-p))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of Protection Check.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun readable-addr-p (ad mem)
+ (declare (xargs :guard (and (addr-p ad) (mem-p mem))
+ :verify-guards nil))
+ (let ((page (get-page (page-num ad) mem)))
+ (if (integerp page)
+ (or (equal page *read-only*)
+ (equal page *read-write*))
+ (or (equal (page-mode page) *read-only*)
+ (equal (page-mode page) *read-write*)))))
+
+(verify-guards readable-addr-p
+ :hints (("Goal" :in-theory (enable mem-p))))
+
+(defun readable-addr? (ad mem)
+ (declare (xargs :guard (and (addr-p ad) (mem-p mem))))
+ (if (readable-addr-p ad mem) 1 0))
+
+(defthm bitp-readable-addr (bitp (readable-addr? ad mem)))
+
+(defun writable-addr-p (ad mem)
+ (declare (xargs :guard (and (addr-p ad) (mem-p mem))
+ :verify-guards nil))
+ (let ((page (get-page (page-num ad) mem)))
+ (if (integerp page)
+ (equal page *read-write*)
+ (equal (page-mode page) *read-write*))))
+
+(verify-guards writable-addr-p
+ :hints (("Goal" :in-theory (enable mem-p))))
+
+(defun writable-addr? (ad mem)
+ (declare (xargs :guard (and (addr-p ad) (mem-p mem))))
+ (if (writable-addr-p ad mem) 1 0))
+
+(defthm bitp-writable-addr (bitp (writable-addr? ad mem)))
+
+(defun set-page-mode (mode pn mem)
+ (declare (xargs :guard (and (integerp mode)
+ (integerp pn) (<= 0 pn) (< pn *num-pages*)
+ (mem-p mem))
+ :verify-guards nil))
+ (let ((page (get-page pn mem)))
+ (if (integerp page)
+ (set-page mode pn mem)
+ (set-page (update-page page :mode mode) pn mem))))
+
+(verify-guards set-page-mode
+ :hints (("Goal" :in-theory (enable mem-p))))
+
+(defthm mem-p-set-page-mode
+ (implies (and (mem-p mem)
+ (integerp mode)
+ (or (equal mode *no-access*)
+ (equal mode *read-only*)
+ (equal mode *read-write*))
+ (integerp pn) (<= 0 pn) (< pn *num-pages*))
+ (mem-p (set-page-mode mode pn mem)))
+ :hints (("Goal" :in-theory (enable mem-p))))
+
+(defthm page-mode-init-page
+ (equal (page-mode (init-page page-num mode)) mode)
+ :hints (("Goal" :in-theory (enable init-page))))
+
+(defthm page-mode-write-page
+ (equal (page-mode (write-page val offset page))
+ (page-mode page))
+ :hints (("Goal" :in-theory (enable write-page))))
+
+(defthm readable-addr-p-set-page-mode
+ (implies (and (integerp mode)
+ (addr-p addr)
+ (integerp pn1) (<= 0 pn1) (< pn1 *num-pages*)
+ (mem-p mem))
+ (equal (readable-addr-p addr (set-page-mode mode pn1 mem))
+ (if (equal (page-num addr) pn1)
+ (or (equal mode *read-only*) (equal mode *read-write*))
+ (readable-addr-p addr mem))))
+ :hints (("Goal" :in-theory (enable set-page-mode mem-p
+ readable-addr-p))))
+
+
+(defthm readable-addr-set-page-mode
+ (implies (and (integerp mode)
+ (addr-p addr)
+ (integerp pn1) (<= 0 pn1) (< pn1 *num-pages*)
+ (mem-p mem))
+ (equal (readable-addr? addr (set-page-mode mode pn1 mem))
+ (if (equal (page-num addr) pn1)
+ (if (or (equal mode *read-only*)
+ (equal mode *read-write*))
+ 1 0)
+ (readable-addr? addr mem))))
+ :hints (("Goal" :in-theory (e/d (readable-addr?) (readable-addr-p
+ SET-PAGE-MODE)))))
+
+(defthm writable-addr-p-set-page-mode
+ (implies (and (integerp mode)
+ (addr-p addr)
+ (integerp pn1) (<= 0 pn1) (< pn1 *num-pages*)
+ (mem-p mem))
+ (equal (writable-addr-p addr (set-page-mode mode pn1 mem))
+ (if (equal (page-num addr) pn1)
+ (equal mode *read-write*)
+ (writable-addr-p addr mem))))
+ :hints (("Goal" :in-theory (enable set-page-mode mem-p
+ writable-addr-p))))
+
+(defthm writable-addr-set-page-mode
+ (implies (and (integerp mode)
+ (addr-p addr)
+ (integerp pn1) (<= 0 pn1) (< pn1 *num-pages*)
+ (mem-p mem))
+ (equal (writable-addr? addr (set-page-mode mode pn1 mem))
+ (if (equal (page-num addr) pn1)
+ (if (equal mode *read-write*) 1 0)
+ (writable-addr? addr mem))))
+ :hints (("Goal" :in-theory (e/d (writable-addr?)
+ (writable-addr-p SET-PAGE-MODE)))))
+
+(defthm readable-addr-p-write-mem
+ (implies (and (addr-p addr) (addr-p addr2) (word-p val) (mem-p mem))
+ (equal (readable-addr-p addr (write-mem val addr2 mem))
+ (readable-addr-p addr mem)))
+ :hints (("Goal" :in-theory (enable readable-addr-p write-mem mem-p))))
+
+(defthm readable-addr-write-mem
+ (implies (and (addr-p addr) (addr-p addr2) (word-p val) (mem-p mem))
+ (equal (readable-addr? addr (write-mem val addr2 mem))
+ (readable-addr? addr mem)))
+ :hints (("Goal" :in-theory (enable readable-addr?))))
+
+(defthm writable-addr-p-write-mem
+ (implies (and (addr-p addr) (addr-p addr2) (word-p val) (mem-p mem))
+ (equal (writable-addr-p addr (write-mem val addr2 mem))
+ (writable-addr-p addr mem)))
+ :hints (("Goal" :in-theory (enable writable-addr-p write-mem mem-p))))
+
+(defthm writable-addr-write-mem
+ (implies (and (addr-p addr) (addr-p addr2) (word-p val) (mem-p mem))
+ (equal (writable-addr? addr (write-mem val addr2 mem))
+ (writable-addr? addr mem)))
+ :hints (("Goal" :in-theory (enable writable-addr?))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Initialize Memory
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defconst *init-mem*
+ (compress1 'mem (list `(:header :name mem
+ :dimensions (,*num-pages*)
+ :default ,*no-access*
+ :maximum-length 2048))))
+
+(defthm mem-p-init-mem
+ (mem-p *init-mem*))
+
+(deflist mem-alist-p (l)
+ (declare (xargs :guard t))
+ (lambda (l) (and (consp l) (addr-p (car l)) (word-p (cdr l)))))
+
+(defun load-mem-alist (alist mem)
+ (declare (xargs :guard (and (mem-alist-p alist) (mem-p mem))))
+ (if (endp alist)
+ mem
+ (load-mem-alist (cdr alist) (write-mem (cdar alist) (caar alist) mem))))
+
+(defthm mem-p-load-mem-alist
+ (implies (and (mem-alist-p alist)
+ (mem-p mem))
+ (mem-p (load-mem-alist alist mem))))
+
+(in-theory (disable page-p page-array-p word-array-p mem-p))
+(in-theory (disable read-reg))
+(in-theory (disable write-reg))
+(in-theory (disable read-mem))
+(in-theory (disable write-mem))
+(in-theory (disable writable-addr-p readable-addr-p
+ writable-addr? readable-addr? set-page-mode))
+
+(defword* word-layout ((op-field 4 12)
+ (rc-field *rname-size* 8)
+ (ra-field *rname-size* 4)
+ (rb-field *rname-size* 0)
+ (im-field *immediate-size* 0))
+ :conc-name ||)
+
+
+(defthm opcd-p-opcode
+ (opcd-p (op-field inst))
+ :hints (("Goal" :in-theory (enable opcd-p))))
+
+(defthm rname-p-rc-field
+ (rname-p (rc-field inst))
+ :hints (("Goal" :in-theory (enable rname-p))))
+
+(defthm rname-p-ra-field
+ (rname-p (ra-field inst))
+ :hints (("Goal" :in-theory (enable rname-p))))
+
+(defthm rname-p-rb-field
+ (rname-p (rb-field inst))
+ :hints (("Goal" :in-theory (enable rname-p))))
+
+
+(defthm immediate-p-immediate-field
+ (immediate-p (im-field inst))
+ :hints (("Goal" :in-theory (enable immediate-p))))
+
+
+(defthm word-p-immediate-field
+ (word-p (im-field inst))
+ :hints (("Goal" :in-theory (enable word-p))))
+
+(defthm word-IM-field
+ (equal (word (IM-field i)) (IM-field i))
+ :hints (("goal" :in-theory (enable word))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of Special registers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defconst *num-sregs* 2)
+
+(defstructure sregs
+ (su (:assert (bitp su) :rewrite ))
+ (sr0 (:assert (word-p sr0) :rewrite))
+ (sr1 (:assert (word-p sr1) :rewrite))
+ (:options :guards))
+
+(defun srname-p (rname)
+ (declare (xargs :guard t))
+ (and (rname-p rname) (< rname *num-sregs*)))
+
+(defthm srname-p-type
+ (implies (srname-p rname)
+ (and (integerp rname)
+ (>= rname 0)
+ (< rname *num-sregs*)))
+ :hints (("Goal" :in-theory (enable rname-p srname-p)))
+ :rule-classes :forward-chaining)
+
+(defun read-sreg (id sregs)
+ (declare (xargs :guard (and (rname-p id) (sregs-p sregs))))
+ (if (equal id 0) (sregs-sr0 sregs)
+ (if (equal id 1) (sregs-sr1 sregs)
+ 0)))
+
+(defun write-sreg (val id sregs)
+ (declare (xargs :guard (and (word-p val) (rname-p id) (sregs-p sregs))))
+ (if (equal id 0) (sregs (sregs-su sregs) val (sregs-sr1 sregs))
+ (if (equal id 1) (sregs (sregs-su sregs) (sregs-sr0 sregs) val)
+ sregs)))
+
+(defthm word-p-read-sreg
+ (implies (and (rname-p id) (sregs-p sregs))
+ (word-p (read-sreg id sregs))))
+
+(defthm numberp-read-sreg
+ (implies (and (sregs-p sregs)
+ (rname-p rname))
+ (and (integerp (read-sreg rname sregs))
+ (acl2-numberp (read-sreg rname sregs))))
+ :hints (("Goal" :in-theory (enable rname-p sregs-p fixlen-word-listp)))
+ :rule-classes
+ ((:type-prescription) (:rewrite)))
+
+(defthm sregs-p-write-sreg
+ (implies (and (word-p val) (rname-p id) (sregs-p sregs))
+ (sregs-p (write-sreg val id sregs))))
+
+(defthm read-sreg-write-sreg
+ (implies (and (srname-p rn1)
+ (srname-p rn2)
+ (sregs-p sregs))
+ (equal (read-sreg rn1 (write-sreg val rn2 sregs))
+ (if (equal rn1 rn2) val (read-sreg rn1 sregs))))
+ :hints (("Goal" :in-theory (enable read-sreg write-sreg sregs-p
+ srname-p))))
+
+(in-theory (disable read-sreg write-sreg srname-p))
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-lemmas.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-lemmas.lisp
new file mode 100644
index 0000000..973bd09
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/basic-lemmas.lisp
@@ -0,0 +1,846 @@
+(in-package "ACL2")
+
+;(include-book "utils")
+(include-book "basic-def")
+(include-book "model")
+(include-book "table-def")
+
+(deflabel begin-basic-lemmas)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Proof of misc lemmas
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Lemmas about bv-eqv
+(defthm bv-eqv-opcode-p
+ (implies (and (opcd-p x) (opcd-p y))
+ (equal (b1p (bv-eqv *opcode-size* x y)) (equal x y)))
+ :hints (("goal" :in-theory (enable opcd-p))))
+
+(defthm bv-eqv-rname-p
+ (implies (and (rname-p x) (rname-p y))
+ (equal (b1p (bv-eqv *opcode-size* x y)) (equal x y)))
+ :hints (("goal" :in-theory (enable rname-p))))
+
+
+; Lemmas about the projection from an MA state to an ISA state.
+(defthm ISA-pc-proj
+ (equal (ISA-pc (proj MA)) (MA-pc MA))
+ :hints (("Goal" :in-theory (enable proj))))
+
+(defthm ISA-regs-proj
+ (equal (ISA-regs (proj MA)) (MA-regs MA))
+ :hints (("Goal" :in-theory (enable proj))))
+
+(defthm ISA-mem-proj
+ (equal (ISA-mem (proj MA)) (MA-mem MA))
+ :hints (("Goal" :in-theory (enable proj))))
+
+; (tail-p sublist list) is true if sublist is a terminating sub-list
+; of list. For instance, (tail-p '(1 2 3 4) '(3 4)) is T, while
+; (tail-p '(1 2 3 4) '(2 3)) is nil.
+(defun tail-p (sublist list)
+ (declare (xargs :guard (and (true-listp sublist) (true-listp list))))
+ (if (equal sublist list)
+ T
+ (if (endp list)
+ nil
+ (tail-p sublist (cdr list)))))
+
+; Basic lemmas bout tail-p.
+(defthm tail-p-cdr-1
+ (implies (and (consp sub) (tail-p sub lst))
+ (tail-p (cdr sub) lst)))
+
+(defthm tail-p-cdr-2
+ (implies (consp lst) (not (tail-p lst (cdr lst))))
+ :hints (("Goal" :induct (len lst))))
+
+; (INST-in i MT) is T, if MT contains i as an instruction entry.
+(defun INST-in (i MT)
+ (member-equal i (MT-trace MT)))
+
+; (subtrace-p trace MT) is T if trace is a terminating sub-list of
+; the list of instruction entries in MT. Since MT stores
+; instruction entries in ISA execution order, trace is a list of
+; entries representing most recently fetched instructions.
+(defun subtrace-p (trace MT)
+ (declare (xargs :guard (and (INST-listp trace) (MAETT-p MT))))
+ (tail-p trace (MT-trace MT)))
+
+(in-theory (disable INST-in subtrace-p))
+
+(defthm subtrace-p-MT-trace
+ (subtrace-p (MT-trace MT) MT)
+ :hints (("Goal" :in-theory (enable subtrace-p))))
+
+(defthm subtrace-p-cdr
+ (implies (and (subtrace-p trace MT) (consp trace))
+ (subtrace-p (cdr trace) MT))
+ :hints (("goal" :in-theory (enable subtrace-p))))
+
+(encapsulate nil
+(local
+(defthm inst-in-car-subtrace-induction
+ (implies (and (consp sub) (tail-p sub trace))
+ (member-equal (car sub) trace))))
+
+(defthm inst-in-car-subtrace
+ (implies (and (consp trace) (subtrace-p trace MT))
+ (INST-in (car trace) MT))
+ :hints (("Goal" :in-theory (enable INST-in subtrace-p))))
+)
+
+; ISA-at-tail is used in the definition of ISA-before
+(defun ISA-at-tail (sub trace pre)
+ (declare (xargs :guard (and (INST-listp sub) (INST-listp trace)
+ (ISA-state-p pre))))
+ (if (equal sub trace)
+ pre
+ (if (endp trace) pre
+ (ISA-at-tail sub (cdr trace) (INST-post-ISA (car trace))))))
+
+(defthm ISA-state-p-ISA-at-tail
+ (implies (and (ISA-state-p pre)
+ (INST-listp trace))
+ (ISA-state-p (ISA-at-tail sub trace pre))))
+
+; (ISA-before sub MT) returns the ISA state before the execution of
+; the first instruction in sub. For instance, MT represents
+; instructions I_1, I_2, I_3 and I_4. If sub = (I_3 I_4), then
+; (ISA-before sub MT) returns ISA state before executing I_3. If sub is nil,
+; (ISA-before sub MT) returns the ISA state after executing all instructions
+; represented in MT.
+(defun ISA-before (sub MT)
+ (declare (xargs :guard (and (INST-listp sub) (MAETT-p MT))))
+ (ISA-at-tail sub (MT-trace MT) (MT-init-ISA MT)))
+
+(in-theory (disable ISA-before))
+
+(defthm ISA-state-p-ISA-before
+ (implies (MAETT-p MT)
+ (ISA-state-p (ISA-before sub MT)))
+ :hints (("goal" :in-theory (enable ISA-before))))
+
+(defthm ISA-before-MT-trace
+ (equal (ISA-before (MT-trace MT) MT)
+ (MT-init-ISA MT))
+ :hints (("Goal" :in-theory (enable ISA-before))))
+
+(encapsulate nil
+(defthm ISA-before-cdr-induction
+ (implies (and (tail-p sub trace)
+ (consp sub))
+ (equal (ISA-at-tail (cdr sub) trace ISA)
+ (INST-post-ISA (car sub)))))
+
+(defthm ISA-before-cdr
+ (implies (and (subtrace-p sub MT)
+ (consp sub))
+ (equal (ISA-before (cdr sub) MT)
+ (INST-post-ISA (car sub))))
+ :hints (("Goal" :in-theory (enable ISA-before subtrace-p))))
+)
+
+(encapsulate nil
+(local
+(defthm INST-p-INST-at-induction
+ (implies (and (INST-listp trace) (trace-INST-at stg trace))
+ (INST-p (trace-INST-at stg trace)))))
+
+; INST-p-INST-at asserts that (INST-at stg MT) is of type INST-p if
+; there exists an instruction at stage stg. (INST-at stg MT) is
+; nil if MT does not contains an entry representing an instruction at
+; stage stg.
+(defthm INST-p-INST-at
+ (implies (and (MAETT-p MT) (INST-at stg MT))
+ (INST-p (INST-at stg MT)))
+ :hints (("Goal" :in-theory (enable INST-p INST-at))))
+)
+
+(encapsulate nil
+(local
+(defthm INST-in-INST-at-induction
+ (implies (trace-INST-at stg trace)
+ (member-equal (trace-INST-at stg trace) trace))))
+
+; (INST-at stg MT) is an instruction entry in MT, unless it is nil.
+(defthm INST-in-INST-at
+ (implies (INST-at stg MT)
+ (INST-in (INST-at stg MT) MT))
+ :hints (("Goal" :in-theory (enable INST-at INST-in))))
+)
+
+
+(encapsulate nil
+(local
+(defthm INST-stg-INST-at-induction
+ (implies (trace-INST-at stg trace)
+ (equal (INST-stg (trace-INST-at stg trace)) stg))))
+
+; Stage of (INST-at stg MT).
+(defthm INST-stg-INST-at
+ (implies (INST-at stg MT) (equal (INST-stg (INST-at stg MT)) stg))
+ :hints (("Goal" :in-theory (enable INST-at))))
+)
+
+; Memory is not updated by our machine.
+(defthm ISA-mem-ISA-step
+ (equal (ISA-mem (ISA-step ISA)) (ISA-mem ISA))
+ :hints (("Goal" :in-theory (enable ISA-step ISA-add ISA-sub ISA-default))))
+
+(defthm ISA-mem-ISA-stepn
+ (equal (ISA-mem (ISA-stepn ISA n)) (ISA-mem ISA)))
+
+; Various small lemmas about attributes of instructions. I don't
+; comment each of them. Most of them are trivial from the definition
+; of the instruction attributes and the definition of step-INST.
+(defthm INST-word-new-INST
+ (equal (INST-word (new-INST ISA))
+ (read-mem (ISA-pc ISA) (ISA-mem ISA)))
+ :hints (("Goal" :in-theory (enable new-INST INST-word))))
+
+(defthm INST-stg-new-INST
+ (equal (INST-stg (new-INST ISA)) 'latch1)
+ :hints (("Goal" :in-theory (enable new-INST))))
+
+(defthm INST-pre-ISA-new-INST
+ (equal (INST-pre-ISA (new-INST ISA)) ISA)
+ :hints (("Goal" :in-theory (enable new-INST))))
+
+(defthm INST-post-ISA-new-INST
+ (equal (INST-post-ISA (new-INST ISA)) (ISA-step ISA))
+ :hints (("Goal" :in-theory (enable new-INST))))
+
+(defthm INST-word-step-INST
+ (implies (INST-p i)
+ (equal (INST-word (step-INST i MA)) (INST-word i)))
+ :hints (("Goal" :in-theory (enable step-INST step-latch1-INST
+ INST-word step-latch2-INST))))
+
+(defthm INST-op-step-INST
+ (implies (INST-p i)
+ (equal (INST-op (step-INST i MA)) (INST-op i)))
+ :hints (("Goal" :in-theory (enable INST-op))))
+
+(defthm INST-rc-step-INST
+ (implies (INST-p i)
+ (equal (INST-rc (step-INST i MA)) (INST-rc i)))
+ :hints (("Goal" :in-theory (enable INST-rc))))
+
+(defthm INST-ra-step-INST
+ (implies (INST-p i)
+ (equal (INST-ra (step-INST i MA)) (INST-ra i)))
+ :hints (("Goal" :in-theory (enable INST-ra))))
+
+(defthm INST-rb-step-INST
+ (implies (INST-p i)
+ (equal (INST-rb (step-INST i MA)) (INST-rb i)))
+ :hints (("Goal" :in-theory (enable INST-rb))))
+
+
+(defthm INST-pre-ISA-step-INST
+ (implies (INST-p i)
+ (equal (INST-pre-ISA (step-INST i MA)) (INST-pre-ISA i)))
+ :hints (("Goal" :in-theory (enable step-INST step-latch1-INST
+ step-latch2-INST))))
+
+(defthm INST-post-ISA-step-INST
+ (implies (INST-p i)
+ (equal (INST-post-ISA (step-INST i MA)) (INST-post-ISA i)))
+ :hints (("Goal" :in-theory (enable step-INST step-latch1-INST
+ step-latch2-INST))))
+(defthm INST-pre-ISA-car-MT-trace
+ (implies (and (invariant MT MA)
+ (consp (MT-trace MT)))
+ (equal (INST-pre-ISA (car (MT-trace MT))) (MT-init-ISA MT)))
+ :hints (("Goal" :in-theory (enable invariant ISA-chain-p))))
+
+
+(defthm MT-init-ISA-init-MT
+ (equal (MT-init-ISA (init-MT MA)) (proj MA))
+ :hints (("Goal" :in-theory (enable init-MT))))
+
+(defthm MT-init-ISA-MT-step
+ (equal (MT-init-ISA (MT-step MT MA sig))
+ (MT-init-ISA MT))
+ :hints (("goal" :in-theory (enable MT-step))))
+
+(defthm MT-init-ISA-MT-stepn
+ (equal (MT-init-ISA (MT-stepn MT MA sig n))
+ (MT-init-ISA MT)))
+
+
+; In order to understand following several lemmas, you need to understand
+; how INST-pre-ISA and INST-post-ISA make a chain of ISA states.
+; Intuitively, (INST-pre-ISA i) is the ISA state before executing the
+; instruction represented by i, and (INST-post-ISA i) is the ISA state
+; after the execution. Suppose we execute instruction I_0, I_1 and I_2
+; in that order successively. Equation
+; (INST-post-ISA I_0) = (INST-pre-ISA I_1)
+; holds because the resulting state of an instruction is a starting state
+; for the immediately following instruction. This relation can be
+; described better with a picture shown below:
+; (INST-pre-ISA i_0)
+; | execution of i_0
+; v
+; (INST-post-ISA i_0) = (INST-pre-ISA i_1)
+; | execution of i_1
+; v
+; (INST-post-ISA i_1) = (INST-pre-ISA i_2)
+; ...
+; The transition relation can be written as
+; (INST-post-ISA I_0) = (ISA-step (INST-pre-ISA I_0)).
+(encapsulate nil
+(local
+(defthm INST-post-ISA-INST-in-induction
+ (implies (and (member-equal i trace)
+ (ISA-chain-trace-p trace ISA)
+ (INST-p i))
+ (equal (INST-post-ISA i)
+ (ISA-step (INST-pre-ISA i))))))
+
+(defthm INST-post-ISA-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT)
+ (INST-in i MT) (INST-p i))
+ (equal (INST-post-ISA i)
+ (ISA-step (INST-pre-ISA i))))
+ :hints (("Goal" :in-theory (enable INST-in invariant ISA-chain-p))))
+)
+
+
+(encapsulate nil
+(local
+(defthm INST-post-ISA-car-subtrace-help
+ (implies (and (ISA-chain-trace-p trace ISA)
+ (tail-p sub trace)
+ (consp sub)
+ (INST-listp trace))
+ (equal (INST-post-ISA (car sub))
+ (ISA-step (INST-pre-ISA (car sub)))))))
+
+(defthm INST-post-ISA-car-subtrace
+ (implies (and (invariant MT MA)
+ (subtrace-p trace MT)
+ (MAETT-p MT)
+ (consp trace)
+ (INST-listp trace))
+ (equal (INST-post-ISA (car trace))
+ (ISA-step (INST-pre-ISA (car trace)))))
+ :hints (("goal" :in-theory (enable invariant subtrace-p
+ ISA-chain-p))))
+)
+
+(encapsulate nil
+(local
+(defthm INST-pre-ISA-cadr-subtrace-induction
+ (implies (and (ISA-chain-trace-p trace ISA)
+ (tail-p sub trace)
+ (INST-listp trace)
+ (consp sub)
+ (consp (cdr sub)))
+ (equal (INST-pre-ISA (cadr sub))
+ (ISA-step (INST-pre-ISA (car sub)))))))
+
+(defthm INST-pre-ISA-cadr-subtrace
+ (implies (and (invariant MT MA)
+ (subtrace-p trace MT)
+ (MAETT-p MT)
+ (INST-listp trace)
+ (consp trace)
+ (consp (cdr trace)))
+ (equal (INST-pre-ISA (cadr trace))
+ (ISA-step (INST-pre-ISA (car trace)))))
+ :hints (("goal" :in-theory (enable invariant ISA-chain-p subtrace-p))))
+)
+
+(encapsulate nil
+(local
+(defthm ISA-before-INST-pre-ISA-car-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-listp trace)
+ (subtrace-p trace MT)
+ (tail-p sub trace)
+ (consp sub))
+ (equal (ISA-at-tail sub trace (INST-pre-ISA (car trace)))
+ (INST-pre-ISA (car sub))))
+ :hints (("Subgoal *1/3" :cases ((consp (cdr trace)))))
+ :rule-classes nil))
+
+; The relation between ISA-before and INST-pre-ISA is described by this
+; lemma.
+(defthm ISA-before-INST-pre-ISA-car
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (consp trace))
+ (equal (ISA-before trace MT)
+ (INST-pre-ISA (car trace))))
+ :hints (("Goal" :in-theory (enable ISA-before subtrace-p)
+ :use (:instance ISA-before-INST-pre-ISA-car-induction
+ (sub trace)
+ (trace (MT-trace MT))))
+ ("Goal'" :cases ((consp (MT-trace MT))))))
+)
+(in-theory (disable ISA-before-INST-pre-ISA-car))
+
+(encapsulate nil
+(local
+(defthm ISA-pc-ISA-before-nil-help
+ (implies (and (equal (trace-pc trace ISA) (MA-pc MA))
+ (MAETT-p MT) (MA-state-p MA))
+ (equal (ISA-pc (ISA-at-tail nil trace ISA)) (MA-pc MA)))))
+
+; The program counter in an MA state points to the instruction which
+; will be fetched in the next machine cycle. Since the MAETT records
+; all fetched instructions, the program counter of post-ISA of the
+; last instruction in the MAETT is equal to the program counter in
+; the MA state.
+(defthm ISA-pc-ISA-before-nil
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (equal (ISA-pc (ISA-before nil MT)) (MA-pc MA)))
+ :hints (("Goal" :in-theory (enable ISA-before invariant pc-match-p
+ MT-pc))))
+)
+
+
+(encapsulate nil
+(local
+(defthm ISA-mem-ISA-before-nil-induction
+ (implies (and (MAETT-p MT) (MA-state-p MA)
+ (ISA-chain-trace-p trace ISA))
+ (equal (ISA-mem (ISA-at-tail nil trace ISA))
+ (ISA-mem ISA)))))
+
+(local
+(defthm ISA-mem-ISA-before-nil-help
+ (implies (and (MAETT-p MT) (MA-state-p MA)
+ (invariant MT MA))
+ (equal (ISA-mem (ISA-before nil MT))
+ (ISA-mem (MT-init-ISA MT))))
+ :hints (("Goal" :in-theory (enable ISA-before invariant ISA-chain-p)))))
+
+; Memory is not updated, therefore the memory state at any ISA state
+; is equal to any MA state.
+(defthm ISA-mem-ISA-before-nil
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (equal (ISA-mem (ISA-before nil MT)) (MA-mem MA)))
+ :hints (("Goal" :in-theory (enable invariant mem-match-p))))
+)
+
+; There are only two states in this pipeline latch1 and latch2. We also
+; count retire as another stage. The stage of an instruction entry
+; should be one of them.
+(defthm stages-of-INST
+ (implies (INST-p i)
+ (or (equal (INST-stg i) 'latch1) (equal (INST-stg i) 'latch2)
+ (equal (INST-stg i) 'retire)))
+ :hints (("goal" :in-theory (enable INST-p stage-p)))
+ :rule-classes nil)
+
+; Following several lemmas are about how the stages of an instruction
+; changes.
+(defthm INST-stg-step-latch1-INST
+ (implies (equal (INST-stg i) 'latch1)
+ (equal (INST-stg (step-INST i MA))
+ (if (b1p (stall-cond? MA)) 'latch1 'latch2)))
+ :hints (("Goal" :in-theory (enable step-INST step-latch1-INST))))
+
+
+(defthm retire-step-INST-if-latch2
+ (implies (equal (INST-stg i) 'latch2)
+ (equal (INST-stg (step-INST i MA)) 'retire))
+ :hints (("Goal" :in-theory (enable step-INST step-latch1-INST
+ step-latch2-INST))))
+
+(defthm retire-step-INST-if-retire
+ (implies (equal (INST-stg i) 'retire)
+ (equal (INST-stg (step-INST i MA)) 'retire))
+ :hints (("Goal" :in-theory (enable step-INST step-latch1-INST
+ step-latch2-INST))))
+
+(defthm not-retire-step-INST-if-not-retire-latch2
+ (implies (and (INST-p i)
+ (not (equal (INST-stg i) 'retire))
+ (not (equal (INST-stg i) 'latch2)))
+ (not (equal (INST-stg (step-INST i MT)) 'retire)))
+ :hints (("Goal" :in-theory (enable INST-p stage-p step-INST
+ step-latch1-INST))))
+
+(encapsulate nil
+(local
+(defthm no-inst-after-INST-latch1-induction
+ (implies (and (trace-in-order-p trace)
+ (tail-p sub trace)
+ (INST-listp trace)
+ (consp sub)
+ (equal (INST-stg (car sub)) 'latch1))
+ (endp (cdr sub)))
+ :rule-classes nil))
+
+; Instruction at latch1 is the most recently fetched instruction. A
+; MAETT records instructions in program order, so the instruction at latch1
+; is always represented by the last entry of a MAETT.
+(defthm no-inst-after-INST-latch1
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (car trace)) 'latch1))
+ (endp (cdr trace)))
+ :hints (("Goal" :in-theory (enable subtrace-p invariant MT-in-order-p)
+ :use (:instance no-inst-after-INST-latch1-induction
+ (sub trace) (trace (MT-trace MT)))))
+ :rule-classes nil)
+)
+
+; A corollary of no-inst-after-INST-latch1.
+(defthm INST-latch1-last-inst-in-MT
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (car trace)) 'latch1))
+ (not (member-equal i (cdr trace))))
+ :hints (("Goal" :use (:instance no-inst-after-INST-latch1))))
+
+; The instruction at stage latch2 is older than the instruction at latch1.
+(defthm no-inst-at-latch2-after-latch1
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (car trace)) 'latch1))
+ (not (trace-INST-at 'latch2 (cdr trace))))
+ :hints (("Goal" :use (:instance no-inst-after-INST-latch1))))
+
+
+(encapsulate nil
+(local
+(defthm no-inst-at-latch2-after-latch2-help
+ (implies (and (trace-in-order-p trace)
+ (tail-p sub trace)
+ (INST-listp trace)
+ (consp sub)
+ (equal (INST-stg (car sub)) 'latch2))
+ (not (trace-INST-at 'latch2 (cdr sub))))))
+
+; There are no two instructions at latch2.
+(defthm no-inst-at-latch2-after-latch2
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (car trace)) 'latch2))
+ (not (trace-INST-at 'latch2 (cdr trace))))
+ :hints (("Goal" :in-theory (enable subtrace-p invariant MT-in-order-p))))
+)
+
+(encapsulate nil
+(local
+(defthm no-inst-at-retire-after-latch2-help
+ (implies (and (trace-in-order-p trace)
+ (tail-p sub trace)
+ (INST-listp trace)
+ (consp sub)
+ (equal (INST-stg (car sub)) 'latch2))
+ (not (trace-INST-at 'retire (cdr sub))))))
+
+; No retired instruction is younger than instruction at latch2.
+; Instructions are retired in program order.
+(defthm no-inst-at-retire-after-latch2
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (car trace)) 'latch2))
+ (not (trace-INST-at 'retire (cdr trace))))
+ :hints (("Goal" :in-theory (enable subtrace-p invariant MT-in-order-p))))
+)
+
+; An instruction at latch2 is immediately followed by an instruction
+; at latch1.
+(defthm INST-latch1-follows-INST-latch2
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace) (consp (cdr trace))
+ (equal (INST-stg (car trace)) 'latch2))
+ (equal (INST-stg (cadr trace)) 'latch1))
+ :hints (("Goal" :use ((:instance stages-of-inst (i (cadr trace)))
+ (:instance no-inst-at-latch2-after-latch2)
+ (:instance no-inst-at-retire-after-latch2))
+ :in-theory (disable no-inst-at-latch2-after-latch2
+ no-inst-at-retire-after-latch2))))
+
+
+; Predicate inst-invariant is an invariant condition that every
+; instruction in a MAETT should satisfy. Following two lemmas shows
+; that in two different formulation.
+(encapsulate nil
+(local
+(defthm inst-invariant-INST-at-help
+ (implies (and (trace-INST-invariant trace MA)
+ (trace-INST-at stg trace))
+ (inst-invariant (trace-INST-at stg trace) MA))))
+
+(defthm inst-invariant-INST-at
+ (implies (and (invariant MT MA)
+ (INST-at stg MT))
+ (inst-invariant (INST-at stg MT) MA))
+ :hints (("Goal" :in-theory (enable INST-at invariant MT-inst-invariant))))
+)
+
+(encapsulate nil
+(local
+ (defthm INST-invariant-INST-in-induction
+ (implies (and (trace-inst-invariant trace MA)
+ (member-equal i trace))
+ (inst-invariant i MA))))
+
+
+(defthm INST-invariant-INST-in
+ (implies (and (invariant MT MA)
+ (INST-in i MT))
+ (inst-invariant i MA))
+ :hints (("Goal" :in-theory (enable invariant INST-in MT-inst-invariant
+ trace-INST-invariant)))
+ :rule-classes nil)
+)
+
+; There must be an instruction at latch1 if flag latch1-valid? in an
+; MA state is on. This lemma shows that a MAETT contains an entry
+; representing the instruction at latch1 if latch1-valid? is on in
+; the corresponding MA state.
+(defthm INST-at-latch1-if-latch1-valid
+ (implies (and (invariant MT MA)
+ (b1p (latch1-valid? (MA-latch1 MA))))
+ (INST-at 'latch1 MT))
+ :hints (("Goal" :in-theory (enable invariant MT-contains-all-insts))))
+
+; If latch1-valid? is off, no instruction is at latch1.
+(defthm not-INST-at-latch1-if-not-latch1-valid
+ (implies (and (invariant MT MA)
+ (not (b1p (latch1-valid? (MA-latch1 MA)))))
+ (not (INST-at 'latch1 MT)))
+ :hints (("Goal" :use (:instance INST-invariant-INST-at (stg 'latch1))
+ :in-theory (e/d (INST-invariant INST-latch1-inv)
+ (INST-invariant-INST-at)))))
+
+; If instruction i is at latch1, latch1-valid? should be on.
+(defthm latch1-valid-if-INST-in
+ (implies (and (invariant MT MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1))
+ (b1p (latch1-valid? (MA-latch1 MA))))
+ :hints (("Goal" :use (:instance INST-invariant-INST-in)
+ :in-theory (e/d (INST-invariant INST-latch1-inv)
+ ()))))
+
+; Same for latch2.
+(defthm INST-at-latch2-if-latch2-valid
+ (implies (and (invariant MT MA)
+ (b1p (latch2-valid? (MA-latch2 MA))))
+ (INST-at 'latch2 MT))
+ :hints (("Goal" :in-theory (enable invariant MT-contains-all-insts))))
+
+(defthm not-INST-at-latch2-if-not-latch2-valid
+ (implies (and (invariant MT MA)
+ (not (b1p (latch2-valid? (MA-latch2 MA)))))
+ (not (INST-at 'latch2 MT)))
+ :hints (("Goal" :use (:instance INST-invariant-INST-at (stg 'latch2))
+ :in-theory (e/d (INST-invariant INST-latch2-inv)
+ (INST-invariant-INST-at)))))
+
+(defthm latch2-valid-if-INST-in
+ (implies (and (invariant MT MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch2))
+ (b1p (latch2-valid? (MA-latch2 MA))))
+ :hints (("Goal" :use (:instance INST-invariant-INST-in)
+ :in-theory (e/d (INST-invariant INST-latch2-inv)
+ ()))))
+
+; Correct intermediate values of instruction execution can be specified
+; using the instruction entry in a MAETT. For
+; instance, if instruction I is in latch1, then the latch1-op should
+; hold the operand of instruction I, which can be specified as
+; (INST-op i). This is shown by Lemma latch1-op-INST-op-if-INST-in.
+; In the rest of this file, we give a list of similar lemmas.
+
+;
+; Note: First, we give all lemmas in the same style as
+; latch1-op-INST-op-if-INST-in. Then we re-state all the lemmas in a
+; different style, starting from latch1-op-INST-op. In the latter
+; style, we use function INST-at to specify the instruction at a
+; specific latch.
+(defthm latch1-op-INST-op-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1))
+ (equal (latch1-op (MA-latch1 MA)) (INST-op i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+(defthm latch1-rc-INST-rc-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1))
+ (equal (latch1-rc (MA-latch1 MA)) (INST-rc i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+(defthm latch1-ra-INST-ra-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1))
+ (equal (latch1-ra (MA-latch1 MA)) (INST-ra i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+(defthm latch1-rb-INST-rb-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1))
+ (equal (latch1-rb (MA-latch1 MA)) (INST-rb i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+(defthm latch2-op-INST-op-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch2))
+ (equal (latch2-op (MA-latch2 MA)) (INST-op i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+(defthm latch2-rc-INST-rc-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch2))
+ (equal (latch2-rc (MA-latch2 MA)) (INST-rc i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+(defthm latch2-val1-INST-val1-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch2))
+ (equal (latch2-ra-val (MA-latch2 MA)) (INST-ra-val i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+(defthm latch2-rb-val-INST-rb-val-if-INST-in
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch2))
+ (equal (latch2-rb-val (MA-latch2 MA)) (INST-rb-val i)))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-in))))
+
+
+(defthm latch1-op-INST-op
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch1 MT))
+ (equal (latch1-op (MA-latch1 MA))
+ (INST-op (INST-at 'latch1 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch1)))))
+
+(defthm latch1-rc-INST-rc
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch1 MT))
+ (equal (latch1-rc (MA-latch1 MA))
+ (INST-rc (INST-at 'latch1 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch1)))))
+
+(defthm latch1-ra-INST-ra
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch1 MT))
+ (equal (latch1-ra (MA-latch1 MA))
+ (INST-ra (INST-at 'latch1 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch1)))))
+
+(defthm latch1-rb-INST-rb
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch1 MT))
+ (equal (latch1-rb (MA-latch1 MA))
+ (INST-rb (INST-at 'latch1 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH1-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch1)))))
+
+(defthm latch2-op-INST-op
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch2 MT))
+ (equal (latch2-op (MA-latch2 MA))
+ (INST-op (INST-at 'latch2 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch2)))))
+
+(defthm latch2-rc-INST-rc
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch2 MT))
+ (equal (latch2-rc (MA-latch2 MA))
+ (INST-rc (INST-at 'latch2 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch2)))))
+
+(defthm latch2-ra-val-INST-ra-val
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch2 MT))
+ (equal (latch2-ra-val (MA-latch2 MA))
+ (INST-ra-val (INST-at 'latch2 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch2)))))
+
+(defthm latch2-rb-val-INST-rb-val
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch2 MT))
+ (equal (latch2-rb-val (MA-latch2 MA))
+ (INST-rb-val (INST-at 'latch2 MT))))
+ :hints (("goal" :in-theory (e/d (INST-INVARIANT INST-LATCH2-INV)
+ (inst-invariant-INST-at))
+ :use (:instance inst-invariant-INST-at (stg 'latch2)))))
+
+
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/ihs.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/ihs.lisp
new file mode 100644
index 0000000..1117cbc
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/ihs.lisp
@@ -0,0 +1,155 @@
+(in-package "ACL2")
+
+;; [Jared] turning this book into an include-book since it is identical to
+;; 1999/pipeline/ihs
+
+(include-book "workshops/1999/pipeline/ihs" :dir :system)
+
+;; (deflabel before-loading-ihs)
+;; (include-book "../../../../../../ihs/ihs-definitions")
+;; (include-book "../../../../../../ihs/ihs-lemmas")
+;; (deflabel after-loading-ihs)
+
+;; (deftheory default-IHS-incompatibles
+;; '(oddp evenp floor mod rem truncate expt
+;; loghead logtail logior lognot logand logand
+;; logeqv logorc1 logorc2 logandc1 logandc2 logcount
+;; lognand lognor logxor))
+
+;; (in-theory
+;; (set-difference-theories (current-theory :here)
+;; (set-difference-theories (universal-theory 'after-loading-IHS)
+;; (universal-theory 'before-loading-IHS))))
+
+;; (in-theory (disable default-ihs-incompatibles))
+;; (in-theory
+;; (enable
+;; ihs-math ; From "math-lemmas"
+;; quotient-remainder-rules ; From "quotient-remainder-lemmas"
+;; logops-lemmas-theory)) ; From "logops-lemmas"
+
+;; (in-theory (disable (force)))
+
+;; (in-theory (disable
+;; (:generalize MOD-X-Y-=-X+Y-for-rationals)
+;; (:generalize MOD-X-Y-=-X-for-rationals)
+;; (:generalize MOD-=-0)
+;; (:generalize FLOOR-TYPE-4)
+;; (:generalize FLOOR-TYPE-3)
+;; (:generalize FLOOR-TYPE-2)
+;; (:generalize FLOOR-TYPE-1)
+;; (:generalize FLOOR-BOUNDED-BY-/)
+;; (:generalize FLOOR-=-X/Y)))
+
+
+;; (defun weak-defword-tuple-p (tuple)
+;; (or (and (true-listp tuple)
+;; (or (equal (length tuple) 3)
+;; (equal (length tuple) 4))
+;; (symbolp (first tuple)))
+;; (er hard 'defword
+;; "A field designator for DEFWORD must be a list, the first ~
+;; element of which is a symbol, the second a positive integer, ~
+;; and the third a non-negative integer. If a fouth element is ~
+;; provided it must be a string. This object violates these ~
+;; constraints: ~p0" tuple)))
+
+;; (defun weak-defword-tuple-p-listp (struct)
+;; (cond
+;; ((null struct) t)
+;; (t (and (weak-defword-tuple-p (car struct))
+;; (weak-defword-tuple-p-listp (cdr struct))))))
+
+;; (defun weak-defword-struct-p (struct)
+;; (cond
+;; ((true-listp struct) (weak-defword-tuple-p-listp struct))
+;; (t (er hard 'defword
+;; "The second argument of DEFWORD must be a true list. ~
+;; This object is not a true list: ~p0" struct))))
+
+;; (defun weak-defword-guards (struct)
+;; (weak-defword-struct-p struct))
+
+;; (defun defword-tuple-typecheck-thms (tuple)
+;; (let ((tuple-thm-name
+;; (pack-intern (first tuple) "DEFWORD-TUPLE-" (first tuple))))
+;; `(local (defthm ,tuple-thm-name
+;; (and
+;; (integerp ,(second tuple))
+;; (> ,(second tuple) 0)
+;; (integerp ,(third tuple))
+;; (>= ,(third tuple) 0)
+;; (implies ,(fourth tuple) (stringp ,(fourth tuple))))
+;; :rule-classes nil))))
+
+
+;; (defun defword-struct-typecheck-thms (struct)
+;; (if (endp struct) nil
+;; (cons (defword-tuple-typecheck-thms (car struct))
+;; (defword-struct-typecheck-thms (cdr struct)))))
+
+;; (defun type-check-thms
+;; (name struct conc-name set-conc-name keyword-updater doc)
+;; (append
+;; (list
+;; `(local (defthm defword-symbolp-name (symbolp ',name)
+;; :rule-classes nil
+;; :doc "Defword name should be a symbol."))
+;; `(local (defthm defword-symbolp-conc-name (symbolp ',conc-name)
+;; :rule-classes nil
+;; :doc "Defword conc-name should be a symbol."))
+;; `(local (defthm defword-symbolp-set-conc-name (symbolp ',set-conc-name)
+;; :rule-classes nil
+;; :doc "Defword set-conc-name should be a symbol."))
+;; `(local
+;; (defthm defword-symbolp-keyword-updater (symbolp ',keyword-updater)
+;; :rule-classes nil
+;; :doc "Defword keyword-updater should be a symbol."))
+;; `(local (defthm defword-stringp-doc
+;; (implies ',doc (stringp ',doc))
+;; :rule-classes nil
+;; :doc "Defword doc should be a string.")))
+;; (defword-struct-typecheck-thms struct)))
+
+
+;; ;; This version of defword postpones the type checking of arguments until
+;; ;; macro expansion is completed. Because the original deword checks
+;; ;; types of arguments before expanding macro, some defword expressions
+;; ;; are rejected even if it can be considered as a legitimate defword
+;; ;; expression. For instance,
+;; ;; (defword new-word ((field1 *field1-pos* *field1-width*)
+;; ;; (field2 *field2-pos* *field2-width*)))
+;; ;; is rejected because *field1-pos* and other constants are not
+;; ;; integers.
+;; (defmacro defword* (name struct &key conc-name set-conc-name keyword-updater
+;; doc)
+;; (cond
+;; ((not (weak-defword-guards struct)))
+;; (t
+;; (let*
+;; ((conc-name (if conc-name
+;; conc-name
+;; (pack-intern name name "-")))
+;; (set-conc-name (if set-conc-name
+;; set-conc-name
+;; (pack-intern name "SET-" name "-")))
+;; (keyword-updater (if keyword-updater
+;; keyword-updater
+;; (pack-intern name "UPDATE-" name)))
+;; (type-check-thms
+;; (type-check-thms name struct conc-name set-conc-name
+;; keyword-updater doc))
+;; (accessor-definitions
+;; (defword-accessor-definitions 'RDB name conc-name struct))
+;; (updater-definitions
+;; (defword-updater-definitions 'WRB name set-conc-name struct))
+;; (field-names (strip-cars struct)))
+
+;; `(ENCAPSULATE () ;Only to make macroexpansion pretty.
+;; (DEFLABEL ,name ,@(if doc `(:DOC ,doc) nil))
+;; ,@type-check-thms
+;; ,@accessor-definitions
+;; ,@updater-definitions
+;; ,(defword-keyword-updater
+;; name keyword-updater set-conc-name field-names))))))
+
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/model.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/model.lisp
new file mode 100644
index 0000000..c9ea05d
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/model.lisp
@@ -0,0 +1,374 @@
+(in-package "ACL2")
+
+(include-book "basic-def")
+
+(deflabel begin-model)
+
+; Basic Pipeline Design
+; Our example machine is very simple. It consists of a program counter,
+; a register file, the memory, pipeline latches latch1 and latch2.
+; The programmer visible components are the program counter, the register
+; file and the memory. It can execute two types of instructions, ADD
+; and SUB. The format of an instruction is as shown here:
+; --------------------------------
+; | op | RC | RA | RB |
+; --------------------------------
+; 15 12 11 8 7 4 3 0
+;
+; where RC, RA and RB are operand register specifiers. There are only
+; two valid opcodes 0 (ADD) and 1 (SUB). An instruction without a
+; valid opcode is considered as a NOP. The ADD instruction reads
+; registers specified by RA and RB, adds the values and writes the
+; result back into the register specified by RC. The SUB subtracts RB
+; from RA. Every machine cycle the program counter is incremented by
+; 1. No exceptions and no interrupts occur. There is one external
+; input to the machine. If this input signal is on, the machine may
+; fetch a new instruction from the memory. Pipeline flushing can be
+; done by running the machine with 0's as its inputs.
+;
+; We define this machine at two levels: instruction-set architecture
+; and micro-architecture.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; ISA Definition
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Description of ISA
+; The ISA state consists of only programmer visible states, that is,
+; the program counter, register file and the memory.
+; ISA behavior is specified by ISA-step. Depending on the operand,
+; it executes ADD or SUB operation.
+
+; Definition of the ISA state.
+;
+; Note: For the detail of the definition with defstructure, please
+; refer to the public ACL2 book data-structures/structures.lisp.
+; Briefly speaking, an expression (ISA-state PC REGS MEM) returns
+; an ISA state whose program counter, register file and memory are PC,
+; REGS and MEM, respectively. The pc value of an ISA state, ISA, can
+; be obtained by (ISA-pc ISA).
+(defstructure ISA-state
+ (pc (:assert (addr-p pc) :rewrite))
+ (regs (:assert (regs-p regs) :rewrite))
+ (mem (:assert (mem-p mem) :rewrite))
+ (:options :guards (:conc-name ISA-)))
+
+(deflabel begin-ISA-def)
+
+; Definition of the effect of an ADD instruction.
+(defun ISA-add (rc ra rb ISA)
+ (declare (xargs :guard (and (rname-p rc) (rname-p ra) (rname-p rb)
+ (ISA-state-p ISA))))
+ (ISA-state (addr (1+ (ISA-pc ISA)))
+ (write-reg (word (+ (read-reg ra (ISA-regs ISA))
+ (read-reg rb (ISA-regs ISA))))
+ rc (ISA-regs ISA))
+ (ISA-mem ISA)))
+
+; Definition of the effect of an SUB instruction.
+(defun ISA-sub (rc ra rb ISA)
+ (declare (xargs :guard (and (rname-p rc) (rname-p ra) (rname-p rb)
+ (ISA-state-p ISA))))
+ (ISA-state (addr (1+ (ISA-pc ISA)))
+ (write-reg (word (- (read-reg ra (ISA-regs ISA))
+ (read-reg rb (ISA-regs ISA))))
+ rc (ISA-regs ISA))
+ (ISA-mem ISA)))
+
+; Definition of NOP. It only increments the program counter.
+(defun ISA-default (ISA)
+ (declare (xargs :guard (ISA-state-p ISA)))
+ (ISA-state (addr (1+ (ISA-pc ISA)))
+ (ISA-regs ISA)
+ (ISA-mem ISA)))
+
+; Next ISA state function. It takes the current ISA state and returns
+; the ISA state after executing one instruction. This function is a
+; simple dispatcher of corresponding functions depending on the
+; instruction type.
+(defun ISA-step (ISA)
+ (declare (xargs :guard (ISA-state-p ISA)))
+ (let ((inst (read-mem (ISA-pc ISA) (ISA-mem ISA))))
+ (let ((op (op-field inst))
+ (rc (rc-field inst))
+ (ra (ra-field inst))
+ (rb (rb-field inst)))
+ (case op
+ (0 (ISA-add rc ra rb ISA)) ; add
+ (1 (ISA-sub rc ra rb ISA)) ; sub
+ (otherwise (ISA-default ISA))))))
+
+; N step ISA function. It returns the ISA state after executing n
+; instructions from the initial state, ISA.
+(defun ISA-stepn (ISA n)
+ (declare (xargs :guard (and (ISA-state-p ISA) (integerp n) (<= 0 n))))
+ (if (zp n) ISA (ISA-stepn (ISA-step ISA) (1- n))))
+
+(deflabel end-ISA-def)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; MA Definition
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of MA states
+;
+; Definition of pipeline latch latch1.
+(defstructure latch1
+ (valid? (:assert (bitp valid?) :rewrite))
+ (op (:assert (opcd-p op) :rewrite))
+ (rc (:assert (rname-p rc) :rewrite))
+ (ra (:assert (rname-p ra) :rewrite))
+ (rb (:assert (rname-p rb) :rewrite))
+ (:options :guards))
+
+; Definition of pipeline latch latch2.
+(defstructure latch2
+ (valid? (:assert (bitp valid?) :rewrite))
+ (op (:assert (opcd-p op) :rewrite))
+ (rc (:assert (rname-p rc) :rewrite))
+ (ra-val (:assert (word-p ra-val) :rewrite))
+ (rb-val (:assert (word-p rb-val) :rewrite))
+ (:options :guards))
+
+; Definition of pipelined micro-architecture.
+(defstructure MA-state
+ (pc (:assert (addr-p pc) :rewrite (:rewrite (acl2-numberp pc))))
+ (regs (:assert (regs-p regs) :rewrite))
+ (mem (:assert (mem-p mem) :rewrite))
+ (latch1 (:assert (latch1-p latch1) :rewrite))
+ (latch2 (:assert (latch2-p latch2) :rewrite))
+ (:options :guards (:conc-name MA-)))
+
+; Defines the signal supplied to the micro-architectural behavioral
+; function. We assume that the micro-architecture takes one bit
+; input, which turn on and off instruction fetching.
+(defun MA-sig-p (sig)
+ (declare (xargs :guard t))
+ (bitp sig))
+
+; List of sig
+(deflist MA-sig-listp (l)
+ (declare (xargs :guard t))
+ MA-sig-p)
+
+(deflabel begin-MA-def)
+; The definition of ALU. The ALU takes opcode and two operands,
+; and outputs the result.
+(defun ALU-output (op val1 val2)
+ (declare (xargs :guard (and (opcd-p op) (word-p val1) (word-p val2))))
+ (cond ((equal op 0) (word (+ val1 val2)))
+ ((equal op 1) (word (- val1 val2)))
+ (t 0)))
+
+; The behavior of the register file. If the latch2 contains an ADD or
+; SUB instruction, the register specified by latch2-rc is updated by
+; the output from the ALU. Otherwise, the register file is unchanged.
+(defun step-regs (MA)
+ (declare (xargs :guard (MA-state-p MA)))
+ (let ((latch2 (MA-latch2 MA)))
+ (b-if (b-and (latch2-valid? latch2)
+ (b-ior (bv-eqv *opcode-size* (latch2-op latch2) 0)
+ (bv-eqv *opcode-size* (latch2-op latch2) 1)))
+ (write-reg (ALU-output (latch2-op latch2)
+ (latch2-ra-val latch2)
+ (latch2-rb-val latch2))
+ (latch2-rc latch2)
+ (MA-regs MA))
+ (MA-regs MA))))
+
+; The dependency check. If there is a true (RAW) dependency
+; between the instructions at latch1 and latch2, the instruction at
+; latch1 should stall until the instruction at latch2 completes. We
+; check whether the destination register of the instruction at latch2
+; is one of the source registers of the instruction at latch1.
+(defun dependency? (MA)
+ (declare (xargs :guard (MA-state-p MA)))
+ (let ((latch1 (MA-latch1 MA))
+ (latch2 (MA-latch2 MA)))
+ (b-ior (bv-eqv *rname-size* (latch1-ra latch1) (latch2-rc latch2))
+ (bv-eqv *rname-size* (latch1-rb latch1) (latch2-rc latch2)))))
+
+(defthm bitp-dependency
+ (bitp (dependency? MA)))
+
+; The stall condition. If both latch1 and latch2 contain valid
+; instructions, and there are dependencies between the two
+; instructions, the instruction at latch1 is stalled.
+(defun stall-cond? (MA)
+ (declare (xargs :guard (MA-state-p MA)))
+ (b-and (latch1-valid? (MA-latch1 MA))
+ (b-and (latch2-valid? (MA-latch2 MA))
+ (dependency? MA))))
+
+(defthm bitp-stall-cond
+ (bitp (stall-cond? MA)))
+
+; Next state function for pipeline latch latch2. The instruction at
+; latch1 advances to latch2, only if stall-cond? is off. Note that
+; the rest of the fields of latch2 are updated anyway. Is it okay?
+; The answer is yes. The instruction at latch2 always complete, and
+; the instruction at latch1 may or may not advance to latch2. If
+; instruction at latch1 stalls, latch2 will hold a bubble in the next
+; cycle. In this case, we don't care the values the fields of latch2
+; except for latch2-valid?, which indicates whether the content of
+; latch2 is a bubble or not.
+(defun step-latch2 (MA)
+ (declare (xargs :guard (MA-state-p MA)))
+ (let ((latch1 (MA-latch1 MA))
+ (latch2 (MA-latch2 MA)))
+ (latch2 (b-and (latch1-valid? latch1)
+ (b-nand (dependency? MA) (latch2-valid? latch2)))
+ (latch1-op latch1)
+ (latch1-rc latch1)
+ (read-reg (latch1-ra latch1) (MA-regs MA))
+ (read-reg (latch1-rb latch1) (MA-regs MA)))))
+
+
+; This function defines how latch1 is updated. If the stall condition
+; is true, latch1 is not updated. If latch1 is currently empty or the
+; stall condition is false, and if the given sig is true, we fetch an
+; instruction. Sig is an external input that directs the processor to
+; fetch a new instruction.
+(defun step-latch1 (MA sig)
+ (declare (xargs :guard (and (MA-state-p MA) (MA-sig-p sig))))
+ (let ((latch1 (MA-latch1 MA))
+ (inst (read-mem (MA-pc MA) (MA-mem MA))))
+ (latch1 (b-ior sig (stall-cond? MA))
+ (b-if (stall-cond? MA) (latch1-op latch1) (op-field inst))
+ (b-if (stall-cond? MA) (latch1-rc latch1) (rc-field inst))
+ (b-if (stall-cond? MA) (latch1-ra latch1) (ra-field inst))
+ (b-if (stall-cond? MA) (latch1-rb latch1) (rb-field inst)))))
+
+
+; The condition whether a new instruction is fetched.
+(defun fetch-inst? (MA sig)
+ (declare (xargs :guard (and (MA-state-p MA) (MA-sig-p sig))))
+ (b-and sig
+ (b-nand (latch1-valid? (MA-latch1 MA))
+ (b-and (latch2-valid? (MA-latch2 MA))
+ (dependency? MA)))))
+
+(defthm bitp-fetch-inst?
+ (bitp (fetch-inst? MA sig)))
+
+; Function step-pc defines how the program counter is updated.
+(defun step-pc (MA sig)
+ (declare (xargs :guard (and (MA-state-p MA) (MA-sig-p sig))))
+ (b-if (fetch-inst? MA sig)
+ (addr (1+ (MA-pc MA)))
+ (MA-pc MA)))
+
+; MA-step defines how the MA state is updated every clock cycle. The
+; memory does not change in our model. The behavior of other
+; components is specified by the corresponding step functions.
+(defun MA-step (MA sig)
+ (declare (xargs :guard (and (MA-state-p MA) (MA-sig-p sig))))
+ (MA-state (step-pc MA sig)
+ (step-regs MA)
+ (MA-mem MA)
+ (step-latch1 MA sig)
+ (step-latch2 MA)))
+
+; MA-stepn returns the MA state after n clock cycles of MA execution.
+; The argument MA is the initial state, and sig-list specifies the
+; series of inputs.
+(defun MA-stepn (MA sig-list n)
+ (declare (xargs :guard (and (MA-state-p MA) (MA-sig-listp sig-list)
+ (integerp n) (<= 0 n)
+ (<= n (len sig-list)))))
+ (if (zp n)
+ MA
+ (MA-stepn (MA-step MA (car sig-list)) (cdr sig-list) (1- n))))
+
+(deflabel end-MA-def)
+
+(deftheory ISA-def
+ (set-difference-theories
+ (set-difference-theories (function-theory 'end-ISA-def)
+ (function-theory 'begin-ISA-def))
+ '(ISA-stepn)))
+
+(deftheory MA-def
+ (set-difference-theories
+ (set-difference-theories (function-theory 'end-MA-def)
+ (function-theory 'begin-MA-def))
+ '(MA-stepn)))
+
+(in-theory (disable ISA-def MA-def MA-sig-p))
+
+;;;;;;;; Type proofs ;;;;;;;;
+(defthm ISA-state-p-ISA-step
+ (implies (ISA-state-p ISA) (ISA-state-p (ISA-step ISA)))
+ :hints (("Goal" :in-theory (enable ISA-step ISA-add ISA-sub ISA-default))))
+
+(defthm ISA-state-p-ISA-stepn
+ (implies (ISA-state-p ISA) (ISA-state-p (ISA-stepn ISA n))))
+
+(defthm addr-p-step-pc
+ (implies (MA-state-p MA) (addr-p (step-pc MA sig)))
+ :hints (("Goal" :in-theory (enable step-pc))))
+
+(defthm word-p-ALU-output
+ (implies (and (opcd-p op) (word-p val1) (word-p val2))
+ (word-p (ALU-output op val1 val2)))
+ :hints (("Goal" :in-theory (enable ALU-output))))
+
+(defthm regs-p-step-regs
+ (implies (MA-state-p MA) (regs-p (step-regs MA)))
+ :hints (("Goal" :in-theory (enable step-regs))))
+
+(defthm latch1-p-step-latch1
+ (implies (and (MA-state-p MA) (MA-sig-p sig))
+ (latch1-p (step-latch1 MA sig)))
+ :hints (("Goal" :in-theory (enable step-latch1 MA-sig-p))))
+
+(defthm latch1-p-step-latch2
+ (implies (and (MA-state-p MA) (MA-sig-p sig))
+ (latch2-p (step-latch2 MA)))
+ :hints (("Goal" :in-theory (enable step-latch2 MA-sig-p))))
+
+(defthm MA-state-p-MA-step
+ (implies (and (MA-state-p MA) (MA-sig-p sig))
+ (MA-state-p (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable MA-step))))
+
+(defthm MA-state-p-MA-stepn
+ (implies (and (MA-state-p MA) (MA-sig-listp sig-list)
+ (<= n (len sig-list)))
+ (MA-state-p (MA-stepn MA sig-list n))))
+
+;;; Predicates for correctness
+
+; The projection function from an MA state to the corresponding ISA
+; state. Function proj strips off pipeline latches from the MA state.
+(defun proj (MA)
+ (declare (xargs :guard (MA-state-p MA)))
+ (ISA-state (MA-pc MA) (MA-regs MA) (MA-mem MA)))
+
+; (flushed? MA) is true if the pipeline of MA is flushed.
+(defun flushed? (MA)
+ (b-nor (latch1-valid? (MA-latch1 MA))
+ (latch2-valid? (MA-latch2 MA))))
+
+
+#|
+We will prove a following lemma for operational correctness:
+(defthm correctness
+ (implies (and (MA-state-p MA)
+ (MA-sig-listp sig-list)
+ (<= n (len sig-list))
+ (b1p (flushed? MA))
+ (b1p (flushed? (MA-stepn MA sig-list n))))
+ (equal (proj (MA-stepn MA sig-list n))
+ (ISA-stepn (proj MA)
+ (num-insts MA sig-list n)))))
+
+where num-insts calculates the nunber of instructions executed in the
+n cycles of MA execution. We also prove the liveness property with:
+
+(defthm liveness
+ (implies (MA-state-p MA)
+ (b1p (flushed? (MA-stepn MA
+ (zeros (flush-cycles MA))
+ (flush-cycles MA)))))).
+
+Function flush-cycles calculates the number of cycles to flush the pipeline.
+|#
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/proof.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/proof.lisp
new file mode 100644
index 0000000..1ef1071
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/proof.lisp
@@ -0,0 +1,938 @@
+(in-package "ACL2")
+
+
+;(include-book "utils")
+(include-book "basic-def")
+(include-book "model")
+(include-book "table-def")
+(include-book "basic-lemmas")
+
+(deflabel begin-proof)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; In this file, we prove our correctness criterion. First we prove that
+; our invariant conditions hold for all micro-architectural states
+; reachable from initial states. Then we prove the correctness of
+; the criterion using the invariant.
+;
+; We verify two lemmas about invariant conditions: invariant-init-MT
+; and invariant-step. Lemma invariant-init-MT shows that invariant
+; conditions are true for all initial states, while lemma
+; invariant-step shows that conditions are invariantly held during
+; the micro-architecture machine transitions.
+;
+; Predicate invariant is a conjunction of seven conditions,
+; pc-match-p, regs-match-p, mem-match-p, ISA-chain-p,
+; MT-inst-invariant, MT-contains-all-insts, and MT-in-order-p. We
+; prove that individual conditions are held at the initial states, and
+; that they are preserved over the machine state transition. For instance,
+; pc-match-p-init-MT shows that condition pc-match-p is true for
+; initial states. And lemma pc-match-p-MT-step shows that pc-match-p
+; is preserved during machine transitions.
+;
+
+;
+;;;;;;; Proof of pc-match-p ;;;
+; PC-match-p is true for initial states.
+(defthm pc-match-p-init-MT
+ (pc-match-p (init-MT MA) MA)
+ :hints (("Goal" :in-theory (enable pc-match-p init-MT MT-pc))))
+
+(encapsulate nil
+(local
+(defthm pc-match-p-MT-step-induction
+ (implies (and (equal (trace-pc trace ISA) (MA-pc MA))
+ (INST-listp trace)
+ (MAETT-p MT) (MA-state-p MA))
+ (equal (trace-pc (step-trace trace MA sig ISA) ISA)
+ (step-pc MA sig)))
+ :hints (("Goal" :in-theory (enable STEP-PC ISA-STEP
+ ISA-add ISA-sub ISA-default)
+ :expand (TRACE-PC (LIST (NEW-INST ISA))
+ ISA)))))
+; PC-match-p is preserved during MA state transitions.
+(defthm pc-match-p-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (pc-match-p (MT-step MT MA sig) (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable pc-match-p MT-step MA-step
+ invariant MT-pc))))
+)
+
+;;;;;;; Proof of regs-match-p
+; Register file is in the correct state in the initial states.
+(defthm regs-match-p-init-MT
+ (regs-match-p (init-MT MA) MA)
+ :hints (("Goal" :in-theory (enable init-MT regs-match-p MT-regs))))
+
+(encapsulate nil
+(local
+(defthm INST-pre-ISA-INST-at-latch2-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT) (INST-listp trace)
+ (trace-INST-at 'latch2 trace))
+ (equal (ISA-regs (INST-pre-ISA (trace-INST-at 'latch2 trace)))
+ (trace-regs trace (INST-pre-ISA (car trace)))))
+ :hints (("subgoal *1/3" :cases ((consp (cdr trace))))
+ ("subgoal *1/2" :use (:instance stages-of-inst (i (car trace)))))))
+
+
+(local
+(defthm INST-pre-ISA-INST-at-latch2-help
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch2 MT))
+ (equal (ISA-regs (INST-pre-ISA (INST-at 'latch2 MT)))
+ (MT-regs MT)))
+ :hints (("Goal" :in-theory (enable MT-regs INST-at)
+ :cases ((consp (MT-trace MT)))))
+ :rule-classes nil))
+
+
+; If an instruction I is in stage latch2, the register file of the MA
+; state looks like the register file in the pre-ISA state I. This is
+; because the register file reflects the result of all
+; retired instructions, while the result of partially executed
+; instructions are not written in the register file.
+(defthm INST-pre-ISA-INST-at-latch2
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch2 MT))
+ (equal (ISA-regs (INST-pre-ISA (INST-at 'latch2 MT)))
+ (MA-regs MA)))
+ :hints (("Goal" :in-theory (enable invariant regs-match-p)
+ :use (:instance INST-pre-ISA-INST-at-latch2-help))))
+)
+
+(encapsulate nil
+(local
+(defthm MT-regs-MT-step-if-latch2-valid-help-help
+ (implies (and (INST-listp trace)
+ (not (trace-INST-at 'latch2 trace))
+ (not (trace-INST-at 'retire trace)))
+ (equal (trace-regs (step-trace trace MA sig ISA) ISA)
+ (ISA-regs ISA)))
+ :hints (("Goal" :cases ((consp trace))))))
+
+
+(local
+(defthm MT-regs-MT-step-if-latch2-valid-help
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (trace-INST-at 'latch2 trace))
+ (equal (trace-regs (step-trace trace MA sig ISA) ISA)
+ (ISA-regs (INST-post-ISA (trace-INST-at 'latch2 trace)))))
+ :hints (("Subgoal *1/6" :use (:instance stages-of-inst (i (car trace)))))))
+
+
+; The correct register file state for the next cycle is defined here.
+; If instruction I is at latch2, I retires in this cycle and the
+; effect of I appears in the register file.
+(defthm MT-regs-MT-step-if-latch2-valid
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-at 'latch2 MT))
+ (equal (MT-regs (MT-step MT MA sig))
+ (ISA-regs (INST-post-ISA (INST-at 'latch2 MT)))))
+ :hints (("Goal" :in-theory (enable MT-regs INST-at MT-step))))
+)
+
+; The effect of ISA execution of instruction I is described by this
+; lemma. If instruction is add (0) or sub (1), the destination register
+; will contain the result of the instruction. If the instruction
+; is a NOP, the register file is unchanged.
+(defthm ISA-regs-INST-post-ISA
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i))
+ (equal (ISA-regs (ISA-step (INST-pre-ISA i)))
+ (if (or (equal (INST-op i) 0) (equal (INST-op i) 1))
+ (write-reg (INST-result i) (INST-rc i)
+ (ISA-regs (INST-pre-ISA i)))
+ (ISA-regs (INST-pre-ISA i)))))
+ :hints (("Goal" :in-theory (enable ISA-step ISA-add ISA-sub ISA-default
+ INST-attrb ALU-output))))
+(in-theory (disable ISA-regs-INST-post-ISA))
+
+
+(encapsulate nil
+(local
+(defthm MT-regs-MT-step-induction
+ (implies (and (INST-listp trace) (not (trace-INST-at 'latch2 trace)))
+ (equal (trace-regs (step-trace trace MA sig ISA) ISA)
+ (trace-regs trace ISA)))
+ :hints (("Goal" :expand (TRACE-REGS (CONS (STEP-INST (CAR TRACE) MA)
+ (STEP-TRACE (CDR TRACE)
+ MA SIG (INST-POST-ISA (CAR TRACE))))
+ ISA)))))
+
+
+; If there is no instruction at latch2, the register file in MA is not
+; updated in this cycle. Correct register file states calculated from the
+; MAETT does not change.
+(defthm MT-regs-MT-step
+ (implies (and (MAETT-p MT) (not (INST-at 'latch2 MT)))
+ (equal (MT-regs (MT-step MT MA sig))
+ (MT-regs MT)))
+ :hints (("Goal" :in-theory (enable MT-regs MT-step
+ INST-at))))
+)
+
+(encapsulate nil
+; This is a help lemma.
+(local
+(defthm MT-regs-MA-regs
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (equal (equal (MT-regs MT) (MA-regs MA)) t))
+ :hints (("Goal" :in-theory (enable invariant regs-match-p)))))
+
+
+; Finally, we prove that predicate regs-match-p is preserved during MA
+; machine cycles. Predicate regs-match-p holds after one MA machine cycle
+; of execution.
+(defthm regs-match-p-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (regs-match-p (MT-step MT MA sig) (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable regs-match-p MA-step step-regs
+ ISA-regs-INST-post-ISA
+ lift-b-ops bv-eqv-iff-equal
+ INST-result)
+ :cases ((b1p (latch2-valid? (MA-latch2 MA)))))))
+)
+
+;;;;;;; Proof of mem-match-p
+; Predicate mem-match-p is true for the initial states.
+(defthm mem-match-p-init-MT
+ (mem-match-p (init-MT MA) MA)
+ :hints (("Goal" :in-theory (enable mem-match-p))))
+
+; Predicate mem-match-p is preserved during MA machines state transitions.
+(defthm mem-match-p-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (mem-match-p (MT-step MT MA sig) (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable mem-match-p MA-STEP
+ invariant))))
+
+;;;;;;; Proof of ISA-chain-p
+; ISA-chain-p is true for initial tables.
+(defthm ISA-chain-p-init-MT
+ (ISA-chain-p (init-MT MA))
+ :hints (("Goal" :in-theory (enable ISA-chain-p init-MT))))
+
+(encapsulate nil
+(local
+(defthm ISA-chain-p-step-MT-induction
+ (implies (and (INST-listp trace) (ISA-chain-trace-p trace ISA))
+ (ISA-chain-trace-p (step-trace trace MA sig ISA) ISA))))
+
+; And it is also preserved during MAETT updates.
+(defthm ISA-chain-p-step-MT
+ (implies (and (invariant MT MA)
+ (MAETT-p MT))
+ (ISA-chain-p (MT-step MT MA sig)))
+ :hints (("Goal" :in-theory (enable ISA-chain-p MT-step invariant
+ MAETT-p))))
+)
+
+;;;;;; MT-inst-invariant
+
+; MT-inst-invariant are true for initial states.
+(defthm MT-inst-invariant-init-MT
+ (MT-inst-invariant (init-MT MA) MA)
+ :hints (("Goal" :in-theory (enable MT-inst-invariant init-MT
+ trace-INST-invariant))))
+
+
+; Proof of MT-inst-invariant-MT-step.
+;
+; MT-inst-invariant checks recursively every instruction in the MAETT
+; satisfies predicate inst-invariant. Predicate inst-invariant
+; represents the conditions that each instructions should satisfy,
+; depending on the current stage.
+; We prove that every instruction invariantly satisfy inst-invariant,
+; and then prove the lemma MT-inst-invariant-MT-step using induction.
+;
+; The check for individual instructions needs to consider two cases:
+; the case in which the instruction is a newly fetched instruction,
+; and the case in which the instruction is in the current MAETT. The
+; first case is proven as lemma inst-invariant-new-INST, and the
+; second case as INST-invariant-step-INST.
+;
+
+; Inst-invariant-new-INST shows that inst-invariant is true for
+; the instruction entry (new-INST (ISA-before nil MT)), which
+; represents the newly fetched instruction.
+(defthm inst-invariant-new-INST
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (fetch-inst? MA sig)))
+ (inst-invariant (new-INST (ISA-before nil MT))
+ (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable new-INST inst-invariant
+ INST-LATCH1-INV fetch-inst?
+ stall-cond?
+ MA-STEP step-latch1 lift-b-ops
+ INST-attrb))))
+
+
+; From here, we prove lemma INST-invariant-step-INST, which asserts
+; that an instruction satisfies inst-invariant at the next machine
+; cycle.
+
+; Read-reg-ISA-step-if-target-reg-differs proves the fact that
+; the value of register is not updated by an instruction whose destination
+; register is different.
+; (INST-rc i) represents the destination register for the instruction
+; i. Suppose register (INST-rc i) differs from register rix. Then
+; ISA execution of instruction i does not update register rix, and the
+; value of register rix is unchanged.
+(defthm read-reg-ISA-step-if-target-reg-differs
+ (implies (and (INST-p i) (rname-p rix) (not (equal (INST-rc i) rix)))
+ (equal (read-reg rix (ISA-regs (ISA-step (INST-pre-ISA i))))
+ (read-reg rix (ISA-regs (INST-pre-ISA i)))))
+ :hints (("Goal" :in-theory (enable ISA-step ISA-add ISA-sub ISA-default
+ INST-attrb))))
+
+; This lemmas assures that the pipeline interlock is working
+; correctly.
+; Briefly speaking, the fact that (dependency? MA) is off implies that
+; instruction i at latch1 and instruction (car trace) at latch2 have
+; no true (RAW) dependencies. Therefore, execution of instruction
+; (car trace) does not change the register (INST-ra i), which is a
+; source register of instruction i. As a result, we don't have to
+; stall the instruction i.
+;
+; Note: trace is a subtrace of the current MAETT MT. We consider the
+; interlocks between instructions represented by (car trace) and i.
+; This is one of the easiest ways to represent the lemma
+; without a fully developed supporting theory, although the resulting
+; lemma is not beautifully formulated.
+(defthm read-regs-latch1-INST-ra-special-case
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (car trace)) 'latch2)
+ (member-equal i (cdr trace))
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (dependency? MA))))
+ (equal (read-reg (INST-ra i)
+ (ISA-regs (INST-pre-ISA (car trace))))
+ (read-reg (INST-ra i)
+ (ISA-regs (INST-pre-ISA i)))))
+ :hints (("Goal" :cases ((consp (cdr trace))))
+ ("Subgoal 1" :cases ((equal (cadr trace) i)))
+ ("Subgoal 1.1" :in-theory (enable dependency? lift-b-ops)
+ :restrict
+ ((latch2-rc-INST-rc-if-INST-in ((i (car trace))))
+ (latch1-ra-INST-ra-if-INST-in ((i (cadr trace))))))))
+
+; Similar lemma for source register (INST-rb i).
+(defthm read-regs-latch1-INST-rb-special-case
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (car trace)) 'latch2)
+ (member-equal i (cdr trace))
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (dependency? MA))))
+ (equal (read-reg (INST-rb i)
+ (ISA-regs (INST-pre-ISA (car trace))))
+ (read-reg (INST-rb i)
+ (ISA-regs (INST-pre-ISA i)))))
+ :hints (("Goal" :cases ((consp (cdr trace))))
+ ("Subgoal 1" :cases ((equal (cadr trace) i)))
+ ("Subgoal 1.1" :in-theory (enable DEPENDENCY? lift-b-ops)
+ :restrict
+ ((latch2-rc-INST-rc-if-INST-in ((i (car trace))))
+ (latch1-rb-INST-rb-if-INST-in ((i (cadr trace))))))))
+
+(encapsulate nil
+(local
+(defthm read-regs-latch1-INST-ra-if-not-stall-cond-help
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (member-equal i trace) (INST-p i)
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (dependency? MA))))
+ (equal (read-reg (INST-ra I)
+ (trace-regs trace (ISA-before trace MT)))
+ (read-reg (INST-ra I) (ISA-regs (INST-pre-ISA I)))))
+ :hints (("Goal" :in-theory (enable ISA-before-INST-pre-ISA-car))
+ ("subgoal *1/2" :use (:instance stages-of-INST (i (car trace)))))
+ :rule-classes nil))
+
+; Suppose instruction i is at latch1, and (dependency? MA) is off. It
+; means there is no instruction at latch2 which updates i's source register
+; (INST-ra i). This lemma proves that the register (INST-ra i) in the MA
+; state contains the correct source value for instruction i.
+(defthm read-regs-latch1-INST-ra-if-not-stall-cond
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (dependency? MA))))
+ (equal (read-reg (INST-ra I) (MA-regs MA))
+ (read-reg (INST-ra I) (ISA-regs (INST-pre-ISA I)))))
+ :hints (("Goal"
+ :use
+ (:instance read-regs-latch1-INST-ra-if-not-stall-cond-help
+ (trace (MT-trace MT)))
+ :in-theory (enable invariant regs-match-p INST-in
+ MT-REGS))))
+)
+
+(encapsulate nil
+(local
+(defthm read-regs-latch1-INST-rb-if-not-stall-cond-help
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (member-equal i trace) (INST-p i)
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (dependency? MA))))
+ (equal (read-reg (INST-rb I)
+ (trace-regs trace (ISA-before trace MT)))
+ (read-reg (INST-rb I) (ISA-regs (INST-pre-ISA I)))))
+ :hints (("Goal" :in-theory (enable ISA-before-INST-pre-ISA-car))
+ ("subgoal *1/2" :use (:instance stages-of-INST (i (car trace)))))
+ :rule-classes nil))
+
+; Similar lemma for RB.
+(defthm read-regs-latch1-INST-rb-if-not-stall-cond
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (dependency? MA))))
+ (equal (read-reg (INST-rb I) (MA-regs MA))
+ (read-reg (INST-rb I) (ISA-regs (INST-pre-ISA I)))))
+ :hints (("Goal"
+ :use
+ (:instance read-regs-latch1-INST-rb-if-not-stall-cond-help
+ (trace (MT-trace MT)))
+ :in-theory (enable invariant regs-match-p INST-in
+ MT-REGS))))
+)
+
+(encapsulate nil
+(local
+(defthm ISA-regs-MA-regs-if-not-latch2-valid-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT) (INST-listp trace)
+ (member-equal i trace)
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (latch2-valid? (MA-latch2 MA)))))
+ (equal (ISA-regs (INST-pre-ISA I))
+ (trace-regs trace (ISA-before trace MT))))
+ :hints (("goal" :in-theory (enable ISA-BEFORE-INST-PRE-ISA-CAR)
+ :restrict ((LATCH2-VALID-IF-INST-IN ((i (car trace))))))
+ ("subgoal *1/2" :use ((:instance stages-of-inst (I (car trace))))))
+ :rule-classes nil))
+
+;
+; If instruction i is at latch1 and no instruction is at latch2, i is the
+; only instruction in the pipeline, and i has not updated the register file
+; in the MA. So, the register file in the MA state is the same as in pre-ISA
+; of i.
+(defthm ISA-regs-MA-regs-if-not-latch2-valid
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1)
+ (not (b1p (latch2-valid? (MA-latch2 MA)))))
+ (equal (ISA-regs (INST-pre-ISA I)) (MA-regs MA)))
+ :hints (("goal" :in-theory (enable invariant regs-match-p
+ MT-REGS INST-in)
+ :use (:instance
+ ISA-regs-MA-regs-if-not-latch2-valid-induction
+ (trace (MT-trace MT))))))
+)
+
+(encapsulate nil
+(local
+(defthm INST-latch1-inv-step-INST-help
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1)
+ (equal (INST-stg (step-INST i MA)) 'latch1))
+ (inst-latch1-inv (step-INST i MA) (MA-step MA sig)))
+ :hints (("Goal" :use (:instance INST-invariant-INST-in)
+ :in-theory (enable INST-invariant INST-latch1-inv
+ MA-step step-latch1 lift-b-ops
+ STEP-INST step-latch1-inst)))))
+
+
+; Instruction i will satisfy predicate inst-latch1-inv in the next
+; machine cycle, if its stage will be latch1.
+(defthm INST-latch1-inv-step-INST
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg (step-INST i MA)) 'latch1))
+ (inst-latch1-inv (step-INST i MA) (MA-step MA sig)))
+ :hints (("Goal" :use ((:instance stages-of-inst)))))
+)
+
+
+(encapsulate nil
+(local
+(defthm INST-latch2-inv-step-INST-help
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg i) 'latch1)
+ (equal (INST-stg (step-INST i MA)) 'latch2))
+ (inst-latch2-inv (step-INST i MA) (MA-step MA sig)))
+ :hints (("Goal" :use (:instance INST-invariant-INST-in)
+ :in-theory (enable INST-invariant INST-latch2-inv
+ STALL-COND?
+ INST-latch1-inv INST-RA-VAL INST-RB-VAL
+ MA-step step-latch2 lift-b-ops)))))
+
+; Similarly, instruction i satisfies inst-latch2-inv in the next
+; machine cycle if it will be in the stage latch2.
+(defthm INST-latch2-inv-step-INST
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i)
+ (equal (INST-stg (step-INST i MA)) 'latch2))
+ (inst-latch2-inv (step-INST i MA) (MA-step MA sig)))
+ :hints (("Goal" :use ((:instance stages-of-inst)))))
+)
+
+
+; Instruction i will satisfy predicate INST-invariant in the next
+; machine cycle.
+(defthm INST-invariant-step-INST
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (INST-in i MT) (INST-p i))
+ (inst-invariant (step-INST i MA) (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable inst-invariant))))
+
+
+(encapsulate nil
+(local
+(defthm MT-init-invariant-MT-step-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT) (INST-listp trace))
+ (trace-inst-invariant (step-trace trace MA sig
+ (ISA-before trace MT))
+ (MA-step MA sig)))
+ :rule-classes nil))
+
+; MT-init-invariant is true for the next machine state.
+; With induction, we prove that MT-inst-invariant is true for the
+; next MA state and the update table.
+(defthm MT-init-invariant-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (MT-inst-invariant (MT-step MT MA sig)
+ (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable MT-inst-invariant MT-step)
+ :use (:instance MT-init-invariant-MT-step-induction
+ (trace (MT-trace MT))))))
+)
+
+; MT-contains-all-insts is correct for initial states.
+(defthm MT-contains-all-insts-init-MT
+ (implies (b1p (flushed? MA))
+ (MT-contains-all-insts (init-MT MA) MA))
+ :hints (("Goal" :in-theory (enable MT-contains-all-insts flushed?
+ lift-b-ops))))
+
+; Proof of MT-contains-all-insts-MT-step.
+; A MAETT represents all instructions currently in the pipeline, as
+; well as those retired. If flag latch1-valid? is on, there must be
+; an instruction at latch1. Similarly, there must be an instruction
+; at latch2 if latch2-valid? is on. We prove them one by one.
+(encapsulate nil
+(local
+(defthm INST-at-latch1-MT-step-if-fetch-inst-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (fetch-inst? MA sig)))
+ (trace-INST-at 'latch1 (step-trace trace MA sig ISA)))))
+
+
+; INST-at-latch1-MT-step is proven by case analysis. In one case,
+; fetch-inst? is on. In other case, dependency? is on. (They are
+; exclusive.) INST-at-latch1-MT-step-if-fetch-inst and
+; INST-at-latch1-MT-step-if-stall-cond covers the two cases, respectively.
+(defthm INST-at-latch1-MT-step-if-fetch-inst
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (fetch-inst? MA sig)))
+ (INST-at 'latch1 (MT-step MT MA sig)))
+ :hints (("Goal" :in-theory (enable MT-step INST-at))))
+)
+
+(encapsulate nil
+(local
+(defthm INST-at-latch1-MT-step-if-stall-cond-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (stall-cond? MA))
+ (trace-INST-at 'latch1 trace))
+ (trace-INST-at 'latch1 (step-trace trace MA sig ISA)))))
+
+(defthm INST-at-latch1-MT-step-if-stall-cond
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (stall-cond? MA))
+ (b1p (latch1-valid? (MA-latch1 MA))))
+ (INST-at 'latch1 (MT-step MT MA sig)))
+ :hints (("Goal" :in-theory (e/d (INST-at MT-step)
+ (INST-AT-LATCH1-IF-LATCH1-VALID))
+ :use (:instance INST-AT-LATCH1-IF-LATCH1-VALID))))
+)
+
+; If latch1-valid? is on for the next MA state, the updated MAETT
+; contains an entry representing the instruction at latch1.
+(defthm INST-at-latch1-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (latch1-valid? (step-latch1 MA sig))))
+ (INST-at 'latch1 (MT-step MT MA sig)))
+ :hints (("Goal" :cases ((b1p (fetch-inst? MA sig))))
+ ("subgoal 2" :in-theory (enable step-latch1 lift-b-ops
+ stall-cond? fetch-inst?))))
+
+(encapsulate nil
+(local
+(defthm INST-at-latch2-MT-step-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (or (not (b1p (dependency? MA)))
+ (not (b1p (latch2-valid? (MA-latch2 MA)))))
+ (trace-INST-at 'latch1 trace))
+ (trace-INST-at 'latch2 (step-trace trace MA sig ISA)))
+ :hints (("Goal" :in-theory (enable step-latch2 lift-b-ops STALL-COND?)))))
+
+; Similarly for latch2.
+(defthm INST-at-latch2-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (latch2-valid? (step-latch2 MA))))
+ (INST-at 'latch2 (MT-step MT MA sig)))
+ :hints (("Goal" :in-theory (e/d (step-latch2 lift-b-ops INST-at MT-step
+)
+ (INST-AT-LATCH1-IF-LATCH1-VALID))
+ :use (:instance INST-AT-LATCH1-IF-LATCH1-VALID))))
+)
+
+; MT-contains-all-insts is true for the next machine state.
+(defthm MT-contains-all-insts-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (MT-contains-all-insts (MT-step MT MA sig)
+ (MA-step MA sig)))
+ :hints (("Goal" :in-theory (enable MT-contains-all-insts MA-step))))
+
+;;;;;; Proof of MT-in-order-p
+;
+; MT-in-order-p is true for initial case.
+(defthm MT-in-order-p-init-MT
+ (MT-in-order-p (init-MT MA))
+ :hints (("Goal" :in-theory (enable init-MT MT-in-order-p))))
+
+
+; Instruction at latch1 is the last fetched instruction in the
+; pipeline. MAETT records fetched and executed instructions in ISA
+; execution order, so the entry representing the instruction at latch1
+; is the last in a MAETT.
+(defthm endp-step-trace-cdr-if-step-INST-latch1
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace)
+ (consp trace)
+ (equal (INST-stg (step-INST (car trace) MA)) 'latch1))
+ (not (consp (step-trace (cdr trace) MA sig ISA))))
+ :hints (("Goal" :use ((:instance stages-of-inst (i (car trace)))
+ (:instance no-inst-after-INST-latch1)
+ (:instance latch1-valid-if-INST-in (i (car trace))))
+ :in-theory (enable fetch-inst? stall-cond? lift-b-ops))))
+
+
+; There cannot be more than two entries of MAETT representing an
+; instruction at latch2.
+(defthm not-trace-INST-at-latch2-step-trace
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (consp trace)
+ (INST-listp trace)
+ (equal (INST-stg (step-INST (car trace) MA)) 'latch2))
+ (not (trace-INST-at 'latch2 (step-trace (cdr trace) MA sig ISA))))
+ :hints (("Goal" :use ((:instance stages-of-inst (i (car trace)))
+ (:instance no-inst-after-INST-latch1)))))
+
+
+; Instructions retire in order. So no retired instruction follows
+; an instruction at latch2.
+(defthm not-trace-INST-at-retire-step-trace
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (consp trace)
+ (INST-listp trace)
+ (equal (INST-stg (step-INST (car trace) MA)) 'latch2))
+ (not (trace-INST-at 'retire (step-trace (cdr trace) MA sig ISA))))
+ :hints (("Goal" :use ((:instance stages-of-inst (i (car trace)))
+ (:instance no-inst-after-INST-latch1)))))
+
+
+(encapsulate nil
+(local
+(defthm MT-in-order-p-MT-step-induction
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (subtrace-p trace MT)
+ (INST-listp trace))
+ (trace-in-order-p (step-trace trace MA sig ISA)))))
+
+; MT-in-order-p is true for the next machine state.
+(defthm MT-in-order-p-MT-step
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (MT-in-order-p (MT-step MT MA sig)))
+ :hints (("Goal" :in-theory (enable MT-step MT-in-order-p))))
+)
+
+;;;;;;;; Proof of invariant
+; Invariant are true for the initial MA state and its MAETT.
+(defthm invariant-init-MT
+ (implies (and (MA-state-p MA) (b1p (flushed? MA)))
+ (invariant (init-MT MA) MA))
+ :hints (("Goal" :in-theory (enable invariant))))
+
+; Predicate Invariant is actually an invariant condition.
+(defthm invariant-step
+ (implies (and (invariant MT MA) (MAETT-p MT) (MA-state-p MA)
+ (MA-sig-p sig))
+ (invariant (MT-step MT MA sig)
+ (MA-step MA sig)))
+ :Hints (("Goal" :in-theory (enable invariant))))
+
+; By induction, invariant is correct after n cycles of MA
+; execution.
+(defthm invariant-stepn
+ (implies (and (invariant MT MA) (MAETT-p MT) (MA-state-p MA)
+ (MA-sig-listp sig-list)
+ (<= n (len sig-list)))
+ (invariant (MT-stepn MT MA sig-list n)
+ (MA-stepn MA sig-list n))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Proof of the correctness criterion.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; The number of instructions recorded in the MAETT. This is the
+; number of fetched instructions since the initial machine state.
+(defun MT-num-insts (MT) (len (MT-trace MT)))
+
+; The number of instructions fetched and executed during the n cycles
+; of machine execution from the initial state MA with input signal list
+; sig-list.
+(defun num-insts (MA sig-list n)
+ (MT-num-insts (MT-stepn (init-MT MA) MA sig-list n)))
+
+(defthm integerp-MT-num-insts (integerp (MT-num-insts MT)))
+
+(defthm integerp-num-insts (integerp (num-insts MA sig-list n)))
+
+(in-theory (disable MT-num-insts num-insts))
+
+(defun trace-all-retired (trace)
+ (if (endp trace)
+ t
+ (and (equal (INST-stg (car trace)) 'retire)
+ (trace-all-retired (cdr trace)))))
+
+; (MT-all-retires MT) is true if all instructions recorded by MT is
+; retired.
+(defun MT-all-retired (MT)
+ (trace-all-retired (MT-trace MT)))
+
+(encapsulate nil
+(local
+(defthm flushed-implies-MT-all-retired-help
+ (implies (and (INST-listp trace)
+ (trace-inst-invariant trace MA)
+ (b1p (flushed? MA)))
+ (trace-all-retired trace))
+ :hints (("goal" :in-theory (enable flushed? lift-b-ops INST-p stage-p
+ inst-invariant INST-latch1-inv
+ INST-latch2-inv)))))
+
+; If a MA state, MA, is flushed, the corresponding MAETT, MT, contains
+; only retired instructions.
+(defthm flushed-implies-MT-all-retired
+ (implies (and (invariant MT MA)
+ (MAETT-p MT)
+ (b1p (flushed? MA)))
+ (MT-all-retired MT))
+ :hints (("goal" :in-theory (enable MT-all-retired invariant
+ MT-inst-invariant))))
+)
+
+; ; A help lemma
+(defthm ISA-extensionality
+ (implies (and (ISA-state-p ISA1)
+ (ISA-state-p ISA2)
+ (equal (ISA-pc ISA1) (ISA-pc ISA2))
+ (equal (ISA-regs ISA1) (ISA-regs ISA2))
+ (equal (ISA-mem ISA1) (ISA-mem ISA2)))
+ (equal ISA1 ISA2))
+ :rule-classes nil)
+
+; Lemma flushed-MA-=-MT-final-ISA is proven by showing the equivalence
+; of LHS and RHS with respect to each programmer visible components such
+; as program counter, register file and memory.
+(encapsulate nil
+(local
+(defthm ISA-pc-ISA-stepn-if-flushed-induction
+ (implies (ISA-chain-trace-p trace ISA)
+ (equal (ISA-pc (ISA-stepn ISA (len trace)))
+ (trace-pc trace ISA)))))
+
+(local
+(defthm ISA-pc-ISA-stepn-if-flushed-help
+ (implies (invariant MT MA)
+ (equal (ISA-pc (ISA-stepn (MT-init-ISA MT) (MT-num-insts MT)))
+ (MT-pc MT)))
+ :hints (("Goal" :in-theory (enable MT-pc MT-num-insts
+ invariant ISA-chain-p)))))
+
+
+; Equivalence with respect to PC.
+(defthm ISA-pc-ISA-stepn-if-flushed
+ (implies (and (invariant MT MA)
+ (MT-all-retired MT))
+ (equal (ISA-pc (ISA-stepn (MT-init-ISA MT) (MT-num-insts MT)))
+ (MA-pc MA)))
+ :hints (("Goal" :in-theory (enable invariant pc-match-p)
+ :restrict ((ISA-pc-ISA-stepn-if-flushed-help
+ ((MT MT) (MA MA)))))))
+)
+
+(encapsulate nil
+(local
+ (defthm ISA-regs-ISA-stepn-if-flushed-induction
+ (implies (and (ISA-chain-trace-p trace ISA)
+ (trace-all-retired trace))
+ (equal (ISA-regs (ISA-stepn ISA (len trace)))
+ (trace-regs trace ISA)))))
+(local
+(defthm ISA-regs-ISA-stepn-if-flushed-help
+ (implies (and (invariant MT MA) (MT-all-retired MT))
+ (equal (ISA-regs (ISA-stepn (MT-init-ISA MT) (MT-num-insts MT)))
+ (MT-regs MT)))
+ :hints (("goal" :in-theory (enable MT-init-ISA MT-all-retired
+ MT-num-insts MT-regs
+ invariant ISA-chain-p)))))
+
+; Equivalence with respect to the register file.
+(defthm ISA-regs-ISA-stepn-if-flushed
+ (implies (and (invariant MT MA)
+ (MT-all-retired MT))
+ (equal (ISA-regs (ISA-stepn (MT-init-ISA MT) (MT-num-insts MT)))
+ (MA-regs MA)))
+ :hints (("Goal" :in-theory (enable invariant regs-match-p)
+ :restrict ((ISA-regs-ISA-stepn-if-flushed-help
+ ((MT MT) (MA MA)))))))
+)
+
+; Equivalence with respect to the memory.
+(defthm ISA-mem-MT-init-ISA-=-MA-mem
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA))
+ (equal (ISA-mem (MT-init-ISA MT)) (MA-mem MA)))
+ :hints (("Goal" :in-theory (enable invariant mem-match-p))))
+
+; One step before the final lemma. Consider a flushed micro-state MA
+; and its MAETT. MAETT contains (MT-num-INST MT) instruction
+; entries. (MT-init-ISA MT) is the initial ISA state before executing
+; the first instruction recorded in MAETT. Therefore,
+; (ISA-stepn (MT-init-ISA MT) (MT-num-insts MT)) is the final ISA state
+; after executing all instructions recorded in MT. Our invariant
+; guarantees that the projection of MA to an ISA state is equal to
+; this final ISA state.
+(defthm flushed-MA-=-MT-final-ISA
+ (implies (and (invariant MT MA)
+ (MAETT-p MT) (MA-state-p MA)
+ (b1p (flushed? MA)))
+ (equal (ISA-stepn (MT-init-ISA MT) (MT-num-insts MT))
+ (proj MA)))
+ :hints (("Goal" :in-theory (enable proj)
+ :use
+ (:instance ISA-extensionality
+ (ISA1 (ISA-stepn (MT-init-ISA MT) (MT-num-insts MT)))
+ (ISA2 (proj MA)))))
+ :rule-classes nil)
+
+; Correctness diagram.
+(defthm commutative-diagram
+ (implies (and (MA-state-p MA)
+ (MA-sig-listp sig-list)
+ (<= n (len sig-list))
+ (b1p (flushed? MA))
+ (b1p (flushed? (MA-stepn MA sig-list n))))
+ (equal (proj (MA-stepn MA sig-list n))
+ (ISA-stepn (proj MA)
+ (num-insts MA sig-list n))))
+ :hints (("Goal" :use (:instance flushed-MA-=-MT-final-ISA
+ (MT (MT-stepn (init-MT MA) MA sig-list n))
+ (MA (MA-stepn MA sig-list n)))
+ :in-theory (enable num-insts))))
+
+; Define the weight of an MA state.
+(defun MA-weight (MA)
+ (+ (if (b1p (latch1-valid? (MA-latch1 MA))) 2 0)
+ (if (b1p (latch2-valid? (MA-latch2 MA))) 1 0)))
+
+; The weight decreases unless MA is flushed.
+(defthm MA-weight-MT-step
+ (implies (not (b1p (flushed? MA)))
+ (< (MA-weight (MA-step MA 0)) (MA-weight MA)))
+ :hints (("Goal" :in-theory (enable flushed? lift-b-ops b1p-b-and
+ MA-step step-latch1 b-and b-nand
+ step-latch2
+ stall-cond?))))
+
+(in-theory (disable MA-weight))
+
+; The number of the cycles to flush the pipeline.
+(defun flush-cycles (MA)
+ (declare (xargs :measure (MA-weight MA)))
+ (if (b1p (flushed? MA))
+ 0
+ (1+ (flush-cycles (MA-step MA 0)))))
+
+; Generate a list of 0 with length n.
+(defun zeros (n)
+ (if (zp n) nil (cons 0 (zeros (1- n)))))
+
+; The MA state after (flush-cycles MA) cycles of MA execution with
+; sig-list 0's is flushed.
+(defthm liveness
+ (implies (MA-state-p MA)
+ (b1p (flushed? (MA-stepn MA
+ (zeros (flush-cycles MA))
+ (flush-cycles MA))))))
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/table-def.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/table-def.lisp
new file mode 100644
index 0000000..a705802
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/table-def.lisp
@@ -0,0 +1,487 @@
+(in-package "ACL2")
+
+(include-book "utils")
+(include-book "basic-def")
+(include-book "model")
+
+(deflabel begin-table-def)
+
+; The valid pipeline stages in this machine are latch1, latch2 and
+; retire.
+(defun stage-p (stg)
+ (declare (xargs :guard t))
+ (or (equal stg 'latch1) (equal stg 'latch2) (equal stg 'retire)))
+
+(in-theory (disable proj flushed? stage-p))
+
+; The definition of MAETT entry which represents an instruction.
+; Only a few fields are required for this example.
+; Field Description
+; stg The current stage of the represented instruction.
+; pre-ISA The ISA state before the execution of this instruction.
+; post-ISA The ISA state after the execution of this instruction.
+(defstructure INST
+ (stg (:assert (stage-p stg) :rewrite))
+ (pre-ISA (:assert (ISA-state-p pre-ISA) :rewrite))
+ (post-ISA (:assert (ISA-state-p post-ISA) :rewrite))
+ (:options :guards))
+
+(deflist INST-listp (l)
+ (declare (xargs :guard t))
+ INST-p)
+
+; Definition of MAETT. It stores the initial ISA state, init-ISA, and
+; a list of MAETT entries, trace. Each entry of trace represents
+; a fetched and executed instruction. Trace stores the entries in
+; the order that the ISA executes the represented instructions. ISA
+; state init-ISA is the ISA state before executing the first
+; instruction in trace.
+(defstructure MAETT
+ (init-ISA (:assert (ISA-state-p init-ISA) :rewrite))
+ (trace (:assert (INST-listp trace) :rewrite))
+ (:options :guards (:conc-name MT-)))
+
+(deflabel begin-MAETT-def)
+
+; Function init-MT constructs the initial MAETT table for an
+; flushed initial MA state. Since no instructions are fetched yet,
+; trace field contains an empty list.
+(defun init-MT (MA)
+ (declare (xargs :guard (MA-state-p MA)))
+ (MAETT (proj MA) nil))
+
+; The MAETT entry representing a newly fetched instruction. Argument
+; ISA is the pre-ISA state of the newly fetched instruction. In other
+; words, it is the correct ISA state before executing the newly
+; fetched instruction.
+(defun new-inst (ISA)
+ (declare (xargs :guard (ISA-state-p ISA)))
+ (INST 'latch1
+ ISA
+ (ISA-step ISA)))
+
+(defun step-latch1-INST (i MA)
+ (declare (xargs :guard (and (INST-p i) (MA-state-p MA))))
+ (if (b1p (stall-cond? MA))
+ i
+ (update-INST i :stg 'latch2)))
+
+(defun step-latch2-INST (i)
+ (declare (xargs :guard (INST-p i)))
+ (update-INST i :stg 'retire))
+
+; Function step-INST updates the MAETT entry to reflect the change of
+; the state of the represented instruction. In this example, we only
+; have to update the stage field as the instruction advances through the
+; pipeline.
+(defun step-INST (i MA)
+ (declare (xargs :guard (and (INST-p i) (MA-state-p MA))))
+ (cond ((equal (INST-stg i) 'latch1)
+ (step-latch1-INST i MA))
+ ((equal (INST-stg i) 'latch2)
+ (step-latch2-INST i))
+ (t i)))
+
+; Function step-trace updates the field, trace, of a MAETT. If a new
+; instruction is fetched, an entry corresponding to the new
+; instruction is added at the end of the trace. The rest of the
+; entries are updated with function step-INST.
+(defun step-trace (trace MA sig last-ISA)
+ (declare (xargs :guard (and (INST-listp trace) (MA-state-p MA)
+ (MA-sig-p sig)
+ (ISA-state-p last-ISA))))
+ (if (endp trace)
+ (if (b1p (fetch-inst? MA sig))
+ (list (new-inst last-ISA))
+ nil)
+ (cons (step-INST (car trace) MA)
+ (step-trace (cdr trace) MA sig (INST-post-ISA (car trace))))))
+
+; Function to update an MAETT. MT-step takes arguments MA and MT,
+; which are the current MA state and the corresponding MAETT, and it
+; returns the updated MAETT. The new MAETT represents the next MA
+; state (MA-step MA sig).
+(defun MT-step (MT MA sig)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)
+ (MA-sig-p sig))))
+ (MAETT (MT-init-ISA MT)
+ (step-trace (MT-trace MT) MA sig (MT-init-ISA MT))))
+
+(deflabel end-MAETT-def)
+
+
+; Function to iteratively update a MAETT, MT, for n cycles. Argument
+; MA and MT are the initial MA state and the corresponding MAETT.
+(defun MT-stepn (MT MA sig-list n)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)
+ (MA-sig-listp sig-list)
+ (integerp n) (<= 0 n))
+ :verify-guards nil))
+ (if (zp n) MT
+ (if (endp sig-list) MT
+ (MT-stepn (MT-step MT MA (car sig-list))
+ (MA-step MA (car sig-list))
+ (cdr sig-list)
+ (1- n)))))
+
+(deftheory MAETT-def
+ (non-rec-functions
+ (set-difference-theories (function-theory 'end-MAETT-def)
+ (function-theory 'begin-MAETT-def))
+ world))
+
+(in-theory (disable MAETT-def))
+
+;; Type proofs
+(defthm ISA-state-p-proj
+ (implies (MA-state-p MA) (ISA-state-p (proj MA)))
+ :hints (("Goal" :in-theory (enable proj))))
+
+(defthm MAETT-p-init-MT
+ (implies (MA-state-p MA) (MAETT-p (init-MT MA)))
+ :hints (("Goal" :in-theory (enable init-MT))))
+
+(defthm inst-p-new-inst
+ (implies (ISA-state-p ISA) (INST-p (new-inst ISA)))
+ :hints (("Goal" :in-theory (enable new-inst))))
+
+(defthm INST-p-step-INST
+ (implies (INST-p i) (INST-p (step-INST i MA)))
+ :Hints (("Goal" :in-theory (enable step-inst step-latch1-inst
+ step-latch2-inst))))
+
+(defthm INST-listp-step-trace
+ (implies (and (INST-listp trace) (ISA-state-p ISA))
+ (INST-listp (step-trace trace MA sig ISA))))
+
+(defthm MAETT-p-MT-step
+ (implies (and (MAETT-p MT) (MA-state-p MA) (MA-sig-p sig))
+ (MAETT-p (MT-step MT MA sig)))
+ :hints (("Goal" :in-theory (enable MT-step))))
+
+(verify-guards MT-step)
+
+(defthm MAETT-p-MT-stepn
+ (implies (and (MAETT-p MT) (MA-state-p MA) (MA-sig-listp sig-list)
+ (<= n (len sig-list)))
+ (MAETT-p (MT-stepn MT MA sig-list n))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of Instruction Attributes
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Various attributes of an instruction are defined as functions which
+; take the MAETT entry representing the instruction. For instance,
+; the opcode of an instruction represented by MAETT entry I is defined
+; as (INST-op I). In the following definitions, we define many
+; attributes such as instruction word, operand registers, source
+; values and result value.
+(deflabel begin-INST-attrb)
+(defun INST-word (i)
+ (declare (xargs :guard (INST-p i)))
+ (read-mem (ISA-pc (INST-pre-ISA i)) (ISA-mem (INST-pre-ISA i))))
+
+(defun INST-op (i)
+ (declare (xargs :guard (INST-p i)))
+ (op-field (INST-word i)))
+
+(defun INST-rc (i)
+ (declare (xargs :guard (INST-p i)))
+ (rc-field (INST-word i)))
+
+(defun INST-ra (i)
+ (declare (xargs :guard (INST-p i)))
+ (ra-field (INST-word i)))
+
+(defun INST-rb (i)
+ (declare (xargs :guard (INST-p i)))
+ (rb-field (INST-word i)))
+
+(defun INST-ra-val (i)
+ (declare (xargs :guard (INST-p i)))
+ (read-reg (INST-ra i) (ISA-regs (INST-pre-ISA i))))
+
+(defun INST-rb-val (i)
+ (declare (xargs :guard (INST-p i)))
+ (read-reg (INST-rb i) (ISA-regs (INST-pre-ISA i))))
+
+(defun INST-result (i)
+ (declare (xargs :guard (INST-p i)))
+ (ALU-output (INST-op i) (INST-ra-val i) (INST-rb-val i)))
+
+(deflabel end-INST-attrb)
+(deftheory INST-attrb
+ (set-difference-theories (function-theory 'end-INST-attrb)
+ (function-theory 'begin-INST-attrb)))
+(in-theory (disable INST-attrb))
+
+(defthm word-p-INST-word
+ (implies (INST-p i) (word-p (INST-word i)))
+ :hints (("Goal" :in-theory (enable INST-word))))
+
+(defthm opcd-p-INST-op
+ (implies (INST-p i) (opcd-p (INST-op i)))
+ :hints (("Goal" :in-theory (enable INST-op))))
+
+(defthm rname-p-INST-rc
+ (implies (INST-p i) (rname-p (INST-rc i)))
+ :hints (("Goal" :in-theory (enable INST-rc))))
+
+(defthm rname-p-INST-ra
+ (implies (INST-p i) (rname-p (INST-ra i)))
+ :hints (("Goal" :in-theory (enable INST-ra))))
+
+(defthm rname-p-INST-rb
+ (implies (INST-p i) (rname-p (INST-rb i)))
+ :hints (("Goal" :in-theory (enable INST-rb))))
+
+(defthm word-p-INST-ra-val
+ (implies (INST-p i) (word-p (INST-ra-val i)))
+ :hints (("Goal" :in-theory (enable INST-ra-val))))
+
+(defthm word-p-INST-rb-val
+ (implies (INST-p i) (word-p (INST-rb-val i)))
+ :hints (("Goal" :in-theory (enable INST-rb-val))))
+
+(defthm word-p-INST-result
+ (implies (INST-p i) (word-p (INST-result i)))
+ :hints (("Goal" :in-theory (enable INST-result ALU-output))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Defintion of INST-at
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; INST-at returns the MAETT entry whose represented instruction is at
+; a particular stage.
+;
+; (INST-at stg MT) is nil if there is no instruction at stage stg in
+; MAETT MT. If there is one, it returns the corresponding MAETT entry
+; representing the instruction.
+
+(defun trace-inst-at (stg trace)
+ (declare (xargs :guard (and (stage-p stg) (INST-listp trace))))
+ (if (endp trace) nil
+ (if (equal (INST-stg (car trace)) stg)
+ (car trace)
+ (trace-inst-at stg (cdr trace)))))
+
+(defun INST-at (stg MT)
+ (declare (xargs :guard (and (stage-p stg) (MAETT-p MT))))
+ (trace-inst-at stg (MT-trace MT)))
+
+(in-theory (disable INST-at))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Definition of invariant conditions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Invariant conditions required for the proof of correctness diagram
+; are defined here. We needed seven invariant conditions.
+;
+; (pc-match-p MT MA)
+; The program counter holds the correct value.
+; (regs-match-p MT MA)
+; The register file contains correct values.
+; (mem-match-p MT MA)
+; The memory is in the correct state.
+; (ISA-chain-p MT)
+; MAETT records correct ISA execution of instructions.
+; (MT-inst-invariant MT MA)
+; Each instruction in the pipeline satisfies "instruction invariant".
+; (MT-contains-all-insts MT MA)
+; MT contains all instructions currently in the pipeline of MA.
+; (MT-in-order-p MT)))
+; MA pipeline executes instructions in program order.
+(deflabel begin-invariant-def)
+
+; Predicate pc-match-p checks whether the program counter in the MA
+; holds the correct value. The reader may ask what the correct value is.
+; The answer is that the program counter should point to the
+; instruction to be fetched in the next cycle. MT-pc calculates
+; it from a MAETT, by first looking for the most recently fetched
+; instruction I, and find the program counter value of (INST-post-ISA I).
+; (INST-post-ISA I) is the ISA state after the execution of I,
+; and before fetching the next instruction.
+(defun trace-pc (trace ISA)
+ (declare (xargs :guard (and (INST-listp trace) (ISA-state-p ISA))))
+ (if (endp trace)
+ (ISA-pc ISA)
+ (trace-pc (cdr trace) (INST-post-ISA (car trace)))))
+
+(defun MT-pc (MT)
+ (declare (xargs :guard (MAETT-p MT)))
+ (trace-pc (MT-trace MT) (MT-init-ISA MT)))
+
+(defun pc-match-p (MT MA)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA))))
+ (equal (MT-pc MT) (MA-pc MA)))
+
+; Predicate regs-match-p checks whether the register file contains the
+; correct values. MT-regs calculate the correct register file
+; state from a MAETT. It first looks for the earliest non-retired
+; instruction I, and returns the register file of (INST-pre-ISA I).
+; The register is updated when an instruction retires. So the
+; register file in the MA holds the results of all retired
+; instruction, but none of the partially executed instructions,
+; including I.
+(defun trace-regs (trace ISA)
+ (declare (xargs :guard (and (INST-listp trace) (ISA-state-p ISA))))
+ (if (endp trace)
+ (ISA-regs ISA)
+ (if (not (equal (INST-stg (car trace)) 'retire))
+ (ISA-regs ISA)
+ (trace-regs (cdr trace) (INST-post-ISA (car trace))))))
+
+(defun MT-regs (MT)
+ (declare (xargs :guard (MAETT-p MT)))
+ (trace-regs (MT-trace MT) (MT-init-ISA MT)))
+
+(defun regs-match-p (MT MA)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA))))
+ (equal (MT-regs MT) (MA-regs MA)))
+
+; Memory state does not change in this model. The memory of the MA state
+; should be equal to that of the initial ISA state.
+(defun mem-match-p (MT MA)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA))))
+ (equal (MA-mem MA) (ISA-mem (MT-init-ISA MT))))
+
+; MAETT represents the sequence of instructions as a list, where each
+; element of the list represents an instruction. Each entry
+; has pre-ISA and post-ISA fields, which store the ISA state before
+; and after executing the represented instruction. This ISA
+; states form a sort of chain. Suppose MT has a list of instruction
+; entries (I_0 I_1 I_2 ...). I_0 represents the first instruction to be
+; executed, I_1 represents the second and so on. Then following
+; equations hold:
+; (ISA-step (INST-pre-ISA I_0)) = (INST-post-ISA I_0)
+; (INST-post-ISA I_0) = (INST-pre-ISA I_1)
+; (ISA-step (INST-pre-ISA I_1)) = (INST-post-ISA I_1)
+; (INST-post-ISA I_1) = (INST-pre-ISA I_2)
+; ....
+; This relations are checked by the predicate ISA-chain-p. In other
+; words, ISA-chain-p checks whether the correct sequence of ISA states
+; are stored in the MAETT. Following picture may help the reader to
+; understand the relations of pre-ISA and post-ISA.
+;
+; (INST-pre-ISA i_0)
+; | execution of i_0
+; v
+; (INST-post-ISA i_0) = (INST-pre-ISA i_1)
+; | execution of i_1
+; v
+; (INST-post-ISA i_1) = (INST-pre-ISA i_2)
+; ...
+(defun ISA-chain-trace-p (trace ISA)
+ (declare (xargs :guard (and (INST-listp trace) (ISA-state-p ISA))))
+ (if (endp trace)
+ T
+ (and (equal (INST-pre-ISA (car trace)) ISA)
+ (equal (ISA-step ISA)
+ (INST-post-ISA (car trace)))
+ (ISA-chain-trace-p (cdr trace) (ISA-step ISA)))))
+
+(defun ISA-chain-p (MT)
+ (declare (xargs :guard (MAETT-p MT)))
+ (ISA-chain-trace-p (MT-trace MT) (MT-init-ISA MT)))
+
+; Each instruction should satisfy some invariant conditions at each
+; stage of the pipeline. Mostly, these conditions are about the
+; intermediate values stored in the pipeline latches.
+;
+; For instance, field latch1-op of latch latch1 in the MA state hould
+; hold the operand of instruction at stage latch1. If you see the
+; definition of inst-latch1-inv, you can find the corresponding
+; equation as the second conjunct of the body of the definition.
+;
+; Predicate inst-invariant checks whether instruction entry i and the
+; corresponding MA state satisfies these stage-dependent invariant.
+; MT-inst-invariant checks all instructions in the MAETT satisfies
+; inst-invariant.
+
+; The condition that instruction should satisfy at state latch1.
+(defun inst-latch1-inv (i MA)
+ (declare (xargs :guard (and (INST-p i) (MA-state-p MA))))
+ (and (b1p (latch1-valid? (MA-latch1 MA)))
+ (equal (latch1-op (MA-latch1 MA)) (INST-op i))
+ (equal (latch1-rc (MA-latch1 MA)) (INST-rc i))
+ (equal (latch1-ra (MA-latch1 MA)) (INST-ra i))
+ (equal (latch1-rb (MA-latch1 MA)) (INST-rb i))))
+
+; The condition that instruction should satisfy at state latch2.
+(defun inst-latch2-inv (i MA)
+ (declare (xargs :guard (and (INST-p i) (MA-state-p MA))))
+ (and (b1p (latch2-valid? (MA-latch2 MA)))
+ (equal (latch2-op (MA-latch2 MA)) (INST-op i))
+ (equal (latch2-rc (MA-latch2 MA)) (INST-rc i))
+ (equal (latch2-ra-val (MA-latch2 MA)) (INST-ra-val i))
+ (equal (latch2-rb-val (MA-latch2 MA)) (INST-rb-val i))))
+
+; Instruction invariant that i should satisfy regardless of its stage.
+(defun inst-invariant (i MA)
+ (declare (xargs :guard (and (INST-p i) (MA-state-p MA))))
+ (cond ((equal (INST-stg i) 'latch1)
+ (inst-latch1-inv i MA))
+ ((equal (INST-stg i) 'latch2)
+ (inst-latch2-inv i MA))
+ (t t)))
+
+(defun trace-inst-invariant (trace MA)
+ (declare (xargs :guard (and (INST-listp trace) (MA-state-p MA))))
+ (if (endp trace) t
+ (and (inst-invariant (car trace) MA)
+ (trace-inst-invariant (cdr trace) MA))))
+
+(defun MT-inst-invariant (MT MA)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA))))
+ (trace-inst-invariant (MT-trace MT) MA))
+
+; If field latch1-valid? of an MA state is on, the corresponding MAETT
+; contains an entry representing the instruction at latch1. Similarly
+; for latch2.
+(defun MT-contains-all-insts (MT MA)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA))))
+ (and (implies (b1p (latch1-valid? (MA-latch1 MA)))
+ (inst-at 'latch1 MT))
+ (implies (b1p (latch2-valid? (MA-latch2 MA)))
+ (inst-at 'latch2 MT))))
+
+; This pipelined machine executes instructions in program order.
+; The instruction at latch1 is younger than the instruction at latch2,
+; and the instruction at latch2 is younger than any retired
+; instructions. This fact is checked by MT-in-order-p, assuming that
+; instructions are recorded in program order in a MAETT.
+(defun trace-in-order-p (trace)
+ (declare (xargs :guard (INST-listp trace)))
+ (if (endp trace)
+ t
+ (if (equal (INST-stg (car trace)) 'latch1)
+ (endp (cdr trace))
+ (if (equal (INST-stg (car trace)) 'latch2)
+ (and (not (trace-inst-at 'latch2 (cdr trace)))
+ (not (trace-inst-at 'retire (cdr trace)))
+ (trace-in-order-p (cdr trace)))
+ (trace-in-order-p (cdr trace))))))
+
+(defun MT-in-order-p (MT)
+ (declare (xargs :guard (MAETT-p MT)))
+ (trace-in-order-p (MT-trace MT)))
+
+; The definition of invariant.
+(defun invariant (MT MA)
+ (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA))))
+ (and (pc-match-p MT MA)
+ (regs-match-p MT MA)
+ (mem-match-p MT MA)
+ (ISA-chain-p MT)
+ (MT-inst-invariant MT MA)
+ (MT-contains-all-insts MT MA)
+ (MT-in-order-p MT)))
+
+(deflabel end-invariant-def)
+(deftheory invariant-def
+ (set-difference-theories (function-theory 'end-invariant-def)
+ (function-theory 'begin-invariant-def)))
+
+(deftheory non-rec-invariant-def
+ (non-rec-functions (theory 'invariant-def) world))
+
+(in-theory (disable non-rec-invariant-def))
+
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/trivia.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/trivia.lisp
new file mode 100644
index 0000000..a930142
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/trivia.lisp
@@ -0,0 +1,99 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Trivia.lisp
+; Copyright reserved by SRC
+; Author Jun Sawada, University of Texas at Austin
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;'
+(in-package "ACL2")
+
+;; Jared: changing this to an include of an identical book
+(include-book "workshops/1999/pipeline/trivia" :dir :system)
+
+;; (include-book "../../../../../../data-structures/array1")
+;; (include-book "../../../../../../arithmetic/top")
+
+;; (deflabel begin-trivia)
+
+;; (defmacro quoted-constant-p (x)
+;; `(and (consp ,x) (equal (car ,x) 'quote)))
+
+;; (defthm append-nil
+;; (implies (true-listp x)
+;; (equal (append x nil) x))
+;; :hints (("Goal" :in-theory (enable binary-append))))
+
+;; (defun natural-induction (i)
+;; (if (zp i) t
+;; (natural-induction (1- i))))
+
+;; ;; in data-structures/list-defthms
+;; ;; (defthm car-nthcdr
+;; ;; (equal (car (nthcdr idx lst)) (nth idx lst)))
+
+;; (defthm cdr-nthcdr
+;; (implies (and (integerp idx) (<= 0 idx))
+;; (equal (cdr (nthcdr idx lst)) (nthcdr (+ 1 idx) lst))))
+
+
+;; (in-theory (disable length))
+
+;; (in-theory (disable array1p compress1 default dimensions header
+;; aref1 aset1 maximum-length))
+
+;; (defthm array1p-module-type
+;; (implies
+;; (array1p name l)
+;; (and (symbolp name)
+;; (alistp l)
+;; (consp (header name l))
+;; (consp (dimensions name l))
+;; (true-listp (dimensions name l))
+;; (integerp (car (dimensions name l)))
+;; (<= 0 (car (dimensions name l)))
+;; (integerp (maximum-length name l))
+;; (<= 0 (maximum-length name l))))
+;; :hints (("Goal" :in-theory (enable array1p header default dimensions
+;; maximum-length)))
+;; :rule-classes
+;; ((:type-prescription :corollary
+;; (implies
+;; (array1p name l)
+;; (and (consp (header name l)))))
+;; (:type-prescription :corollary
+;; (implies
+;; (array1p name l)
+;; (and (consp (dimensions name l))
+;; (true-listp (dimensions name l)))))
+;; (:type-prescription :corollary
+;; (implies
+;; (array1p name l)
+;; (and (integerp (car (dimensions name l)))
+;; (<= 0 (car (dimensions name l))))))
+;; (:type-prescription :corollary
+;; (implies
+;; (array1p name l)
+;; (and (integerp (maximum-length name l))
+;; (<= 0 (maximum-length name l)))))))
+
+
+;; (local
+;; (defthm compress11-empty-array
+;; (implies (and (integerp n) (>= n 0))
+;; (equal (compress11 name (list (cons :header info)) n dim default)
+;; nil))
+;; :hints (("Goal" :In-theory (enable compress11)))))
+
+
+;; (defthm compress1-empty-array
+;; (equal (compress1 tag (list (cons :header x)))
+;; (list (cons :header x)))
+;; :hints (("Goal" :in-theory (enable compress1 compress11
+;; header default))))
+
+;; (defthm array1p-cons-with-dimensions
+;; (implies (and (array1p tag array)
+;; (integerp index)
+;; (>= index 0)
+;; (> (car (dimensions tag array)) index))
+;; (array1p tag (cons (cons index val) array)))
+;; :hints (("goal" :in-theory (enable dimensions header))))
+
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.acl2 b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.acl2
new file mode 100644
index 0000000..fee05b6
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.acl2
@@ -0,0 +1,4 @@
+(in-package "ACL2")
+(include-book "data-structures/portcullis" :dir :system)
+(certify-book "utils" ? t)
+
diff --git a/books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.lisp b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.lisp
new file mode 100644
index 0000000..5c59580
--- /dev/null
+++ b/books/workshops/2000/manolios/pipeline/trivial/sawada-model/utils.lisp
@@ -0,0 +1,104 @@
+(in-package "ACL2")
+
+(include-book "../../../../../../data-structures/utilities")
+
+(u::import-as-macros
+ U::A-UNIQUE-SYMBOL-IN-THE-U-PACKAGE
+ defloop)
+
+(defloop non-rec-functions (runes world)
+ (for ((rune in runes))
+ (unless (fgetprop (cadr rune) 'induction-machine nil world)
+ (collect rune))))
+
+(defloop rec-functions (runes world)
+ (for ((rune in runes))
+ (when (fgetprop (cadr rune) 'induction-machine nil world)
+ (collect rune))))
+
+
+(defmacro ww (form)
+ "With (W state) ..."
+ `(LET ((WORLD (W STATE))) ,form))
+
+;Example
+;(ww (non-rec-functions (definition-theory (current-theory :here)) world))
+
+;Example
+; (deftheory test (non-rec-functions (theory 'table-def) world))
+
+
+;
+; Macro ld-up-to fast loads ACL2 events in a file to a specified point.
+; (ld-up-to "<filename>" <event_name> {:speed <speed> })
+; This command loads ACL2 file <filename> to the point where
+; <event_name> is first defined.
+
+; Since ld-up-to skips proofs of the theorems in a loaded file by
+; default, a user can quickly reach the state where he or she wants
+; to work in. <even_name> can be any symbol newly defined by the
+; event at the desired breaking point. For instance, a label
+; defined by deflabel can be used as well. Keyword :all can be
+; specified when the user want to load the whole file.
+
+;
+; The user can specify loading speed using keyword :speed
+; :speed 0 Does not skip proofs. The slowest way to load a file.
+; :speed 1 Skips proofs, but performs other checks on theorems.
+; Ld-up-to loads files at this speed by default.
+; :speed 2 Skips proofs and other checks on theorems. Warning
+; will not be printed out. It also skips events local to
+; the ACL2 file.
+
+; Example
+; (ld-up-to "invariants-def.lisp" invariants)
+; This command loads ACL2 file invariant-def.lisp until it finds the
+; definition of function invariants.
+;
+; (ld-up-to "invariants-def.lisp" :all :speed 2)
+; this command load the all events in invariants-def.lisp except
+; events local to the ACL2 book.
+(defmacro ld-up-to (file event &key (speed '1))
+ (let ((skip-proofs-flag (if (equal speed 0) nil
+ (if (equal speed 1) t ''include-book))))
+ `(ld ,file :ld-pre-eval-filter ',event :ld-skip-proofsp ,skip-proofs-flag)))
+
+
+; Macro refresh rolls back ACL2 history and reloads ACL2 events fast.
+;
+; (refresh <filename> {:back-to <event1>} {:up-to <event2>} {:speed <speed>})
+;
+
+; Refresh first undoes events back to the point where <event1> was
+; defined, then it loads ACL2 file <filename> up to the point where
+; <event2> is newly defined. When previously executed ACL2 events
+; like definition and theorems are modified, the current world of ACL2
+; is corrupted and a user may want to restart the ACL2 from scratch.
+; However, restarting ACL2 takes a long time especially if many books
+; are loaded. Refresh helps to reload modified files and get the
+; newest state of ACL2 world quickly. It only undoes to the point
+; where symbol <event1> is defined, and then loads file <filename>,
+; skipping proofs by default. Since refresh loads ACL2 books included
+; by <filename>, usually the user only has to specify the top ACL2 book.
+; <event1> can be a symbol defined in an included book, and refresh
+; undoes the include-book of the included book. If :back-to
+; keyword is not supplied, refresh undoes all user defined events. If
+; :up-to keyword is not given, it load all events in <filename>. So
+; (refresh <filename>) is equivalent to (refresh <filename> :back-to 1
+; :up-to :all). <event1> can be a number designating an event.
+;
+; The user can also specify loading speed using keyword :speed
+; :speed 0 Does not skip proofs. The slowest way to load a file.
+; :speed 1 Skips proofs, but performs other checks on theorems.
+; Ld-up-to loads files at this speed by default.
+; :speed 2 Skips proofs and other checks on theorems. Warning
+; will not be printed out. It also skips events local to
+; the ACL2 file.
+
+(defmacro refresh (file &key (back-to '1) (up-to ':all) (speed '1))
+ (let ((skip-proofs-flag (if (equal speed 0) nil
+ (if (equal speed 1) t ''include-book))))
+ `(ld '((ubt! ',back-to) (ld ,file :ld-pre-eval-filter ',up-to
+ :ld-skip-proofsp ,skip-proofs-flag)))))
+
+