summaryrefslogtreecommitdiff
path: root/books/workshops/2003
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/2003
Import acl2_7.4dfsg.orig.tar.gz
[dgit import orig acl2_7.4dfsg.orig.tar.gz]
Diffstat (limited to 'books/workshops/2003')
-rw-r--r--books/workshops/2003/README4
-rw-r--r--books/workshops/2003/austel/abs-type.pdf.gzbin0 -> 89967 bytes
-rw-r--r--books/workshops/2003/austel/abs-type.ps.gzbin0 -> 56188 bytes
-rw-r--r--books/workshops/2003/austel/slides.pdf.gzbin0 -> 34207 bytes
-rw-r--r--books/workshops/2003/austel/slides.ps.gzbin0 -> 310392 bytes
-rw-r--r--books/workshops/2003/austel/support/abs-type.lisp777
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.pdf.gzbin0 -> 80428 bytes
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.ps.gzbin0 -> 56817 bytes
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.pdf.gzbin0 -> 97180 bytes
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.ps.gzbin0 -> 63739 bytes
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/alist2.lisp604
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/array2.lisp615
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matalg.lisp2705
-rw-r--r--books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matrix.lisp9871
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.pdf.gzbin0 -> 48039 bytes
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.ps.gzbin0 -> 63117 bytes
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/kalman.pdf.gzbin0 -> 162395 bytes
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/kalman.ps.gzbin0 -> 143725 bytes
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/certify.lsp18
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/defpkg.lsp4
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.acl24
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.lisp805
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.acl24
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.lisp161
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.acl24
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.lisp2271
-rw-r--r--books/workshops/2003/gamboa-cowles-van-baalen/support/linalg.lisp1079
-rw-r--r--books/workshops/2003/gamboa-patterson/polymorphism.pdf.gzbin0 -> 131840 bytes
-rw-r--r--books/workshops/2003/gamboa-patterson/polymorphism.ps.gzbin0 -> 79183 bytes
-rw-r--r--books/workshops/2003/gamboa-patterson/slides.pdf.gzbin0 -> 219744 bytes
-rw-r--r--books/workshops/2003/gamboa_lit-programming/litproofs.pdf.gzbin0 -> 91804 bytes
-rw-r--r--books/workshops/2003/gamboa_lit-programming/litproofs.ps.gzbin0 -> 90139 bytes
-rw-r--r--books/workshops/2003/gamboa_lit-programming/slides.pdf.gzbin0 -> 146896 bytes
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/deps.lisp8
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/security-policy.pdf.gzbin0 -> 122828 bytes
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/security-policy.ps.gzbin0 -> 56550 bytes
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/.gitignore3
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/Makefile45
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/cert_pl_exclude2
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/compatible.acl24
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/compatible.lisp87
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.acl24
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.lisp120
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.acl212
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.lisp340
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/make-consistency-test.lisp47
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/separation.acl24
-rw-r--r--books/workshops/2003/greve-wilding-vanfleet/support/separation.lisp118
-rw-r--r--books/workshops/2003/greve-wilding_defrecord/defrecord.pdf.gzbin0 -> 70741 bytes
-rw-r--r--books/workshops/2003/greve-wilding_defrecord/defrecord.ps.gzbin0 -> 35137 bytes
-rw-r--r--books/workshops/2003/greve-wilding_defrecord/support/defrecord.lisp245
-rw-r--r--books/workshops/2003/greve-wilding_mbe/mbe.pdf.gzbin0 -> 78063 bytes
-rw-r--r--books/workshops/2003/greve-wilding_mbe/mbe.ps.gzbin0 -> 38633 bytes
-rw-r--r--books/workshops/2003/greve-wilding_mbe/support/README23
-rw-r--r--books/workshops/2003/greve-wilding_mbe/support/fpst.lisp905
-rw-r--r--books/workshops/2003/greve-wilding_mbe/support/run-fpst.lisp425
-rw-r--r--books/workshops/2003/hbl/dynamic-hbl.pdf.gzbin0 -> 81530 bytes
-rw-r--r--books/workshops/2003/hbl/dynamic-hbl.ps.gzbin0 -> 53389 bytes
-rw-r--r--books/workshops/2003/hbl/hanbing-slides.pdf.gzbin0 -> 77171 bytes
-rw-r--r--books/workshops/2003/hbl/hanbing-slides.ps.gzbin0 -> 65040 bytes
-rw-r--r--books/workshops/2003/hbl/support/sol1.lisp1813
-rw-r--r--books/workshops/2003/hbl/support/sol2.lisp3010
-rw-r--r--books/workshops/2003/hendrix/hendrix-slides.pdf.gzbin0 -> 35673 bytes
-rw-r--r--books/workshops/2003/hendrix/hendrix-slides.ps.gzbin0 -> 43641 bytes
-rw-r--r--books/workshops/2003/hendrix/hendrix.pdf.gzbin0 -> 52260 bytes
-rw-r--r--books/workshops/2003/hendrix/hendrix.ps.gzbin0 -> 77532 bytes
-rw-r--r--books/workshops/2003/hendrix/support/madd.lisp156
-rw-r--r--books/workshops/2003/hendrix/support/matrices.lisp15
-rw-r--r--books/workshops/2003/hendrix/support/mdefthms.lisp651
-rw-r--r--books/workshops/2003/hendrix/support/mdefuns.lisp127
-rw-r--r--books/workshops/2003/hendrix/support/mentry.lisp118
-rw-r--r--books/workshops/2003/hendrix/support/mid.lisp53
-rw-r--r--books/workshops/2003/hendrix/support/mmult.lisp446
-rw-r--r--books/workshops/2003/hendrix/support/mscal.lisp139
-rw-r--r--books/workshops/2003/hendrix/support/msub.lisp15
-rw-r--r--books/workshops/2003/hendrix/support/mtrans.lisp124
-rw-r--r--books/workshops/2003/hendrix/support/mzero.lisp56
-rw-r--r--books/workshops/2003/hendrix/support/vector.lisp255
-rw-r--r--books/workshops/2003/kaufmann/LICENSE2
-rw-r--r--books/workshops/2003/kaufmann/deps.lisp16
-rw-r--r--books/workshops/2003/kaufmann/paper.pdf.gzbin0 -> 97121 bytes
-rw-r--r--books/workshops/2003/kaufmann/paper.ps.gzbin0 -> 55881 bytes
-rw-r--r--books/workshops/2003/kaufmann/slides.pdf.gzbin0 -> 59853 bytes
-rw-r--r--books/workshops/2003/kaufmann/slides.ps.gzbin0 -> 45979 bytes
-rw-r--r--books/workshops/2003/kaufmann/slides4.pdf.gzbin0 -> 37087 bytes
-rw-r--r--books/workshops/2003/kaufmann/slides4.ps.gzbin0 -> 47035 bytes
-rw-r--r--books/workshops/2003/kaufmann/support/Makefile2
-rw-r--r--books/workshops/2003/kaufmann/support/README9
-rw-r--r--books/workshops/2003/kaufmann/support/input/.gitignore4
-rw-r--r--books/workshops/2003/kaufmann/support/input/Makefile55
-rw-r--r--books/workshops/2003/kaufmann/support/input/cert_pl_exclude2
-rw-r--r--books/workshops/2003/kaufmann/support/input/defs-eq.acl29
-rw-r--r--books/workshops/2003/kaufmann/support/input/defs-in.acl27
-rw-r--r--books/workshops/2003/kaufmann/support/input/defs-in.lisp41
-rw-r--r--books/workshops/2003/kaufmann/support/input/defs-out.acl27
-rw-r--r--books/workshops/2003/kaufmann/support/input/defs-out.cmds22
-rw-r--r--books/workshops/2003/kaufmann/support/input/inputs.lisp7
-rw-r--r--books/workshops/2003/kaufmann/support/input/lemmas-in.lisp8
-rw-r--r--books/workshops/2003/kaufmann/support/output/cert_pl_exclude8
-rw-r--r--books/workshops/2003/kaufmann/support/output/defs-eq.lisp188
-rw-r--r--books/workshops/2003/kaufmann/support/output/defs-out.lisp33
-rw-r--r--books/workshops/2003/kaufmann/support/output/lemmas-out.lisp15
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/.gitignore4
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/Makefile123
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/README8
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/bvecp-raw.lisp33
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/cert.acl23
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/common.lisp134
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/model-macro-aliases.lsp18
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/model-macros.lisp8
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/model-raw.lisp76
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/package-defs.acl23
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/package-defs.lisp33
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/pkgs.lsp23
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/results/bvecp.lisp19
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/results/cert_pl_exclude8
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/results/model-eq.lisp161
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/results/model.lisp59
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/tool/Makefile2
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/tool/file-io-pkgs.lisp188
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/tool/simplify-defuns.lisp1181
-rw-r--r--books/workshops/2003/kaufmann/support/rtl/tool/wrapper.lisp68
-rw-r--r--books/workshops/2003/manolios-vroon/ordinals.pdf.gzbin0 -> 185942 bytes
-rw-r--r--books/workshops/2003/manolios-vroon/ordinals.ps.gzbin0 -> 240205 bytes
-rw-r--r--books/workshops/2003/matlin-mccune/final.pdf.gzbin0 -> 22164 bytes
-rw-r--r--books/workshops/2003/matlin-mccune/final.ps.gzbin0 -> 15982 bytes
-rw-r--r--books/workshops/2003/matlin-mccune/matlin.ppt.gzbin0 -> 11140 bytes
-rw-r--r--books/workshops/2003/matlin-mccune/slides.pdf.gzbin0 -> 13319 bytes
-rw-r--r--books/workshops/2003/matlin-mccune/slides.ps.gzbin0 -> 36937 bytes
-rw-r--r--books/workshops/2003/matlin-mccune/support/simp.lisp908
-rw-r--r--books/workshops/2003/moore_rockwell/report.pdf.gzbin0 -> 125101 bytes
-rw-r--r--books/workshops/2003/moore_rockwell/report.ps.gzbin0 -> 79674 bytes
-rw-r--r--books/workshops/2003/moore_rockwell/support/memory-taggings.lisp1513
-rw-r--r--books/workshops/2003/moore_vcg/report.pdf.gzbin0 -> 115573 bytes
-rw-r--r--books/workshops/2003/moore_vcg/report.ps.gzbin0 -> 68612 bytes
-rw-r--r--books/workshops/2003/moore_vcg/support/README11
-rw-r--r--books/workshops/2003/moore_vcg/support/certify.lsp172
-rw-r--r--books/workshops/2003/moore_vcg/support/demo.acl27
-rw-r--r--books/workshops/2003/moore_vcg/support/demo.lisp714
-rw-r--r--books/workshops/2003/moore_vcg/support/m5.acl2160
-rw-r--r--books/workshops/2003/moore_vcg/support/m5.lisp3032
-rw-r--r--books/workshops/2003/moore_vcg/support/utilities.acl27
-rw-r--r--books/workshops/2003/moore_vcg/support/utilities.lisp209
-rw-r--r--books/workshops/2003/moore_vcg/support/vcg-examples.acl26
-rw-r--r--books/workshops/2003/moore_vcg/support/vcg-examples.lisp904
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/handouts.pdf.gzbin0 -> 59958 bytes
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/handouts.ps.gzbin0 -> 125158 bytes
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/ltl-redux.pdf.gzbin0 -> 169018 bytes
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/ltl-redux.ps.gzbin0 -> 108029 bytes
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/slides.pdf.gzbin0 -> 74487 bytes
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/slides.ps.gzbin0 -> 140338 bytes
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/apply-total-order.lisp111
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/bis.lisp156
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp2780
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/certify.lsp123
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/circuit-bisim.lisp726
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/circuits.lisp1146
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/concrete-ltl.lisp308
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/cone-of-influence.lisp1976
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/conjunction.lisp99
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/impl-hack.acl23
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/impl-hack.lisp81
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/ltl.lisp479
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/records.lisp299
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/reductions.lisp392
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/sets.lisp137
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/total-order.lisp33
-rw-r--r--books/workshops/2003/schmaltz-al-sammane-et-al/combining.pdf.gzbin0 -> 69642 bytes
-rw-r--r--books/workshops/2003/schmaltz-al-sammane-et-al/combining.ps.gzbin0 -> 51570 bytes
-rw-r--r--books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.pdf.gzbin0 -> 683751 bytes
-rw-r--r--books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.ps.gzbin0 -> 688247 bytes
-rw-r--r--books/workshops/2003/schmaltz-al-sammane-et-al/support/acl2link.txt56
-rw-r--r--books/workshops/2003/schmaltz-al-sammane-et-al/support/consistency.lisp85
-rw-r--r--books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.pdf.gzbin0 -> 146471 bytes
-rw-r--r--books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.ps.gzbin0 -> 86042 bytes
-rw-r--r--books/workshops/2003/schmaltz-borrione/schmaltz-presentation.pdf.gzbin0 -> 168567 bytes
-rw-r--r--books/workshops/2003/schmaltz-borrione/schmaltz-presentation.ps.gzbin0 -> 171072 bytes
-rw-r--r--books/workshops/2003/schmaltz-borrione/support/arbiter.lisp505
-rw-r--r--books/workshops/2003/schmaltz-borrione/support/decoder.lisp218
-rw-r--r--books/workshops/2003/schmaltz-borrione/support/inequalities.lisp100
-rw-r--r--books/workshops/2003/schmaltz-borrione/support/predicates.lisp160
-rw-r--r--books/workshops/2003/schmaltz-borrione/support/transfers.lisp412
-rw-r--r--books/workshops/2003/sumners/fair.pdf.gzbin0 -> 61352 bytes
-rw-r--r--books/workshops/2003/sumners/fair.ps.gzbin0 -> 44093 bytes
-rw-r--r--books/workshops/2003/sumners/slides.pdf.gzbin0 -> 123596 bytes
-rw-r--r--books/workshops/2003/sumners/slides.ps.gzbin0 -> 72256 bytes
-rw-r--r--books/workshops/2003/sumners/support/README22
-rw-r--r--books/workshops/2003/sumners/support/cfair.lisp437
-rw-r--r--books/workshops/2003/sumners/support/example1.lisp113
-rw-r--r--books/workshops/2003/sumners/support/example2.lisp113
-rw-r--r--books/workshops/2003/sumners/support/example3.lisp349
-rw-r--r--books/workshops/2003/sumners/support/fair1.lisp239
-rw-r--r--books/workshops/2003/sumners/support/fair2.lisp164
-rw-r--r--books/workshops/2003/sumners/support/n2n.lisp448
-rw-r--r--books/workshops/2003/sumners/support/simple.lisp133
-rw-r--r--books/workshops/2003/sustik/dickson.pdf.gzbin0 -> 51422 bytes
-rw-r--r--books/workshops/2003/sustik/dickson.ps.gzbin0 -> 35300 bytes
-rw-r--r--books/workshops/2003/sustik/dicksonslides.pdf.gzbin0 -> 34708 bytes
-rw-r--r--books/workshops/2003/sustik/dicksonslides.ps.gzbin0 -> 26408 bytes
-rw-r--r--books/workshops/2003/sustik/support/dickson.lisp1056
-rw-r--r--books/workshops/2003/toma-borrione/sha-form-slides.pdf.gzbin0 -> 340124 bytes
-rw-r--r--books/workshops/2003/toma-borrione/sha-form-slides.ps.gzbin0 -> 334959 bytes
-rw-r--r--books/workshops/2003/toma-borrione/sha-form.pdf.gzbin0 -> 53702 bytes
-rw-r--r--books/workshops/2003/toma-borrione/sha-form.ps.gzbin0 -> 320009 bytes
-rw-r--r--books/workshops/2003/toma-borrione/support/bv-op-defthms.lisp717
-rw-r--r--books/workshops/2003/toma-borrione/support/bv-op-defuns.lisp335
-rw-r--r--books/workshops/2003/toma-borrione/support/misc.lisp142
-rw-r--r--books/workshops/2003/toma-borrione/support/padding-1-256.lisp239
-rw-r--r--books/workshops/2003/toma-borrione/support/padding-384-512.lisp189
-rw-r--r--books/workshops/2003/toma-borrione/support/parsing.lisp164
-rw-r--r--books/workshops/2003/toma-borrione/support/sha-1.lisp430
-rw-r--r--books/workshops/2003/toma-borrione/support/sha-256.lisp533
-rw-r--r--books/workshops/2003/toma-borrione/support/sha-384-512.lisp721
-rw-r--r--books/workshops/2003/toma-borrione/support/sha-functions.lisp164
-rw-r--r--books/workshops/2003/tsong/shim.pdf.gzbin0 -> 39632 bytes
-rw-r--r--books/workshops/2003/tsong/shim.ps.gzbin0 -> 270800 bytes
-rw-r--r--books/workshops/2003/tsong/support/shim.lisp1886
-rw-r--r--books/workshops/2003/whats-new/note-v2-7.txt.gzbin0 -> 14808 bytes
-rw-r--r--books/workshops/2003/whats-new/note-v2-8.txt.gzbin0 -> 4437 bytes
-rw-r--r--books/workshops/2003/whats-new/talk.txt.gzbin0 -> 3856 bytes
220 files changed, 57505 insertions, 0 deletions
diff --git a/books/workshops/2003/README b/books/workshops/2003/README
new file mode 100644
index 0000000..b95d47b
--- /dev/null
+++ b/books/workshops/2003/README
@@ -0,0 +1,4 @@
+# The following do not have any supporting materials with certifiable books:
+gamboa-patterson/support
+gamboa_lit-programming/support
+manolios-vroon
diff --git a/books/workshops/2003/austel/abs-type.pdf.gz b/books/workshops/2003/austel/abs-type.pdf.gz
new file mode 100644
index 0000000..5d7e9d2
--- /dev/null
+++ b/books/workshops/2003/austel/abs-type.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/austel/abs-type.ps.gz b/books/workshops/2003/austel/abs-type.ps.gz
new file mode 100644
index 0000000..1a555ad
--- /dev/null
+++ b/books/workshops/2003/austel/abs-type.ps.gz
Binary files differ
diff --git a/books/workshops/2003/austel/slides.pdf.gz b/books/workshops/2003/austel/slides.pdf.gz
new file mode 100644
index 0000000..f5440fa
--- /dev/null
+++ b/books/workshops/2003/austel/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/austel/slides.ps.gz b/books/workshops/2003/austel/slides.ps.gz
new file mode 100644
index 0000000..1a396ef
--- /dev/null
+++ b/books/workshops/2003/austel/slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/austel/support/abs-type.lisp b/books/workshops/2003/austel/support/abs-type.lisp
new file mode 100644
index 0000000..b0b1d3b
--- /dev/null
+++ b/books/workshops/2003/austel/support/abs-type.lisp
@@ -0,0 +1,777 @@
+(in-package "ACL2")
+
+#|
+Events accompanying "Implementing abstract types in ACL2",
+by Vernon Austel
+|#
+
+;; Events for the simple example concerning lists.
+(defun listfix (x)
+ (if (endp x)
+ nil
+ (cons (car x) (listfix (cdr x)))))
+
+(defun list= (x y)
+ (equal (listfix x) (listfix y)))
+
+(defequiv list=)
+
+(defthm listfix-listfix
+ (equal (listfix (listfix x))
+ (listfix x)))
+
+(defthm list=-listfix
+ (list= (listfix x) x))
+
+(defcong list= list= (cons x y) 2)
+(defcong list= equal (car x) 1)
+
+(defthm not-consp-list=-nil
+ (implies (not (consp l))
+ (list= l nil))
+ :rule-classes :forward-chaining)
+
+(defthm listfix-append
+ (equal (listfix (append x y))
+ (append (listfix x) (listfix y))))
+
+(defcong list= list= (append x y) 1)
+(defcong list= list= (append x y) 2)
+
+(in-theory (disable list=))
+
+
+(defthm list=-append-nil
+ (list= (append l nil) l))
+
+
+
+
+;; Events concerning the expression evaluation example.
+
+;; the defcong-fix macro
+(progn
+ ;; don't use: (defstub-equiv defcong-equiv2)
+ ;; because this expands into a formula using x, y and z,
+ ;; and this causes problems with variable capture in functional instantiation
+ (encapsulate
+ (((defcong-equiv2 * *) => *))
+
+ (local (defun defcong-equiv2 (x y) (equal x y)))
+
+ (defthm defcong-equiv2-is-an-equivalence
+ (and (booleanp (defcong-equiv2 xxx yyy))
+ (defcong-equiv2 xxx xxx)
+ (implies (defcong-equiv2 xxx yyy)
+ (defcong-equiv2 yyy xxx))
+ (implies (and (defcong-equiv2 xxx yyy)
+ (defcong-equiv2 yyy zzz))
+ (defcong-equiv2 xxx zzz)))
+ :rule-classes (:equivalence))
+ )
+
+
+ (encapsulate
+ (((defcong-equiv1-norm *) => *))
+
+ (local (defun defcong-equiv1-norm (dummy-arg) (declare (ignore dummy-arg)) t))
+
+ (defthm defcong-equiv1-norm-prop
+ (equal (defcong-equiv1-norm (defcong-equiv1-norm xxx))
+ (defcong-equiv1-norm xxx)))
+ )
+
+ (defun defcong-equiv1 (the-value1 the-value2)
+ (equal (defcong-equiv1-norm the-value1) (defcong-equiv1-norm the-value2)))
+ (defequiv defcong-equiv1)
+
+
+ (encapsulate
+ (((defcong-norm-fn *) => *))
+
+ (local (defun defcong-norm-fn (dummy-arg) (declare (ignore dummy-arg)) t))
+
+ (defthm defcong-norm-fn-prop
+ (defcong-equiv2
+ (defcong-norm-fn (defcong-equiv1-norm xxx))
+ (defcong-norm-fn xxx)))
+ )
+
+
+ (defcong defcong-equiv1 defcong-equiv2 (defcong-norm-fn xxx) 1
+ :hints (("Goal" :in-theory (e/d (defcong-equiv1) (defcong-norm-fn-prop))
+ :use ((:instance defcong-norm-fn-prop)
+ (:instance defcong-norm-fn-prop (xxx xxx-equiv))))))
+
+
+ (defmacro if-stable (&rest rest)
+ `(if STABLE-UNDER-SIMPLIFICATIONP
+ ',rest
+ nil))
+
+ (progn
+ (defthm character-listp-first-n-ac
+ (implies (and (character-listp l) (character-listp ac)
+ (<= n (len l)))
+ (character-listp (first-n-ac n l ac)))
+ :hints (("Goal" :expand (first-n-ac n nil ac))))
+
+ (defthm character-listp-take
+ (implies (and (character-listp l) (<= n (len l)))
+ (character-listp (take n l))))
+
+ (in-theory (disable take))
+
+ (defun symchop (sym)
+ (declare (xargs :guard (symbolp sym)))
+ (intern-in-package-of-symbol
+ (coerce (butlast (coerce (symbol-name sym) 'LIST) 1) 'STRING)
+ sym))
+ )
+ (defun symcat (sym suffix)
+ (declare (xargs :guard (and (symbolp sym)
+ (or (symbolp suffix)
+ (stringp suffix)))))
+ (intern-in-package-of-symbol
+ (concatenate 'STRING
+ (symbol-name sym)
+ (if (symbolp suffix)
+ (symbol-name suffix)
+ suffix))
+ sym))
+
+ (defun symchop (sym)
+ (declare (xargs :guard (symbolp sym)))
+ (intern-in-package-of-symbol
+ (coerce (butlast (coerce (symbol-name sym) 'list)
+ 1)
+ 'string)
+ sym))
+
+ (defmacro defcong-fix (equiv1 equiv2 tm n &key (hints 'nil))
+ (let ((defcong-equiv1-norm (symcat (symchop equiv1) 'fix))
+ (xxx (nth n tm)))
+ `(defcong ,equiv1 ,equiv2 ,tm ,n
+ :hints (("Goal"
+ :use (:instance
+ (:functional-instance
+ defcong-equiv1-implies-defcong-equiv2-defcong-norm-fn-1
+ (defcong-equiv2
+ ,equiv2)
+ (defcong-equiv1-norm
+ ,defcong-equiv1-norm)
+ (defcong-equiv1
+ (lambda (x y)
+ (equal (,defcong-equiv1-norm x) (,defcong-equiv1-norm y))))
+ (defcong-norm-fn
+ (lambda (,xxx)
+ ,tm)))
+ (xxx ,xxx)
+ (xxx-equiv ,(symcat xxx '-equiv)))
+ :expand (,equiv1 ,xxx ,(symcat xxx '-equiv)))
+ ,@hints
+
+
+ ;; left to itself, the prover will try induction on the
+ ;; original goal.
+ ;; that strategy fails.
+ ;; we have to make it pick just the one subgoal
+ ;; that needs induction.
+ ;; The particular subgoal varies, so we can't use
+ ;; a literal goalspec.
+ (if-stable :induct t)))))
+ )
+
+
+(defun expr-kind (expr)
+ (cond ((symbolp expr) 'SYMBOL)
+ ((consp expr) 'BINOP)
+ (t 'LIT)))
+
+;; destructors
+(defun binop-op (x)
+ (if (equal (expr-kind x) 'BINOP)
+ (cadr x)
+ nil))
+
+(defun binop-left (expr)
+ (if (equal (expr-kind expr) 'BINOP)
+ (caddr expr)
+ nil))
+
+(defun binop-right (expr)
+ (if (equal (expr-kind expr) 'BINOP)
+ (cadddr expr)
+ nil))
+
+
+;; constructors
+(defun mk-binop (op left right)
+ (list 'BINOP op left right))
+
+(defun litfix (x)
+ (ifix x))
+
+;; fixer
+(defun exprfix (expr)
+ (let ((kind (expr-kind expr)))
+ (case kind
+ (SYMBOL expr)
+
+ (LIT (litfix expr))
+
+ (otherwise
+ (mk-binop (binop-op expr)
+ (exprfix (binop-left expr))
+ (exprfix (binop-right expr)))))))
+
+(defun expr= (x y)
+ (equal (exprfix x) (exprfix y)))
+
+(defequiv expr=)
+
+
+;; congruence rule for the "kind" function.
+(defcong expr= equal (expr-kind expr) 1
+ :hints (("Goal" :expand ((exprfix expr)
+ (exprfix expr-equiv)))))
+
+;; distinguishing between different kinds can be a pain.
+(defthm expr-kind-otherwise
+ (implies (and (not (equal (expr-kind expr) 'lit))
+ (not (equal (expr-kind expr) 'symbol)))
+ (iff (equal (expr-kind expr) 'binop)
+ t)))
+
+(defthm expr-kind-symbol
+ (implies (equal (expr-kind expr) 'SYMBOL)
+ (symbolp expr))
+ :rule-classes :forward-chaining
+ :hints (("Goal" :in-theory (e/d (expr-kind)))))
+
+(defthm expr-kind-lit
+ (implies (equal (expr-kind expr) 'LIT)
+ (not (consp expr)))
+ :rule-classes :forward-chaining
+ :hints (("Goal" :in-theory (e/d (expr-kind)))))
+
+(defthm expr-kind-otherwise-2
+ (implies (and (not (equal (expr-kind expr) 'lit))
+ (not (equal (expr-kind expr) 'symbol)))
+ (consp expr))
+ :rule-classes :forward-chaining
+ :hints (("Goal" :in-theory (e/d (expr-kind)))))
+
+(defthm expand-expr-kind
+ (equal (expr-kind (mk-binop binop left right))
+ 'BINOP)
+ :hints (("Goal" :in-theory (e/d (expr-kind mk-binop)))))
+
+
+
+;; congruences for destructors
+(defcong expr= equal (binop-op expr) 1
+ :hints (("Goal" :expand ((exprfix expr)
+ (exprfix expr-equiv)))))
+
+(defcong expr= expr= (binop-left expr) 1)
+(defcong expr= expr= (binop-right expr) 1)
+
+(defcong expr= expr= (mk-binop bop left right) 2)
+(defcong expr= expr= (mk-binop bop left right) 3)
+
+(defthm exprfix-exprfix
+ (equal (exprfix (exprfix expr))
+ (exprfix expr)))
+
+(defthm expr=-exprfix
+ (expr= (exprfix expr) expr))
+
+
+;; measure lemmas for destructors
+(defthm acl2-count-binop-left
+ (implies (equal (expr-kind expr) 'BINOP)
+ (< (acl2-count (binop-left expr))
+ (acl2-count expr)))
+ :rule-classes (:rewrite :linear))
+
+(defthm acl2-count-binop-right
+ (implies (equal (expr-kind expr) 'BINOP)
+ (< (acl2-count (binop-right expr))
+ (acl2-count expr)))
+ :rule-classes (:rewrite :linear))
+
+;; elimination rules for constructors
+(defthm elim-binop
+ (implies (equal (expr-kind expr) 'BINOP)
+ (expr= (mk-binop (binop-op expr)
+ (binop-left expr)
+ (binop-right expr))
+ expr))
+ :rule-classes (:rewrite :elim))
+
+;; These kinds of expansions are also handy
+(defthm expand-binop-destructors
+ (and (equal (binop-op (mk-binop op left right)) op)
+ (equal (binop-left (mk-binop op left right)) left)
+ (equal (binop-right (mk-binop op left right)) right)))
+
+(defthm integerp-exprfix
+ (equal (integerp (exprfix expr))
+ (and (not (symbolp expr))
+ (not (consp expr)))))
+
+
+(deftheory expr-destructors
+ '(binop-op binop-left binop-right))
+
+(deftheory expr-constructors
+ '(litfix mk-binop))
+
+(in-theory (disable expr-kind))
+(in-theory (disable expr=))
+(in-theory (disable expr-destructors expr-constructors))
+
+
+
+
+
+;; The first example function.
+(defun free-vars (expr)
+ (let ((kind (expr-kind expr)))
+ (case kind
+ (SYMBOL (list expr))
+ (LIT nil)
+ (t (append (free-vars (binop-left expr))
+ (free-vars (binop-right expr)))))))
+
+;; its associated expansion rule
+(defthm expand-free-vars
+ (and (implies (equal (expr-kind expr) 'SYMBOL)
+ (equal (free-vars expr) (list expr)))
+
+ (implies (equal (expr-kind expr) 'LIT)
+ (equal (free-vars expr) nil))
+
+ (equal (free-vars (litfix expr)) nil)
+
+ (equal (free-vars (mk-binop op left right))
+ (append (free-vars left)
+ (free-vars right))))
+ :hints (("Goal" :in-theory (e/d (expr-kind
+ expr-destructors expr-constructors)))))
+
+;; Its congruence theorem
+;; type:
+;; :trans1 (defcong-fix expr= equal (free-vars expr) 1)
+;; at the ACL2 command prompt to see what it turns into
+(defcong-fix expr= equal (free-vars expr) 1)
+
+
+;; We shouldn't need this anymore, although we enable
+;; it for the example inductive proof.
+(in-theory (disable free-vars))
+
+
+#|
+This shows what the congruence proof will look like
+if fixing functions are not used to define the equivalence relation.
+
+(defun expr=-2 (expr y)
+ (let ((kind (expr-kind expr)))
+ (and (equal (expr-kind y) kind)
+ (case kind
+ (SYMBOL (equal y expr))
+
+ (LIT (equal (litfix expr) (litfix y)))
+
+ (otherwise
+ (and (equal (binop-op expr)
+ (binop-op y))
+ (expr=-2 (binop-left expr)
+ (binop-left y))
+ (expr=-2 (binop-right expr)
+ (binop-right y))))))))
+
+
+(defthm expr=-2-thm
+ (iff (expr=-2 x y)
+ (expr= x y))
+ :hints (("Goal"
+ :expand ((exprfix x) (exprfix y))
+ :induct (expr=-2 x y)
+ :in-theory (e/d (expr= expr-kind
+ expr-destructors expr-constructors)))))
+
+(defthm expr=-ind-pat T
+ :rule-classes
+ ((:induction
+ :pattern (expr= x y)
+ :condition t
+ :scheme (expr=-2 x y))))
+
+(defcong expr= equal (free-vars expr) 1
+ :hints (("Goal" :in-theory (e/d (free-vars)))
+ ("Subgoal *1/1" :expand (expr= expr expr-equiv))))
+
+|#
+
+;; The second example function
+(defun eval-expr (expr env)
+ (let ((kind (expr-kind expr)))
+ (case kind
+ (SYMBOL (cdr (assoc expr env)))
+ (LIT (litfix expr))
+ (t (+ (eval-expr (binop-left expr) env)
+ (eval-expr (binop-right expr) env))))))
+
+(defthm expand-eval-expr
+ (and (implies (equal (expr-kind expr) 'SYMBOL)
+ (equal (eval-expr expr env) (cdr (assoc expr env))))
+
+ (implies (equal (expr-kind expr) 'LIT)
+ (equal (eval-expr expr env) (litfix expr)))
+
+ (equal (eval-expr (litfix expr) env) (litfix expr))
+
+ (equal (eval-expr (mk-binop op left right) env)
+ (+ (eval-expr left env)
+ (eval-expr right env))))
+ :hints (("Goal" :in-theory (e/d (expr-destructors expr-constructors)))))
+
+(defthm not-integerp-litfix
+ (implies (not (integerp x))
+ (equal (litfix x) 0))
+ :hints (("Goal" :in-theory (e/d (litfix)))))
+
+(defcong-fix expr= equal (eval-expr expr env) 1)
+
+(in-theory (disable eval-expr))
+
+(defthm true-listp-free-vars
+ (true-listp (free-vars expr))
+ :hints (("Goal" :in-theory (e/d ((:induction free-vars))))))
+
+(defthm consp-append
+ (equal (consp (append x y))
+ (or (consp x) (consp y))))
+
+(defthm env-irrelevant-using-induction
+ (implies (not (consp (free-vars expr)))
+ (equal (eval-expr expr env)
+ (eval-expr expr nil)))
+ :rule-classes nil
+ :hints (("Goal" :in-theory (e/d (eval-expr free-vars)))))
+
+
+;; The constraints for a simple induction on expr=
+(encapsulate
+ ((expr-induct (expr) t))
+
+ (local (defun expr-induct (x) (declare (ignore x)) t))
+
+ (defthm expr-induct-symbol
+ (implies (equal (expr-kind expr) 'SYMBOL)
+ (expr-induct expr)))
+
+ (defthm expr-induct-lit
+ (expr-induct (litfix expr)))
+
+ (defthm expr-induct-binop
+ (implies (and (expr-induct left)
+ (expr-induct right))
+ (expr-induct (mk-binop binop left right))))
+
+ (defcong expr= iff (expr-induct expr) 1)
+ )
+
+
+
+;; the proof that expr-induct is always true.
+(encapsulate
+ nil
+
+ ;; basecases need extra help
+ (local
+ (defthm symbolp-expr-induct
+ (implies (symbolp expr)
+ (expr-induct expr))
+ :hints (("Goal" :in-theory (e/d (expr-kind) (expr-induct-symbol))
+ :use expr-induct-symbol))))
+
+ (local
+ (defthm integerp-expr-induct
+ (implies (integerp expr)
+ (expr-induct expr))
+ :hints (("Goal" :in-theory (e/d (litfix) (expr-induct-lit))
+ :use expr-induct-lit))))
+
+ (local
+ (defthmd expr-induct-thm-exprfix
+ (expr-induct (exprfix expr))
+ :hints (("Goal" :in-theory (e/d () (expr=-implies-iff-expr-induct-1))))))
+
+
+ ;; Then we just allow the congruence rule to fire.
+ (defthm expr-induct-thm
+ (expr-induct expr)
+ :hints (("Goal" :use expr-induct-thm-exprfix)))
+ )
+
+;; prove the same theorem as above using functional instantiation.
+(defthm env-irrelevant
+ (implies (not (consp (free-vars expr)))
+ (equal (eval-expr expr env)
+ (eval-expr expr nil)))
+ :hints (("Goal" :use (:functional-instance
+ expr-induct-thm
+ (expr-induct
+ (lambda (expr)
+ (implies (not (consp (free-vars expr)))
+ (equal (eval-expr expr env)
+ (eval-expr expr nil)))))))))
+
+
+(defmacro defexprthm (name tm)
+ `(defthm ,name
+ ,tm
+ :hints (("Goal"
+ :do-not-induct t
+ :use (:instance
+ (:functional-instance
+ expr-induct-thm
+ (expr-induct (lambda (expr) ,tm))))))))
+
+;; an easier way to do the same thing
+;; (this event will be redundant)
+(defexprthm env-irrelevant
+ (implies (not (consp (free-vars expr)))
+ (equal (eval-expr expr env)
+ (eval-expr expr nil))))
+
+
+
+;; all we know about this function is that it is an
+;; equivalence relation.
+(encapsulate
+ ((expr-fn= (x y) t))
+
+ (local (defun expr-fn= (x y) (equal x y)))
+
+ (defequiv expr-fn=)
+ )
+
+;; these functions serve as placeholders for what
+;; a particular function may do.
+(encapsulate
+ ((expr-symbol-fn (expr) t)
+ (expr-lit-fn (expr) t)
+ (expr-binop-fn (op left $left right $right) t))
+
+ (set-ignore-ok t)
+ (set-irrelevant-formals-ok t)
+
+ (local (defun expr-symbol-fn (expr) t))
+ (local (defun expr-lit-fn (expr) t))
+ (local (defun expr-binop-fn (op left $left right $right) t))
+
+ (defcong expr= expr-fn= (expr-lit-fn expr) 1)
+
+ (defcong expr= expr-fn= (expr-binop-fn op left $left right $right) 2)
+ (defcong expr-fn= expr-fn= (expr-binop-fn op left $left right $right) 3)
+ (defcong expr= expr-fn= (expr-binop-fn op left $left right $right) 4)
+ (defcong expr-fn= expr-fn= (expr-binop-fn op left $left right $right) 5)
+ )
+
+;; now define a "typical" function on expressions.
+(defun expr-fn (expr)
+ (let ((kind (expr-kind expr)))
+ (case kind
+ (SYMBOL (expr-symbol-fn expr))
+ (LIT (expr-lit-fn expr))
+ (t (expr-binop-fn (binop-op expr)
+ (binop-left expr)
+ (expr-fn (binop-left expr))
+ (binop-right expr)
+ (expr-fn (binop-right expr)))))))
+
+
+;; its corresponding expansion
+(defthm expand-expr-fn
+ (and (implies (equal (expr-kind expr) 'SYMBOL)
+ (expr-fn= (expr-fn expr)
+ (expr-symbol-fn expr)))
+
+ (implies (equal (expr-kind expr) 'LIT)
+ (expr-fn= (expr-fn expr)
+ (expr-lit-fn expr)))
+
+ (expr-fn= (expr-fn (litfix expr))
+ (expr-lit-fn (litfix expr)))
+
+ (expr-fn= (expr-fn (mk-binop op left right))
+ (expr-binop-fn op
+ left (expr-fn left)
+ right (expr-fn right))))
+ :hints (("Goal" :in-theory (e/d (expr-kind
+ expr-destructors expr-constructors)))))
+
+;; and its congruence theorem
+;; (similar to the proofs for free-vars and eval-expr)
+(encapsulate
+ nil
+ (local
+ (defthm expr-lit-lemma
+ (implies (and (equal (expr-kind expr) 'LIT)
+ (not (integerp expr)))
+ (expr= expr 0))
+ :rule-classes :forward-chaining
+ :hints (("Goal" :in-theory (e/d (expr= expr-kind))))))
+
+ (defcong-fix expr= expr-fn= (expr-fn expr) 1
+ :hints ((if-stable
+ :in-theory (e/d (litfix) ((expr-fn)))
+ :expand (expr-fn (mk-binop bop (exprfix blt)
+ (exprfix brt))))))
+ )
+
+;; Writing macros like this gets old pretty fast.
+(defun defexpr-fn (expr-fn args expr-fn=
+ expr-symbol-fn
+ expr-lit-fn
+ expr-binop-fn)
+ (declare (xargs :mode :program))
+ `(progn
+ ;; many variables in the BINOP case are unused.
+ ;; ACL2 complains about this.
+ ;; just kludge it for our example.
+ (set-ignore-ok t)
+
+ (defun ,expr-fn ,args
+ (let ((kind (expr-kind expr)))
+ (case kind
+ (SYMBOL ,expr-symbol-fn)
+ (LIT ,expr-lit-fn)
+ (t (let ((op (binop-op expr))
+ (left (binop-left expr))
+ ($left (,expr-fn (binop-left expr)
+ ,@(cdr args)))
+ (right (binop-right expr))
+ ($right (,expr-fn (binop-right expr)
+ ,@(cdr args))))
+ ,expr-binop-fn)))))
+
+ (defthm ,(packn (list 'expand- expr-fn))
+ (and (implies (equal (expr-kind expr) 'SYMBOL)
+ (,expr-fn= (,expr-fn ,@args)
+ ,expr-symbol-fn))
+
+ (implies (equal (expr-kind expr) 'LIT)
+ (,expr-fn= (,expr-fn ,@args)
+ ,expr-lit-fn))
+
+ (,expr-fn= (,expr-fn (litfix expr) ,@(cdr args))
+ (let ((expr (litfix expr)))
+ ,expr-lit-fn))
+
+ (,expr-fn= (,expr-fn (mk-binop op left right) ,@(cdr args))
+ (let (($left (,expr-fn left ,@(cdr args)))
+ ($right (,expr-fn right ,@(cdr args))))
+ ,expr-binop-fn)))
+ :hints (("Goal"
+ :do-not-induct t
+ :use
+ (:functional-instance expand-expr-fn
+ (expr-fn
+ ;; because expr-fn may take more than one arg
+ (lambda (expr)
+ (,expr-fn ,@args)))
+ (expr-fn= ,expr-fn=)
+ (expr-symbol-fn
+ (lambda (expr)
+ ,expr-symbol-fn))
+ (expr-lit-fn
+ (lambda (expr)
+ ,expr-lit-fn))
+ (expr-binop-fn
+ (lambda (op left $left right $right)
+ ,expr-binop-fn))))))
+
+
+ (defthm ,(packn (list 'expr=-implies- expr-fn= '- expr-fn '-1))
+ (implies (expr= expr expr-equiv)
+ (,expr-fn= (,expr-fn expr ,@(cdr args))
+ (,expr-fn expr-equiv ,@(cdr args))))
+ :hints
+ (("Goal"
+ :do-not-induct t
+ :use
+ ;; except for the theorem name,
+ ;; this functional instance is the same as the above
+ (:functional-instance expr=-implies-expr-fn=-expr-fn-1
+ (expr-fn
+ ;; because expr-fn may take more than one arg
+ (lambda (expr)
+ (,expr-fn ,@args)))
+ (expr-fn= ,expr-fn=)
+ (expr-symbol-fn
+ (lambda (expr)
+ ,expr-symbol-fn))
+ (expr-lit-fn
+ (lambda (expr)
+ ,expr-lit-fn))
+ (expr-binop-fn
+ (lambda (op left $left right $right)
+ ,expr-binop-fn)))))
+ :rule-classes ((:congruence)))
+ ))
+
+;; This macro can be made much fancier,
+;; with default arguments and so forth,
+;; but this gives the general idea.
+(defmacro defexpr (expr-fn args expr-fn=
+ &key symbol lit binop)
+ (defexpr-fn expr-fn args expr-fn=
+ symbol lit binop))
+
+
+
+
+;; use the new macro to
+;; define the function
+;; generate its expansion theorem
+;; generate its congruence theorem
+(defexpr variable-free (expr) equal
+ :SYMBOL nil
+ :LIT t
+ :BINOP (and $left $right))
+
+;; not much we can say about this, actually...
+(defexprthm variable-free-lemma
+ (iff (variable-free expr)
+ (not (consp (free-vars expr)))))
+
+;; This would have problems if we constrained expr-symbol-fn above.
+(defexpr expr-subst (expr sbst) expr=
+ :SYMBOL (if (assoc expr sbst)
+ (cdr (assoc expr sbst))
+ expr)
+ :LIT expr
+ :BINOP (mk-binop op $left $right))
+
+(defexprthm eval-expr-expr-subst-nil
+ (equal (eval-expr (expr-subst expr nil) env)
+ (eval-expr expr env)))
+
+
+
+
+;; This is curious, but probably not useful.
+(defthm litfix-elim
+ (implies (equal (expr-kind expr) 'LIT)
+ (expr= (litfix expr) expr))
+ :rule-classes :elim
+ :hints (("Goal" :in-theory (e/d (litfix expr= expr-kind)))))
+
+
+
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.pdf.gz b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.pdf.gz
new file mode 100644
index 0000000..82729c1
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.ps.gz b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.ps.gz
new file mode 100644
index 0000000..10656db
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/matrix.ps.gz
Binary files differ
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.pdf.gz b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.pdf.gz
new file mode 100644
index 0000000..8a30ea3
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.ps.gz b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.ps.gz
new file mode 100644
index 0000000..08d0446
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/alist2.lisp b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/alist2.lisp
new file mode 100644
index 0000000..099f7dc
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/alist2.lisp
@@ -0,0 +1,604 @@
+; The ACL2 two-dimensional Alist Book.
+; Copyright (C) 2003 John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+
+; Spring 2003
+; Last modified 21 May 2003
+
+; This book is similar to the book array2.lisp.
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+To certify at UW:
+
+:set-cbd "/home/faculty/cowles/acl2/matrix/" ;;pyramid
+
+:set-cbd "/home/cowles/matrix/" ;;turing
+
+(certify-book "alist2")
+|#
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+To use at UW:
+
+:set-cbd "/home/faculty/cowles/acl2/matrix/" ;;pyramid
+
+:set-cbd "/home/cowles/matrix/" ;;turing
+
+(include-book
+ "alist2")
+|#
+(in-package "ACL2")
+
+;; Logically, an ACL2 two-dimensional array is an alist that satisfies these
+;; properties:
+
+(defun
+ alist2p (name L)
+ "Determine if L satisfies the logical properties of an ACL2 array2p.
+ The ignored argument, name, is there only to make life easier later
+ when using such standard ACL2 array functions as aref2, aset2, header,
+ default, etc., that also have such an argument."
+ (declare (ignore name)(xargs :guard t))
+ (and (alistp l)
+ (let ((header-keyword-list (cdr (assoc-eq :header L))))
+ (and (keyword-value-listp header-keyword-list)
+ (let ((dimensions
+ (cadr (assoc-keyword :dimensions header-keyword-list))))
+ (and (consp dimensions)
+ (let ((cdr-dim (cdr dimensions)))
+ (and (consp cdr-dim)
+ (let ((d1 (car dimensions))
+ (d2 (car cdr-dim)))
+ (and (integerp d1)
+ (integerp d2)
+ (< 0 d1)
+ (< 0 d2)
+ (bounded-integer-alistp2 L d1 d2)))
+ ))))))))
+
+(defthm
+ array2p-alist2p
+ (implies (array2p name L)
+ (alist2p name L)))
+
+(local
+ (defthm
+ assoc-eq-properties
+ (implies
+ (and (alistp l)
+ (assoc-eq x l))
+ (and (consp (assoc-eq x l))
+ (equal (car (assoc-eq x l)) x)))))
+
+(local
+ (defthm
+ assoc2-properties
+ (implies
+ (and (alistp l)
+ (assoc2 i j l))
+ (and (consp (assoc2 i j l))
+ (consp (car (assoc2 i j l)))
+ (equal (car (car (assoc2 i j l))) i)
+ (equal (cdr (car (assoc2 i j l))) j)))))
+
+(local
+ (defthm
+ assoc-keyword-properties
+ (implies
+ (and (alistp l)
+ (assoc-keyword x l))
+ (and (consp (assoc-keyword x l))
+ (equal (car (assoc-keyword x l)) x)))))
+
+(local
+ (defthm
+ bounded-integer-alistp2-car-assoc2-properties
+ (implies
+ (and (bounded-integer-alistp2 l m n)
+ (assoc2 i j l))
+ (and (integerp (car (car (assoc2 i j l))))
+ (integerp (cdr (car (assoc2 i j l))))
+ (>= (car (car (assoc2 i j l))) 0)
+ (>= (cdr (car (assoc2 i j l))) 0)
+ (< (car (car (assoc2 i j l))) m)
+ (< (cdr (car (assoc2 i j l))) n)))))
+
+(local
+ (defthm alist2p-forward-local
+ (implies
+ (alist2p name L)
+ (and
+ (alistp L)
+ (keyword-value-listp (cdr (assoc-eq :header L)))
+ (consp (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq :header L)))))
+ (consp (cdadr (assoc-keyword :dimensions
+ (cdr (assoc-eq :header L)))))
+ (integerp
+ (car (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq :header L))))))
+ (integerp
+ (cadr (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq :header L))))))
+ (< 0 (car (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq :header L))))))
+ (< 0 (cadr (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq :header L))))))
+ (bounded-integer-alistp2 L
+ (car (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header L)))))
+ (cadr (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header L))))))))
+ :rule-classes :forward-chaining))
+
+(local
+ (defthm alist2p-header-exists
+ (implies
+ (alist2p name L)
+ (assoc-eq :header L))))
+
+(local
+ (defthm alist2p-cons-1
+ (implies
+ (and (alist2p name L)
+ (integerp i)
+ (>= i 0)
+ (< i (car (dimensions name l)))
+ (integerp j)
+ (>= j 0)
+ (< j (cadr (dimensions name l))))
+ (alist2p name (cons (cons (cons i j) val) L)))))
+
+(local (in-theory (disable alist2p)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;(compress211 name L i x j default) processes array elements
+;; L(i x) . . . L(i (- j 1)).
+
+(local
+ (defthm
+ alistp-compress211
+ (alistp (compress211 name L i x j default))))
+
+(local
+ (defthm bounded-integer-alistp2-compress211
+ (implies
+ (and (alist2p name L)
+ (integerp i)
+ (integerp x)
+ (integerp k)
+ (>= x 0)
+ (>= i 0)
+ (> k i))
+ (bounded-integer-alistp2 (compress211 name L i x j default)
+ k
+ j))))
+
+(local
+ (defthm
+ compress211-assoc2-property-0
+ (implies (and (alistp L)
+ (assoc2 m n L)
+ (assoc2 m n (compress211 name L i x j default)))
+ (equal (assoc2 m n (compress211 name L i x j default))
+ (assoc2 m n L)))))
+
+(local
+ (defthm
+ compress211-assoc2-property-1
+ (implies
+ (and (not (assoc2 i n (compress211 name L i x j default)))
+ (alistp L)
+ (integerp x)
+ (integerp j)
+ (integerp n)
+ (<= x n)
+ (< n j)
+ (assoc2 i n L))
+ (equal (cdr (assoc2 i n L))
+ default))))
+
+(local
+ (defthm
+ compress211-assoc2-property-2
+ (implies
+ (and (alistp L)
+ (not (assoc2 m n L)))
+ (not (assoc2 m n (compress211 name L i x j default))))))
+
+(local
+ (defthm
+ not-assoc2-compress211
+ (implies (and (alistp L)
+ (not (equal k i)))
+ (not (assoc2 k m (compress211 name L i x j default)))
+ )))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;(compress21 name L n i j default) processes array elements
+;; L(n 0) . . . L(n (- j 1))
+;; . . .
+;; . . .
+;; . . .
+;; L((- i 1) 0) . . . L((- i 1)(- j 1))
+
+(local
+ (defthm
+ alistp-append
+ (implies (and (alistp L1)
+ (alistp L2))
+ (alistp (append L1 L2)))))
+
+(local
+ (defthm
+ alistp-compress21
+ (alistp (compress21 name L n i j default))))
+
+(local
+ (defthm
+ bounded-integer-alistp2-append
+ (implies (and (bounded-integer-alistp2 L1 i j)
+ (bounded-integer-alistp2 L2 i j))
+ (bounded-integer-alistp2 (append L1 L2)
+ i
+ j))))
+
+(local
+ (defthm
+ bounded-integer-alistp2-compress21
+ (implies
+ (and (alist2p name L)
+ (integerp i)
+ (integerp n)
+ (>= n 0))
+ (bounded-integer-alistp2 (compress21 name L n i j default)
+ i
+ j))))
+
+(local
+ (defthm
+ assoc2-append
+ (equal (assoc2 i j (append L1 L2))
+ (if (assoc2 i j L1)
+ (assoc2 i j L1)
+ (assoc2 i j L2)))))
+
+(local
+ (defthm
+ compress21-assoc2-property-0
+ (implies
+ (and (alistp L)
+ (assoc2 k m L)
+ (assoc2 k m (compress21 name L n i j default)))
+ (equal (assoc2 k m (compress21 name L n i j default))
+ (assoc2 k m L)))))
+
+(local
+ (defthm
+ compress21-assoc2-property-1
+ (implies
+ (and (not (assoc2 k m (compress21 name L n i j default)))
+ (alistp L)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (integerp m)
+ (integerp n)
+ (<= n i)
+ (<= n k)
+ (< k i)
+ (<= 0 m)
+ (< m j)
+ (assoc2 k m L))
+ (equal (cdr (assoc2 k m L))
+ default))
+ :hints (("Subgoal *1/5"
+ :use (:instance
+ compress211-assoc2-property-1
+ (i k)
+ (n m)
+ (x 1))))))
+
+(local
+ (defthm
+ compress21-assoc2-property-2
+ (implies
+ (and (alistp L)
+ (not (assoc2 k m L)))
+ (not (assoc2 k m (compress21 name L n i j default))))))
+
+(local
+ (defthm
+ compress2-assoc2-property-0
+ (implies
+ (and (alistp L)
+ (assoc2 k m L)
+ (assoc2 k m (compress2 name L)))
+ (equal (cdr (assoc2 k m (compress2 name L)))
+ (cdr (assoc2 k m L))))))
+
+(local
+ (defthm
+ compress2-assoc2-property-1
+ (implies
+ (and (alist2p name L)
+ (integerp k)
+ (integerp m)
+ (<= 0 k)
+ (< k (car (dimensions name L)))
+ (<= 0 m)
+ (< m (cadr (dimensions name L)))
+ (assoc2 k m L)
+ (not (assoc2 k m (compress2 name L))))
+ (equal (cdr (assoc2 k m L))
+ (cadr (assoc-keyword :default (cdr (assoc-eq :header L))
+ ))))))
+
+(local
+ (defthm
+ compress2-assoc2-property-2
+ (implies
+ (and (alistp L)
+ (not (assoc2 k m L)))
+ (not (assoc2 k m (compress2 name L))))))
+
+(local
+ (defthm
+ header-compress2
+ (implies
+ (alist2p name L)
+ (equal (assoc-eq :header (compress2 name L))
+ (assoc-eq :header L)))))
+
+(defthm
+ alist2p-compress2
+ (implies
+ (alist2p name L)
+ (alist2p name (compress2 name L)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((compress2 name L))))
+ :hints (("Goal"
+ :in-theory (enable alist2p))))
+
+(defthm
+ alist2p-compress2-properties
+ (implies
+ (alist2p name L)
+ (and
+ (equal (header name (compress2 name L))
+ (header name L))
+ (equal (dimensions name (compress2 name L))
+ (dimensions name L))
+ (equal (maximum-length name (compress2 name L))
+ (maximum-length name L))
+ (equal (default name (compress2 name L))
+ (default name L)))))
+
+(local (in-theory (disable compress2)))
+
+(defthm
+ alist2p-aset2
+ (implies
+ (and (alist2p name L)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name L)))
+ (< j (cadr (dimensions name L))))
+ (alist2p name (aset2 name L i j val))))
+
+(defthm
+ alist2p-aref2-compress2
+ (implies
+ (and (alist2p name L)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name L)))
+ (< j (cadr (dimensions name L))))
+ (equal (aref2 name (compress2 name L) i j)
+ (aref2 name L i j))))
+
+(defthm
+ array2p-acons-properties
+ (and
+ (equal (header name (cons (cons (cons i j) val) L))
+ (header name L))
+ (equal (dimensions name (cons (cons (cons i j) val) L))
+ (dimensions name L))
+ (equal (maximum-length name (cons (cons (cons i j) val) L))
+ (maximum-length name L))
+ (equal (default name (cons (cons (cons i j) val) L))
+ (default name L))))
+
+(defthm
+ alist2p-aset2-properties
+ (implies
+ (and (alist2p name L)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name L)))
+ (< j (cadr (dimensions name L))))
+ (and
+ (equal (header name (aset2 name L i j val))
+ (header name L))
+ (equal (dimensions name (aset2 name L i j val))
+ (dimensions name L))
+ (equal (maximum-length name (aset2 name L i j val))
+ (maximum-length name L))
+ (equal (default name (aset2 name L i j val))
+ (default name L)))))
+
+(defthm
+ alist2p-consp-header
+ (implies
+ (alist2p name L)
+ (consp (header name L)))
+ :rule-classes :type-prescription)
+
+(defthm
+ alist2p-car-header
+ (implies
+ (alist2p name L)
+ (equal (car (header name L))
+ :header)))
+
+; These two theorems for the ALISR2P-AREF2-ASET2 cases are used to prove a
+; combined result, and then exported DISABLEd:
+; NOTE: The combined result below can be proved without first proving the
+; two cases, but we'll keep these results organized as they were.
+
+(defthm
+ alist2p-aref2-aset2-equal
+ (implies
+ (and (alist2p name L)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name L)))
+ (< j (cadr (dimensions name L))))
+ (equal (aref2 name (aset2 name L i j val) i j)
+ val)))
+
+(defthm
+ alist2p-aref2-aset2-not-equal
+ (implies
+ (and (alist2p name L)
+ (integerp i1)
+ (integerp j1)
+ (>= i1 0)
+ (>= j1 0)
+ (< i1 (car (dimensions name L)))
+ (< j1 (cadr (dimensions name L)))
+ (integerp i2)
+ (integerp j2)
+ (>= i2 0)
+ (>= j2 0)
+ (< i2 (car (dimensions name L)))
+ (< j2 (cadr (dimensions name L)))
+ (not (and (equal i1 i2)
+ (equal j1 j2))))
+ (equal (aref2 name (aset2 name L i1 j1 val) i2 j2)
+ (aref2 name L i2 j2))))
+
+(defthm
+ alist2p-aref2-aset2
+ (implies
+ (and (alist2p name L)
+ (integerp i1)
+ (integerp j1)
+ (>= i1 0)
+ (>= j1 0)
+ (< i1 (car (dimensions name L)))
+ (< j1 (cadr (dimensions name L)))
+ (integerp i2)
+ (integerp j2)
+ (>= i2 0)
+ (>= j2 0)
+ (< i2 (car (dimensions name L)))
+ (< j2 (cadr (dimensions name L)))
+ )
+ (equal (aref2 name (aset2 name L i1 j1 val) i2 j2)
+ (if (and (equal i1 i2)
+ (equal j1 j2))
+ val
+ (aref2 name l i2 j2)))))
+
+(in-theory (disable alist2p-aref2-aset2-equal alist2p-aref2-aset2-not-equal))
+
+;;; The final form of the :FORWARD-CHAINING lemma for ALIST2P.
+;;; A forward definition of (ALIST2P name l), in terms of
+;;; HEADER, DIMENSIONS, and MAXIMUM-LENGTH.
+
+;;; One should normaly DISABLE ALIST2P in favor of this
+;;; :FORWARD-CHAINING rule. If allowed to open, ALIST2P can
+;;; cause severe performance degradation due to its large size
+;;; and many recursive functions. This lemma is designed to be
+;;; used with the ALISP2-FUNCTIONS theory DISABLEd.
+
+;; This forward-chaining rule appears to require the ignored argument, name,
+;; in alist2p in order to avoid name as a free variable.
+(defthm alist2p-forward-modular
+ (implies
+ (alist2p name L)
+ (and (alistp L)
+ (keyword-value-listp (cdr (header name L)))
+ (consp (dimensions name L))
+ (consp (cdr (dimensions name L)))
+ (integerp (car (dimensions name L)))
+ (integerp (cadr (dimensions name L)))
+ (< 0 (car (dimensions name L)))
+ (< 0 (cadr (dimensions name L)))
+ (bounded-integer-alistp2 L
+ (car (dimensions name L))
+ (cadr (dimensions name L)))))
+ :rule-classes :forward-chaining)
+
+(defthm alist2p-linear-modular
+ (implies
+ (alist2p name L)
+ (and (< 0 (car (dimensions name L)))
+ (< 0 (cadr (dimensions name L)))))
+ :rule-classes :linear)
+
+(deftheory
+ alist2-functions
+ '(alist2p aset2 aref2 compress2 header dimensions maximum-length
+ default)
+; Matt K. mod 10/30/2015: :doc is no longer supported for deftheory.
+; :doc "A theory of all functions specific to 2-dimensional alists.
+; This theory must be DISABLEd in order for the lemmas
+; exported by the alist2 book to be applicable."
+ )
+
+(deftheory
+ alist2-lemmas
+ '(alist2p-compress2
+ alist2p-compress2-properties
+ alist2p-aset2
+ alist2p-aset2-properties
+ alist2p-aref2-compress2
+ array2p-acons-properties
+ alist2p-consp-header
+ alist2p-car-header
+ alist2p-aref2-aset2
+ alist2p-forward-modular
+ alist2p-linear-modular))
+
+(deftheory
+ alist2-disabled-lemmas
+ '(alist2p-aref2-aset2-equal
+ alist2p-aref2-aset2-not-equal)
+; Matt K. mod 10/30/2015: :doc is no longer supported for deftheory.
+; :doc "A theory of all rules exported DISABLEd by the alist2 book.
+; Note that in order for these rules to be applicable you
+; will first need to (DISABLE ALIST2-FUNCTIONS)."
+ )
+
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/array2.lisp b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/array2.lisp
new file mode 100644
index 0000000..1ba3767
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/array2.lisp
@@ -0,0 +1,615 @@
+; The ACL2 two-dimensional Arrays Book.
+; Copyright (C) 2003 John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+; Summer and Fall 2002.
+; Last modified 19 May 2003
+
+; This book is based on a similar book about one-dimensional arrays
+; Written by: Bishop Brock
+; Computational Logic, Inc.
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+To certify at UW:
+
+:set-cbd "/home/faculty/cowles/acl2/matrix/" ;;pyramid
+
+:set-cbd "/home/cowles/matrix/" ;;turing
+
+(certify-book "array2"
+ 0
+ nil ;;compile-flg
+ )
+|#
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+To use at UW:
+
+:set-cbd "/home/faculty/cowles/acl2/matrix/" ;;pyramid
+
+:set-cbd "/home/cowles/matrix/" ;;turing
+
+(include-book
+ "array2")
+|#
+(in-package "ACL2")
+
+(local
+ (defthm
+ assoc-eq-properties
+ (implies
+ (and (alistp l)
+ (assoc-eq x l))
+ (and (consp (assoc-eq x l))
+ (equal (car (assoc-eq x l)) x)))))
+
+(local
+ (defthm
+ assoc2-properties
+ (implies
+ (and (alistp l)
+ (assoc2 i j l))
+ (and (consp (assoc2 i j l))
+ (consp (car (assoc2 i j l)))
+ (equal (car (car (assoc2 i j l))) i)
+ (equal (cdr (car (assoc2 i j l))) j)))))
+
+(local
+ (defthm
+ assoc-keyword-properties
+ (implies
+ (and (alistp l)
+ (assoc-keyword x l))
+ (and (consp (assoc-keyword x l))
+ (equal (car (assoc-keyword x l)) x)))))
+
+(local
+ (defthm
+ bounded-integer-alistp2-car-assoc2-properties
+ (implies
+ (and (bounded-integer-alistp2 l m n)
+ (assoc2 i j l))
+ (and (integerp (car (car (assoc2 i j l))))
+ (integerp (cdr (car (assoc2 i j l))))
+ (>= (car (car (assoc2 i j l))) 0)
+ (>= (cdr (car (assoc2 i j l))) 0)
+ (< (car (car (assoc2 i j l))) m)
+ (< (cdr (car (assoc2 i j l))) n)))))
+
+(local
+ (defthm array2p-forward-local
+ (implies
+ (array2p name l)
+ (and
+ (symbolp name)
+ (alistp l)
+ (keyword-value-listp (cdr (assoc-eq :header l)))
+ (true-listp
+ (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq :header l)))))
+ (equal
+ (length (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq
+ :header l)))))
+ 2)
+ (integerp
+ (car (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq
+ :header l))))))
+ (integerp
+ (cadr (cadr (assoc-keyword :dimensions
+ (cdr (assoc-eq
+ :header l))))))
+ (integerp
+ (cadr (assoc-keyword :maximum-length
+ (cdr (assoc-eq :header l)))))
+ (< 0
+ (car (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header l))))))
+ (< 0
+ (cadr (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header l))))))
+ (< (* (car (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header l)))))
+ (cadr (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header l))))))
+ (cadr (assoc-keyword
+ :maximum-length
+ (cdr (assoc-eq :header l)))))
+ (<= (cadr (assoc-keyword
+ :maximum-length
+ (cdr (assoc-eq :header l))))
+ *maximum-positive-32-bit-integer*)
+ (bounded-integer-alistp2
+ l
+ (car (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header l)))))
+ (cadr (cadr (assoc-keyword
+ :dimensions
+ (cdr (assoc-eq :header l))))))))
+ :rule-classes :forward-chaining))
+
+(local
+ (defthm array2p-header-exists
+ (implies
+ (array2p name l)
+ (assoc-eq :header l))))
+
+(local
+ (defthm array2p-cons-1
+ (implies
+ (and (array2p name l)
+ (integerp i)
+ (>= i 0)
+ (< i (car (dimensions name l)))
+ (integerp j)
+ (>= j 0)
+ (< j (cadr (dimensions name l))))
+ (array2p name (cons (cons (cons i j) val) l)))))
+
+(local (in-theory (disable array2p)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;(compress211 name L i x j default) processes array elements
+;; L(i x) . . . L(i (- j 1)).
+
+(local
+ (defthm
+ alistp-compress211
+ (alistp (compress211 name l i x j default))))
+
+(local
+ (defthm bounded-integer-alistp2-compress211
+ (implies
+ (and (array2p name l)
+ (integerp i)
+ (integerp x)
+ (integerp k)
+ (>= x 0)
+ (>= i 0)
+ (> k i))
+ (bounded-integer-alistp2 (compress211 name l i x j default)
+ k
+ j))))
+
+(local
+ (defthm
+ compress211-assoc2-property-0
+ (implies (and (alistp l)
+ (assoc2 m n l)
+ (assoc2 m n (compress211 name l i x j default)))
+ (equal (assoc2 m n (compress211 name l i x j default))
+ (assoc2 m n l)))))
+
+(local
+ (defthm
+ compress211-assoc2-property-1
+ (implies
+ (and (not (assoc2 i n (compress211 name l i x j default)))
+ (alistp l)
+ (integerp x)
+ (integerp j)
+ (integerp n)
+ (<= x n)
+ (< n j)
+ (assoc2 i n l))
+ (equal (cdr (assoc2 i n l))
+ default))))
+
+(local
+ (defthm
+ compress211-assoc2-property-2
+ (implies
+ (and (alistp l)
+ (not (assoc2 m n l)))
+ (not (assoc2 m n (compress211 name l i x j default))))))
+
+(local
+ (defthm
+ not-assoc2-compress211
+ (implies (and (alistp l)
+ (not (equal k i)))
+ (not (assoc2 k m (compress211 name L i x j default)))
+ )))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;(compress21 name L n i j default) processes array elements
+;; L(n 0) . . . L(n (- j 1))
+;; . . .
+;; . . .
+;; . . .
+;; L((- i 1) 0) . . . L((- i 1)(- j 1))
+
+(local
+ (defthm
+ alistp-append
+ (implies (and (alistp l1)
+ (alistp l2))
+ (alistp (append l1 l2)))))
+
+(local
+ (defthm
+ alistp-compress21
+ (alistp (compress21 name l n i j default))))
+
+(local
+ (defthm
+ bounded-integer-alistp2-append
+ (implies (and (bounded-integer-alistp2 l1 i j)
+ (bounded-integer-alistp2 l2 i j))
+ (bounded-integer-alistp2 (append l1 l2)
+ i
+ j))))
+
+(local
+ (defthm
+ bounded-integer-alistp2-compress21
+ (implies
+ (and (array2p name l)
+ (integerp i)
+ (integerp n)
+ (>= n 0))
+ (bounded-integer-alistp2 (compress21 name l n i j default)
+ i
+ j))))
+
+(local
+ (defthm
+ assoc2-append
+ (equal (assoc2 i j (append l1 l2))
+ (if (assoc2 i j l1)
+ (assoc2 i j l1)
+ (assoc2 i j l2)))))
+
+(local
+ (defthm
+ compress21-assoc2-property-0
+ (implies
+ (and (alistp l)
+ (assoc2 k m l)
+ (assoc2 k m (compress21 name l n i j default)))
+ (equal (assoc2 k m (compress21 name l n i j default))
+ (assoc2 k m l)))))
+
+(local
+ (defthm
+ compress21-assoc2-property-1
+ (implies
+ (and (not (assoc2 k m (compress21 name l n i j default)))
+ (alistp l)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (integerp m)
+ (integerp n)
+ (<= n i)
+ (<= n k)
+ (< k i)
+ (<= 0 m)
+ (< m j)
+ (assoc2 k m l))
+ (equal (cdr (assoc2 k m l))
+ default))
+ :hints (("Subgoal *1/5"
+ :use (:instance
+ compress211-assoc2-property-1
+ (i k)
+ (n m)
+ (x 1))))))
+
+(local
+ (defthm
+ compress21-assoc2-property-2
+ (implies
+ (and (alistp l)
+ (not (assoc2 k m l)))
+ (not (assoc2 k m (compress21 name l n i j default))))))
+
+(local
+ (defthm
+ compress2-assoc2-property-0
+ (implies
+ (and (alistp l)
+ (assoc2 k m l)
+ (assoc2 k m (compress2 name l)))
+ (equal (cdr (assoc2 k m (compress2 name l)))
+ (cdr (assoc2 k m l))))))
+
+(local
+ (defthm
+ compress2-assoc2-property-1
+ (implies
+ (and (array2p name l)
+ (integerp k)
+ (integerp m)
+ (<= 0 k)
+ (< k (car (dimensions name l)))
+ (<= 0 m)
+ (< m (cadr (dimensions name l)))
+ (assoc2 k m l)
+ (not (assoc2 k m (compress2 name l))))
+ (equal (cdr (assoc2 k m l))
+ (cadr (assoc-keyword :default (cdr (assoc-eq :header l))
+ ))))))
+
+(local
+ (defthm
+ compress2-assoc2-property-2
+ (implies
+ (and (alistp l)
+ (not (assoc2 k m l)))
+ (not (assoc2 k m (compress2 name l))))))
+
+(local
+ (defthm
+ header-compress2
+ (implies
+ (array2p name l)
+ (equal (assoc-eq :header (compress2 name l))
+ (assoc-eq :header l)))))
+
+(defthm
+ array2p-compress2
+ (implies
+ (array2p name l)
+ (array2p name (compress2 name l)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((compress2 name l))))
+ :hints (("Goal"
+ :in-theory (enable array2p))))
+
+(defthm
+ array2p-compress2-properties
+ (implies
+ (array2p name l)
+ (and
+ (equal (header name (compress2 name l))
+ (header name l))
+ (equal (dimensions name (compress2 name l))
+ (dimensions name l))
+ (equal (maximum-length name (compress2 name l))
+ (maximum-length name l))
+ (equal (default name (compress2 name l))
+ (default name l)))))
+
+(local (in-theory (disable compress2)))
+
+(defthm
+ array2p-aset2
+ (implies
+ (and (array2p name l)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l)))
+ (< j (cadr (dimensions name l))))
+ (array2p name (aset2 name l i j val))))
+
+(defthm
+ array2p-aset2-properties
+ (implies
+ (and (array2p name l)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l)))
+ (< j (cadr (dimensions name l))))
+ (and
+ (equal (header name (aset2 name l i j val))
+ (header name l))
+ (equal (dimensions name (aset2 name l i j val))
+ (dimensions name l))
+ (equal (maximum-length name (aset2 name l i j val))
+ (maximum-length name l))
+ (equal (default name (aset2 name l i j val))
+ (default name l)))))
+
+(defthm
+ aref2-compress2
+ (implies
+ (and (array2p name l)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l)))
+ (< j (cadr (dimensions name l))))
+ (equal (aref2 name (compress2 name l) i j)
+ (aref2 name l i j))))
+
+(defthm
+ array2p-acons-properties
+ (and
+ (equal (header name (cons (cons (cons i j) val) l))
+ (header name l))
+ (equal (dimensions name (cons (cons (cons i j) val) l))
+ (dimensions name l))
+ (equal (maximum-length name (cons (cons (cons i j) val) l))
+ (maximum-length name l))
+ (equal (default name (cons (cons (cons i j) val) l))
+ (default name l))))
+
+(defthm
+ array2p-consp-header
+ (implies
+ (array2p name l)
+ (consp (header name l)))
+ :rule-classes :type-prescription)
+
+(defthm
+ array2p-car-header
+ (implies
+ (array2p name l)
+ (equal (car (header name l))
+ :header)))
+
+; These two theorems for the AREF2-ASET2 cases are used to prove a
+; combined result, and then exported DISABLEd:
+
+(defthm
+ aref2-aset2-equal
+ (implies
+ (and (array2p name l)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l)))
+ (< j (cadr (dimensions name l))))
+ (equal (aref2 name (aset2 name l i j val) i j)
+ val)))
+
+(defthm
+ aref2-aset2-not-equal
+ (implies
+ (and (array2p name l)
+ (integerp i1)
+ (integerp j1)
+ (>= i1 0)
+ (>= j1 0)
+ (< i1 (car (dimensions name l)))
+ (< j1 (cadr (dimensions name l)))
+ (integerp i2)
+ (integerp j2)
+ (>= i2 0)
+ (>= j2 0)
+ (< i2 (car (dimensions name l)))
+ (< j2 (cadr (dimensions name l)))
+ (not (and (equal i1 i2)
+ (equal j1 j2))))
+ (equal (aref2 name (aset2 name l i1 j1 val) i2 j2)
+ (aref2 name l i2 j2))))
+
+(defthm
+ aref2-aset2
+ (implies
+ (and (array2p name l)
+ (integerp i1)
+ (integerp j1)
+ (>= i1 0)
+ (>= j1 0)
+ (< i1 (car (dimensions name l)))
+ (< j1 (cadr (dimensions name l)))
+ (integerp i2)
+ (integerp j2)
+ (>= i2 0)
+ (>= j2 0)
+ (< i2 (car (dimensions name l)))
+ (< j2 (cadr (dimensions name l)))
+ )
+ (equal (aref2 name (aset2 name l i1 j1 val) i2 j2)
+ (if (and (equal i1 i2)
+ (equal j1 j2))
+ val
+ (aref2 name l i2 j2)))))
+
+(in-theory (disable aref2-aset2-equal aref2-aset2-not-equal))
+
+;;; The final form of the :FORWARD-CHAINING lemma for ARRAY2P.
+;;; A forward definition of (ARRAY2P name l), in terms of
+;;; HEADER, DIMENSIONS, and MAXIMUM-LENGTH.
+;;; Note that ACL2 also defines a lemma ARRAY2P-FORWARD, but
+;;; that lemma is in terms of the expansions of HEADER,
+;;; DIMENSIONS, and MAXIMUM-LENGTH.
+
+;;; One should normaly DISABLE ARRAY2P in favor of this
+;;; :FORWARD-CHAINING rule. If allowed to open, ARRAY2P can
+;;; cause severe performance degradation due to its large size
+;;; and many recursive functions. This lemma is designed to be
+;;; used with the ARRAY2-FUNCTIONS theory DISABLEd.
+
+(defthm array2p-forward-modular
+ (implies
+ (array2p name l)
+ (and (symbolp name)
+ (alistp l)
+ (keyword-value-listp (cdr (header name l)))
+ (true-listp (dimensions name l))
+ (equal (length (dimensions name l)) 2)
+ (integerp (car (dimensions name l)))
+ (integerp (cadr (dimensions name l)))
+ (integerp (maximum-length name l))
+ (< 0 (car (dimensions name l)))
+ (< 0 (cadr (dimensions name l)))
+ (< (* (car (dimensions name l))
+ (cadr (dimensions name l)))
+ (maximum-length name l))
+ (<= (maximum-length name l)
+ *maximum-positive-32-bit-integer*)
+ (bounded-integer-alistp2 l
+ (car (dimensions name l))
+ (cadr (dimensions name l)))))
+ :rule-classes :forward-chaining)
+
+(defthm array2p-linear-modular
+ (implies
+ (array2p name l)
+ (and (< 0 (car (dimensions name l)))
+ (< 0 (cadr (dimensions name l)))
+ (< (* (car (dimensions name l))
+ (cadr (dimensions name l)))
+ (maximum-length name l))
+ (<= (maximum-length name l)
+ *maximum-positive-32-bit-integer*)))
+ :rule-classes :linear)
+
+(deftheory
+ array2-functions
+ '(array2p aset2 aref2 compress2 header dimensions maximum-length
+ default)
+; Matt K. mod 10/30/2015: :doc is no longer supported for deftheory.
+; :doc "A theory of all functions specific to 2-dimensional arrays.
+; This theory must be DISABLEd in order for the lemmas
+; exported by the array2 book to be applicable."
+ )
+
+(deftheory
+ array2-lemmas
+ '(array2p-compress2
+ array2p-compress2-properties
+ array2p-aset2
+ array2p-aset2-properties
+ aref2-compress2
+ array2p-acons-properties
+ array2p-consp-header
+ array2p-car-header
+ aref2-aset2
+ array2p-forward-modular
+ array2p-linear-modular))
+
+(deftheory
+ array2-disabled-lemmas
+ '(aref2-aset2-equal
+ aref2-aset2-not-equal)
+; Matt K. mod 10/30/2015: :doc is no longer supported for deftheory.
+; :doc "A theory of all rules exported DISABLEd by the array2 book.
+; Note that in order for these rules to be applicable you
+; will first need to (DISABLE ARRAY2-FUNCTIONS)."
+ )
+
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matalg.lisp b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matalg.lisp
new file mode 100644
index 0000000..9f4f37e
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matalg.lisp
@@ -0,0 +1,2705 @@
+; The ACL2 Matrix Algebra Book. Summary of definitions and algebra in matrix.lisp.
+; Copyright (C) 2002 Ruben Gamboa and John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; Ruben Gamboa and John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+; Summer and Fall 2002.
+; Last modified 17 June 2003.
+
+; ACL2 Version 2.8 alpha (as of May 11 03)
+#|
+ To certify in
+ ACL2 Version 2.8 alpha (as of May 11 03)
+
+(certify-book "matalg"
+ 0
+ t ;;compile-flg
+ )
+|#
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+At UW:
+
+:set-cbd "/home/faculty/cowles/acl2/matrix/" ;;pyramid
+
+:set-cbd "/home/cowles/matrix/" ;; turing
+|#
+
+(in-package "ACL2")
+
+(include-book "alist2")
+
+(local (include-book "matrix"))
+
+(defthm array2p-forward-modular
+ (implies
+ (array2p name l)
+ (and (symbolp name)
+ (alistp l)
+ (keyword-value-listp (cdr (header name l)))
+ (true-listp (dimensions name l))
+ (equal (length (dimensions name l)) 2)
+ (integerp (car (dimensions name l)))
+ (integerp (cadr (dimensions name l)))
+ (integerp (maximum-length name l))
+ (< 0 (car (dimensions name l)))
+ (< 0 (cadr (dimensions name l)))
+ (< (* (car (dimensions name l))
+ (cadr (dimensions name l)))
+ (maximum-length name l))
+ (<= (maximum-length name l)
+ *maximum-positive-32-bit-integer*)
+ (bounded-integer-alistp2 l
+ (car (dimensions name l))
+ (cadr (dimensions name l)))))
+ :rule-classes :forward-chaining)
+
+(defthm array2p-linear-modular
+ (implies
+ (array2p name l)
+ (and (< 0 (car (dimensions name l)))
+ (< 0 (cadr (dimensions name l)))
+ (< (* (car (dimensions name l))
+ (cadr (dimensions name l)))
+ (maximum-length name l))
+ (<= (maximum-length name l)
+ *maximum-positive-32-bit-integer*)))
+ :rule-classes :linear)
+
+(defthm
+ alist2p-$arg
+ (implies (alist2p name l)
+ (alist2p '$arg l))
+ :rule-classes :forward-chaining)
+
+(defthm
+ array2p-$arg
+ (implies (array2p name l)
+ (array2p '$arg l))
+ :rule-classes :forward-chaining)
+
+
+(defthm
+ not-alist2p-arg$
+ (implies (not (alist2p name l))
+ (not (alist2p '$arg l)))
+ :rule-classes :forward-chaining)
+
+(defthm
+ not-array2p-arg$
+ (implies (and (not (array2p name l))
+ (symbolp name))
+ (not (array2p '$arg l)))
+ :rule-classes :forward-chaining)
+
+(in-theory (disable alist2p array2p aset2 aref2 compress2 header
+ dimensions maximum-length default))
+
+(defthm
+ sqrt-*-sqrt-<-sq
+ (implies (and (rationalp x)
+ (rationalp y)
+ (>= x 0)
+ (>= y 0)
+ (<= x 46340)
+ (<= y 46340))
+ (< (* x y) 2147483647))
+ :rule-classes (:rewrite :linear)
+ :hints (("Goal"
+ :use (:instance
+ *-PRESERVES->=-FOR-NONNEGATIVES
+ (x2 x)
+ (y2 y)
+ (x1 46340)
+ (y1 46340)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Boolean test for a matrix:
+
+;; The need for the following constant is explained in
+;; detail later in this book:
+
+;; Search for
+;; ; Ensuring closure of matrix multiplication.
+
+(defconst
+ *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*
+ 46340)
+
+;; To ensure that matrix multiplication is closed, the
+;; matrix can have no more that 46,340 rows and no more
+;; 46,340 columns.
+
+(defun
+ matrixp (m n X)
+ "Determine if X is a m by n matrix."
+ (declare (xargs :guard t))
+ (and (array2p '$arg X)
+ (let ((dims (dimensions '$arg X)))
+ (and (equal m (first dims))
+ (equal n (second dims))))
+ (<= m *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= n *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)))
+
+(defmacro
+ r (M)
+ "Return the number of rows in the matrix M."
+ `(car (dimensions '$arg ,M)))
+
+(defmacro
+ c (M)
+ "Return the number of columns in the matrix M."
+ `(cadr (dimensions '$arg ,M)))
+
+(defthm
+ array2p-matrixp
+ (implies (and (array2p name M)
+ (<= (r M) *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= (c M) *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (matrixp (r M)(c M) M)))
+
+;;;;;;;;;;;;;;;;;;;
+;; Matrix equality:
+
+(defun
+ m-=-row (M1 M2 m n)
+ "Determine if all the following equalities hold:
+ M1(m 0) = M2(m 0), . . . , M1(m n) = M2(m n);
+ ie. determine if the m'th row of M1 matches the
+ m'th row of M2.
+ All entries are treated as numbers."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (car dims1))
+ (< n (cadr dims1))))
+ (let ((dims2 (dimensions '$arg2 M2)))
+ (and (< m (car dims2))
+ (< n (cadr dims2)))))))
+ (if (zp n)
+ (equal (fix (aref2 '$arg1 M1 m 0))
+ (fix (aref2 '$arg2 M2 m 0)))
+ (and (equal (fix (aref2 '$arg1 M1 m n))
+ (fix (aref2 '$arg2 M2 m n)))
+ (m-=-row M1 M2 m (- n 1)))))
+
+(defun
+ m-=-row-1 (M1 M2 m n)
+ "Determine if all the following equalities hold:
+ M1(0 0) = M2(0 0), . . . , M1(0 n) = M2(0 n)
+ . . .
+ . . .
+ . . .
+ M1(m 0) = M2(m 0), . . . , M1(m n) = M2(m n);
+ ie. determine if rows 0 thru m of M1 matches
+ rows 0 thru m of M2.
+ All entries are treated as numbers."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (car dims1))
+ (< n (cadr dims1))))
+ (let ((dims2 (dimensions '$arg2 M2)))
+ (and (< m (car dims2))
+ (< n (cadr dims2)))))))
+ (if (zp m)
+ (m-=-row M1 M2 0 n)
+ (and (m-=-row M1 M2 m n)
+ (m-=-row-1 M1 M2 (- m 1) n))))
+
+(defun
+ m-= (M1 M2)
+ "Determine if the matrices represented by the alists
+ M1 and M2 are equal (as matrices of numbers)."
+ (declare (xargs :guard (and (array2p '$arg1 M1)
+ (array2p '$arg2 M2))))
+ (if (mbt (and (alist2p '$arg1 M1)
+ (alist2p '$arg2 M2)))
+ (let ((dim1 (dimensions '$arg1 M1))
+ (dim2 (dimensions '$arg2 M2)))
+ (if (and (= (first dim1)
+ (first dim2))
+ (= (second dim1)
+ (second dim2)))
+ (m-=-row-1 (compress2 '$arg1 M1)
+ (compress2 '$arg2 M2)
+ (- (first dim1) 1)
+ (- (second dim1) 1))
+ nil))
+ (equal M1 M2)))
+
+(defequiv
+ ;; m-=-is-an-equivalence
+ m-=)
+
+(defcong
+ ;; m-=-implies-equal-alist2p-2
+ m-= equal (alist2p name M) 2
+ :hints (("Goal"
+ :use (:theorem
+ (implies (m-= M M-equiv)
+ (iff (alist2p name M)
+ (alist2p name M-equiv)
+ ))))))
+
+;;;;;;;;;;;;;;;
+;; Zero matrix:
+
+(defun
+ m-0 (m n)
+ "Return an alist representing the m by n matrix whose
+ elements are all equal to 0.
+ To use the ACL2 efficient array mechanism to store (m-0 m n),
+ (* m n)) must be stictly less than 2147483647 which is
+ the *MAXIMUM-POSITIVE-32-BIT-INTEGER*."
+ (declare (xargs :guard (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))))
+ (list (list :HEADER
+ :DIMENSIONS (list m n)
+ :MAXIMUM-LENGTH (+ 1 (* m n))
+ :DEFAULT 0
+ :NAME 'zero-matrix)))
+
+(defthm
+ alist2p-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))
+ (alist2p name (m-0 m n)))
+ :hints (("Goal" :in-theory (enable alist2p))))
+
+(defthm
+ array2p-m-0
+ (implies (and (symbolp name)
+ (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0)
+ (< (* m n) *MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-0 m n)))
+ :hints (("Goal" :in-theory (enable array2p))))
+
+(defthm
+ matrixp-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0)
+ (<= m *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= n *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (matrixp m n (m-0 m n)))
+ :hints (("Goal" :in-theory (enable array2p
+ dimensions
+ header))))
+
+(defthm
+ aref2-m-0
+ (equal (aref2 name (m-0 m n) i j) 0)
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ dimensions-m-0
+ (equal (dimensions name (m-0 m n))(list m n))
+ :hints (("Goal"
+ :in-theory (enable header dimensions))))
+
+(defthm
+ default-m-0
+ (equal (default name (m-0 m n))
+ 0)
+ :hints (("Goal"
+ :in-theory (enable header default))))
+
+(defthm
+ alist2p-alist2p-m-0
+ (implies (alist2p name1 M)
+ (alist2p name2 (m-0 (car (dimensions
+ '$arg M))
+ (cadr (dimensions
+ '$arg M))))))
+
+(defthm
+ array2p-array2p-m-0
+ (implies (and (array2p name1 M)
+ (symbolp name2))
+ (array2p name2 (m-0 (car (dimensions
+ '$arg M))
+ (cadr (dimensions
+ '$arg M))))))
+
+;;;;;;;;;;;;;;;;;;;
+;; Identity matrix:
+
+(defun
+ m-1a (n)
+ "Return alist of length n of the form
+ ( ((- n 1) . (- n 1)) . 1) . . . ((0 . 0) . 1) )."
+ (declare (xargs :guard (and (integerp n)
+ (>= n 0))
+ :verify-guards nil))
+ (if (zp n)
+ nil
+ (acons (cons (- n 1)(- n 1)) 1 (m-1a (- n 1)))))
+
+(verify-guards m-1a)
+
+(defun
+ m-1 (n)
+ "Return an alist representing the n by n identity matrix.
+ To use the ACL2 efficient array mechanism to store (m-1 n),
+ (* n n)) must be stictly less than 2147483647 which is
+ the *MAXIMUM-POSITIVE-32-BIT-INTEGER*."
+ (declare (xargs :guard (and (integerp n)
+ (>= n 0))))
+ (cons (list :HEADER
+ :DIMENSIONS (list n n)
+ :MAXIMUM-LENGTH (+ 1 (* n n))
+ :DEFAULT 0
+ :NAME 'identity-matrix)
+ (m-1a n)))
+
+(defthm
+ alist2p-m-1
+ (implies (and (integerp n)
+ (> n 0))
+ (alist2p name (m-1 n)))
+ :hints (("Goal"
+ :in-theory (enable alist2p))))
+
+(defthm
+ array2p-m-1
+ (implies (and (symbolp name)
+ (integerp n)
+ (> n 0)
+ (< (* n n) *MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-1 n)))
+ :hints (("Goal"
+ :in-theory (enable array2p))))
+
+(defthm
+ matrixp-m-1
+ (implies (and (integerp n)
+ (> n 0)
+ (<= n *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (matrixp n n (m-1 n)))
+ :hints (("Goal"
+ :in-theory (enable array2p dimensions header))))
+
+(defthm
+ aref2-m-1-i-i
+ (implies (and (integerp i)
+ (integerp n)
+ (<= 0 i)
+ (< i n))
+ (equal (aref2 name (m-1 n) i i) 1))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ aref2-m-1-i-j
+ (implies (not (equal i j))
+ (equal (aref2 name (m-1 n) i j) 0))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ dimensions-m-1
+ (equal (dimensions name (m-1 n))(list n n))
+ :hints (("Goal"
+ :in-theory (enable header dimensions))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Transpose of a matrix:
+
+(defun
+ m-trans-a (M)
+ (declare (xargs :guard (alistp M)))
+ (if (consp M)
+ (let ((key (caar M))
+ (datum (cdar M)))
+ (if (consp key)
+ (acons (cons (cdr key)
+ (car key))
+ datum
+ (m-trans-a (cdr M)))
+ (m-trans-a (cdr M))))
+ nil))
+
+(defun
+ m-trans (M)
+ "Return an alist representing the transpose of the matrix
+ represented by the alist M."
+ (declare (xargs :guard (array2p '$arg M)))
+ (cons (list :HEADER
+ :DIMENSIONS (let ((dims (dimensions '$arg M)))
+ (list (cadr dims)(car dims)))
+ :MAXIMUM-LENGTH (maximum-length '$arg M)
+ :DEFAULT (default '$arg M)
+ :NAME 'transpose-matrix)
+ (m-trans-a M)))
+
+(defthm
+ alist2p-m-trans
+ (implies (alist2p name M)
+ (alist2p name (m-trans M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-trans M))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-m-trans
+ (implies (array2p name M)
+ (array2p name (m-trans M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-trans M))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-m-trans
+ (equal (dimensions name (m-trans M))
+ (list (cadr (dimensions name M))
+ (car (dimensions name M))))
+ :hints (("Goal"
+ :in-theory (enable dimensions header))))
+
+(defthm
+ aref2-m-trans
+ (equal (aref2 name (m-trans M) i j)
+ (aref2 name M j i))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ matrixp-m-trans
+ (implies (matrixp m n X)
+ (matrixp n m (m-trans X))))
+
+(defthm
+ idempotency-of-m-trans-alist2p
+ (implies (alist2p name M)
+ (m-= (m-trans (m-trans M)) M)))
+
+(defthm
+ idempotency-of-m-trans-array2p
+ (implies (array2p name M)
+ (m-= (m-trans (m-trans M)) M))
+ :hints (("Goal'"
+ :use (:theorem
+ (implies (array2p '$arg1 M)
+ (alist2p '$arg1
+ (m-trans
+ (m-trans M))))))))
+
+(defcong
+ ;; M-=-IMPLIES-M-=-M-TRANS-1
+ m-= m-= (m-trans M) 1)
+
+(defthm
+ m-=-m-trans-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))
+ (m-= (m-trans (m-0 m n))
+ (m-0 n m))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Unary minus of a matrix:
+
+(defun
+ m-unary--a (M)
+ (declare (xargs :guard (alistp M)))
+ (if (consp M)
+ (let ((key (caar M))
+ (datum (cdar M)))
+ (if (consp key)
+ (acons key
+ (- (fix datum))
+ (m-unary--a (cdr M)))
+ (m-unary--a (cdr M))))
+ nil))
+
+(defun
+ m-unary-- (M)
+ "Return an alist representing the unary minus of the matrix
+ represented by the alist M."
+ (declare (xargs :guard (array2p '$arg M)))
+ (cons (list :HEADER
+ :DIMENSIONS (dimensions '$arg M)
+ :MAXIMUM-LENGTH (maximum-length '$arg M)
+ :DEFAULT (- (fix (default '$arg M)))
+ :NAME 'unary-minus-matrix)
+ (m-unary--a M)))
+
+(defthm
+ alist2p-m-unary--
+ (implies (alist2p name M)
+ (alist2p name (m-unary-- M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-unary-- M))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-m-unary--
+ (implies (array2p name M)
+ (array2p name (m-unary-- M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-unary-- M))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-m-unary--
+ (equal (dimensions name (m-unary-- M))
+ (dimensions name M))
+ :hints (("Goal"
+ :in-theory (enable array2p dimensions header))))
+
+(defthm
+ aref2-m-unary--
+ (equal (aref2 name (m-unary-- M) i j)
+ (- (aref2 name M i j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ matrixp-m-unary--
+ (implies (matrixp m n X)
+ (matrixp m n (m-unary-- X))))
+
+(defthm
+ idempotency-of-m-unary--_alist2p
+ (implies (alist2p name M)
+ (m-= (m-unary-- (m-unary-- M)) M)))
+
+(defthm
+ idempotency-of-m-unary--_array2p
+ (implies (array2p name M)
+ (m-= (m-unary-- (m-unary-- M)) M)))
+
+(defcong
+ ;; M-=-IMPLIES-M-=-M-UNARY---1
+ m-= m-= (m-unary-- M) 1)
+
+(defthm
+ m-=-m-trans-m-unary--
+ (implies (alist2p name M)
+ (m-= (m-trans (m-unary-- M))
+ (m-unary-- (m-trans M)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Scalar multiplication of a matrix:
+
+(defun
+ s-*-a (a M)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (alistp M))))
+ (if (consp M)
+ (let ((key (caar M))
+ (datum (cdar M)))
+ (if (consp key)
+ (acons key
+ (* a (fix datum))
+ (s-*-a a (cdr M)))
+ (s-*-a a (cdr M))))
+ nil))
+
+(defun
+ s-* (a M)
+ "Return an alist representing the multiplication
+ of the scalar a times the matrix represented by
+ the alist M."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p '$arg M))))
+ (cons (list :HEADER
+ :DIMENSIONS (dimensions '$arg M)
+ :MAXIMUM-LENGTH (maximum-length '$arg M)
+ :DEFAULT (* a (fix (default '$arg M)))
+ :NAME 'scalar-mult-matrix)
+ (s-*-a a M)))
+
+(defthm
+ alist2p-s-*
+ (implies (alist2p name M)
+ (alist2p name (s-* a M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((s-* a M))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-s-*
+ (implies (array2p name M)
+ (array2p name (s-* a M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((s-* a M))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-s-*
+ (equal (dimensions name (s-* a M))
+ (dimensions name M))
+ :hints (("Goal"
+ :in-theory (enable array2p dimensions header))))
+
+(defthm
+ aref2-s-*
+ (equal (aref2 name (s-* a M) i j)
+ (* a (aref2 name M i j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ matrixp-s-*
+ (implies (matrixp m n X)
+ (matrixp m n (s-* a X))))
+
+(defcong
+ ;; M-=-IMPLIES-M-=-S-*-2
+ m-= m-= (s-* a M) 2)
+
+(defthm
+ associate-scalars-left-s-*
+ (implies (alist2p name M)
+ (m-= (s-* a1 (s-* a2 M))
+ (s-* (* a1 a2) M))))
+
+(defthm
+ m-=-s-*-0
+ (implies (alist2p name M)
+ (m-= (s-* 0 M)(m-0 (r M)(c M)))))
+
+(defthm
+ m-=-s-*-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))
+ (m-= (s-* a (m-0 m n))(m-0 m n))))
+
+(defthm
+ m-=-s-*-1
+ (implies (alist2p name M)
+ (m-= (s-* 1 M) M)))
+
+(defthm
+ m-=-s-*_-1
+ (implies (alist2p name M)
+ (m-= (s-* -1 M)(m-unary-- M))))
+
+(defthm
+ m-=-m-trans-s-*
+ (implies (alist2p name M)
+ (m-= (m-trans (s-* s M))
+ (s-* s (m-trans M)))))
+
+;;;;;;;;;;;;;;
+;; Matrix sum:
+
+(defun
+ m-binary-+-row (M1 M2 m n)
+ "Return an alist with the following values:
+ M1(m 0)+M2(m 0), . . . , M1(m n)+M2(m n);
+ ie. construct an alist of values representing
+ the vector sum of the m'th row of M1 and the
+ m'th row of M2."
+ (declare (xargs :guard
+ (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions
+ '$arg1 M1)))
+ (and (< m (first dims1))
+ (< n (second dims1))))
+ (let ((dims2 (dimensions
+ '$arg2 M2)))
+ (and (< m (first dims2))
+ (< n (second dims2))))
+ )))
+ (if (zp n)
+ (list (cons (cons m 0)
+ (+ (fix (aref2 '$arg1 M1 m 0))
+ (fix (aref2 '$arg2 M2 m 0)))))
+ (cons (cons (cons m n)
+ (+ (fix (aref2 '$arg1 M1 m n))
+ (fix (aref2 '$arg2 M2 m n))))
+ (m-binary-+-row M1 M2 m (- n 1)))))
+
+(defun
+ m-binary-+-row-1 (M1 M2 m n)
+ "Return an alist with all the following values:
+ M1(0 0)+M2(0 0), . . . , M1(0 n)+M2(0 n)
+ . . .
+ . . .
+ . . .
+ M1(m 0)+M2(m 0), . . . , M1(m n)+M2(m n);
+ ie. construct an alist of values representing
+ the vector sum of rows 0 thru m of M1 with
+ the corresponding rows 0 thru m of M2."
+ (declare (xargs :guard
+ (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions
+ '$arg1 M1)))
+ (and (< m (first dims1))
+ (< n (second dims1))))
+ (let ((dims2 (dimensions
+ '$arg2 M2)))
+ (and (< m (first dims2))
+ (< n (second dims2))))
+ )))
+ (if (zp m)
+ (m-binary-+-row M1 M2 0 n)
+ (append (m-binary-+-row M1 M2 m n)
+ (m-binary-+-row-1 M1 M2 (- m 1) n))))
+
+(defun
+ m-binary-+ (M1 M2)
+ "Return an alist representing the matrix sum
+ of the matrices represented by the alists M1
+ and M2. This is done by adding a header to an
+ alist containing the appropriate values."
+ (declare (xargs :guard
+ (and (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dim1 (dimensions '$arg1
+ M1))
+ (dim2 (dimensions '$arg2
+ M2)))
+ (and
+ (= (first dim1)
+ (first dim2))
+ (= (second dim1)
+ (second dim2)))))
+ ))
+ (let* ((dim1 (dimensions '$arg1 M1))
+ (dim2 (dimensions '$arg2 M2))
+ (dim11 (first dim1))
+ (dim12 (second dim1))
+ (dim21 (first dim2))
+ (dim22 (second dim2)))
+ (if (mbt (and (alist2p '$arg1 M1)
+ (alist2p '$arg2 M2)
+ (= dim11 dim21)
+ (= dim12 dim22)))
+ (cons (list :HEADER
+ :DIMENSIONS (list dim11 dim12)
+ :MAXIMUM-LENGTH
+ (+ 1 (* dim11 dim12))
+ :DEFAULT 0
+ :NAME 'matrix-sum)
+ (m-binary-+-row-1 (compress2 '$arg1 M1)
+ (compress2 '$arg2 M2)
+ (- dim11 1)
+ (- dim12 1)))
+ (+ M1 M2))))
+
+(defmacro
+ m-+ (&rest rst)
+ (if rst
+ (if (cdr rst)
+ (xxxjoin 'm-binary-+ rst)
+ (car rst))
+ 0))
+
+(add-binop m-+ m-binary-+)
+
+(defthm
+ alist2p-m-+
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (alist2p name (m-+ M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-+ M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-m-+
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (array2p name (m-+ M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-+ M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ array2p-m-+-1
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (array2p name (m-+ M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-+ M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+
+ equal-list-dimensions-array2p)
+ :use ((:instance
+ equal-list-dimensions-array2p
+ (M M1))
+ (:instance
+ equal-list-dimensions-array2p
+ (M M2))))))
+
+(defthm
+ dimensions-m-+-alist2p
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (equal (dimensions name (m-+ M1 M2))
+ (list (car (dimensions name M1))
+ (cadr (dimensions name M1)))))
+ :hints (("Goal"
+ :in-theory (enable alist2p dimensions
+ header))))
+
+(defthm
+ dimensions-m-+-array2p
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (equal (dimensions name (m-+ M1 M2))
+ (dimensions name M1)))
+ :hints (("Goal"
+ :in-theory (disable
+ equal-list-dimensions-array2p
+ dimensions-m-+-alist2p)
+ :use ((:instance
+ equal-list-dimensions-array2p
+ (M M1))
+ dimensions-m-+-alist2p))))
+
+(defthm
+ matrixp-m-+
+ (implies (and (matrixp m n X1)
+ (matrixp m n X2))
+ (matrixp m n (m-+ X1 X2)))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ default-m-+-alist2p
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (equal (default name (m-+ M1 M2)) 0))
+ :hints (("Goal"
+ :in-theory (enable alist2p default
+ header))))
+
+(defthm
+ default-m-+-array2p
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (equal (default name (m-+ M1 M2)) 0))
+ :hints (("Goal"
+ :in-theory (enable array2p default header))))
+
+(defthm
+ maximum-length-m-+
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (equal (maximum-length name (m-+ M1 M2))
+ (+ 1 (* (car (dimensions name M1))
+ (cadr (dimensions name M1))))))
+ :hints (("Goal"
+ :in-theory (enable array2p maximum-length header))))
+
+(defthm
+ aref2-m-+
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2)))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name M1)))
+ (< j (cadr (dimensions name M1))))
+ (equal (aref2 name (m-+ M1 M2) i j)
+ (+ (aref2 name M1 i j)
+ (aref2 name M2 i j))))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-+-1
+ m-= equal (M-+ M1 M2) 1)
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-+-2
+ m-= equal (M-+ M1 M2) 2)
+
+(defthm
+ commutativity-of-m-+
+ (equal (m-+ M1 M2)
+ (m-+ M2 M1)))
+
+(defthm
+ associativity-of-m-+
+ (equal (m-+ (m-+ M1 M2) M3)
+ (m-+ M1 M2 M3))
+ :hints (("Goal"
+ :in-theory (disable commutativity-of-m-+))))
+
+(local
+ (defthm
+ commutativity-2-of-m-+-lemma
+ (equal (m-+ (m-+ X Y) Z)
+ (m-+ (m-+ Y X) Z))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable associativity-of-m-+)))))
+
+(defthm
+ commutativity-2-of-m-+
+ (equal (m-+ X Y Z)
+ (m-+ Y X Z))
+ :hints (("Goal"
+ :use commutativity-2-of-m-+-lemma)))
+
+(defthm
+ right-m-+-unicity-of-m-0
+ (implies (alist2p name M)
+ (m-= (m-+ M (m-0 (car (dimensions name M))
+ (cadr (dimensions name M))))
+ M)))
+
+(defthm
+ left-m-+-unicity-of-m-0
+ (implies (alist2p name M)
+ (m-= (m-+ (m-0 (car (dimensions name M))
+ (cadr (dimensions name M)))
+ M)
+ M)))
+
+(defmacro
+ m-- (x &optional (y 'nil binary-casep))
+ (if binary-casep
+ `(m-binary-+ ,x (m-unary-- ,y))
+ `(m-unary-- ,x)))
+
+(add-macro-alias m-- m-unary--)
+
+(add-invisible-fns m-binary-+ m-unary--)
+(add-invisible-fns m-unary-- m-unary--)
+
+(defthm
+ left-m-+-inverse-of-m--
+ (implies (alist2p name M)
+ (m-= (m-+ (m-- M) M)
+ (m-0 (car (dimensions name M))
+ (cadr (dimensions name M))))))
+
+(defthm
+ right-m-+-inverse-of-m--
+ (implies (alist2p name M)
+ (m-= (m-+ M (m-- M))
+ (m-0 (car (dimensions name M))
+ (cadr (dimensions name M))))))
+
+(local
+ (defthm
+ right-m-+-inverse-of-m--_2-lemma
+ (implies (and (alist2p name X)
+ (alist2p name Y)
+ (equal (r X)(r Y))
+ (equal (c X)(c Y)))
+ (m-= (m-+ (m-+ X (m-- X)) Y)
+ Y))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable m-binary-+ m-=
+ associativity-of-m-+)
+ :use (:instance
+ right-m-+-unicity-of-m-0
+ (M Y))))))
+
+(defthm
+ right-m-+-inverse-of-m--_2
+ (implies (and (alist2p name X)
+ (alist2p name Y)
+ (equal (r X)(r Y))
+ (equal (c X)(c Y)))
+ (m-= (m-+ X (m-- X) Y)
+ Y))
+ :hints (("Goal"
+ :use right-m-+-inverse-of-m--_2-lemma)))
+
+(local
+ (defthm
+ left-m-+-inverse-of-m--_2-lemma
+ (implies (and (alist2p name X)
+ (alist2p name Y)
+ (equal (r X)(r Y))
+ (equal (c X)(c Y)))
+ (m-= (m-+ (m-+ (m-- X) X) Y)
+ Y))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable m-binary-+ m-=
+ associativity-of-m-+)
+ :use (:instance
+ right-m-+-unicity-of-m-0
+ (M Y))))))
+
+(defthm
+ left-m-+-inverse-of-m--_2
+ (implies (and (alist2p name X)
+ (alist2p name Y)
+ (equal (r X)(r Y))
+ (equal (c X)(c Y)))
+ (m-= (m-+ (m-- X) X Y)
+ Y))
+ :hints (("Goal"
+ :use left-m-+-inverse-of-m--_2-lemma)))
+
+(defthm
+ uniqueness-of-m-+-inverse
+ (implies (and (alist2p name X)
+ (alist2p name Y)
+ (equal (r X)(r Y))
+ (equal (c X)(c Y))
+ (m-= (m-+ X Y)
+ (m-0 (r X)(c X))))
+ (m-= X (m-- Y)))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable m-binary-+ m-=)
+ :use ((:instance
+ right-m-+-unicity-of-m-0
+ (M X))
+ (:instance
+ right-m-+-unicity-of-m-0
+ (M (m-- Y)))))))
+
+(defthm
+ distributivity-of-s-*-over-+
+ (implies (alist2p name M)
+ (m-= (s-* (+ a b) M)
+ (m-+ (s-* a M)(s-* b m))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+
+ alist2p-m-+)
+ :use ((:instance
+ alist2p-m-+
+ (M1 (s-* a M))
+ (M2 (s-* b M)))))))
+
+(defthm
+ distributivity-of-s-*-over-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (s-* a (m-+ M1 M2))
+ (m-+ (s-* a M1)(s-* a M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+
+ alist2p-s-*)
+ :use ((:instance
+ alist2p-s-*
+ (M (m-binary-+ M1 M2)))
+ (:instance
+ alist2p-s-*
+ (M M1))
+ (:instance
+ alist2p-s-*
+ (M M2))
+ (:instance
+ alist2p-m-+
+ (M1 (s-* a M1))
+ (M2 (s-* a M2)))))))
+
+(defthm
+ double-m-+-s-*
+ (implies (alist2p name M)
+ (m-= (m-+ M M)
+ (s-* 2 M)))
+ :hints (("Goal"
+ :use (:instance
+ distributivity-of-s-*-over-+
+ (a 1)
+ (b 1)))))
+
+(defthm
+ m-trans-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (m-trans (m-+ M1 M2))
+ (m-+ (m-trans M1)(m-trans M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-+
+ alist2p-m-trans)
+ :use (:instance
+ alist2p-m-trans
+ (name '$arg)
+ (M (m-+ M1 M2))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-+
+ alist2p-m-+)
+ :use (:instance
+ alist2p-m-+
+ (name '$arg)
+ (M1 (m-trans M1))
+ (M2 (m-trans M2))))))
+
+;;;;;;;;;;;;;;;;;;
+;; Matrix product:
+
+(defun
+ dot (M1 M2 i j k)
+ "Return the dot product
+ (M1 i 0)*(M2 0 k) + . . . + (M1 i j)*(M2 j k)."
+ (declare (xargs :guard (and (integerp i)
+ (>= i 0)
+ (integerp j)
+ (>= j 0)
+ (integerp k)
+ (>= k 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< i (first dims1))
+ (< j (second dims1))))
+ (let ((dims2 (dimensions '$arg1 M2)))
+ (and (< j (first dims2))
+ (< k (second dims2)))))))
+ (if (zp j)
+ (* (fix (aref2 '$arg1 M1 i 0))
+ (fix (aref2 '$arg2 M2 0 k)))
+ (+ (* (fix (aref2 '$arg1 M1 i j))
+ (fix (aref2 '$arg2 M2 j k)))
+ (dot M1 M2 i (- j 1) k))))
+
+(defun
+ m-binary-*-row (M1 M2 m j n)
+ "Return an alist with the following values:
+ (dot M1 M2 m j 0), . . . , (dot M1 M2 m j n);
+ ie. construct an alist of values representing
+ the vector of dot products of the m'th row of M1
+ with columns 0 thru n of M2."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp j)
+ (>= j 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (first dims1))
+ (< j (second dims1))))
+ (let ((dims2 (dimensions '$arg1 M2)))
+ (and (< j (first dims2))
+ (< n (second dims2)))))))
+ (if (zp n)
+ (list (cons (cons m 0)
+ (dot M1 M2 m j 0)))
+ (cons (cons (cons m n)
+ (dot M1 M2 m j n))
+ (m-binary-*-row M1 M2 m j (- n 1)))))
+
+(defun
+ m-binary-*-row-1 (M1 M2 m j n)
+ "Return an alist with all the following values:
+ (dot M1 M2 0 j 0), . . . , (dot M1 M2 0 j n)
+ . . .
+ . . .
+ . . .
+ (dot M1 M2 m j 0), . . . , (dot M1 M2 m j n)."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp j)
+ (>= j 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (first dims1))
+ (< j (second dims1))))
+ (let ((dims2 (dimensions '$arg1 M2)))
+ (and (< j (first dims2))
+ (< n (second dims2)))))))
+ (if (zp m)
+ (m-binary-*-row M1 M2 0 j n)
+ (append (m-binary-*-row M1 M2 m j n)
+ (m-binary-*-row-1 M1 M2 (- m 1) j n))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Ensuring closure of matrix multiplication.
+
+; Let dim1 be the number of rows and dim2 be the number of columns
+; in an ACL2 two dimensional array. The product, dim1*dim2, is
+; required to fit into 32 bits so that some compilers can lay down
+; faster code. Thus, dim1*dim2 <= maximum-positive-32-bit-integer
+; = 2^31 - 1
+; = 2,147,483,647.
+
+; This restriction on the size of dim1*dim2 means that matrices
+; representable by ACL2 arrays are NOT closed under matrix
+; multiplication, even when the product is mathematically defined.
+; To illustrate, suppose dim1*dim2 is required to be no larger than
+; 20; M1 is a matrix with 5 rows and 2 columns; and M2 is a matrix
+; with 2 rows and 5 columns. Then M1 and M2 would both be
+; representable and their product, M1 * M2, would be mathematically
+; defined, but not representable (since 25 > 20).
+
+; Furthermore, when there are more than two matrices involved in a
+; matrix multiplication, the final product may be both mathematically
+; defined and representable by an ACL2 array, but yet not
+; computable in ACL2. Let's illustrate by extending the example given
+; above with M1 and M2. Suppose M0 is a matrix with 2 rows and 5
+; colums. Then the product (M0 * M1) * M2 is mathematically defined,
+; representable in ACL2, and computable in ACL2 (since both partial
+; products (M0 * M1) and (M0 * M1) * M2 are representable in ACL2).
+; But the product M0 * (M1 * M2) is mathematically defined,
+; representable in ACL2, but NOT computable in ACL2 (since the
+; partial product (M1 * M2) is NOT representable in ACL2).
+
+; One way to prevent this last problem and also ensure closure for
+; matrix multiplication is to require that each of dim1 and dim2
+; be less than or equal to 46,340 which is the integer square root
+; of 2,147,483,647, the maximum-positive-32-bit-integer. Then
+; the product of dim1*dim2 is guarenteed to be less than the
+; the maximum-positive-32-bit-integer. Futhermore, with this stronger
+; restriction, if the product M1 * . . . * Mn is both mathematically
+; defined and representable in ACL2, then, for any way of
+; parenthesizing this product, all the partial products are also
+; mathematically defined and representable in ACL2.
+
+; Thus, for matrix multiplication, it is required that both the
+; number of rows and the number of columns be less than or equal
+; to 46,340.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun m-binary-* (M1 M2)
+ "Return an alist representing the matrix product
+ of the matrices represented by the alists M1
+ and M2. This is done by adding a header to an
+ alist containing the appropriate values."
+ (declare (xargs :guard (and (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (= (second (dimensions '$arg1 M1))
+ (first (dimensions '$arg2 M2))))))
+ (let* ((dim1 (dimensions '$arg1 M1))
+ (dim2 (dimensions '$arg2 M2))
+ (dim11 (first dim1))
+ (dim12 (second dim1))
+ (dim21 (first dim2))
+ (dim22 (second dim2)))
+ (if (mbt (and (alist2p '$arg1 M1)
+ (alist2p '$arg2 M2)
+ (= dim12 dim21)))
+ (cons (list :HEADER
+ :DIMENSIONS
+ (list dim11 dim22)
+ :MAXIMUM-LENGTH
+ (+ 1 (* dim11 dim22))
+ :DEFAULT 0
+ :NAME 'matrix-product)
+ (m-binary-*-row-1 (compress2 '$arg1 M1)
+ (compress2 '$arg2 M2)
+ (- dim11 1)
+ (- dim12 1)
+ (- dim22 1)))
+ (* M1 M2))))
+
+(defmacro
+ m-* (&rest rst)
+ (if rst
+ (if (cdr rst)
+ (xxxjoin 'm-binary-* rst)
+ (car rst))
+ 1))
+
+(add-binop m-* m-binary-*)
+
+(defthm
+ alist2p-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (alist2p name (m-* M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ array2p-m-*-1
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2)))
+ (< (* (first (dimensions name M1))
+ (second (dimensions name M2)))
+ *MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-* M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ array2p-m-*
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2)))
+ (<= (first (dimensions name M1))
+ *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= (second (dimensions name M2))
+ *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-* M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (equal (dimensions name (m-* M1 M2))
+ (list (first (dimensions name M1))
+ (second (dimensions name M2)))))
+ :hints (("Goal"
+ :in-theory (enable alist2p dimensions header))))
+
+(defthm
+ matrixp-m-*
+ (implies (and (matrixp m n X1)
+ (matrixp n p X2))
+ (matrixp m p (m-* X1 X2)))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ default-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (equal (default name (m-* M1 M2))
+ 0))
+ :hints (("Goal"
+ :in-theory (enable alist2p default header))))
+
+(defthm
+ maximum-length-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (equal (maximum-length name (m-* M1 M2))
+ (+ 1 (* (first (dimensions name M1))
+ (second (dimensions name M2))))))
+ :hints (("Goal"
+ :in-theory (enable alist2p maximum-length header))))
+
+(defthm
+ aref2-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2)))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M1)))
+ (< j (second (dimensions name M2))))
+ (equal (aref2 name (m-* M1 M2) i j)
+ (dot M1
+ M2
+ i
+ (+ -1 (second (dimensions name M1)))
+ j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-*-1
+ m-= equal (M-* M1 M2) 1)
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-*-2
+ m-= equal (M-* M1 M2) 2)
+
+(defthm
+ left-nullity-of-m-0-for-m-*
+ (implies (and (alist2p name M1)
+ (integerp m)
+ (> m 0))
+ (m-= (m-* (m-0 m (first (dimensions name M1)))
+ M1)
+ (m-0 m (second (dimensions name M1))))))
+
+(defthm
+ right-nullity-of-m-0-for-m-*
+ (implies (and (alist2p name M1)
+ (integerp p)
+ (> p 0))
+ (m-= (m-* M1
+ (m-0 (second (dimensions name M1))
+ p))
+ (m-0 (first (dimensions name M1))
+ p))))
+
+(defthm
+ aref2-m-1
+ (implies (and (integerp i)
+ (integerp n)
+ (<= 0 i)
+ (< i n))
+ (equal (aref2 name (m-1 n) i j)
+ (if (equal i j)
+ 1
+ 0))))
+
+(defthm
+ left-unity-of-m-1-for-m-*
+ (implies (alist2p name M1)
+ (m-= (m-* (m-1 (first (dimensions name M1)))
+ M1)
+ M1)))
+
+(defthm
+ right-unity-of-m-1-for-m-*
+ (implies (alist2p name M1)
+ (m-= (m-* M1
+ (m-1 (second (dimensions name M1))))
+ M1)))
+
+(defthm
+ associativity-of-m-*
+ (equal (m-* (m-* M1 M2) M3)
+ (m-* M1 M2 M3)))
+
+(defthm
+ left-distributivity-of-m-*-over-m-+
+ (m-= (m-* M1 (m-+ M2 M3))
+ (m-+ (m-* M1 M2)
+ (m-* M1 M3))))
+
+(defthm
+ right-distributivity-of-m-*-over-m-+
+ (m-= (m-* (m-+ M1 M2) M3)
+ (m-+ (m-* M1 M3)
+ (m-* M2 M3))))
+
+(local
+ (defthm
+ m-*-m--_left-lemma
+ (implies (and (equal (c M1)(r M2))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (m-+ (m-* M1 M2)(m-* (m-- M1) M2))
+ (m-0 (r M1)(c M2))))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable m-= m-binary-+ m-binary-*)
+ :use (:theorem
+ (m-= (m-+ (m-* M1 M2)(m-* (m-- M1) M2))
+ (m-* (m-+ M1 (m-- M1)) M2)))))))
+
+(defthm
+ m-*-m--_left
+ (implies (and (equal (c M1)(r M2))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (m-* (m-- M1) M2)
+ (m-- (m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-= m-binary-+ m-binary-*)
+ :use ((:instance
+ uniqueness-of-m-+-inverse
+ (X (m-* (m-- M1) M2))
+ (Y (m-* M1 M2)))
+ m-*-m--_left-lemma))))
+
+(local
+ (defthm
+ m-*-m--_right-lemma
+ (implies (and (equal (c M1)(r M2))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (m-+ (m-* M1 M2)(m-* M1 (m-- M2)))
+ (m-0 (r M1)(c M2))))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable m-= m-binary-+ m-binary-*)
+ :use ((:theorem
+ (m-= (m-+ (m-* M1 M2)(m-* M1 (m-- M2)))
+ (m-* M1 (m-+ M2 (m-- M2)))))
+ (:instance
+ right-nullity-of-m-0-for-m-*
+ (p (c M2))))))))
+
+(defthm
+ m-*-m--_right
+ (implies (and (equal (c M1)(r M2))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (m-* M1 (m-- M2))
+ (m-- (m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-= m-binary-+ m-binary-*)
+ :use ((:instance
+ uniqueness-of-m-+-inverse
+ (X (m-* M1 (m-- M2)))
+ (Y (m-* M1 M2)))
+ m-*-m--_right-lemma))))
+
+(defthm
+ m-=-m-trans-m-1
+ (implies (and (integerp n)
+ (> n 0))
+ (m-= (m-trans (m-1 n))
+ (m-1 n))))
+
+(defthm
+ m-*-s-*-left
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2)))
+ (m-= (m-* (s-* a M1) M2)
+ (s-* a (m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-*
+ alist2p-m-*)
+ :use (:instance
+ alist2p-m-*
+ (name '$arg)
+ (M1 (s-* a M1))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-*
+ alist2p-s-*)
+ :use (:instance
+ alist2p-s-*
+ (name '$arg)
+ (M (m-* M1 M2))))))
+
+(defthm
+ m-*-s-*-right
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2)))
+ (m-= (m-* M1 (s-* a M2))
+ (s-* a (m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-*
+ alist2p-m-*)
+ :use (:instance
+ alist2p-m-*
+ (name '$arg)
+ (M2 (s-* a M2))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-*
+ alist2p-s-*)
+ :use (:instance
+ alist2p-s-*
+ (name '$arg)
+ (M (m-* M1 M2))))))
+
+(defthm
+ m-trans-m-*=m-*-m-trans
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2)))
+ (m-= (m-trans (m-* M1 M2))
+ (m-* (m-trans M2)(m-trans M1))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-*
+ alist2p-m-trans)
+ :use (:instance
+ alist2p-m-trans
+ (name '$arg)
+ (M (m-* M1 M2))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-*
+ alist2p-m-*)
+ :use (:instance
+ alist2p-m-*
+ (name '$arg)
+ (M1 (m-trans M2))
+ (M2 (m-trans M1))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Row and column operations on ACL2 arrays:
+
+(defun
+ Ri<->Rj-loop (name M i j k)
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims))
+ (dims2 (second dims)))
+ (and (< i dims1)
+ (< j dims1)
+ (< k dims2))))))
+ (if (zp k)
+ (let ((temp (aref2 name M i 0)))
+ (aset2 name
+ (aset2 name
+ M
+ i
+ 0
+ (aref2 name
+ M
+ j
+ 0))
+ j
+ 0
+ temp))
+ (Ri<->Rj-loop name
+ (let ((temp (aref2 name M i k)))
+ (aset2 name
+ (aset2 name
+ M
+ i
+ k
+ (aref2 name
+ M
+ j
+ k))
+ j
+ k
+ temp))
+ i
+ j
+ (- k 1))))
+
+(defun
+ Ri<->Rj (name M i j)
+ "Return the result of interchanging
+ row i and row j in array M."
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims)))
+ (and (< i dims1)
+ (< j dims1))))))
+ (Ri<->Rj-loop name
+ M
+ i
+ j
+ (- (second (dimensions name M)) 1)))
+
+(defun
+ Ci<->Cj-loop (name M i j k)
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2)
+ (< k dims1))))))
+ (if (zp k)
+ (let ((temp (aref2 name M 0 i)))
+ (aset2 name
+ (aset2 name
+ M
+ 0
+ i
+ (aref2 name
+ M
+ 0
+ j))
+ 0
+ j
+ temp))
+ (Ci<->Cj-loop name
+ (let ((temp (aref2 name M k i)))
+ (aset2 name
+ (aset2 name
+ M
+ k
+ i
+ (aref2 name
+ M
+ k
+ j))
+ k
+ j
+ temp))
+ i
+ j
+ (- k 1))))
+
+(defun
+ Ci<->Cj (name M i j)
+ "Return the result of interchanging
+ column i and column j in array M."
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2))))))
+ (Ci<->Cj-loop name
+ M
+ i
+ j
+ (- (first (dimensions name M)) 1)))
+
+(defun
+ Ri<-aRi-loop (name M a i k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp k)
+ (>= i 0)
+ (>= k 0)
+ (let ((dims (dimensions name M)))
+ (and (< i (first dims))
+ (< k (second dims)))))))
+ (if (zp k)
+ (aset2 name
+ M
+ i
+ 0
+ (* a (fix (aref2 name
+ M
+ i
+ 0))))
+ (Ri<-aRi-loop name
+ (aset2 name
+ M
+ i
+ k
+ (* a (fix (aref2 name
+ M
+ i
+ k))))
+ a
+ i
+ (- k 1))))
+
+(defun
+ Ri<-aRi (name M a i)
+ "Return the result of replacing each element,
+ Mij, in row i of array M, with (* a Mij)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M))))))
+ (Ri<-aRi-loop name
+ M
+ a
+ i
+ (- (second (dimensions name M)) 1)))
+
+(defun
+ Ci<-aCi-loop (name M a i k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp k)
+ (>= i 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< k dims1))))))
+
+ (if (zp k)
+ (aset2 name
+ M
+ 0
+ i
+ (* a (fix (aref2 name
+ M
+ 0
+ i))))
+ (Ci<-aCi-loop name
+ (aset2 name
+ M
+ k
+ i
+ (* a (fix (aref2 name
+ M
+ k
+ i))))
+ a
+ i
+ (- k 1))))
+
+(defun
+ Ci<-aCi (name M a i)
+ "Return the result of replacing each element,
+ Mji, in column i of array M, with (* a Mji)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M))))))
+ (Ci<-aCi-loop name
+ M
+ a
+ i
+ (- (first (dimensions name M)) 1)))
+
+(defun
+ Rj<-aRi+Rj-loop (name M a i j k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims)))
+ (and (< i dims1)
+ (< j dims1)
+ (< k (second dims)))))))
+ (if (zp k)
+ (aset2 name
+ M
+ j
+ 0
+ (+ (* a (fix (aref2 name
+ M
+ i
+ 0)))
+ (fix (aref2 name
+ M
+ j
+ 0))))
+ (Rj<-aRi+Rj-loop name
+ (aset2 name
+ M
+ j
+ k
+ (+ (* a (fix (aref2 name
+ M
+ i
+ k)))
+ (fix (aref2 name
+ M
+ j
+ k))))
+ a
+ i
+ j
+ (- k 1))))
+
+(defun
+ Rj<-aRi+Rj (name M a i j)
+ "Return the result of replacing each element,
+ Mjk, in row j of matrix M, with (+ (* a Mik) Mjk)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims)))
+ (and (< i dims1)
+ (< j dims1))))))
+ (Rj<-aRi+Rj-loop name
+ M
+ a
+ i
+ j
+ (- (second (dimensions name M)) 1)))
+
+(defun
+ Cj<-aCi+Cj-loop (name M a i j k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2)
+ (< k (first dims)))))))
+ (if (zp k)
+ (aset2 name
+ M
+ 0
+ j
+ (+ (* a (fix (aref2 name
+ M
+ 0
+ i)))
+ (fix (aref2 name
+ M
+ 0
+ j))))
+ (Cj<-aCi+Cj-loop name
+ (aset2 name
+ M
+ k
+ j
+ (+ (* a (fix (aref2 name
+ M
+ k
+ i)))
+ (fix (aref2 name
+ M
+ k
+ j))))
+ a
+ i
+ j
+ (- k 1))))
+
+(defun
+ Cj<-aCi+Cj (name M a i j)
+ "Return the result of replacing each element,
+ Mkj, in column j of matrix M, with (+ (* a Mki)
+ Mkj)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2))))))
+
+ (Cj<-aCi+Cj-loop name
+ M
+ a
+ i
+ j
+ (- (first (dimensions name M)) 1)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Matrix inverse and determinant:
+
+;; Description of algorithm for computing the
+;; inverse and determinant.
+
+;; Input a square matrix M.
+
+;; let A <- I
+;; B <- I
+;; C <- M
+;; D <- 1
+
+;; Row reduce C to I.
+;; Apply same row operations to B.
+;; Multiply A successively on right by
+;; inverse of same row operations.
+;; (Done with equivalent column operations.)
+;; Modify D according to column operations on A.
+;; Ci<->Cj: D <- -1 * D
+;; Ci<-aCi: D <- a * D
+;; Cj<-aCi+Cj: D <- D
+
+;; Invariants
+;; A * B = I
+;; B * M = C
+;; D = determinant of A
+
+;; After termination
+;; A = left inverse of B
+;; B = left inverse of M (because C contains I
+;; after termination)
+
+;; Prove that after termination A = M:
+;; A = A * I = A * (B * M)
+;; = (A * B) * M = I * M = M
+
+;; Thus B is both left and right inverse of M
+;; and D is the determinant of M.
+
+;; Inverse row operations:
+;; (Ri<->Rj)^(-1) = Ri<->Rj
+;; (Ri<-aRi)^(-1) = Ri<-(/a)Ri
+;; (Rj<-aRi+Rj)^(-1) = Rj<-(-a)Ri+Rj
+
+;; Equivalent row and column operations as
+;; applied to identity matrix: I
+;; Ri<->Rj(I) = Ci<->Cj(I)
+;; Ri<-aRi(I) = Ci<-aCi(I)
+;; Rj<-aRi+Rj(I) = Ci<-aCj+Ci(I)
+
+;; Row operation applied to M is the same as
+;; multiplying M on the LEFT by the result
+;; of applying the same operation to I.
+
+;; Column operation applied to M is the same as
+;; multiplying M on the RIGHT by the result
+;; of applying the same operation to I.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun
+ zero-column (A B C i1 j i)
+ "For k = i downto 0,
+ when k differs from i1 and (aref2 '$C C k j) is a nonzero number then
+ replace column i1 in A with (aref2 '$C C k j) * column k + column i1,
+ replace row k in B with (- (aref2 '$C C k j)) * row i1 + row k,
+ replace row k in C with (- (aref2 '$C C k j)) * row i1 + row k.
+ When (aref2 '$C C i1 j) = 1, then all other entries in the jth
+ column of C are modified to 0."
+ (declare (xargs :guard (and (array2p '$a A)
+ (array2p '$b B)
+ (array2p '$c C)
+ (integerp i)
+ (>= i 0)
+ (integerp i1)
+ (>= i1 0)
+ (integerp j)
+ (>= j 0)
+ (< i (second
+ (dimensions '$a
+ A)))
+ (< i (first
+ (dimensions '$b
+ B)))
+ (< i (first
+ (dimensions '$c
+ C)))
+ (< i1 (second
+ (dimensions '$a
+ A)))
+ (< i1 (first
+ (dimensions '$b
+ B)))
+ (< i1 (first
+ (dimensions '$c
+ C)))
+ (< j (second
+ (dimensions '$c
+ C))))))
+ (if (zp i)
+ (if (not (zp i1))
+ (let ((val (fix (aref2 '$C C 0 j))))
+ (if (= val 0)
+ (mv A B C)
+ (mv (Cj<-aCi+Cj '$A A val 0 i1)
+ (Rj<-aRi+Rj '$B B (- val) i1 0)
+ (Rj<-aRi+Rj '$C C (- val) i1 0))))
+ (mv A B C))
+ (if (not (equal i i1))
+ (let ((val (fix (aref2 '$C C i j))))
+ (if (= val 0)
+ (zero-column A B C i1 j (- i 1))
+ (zero-column (Cj<-aCi+Cj '$A A val i i1)
+ (Rj<-aRi+Rj '$B B (- val) i1 i)
+ (Rj<-aRi+Rj '$C C (- val) i1 i)
+ i1
+ j
+ (- i 1))))
+ (zero-column A B C i1 j (- i 1)))))
+
+(defun
+ find-non-zero-col (name C i j k)
+ "Determine if there is a nonzero value among
+ C(i k), C(i+1) k), . . . , C(j k).
+ If not, return nil, otherwise return the
+ first n such that C(n k) is nonzero."
+ (declare (xargs :measure (let ((i (nfix i))
+ (j (nfix j)))
+ (if (> i j)
+ 0
+ (- (+ j 1) i)))
+ :guard (and (array2p name C)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= k 0)
+ (< j (first
+ (dimensions name
+ C)))
+ (< k (second
+ (dimensions name
+ C))))))
+ (let ((i (nfix i))
+ (j (nfix j)))
+ (cond ((> i j) nil)
+ ((zerop (fix (aref2 name C i k)))
+ (find-non-zero-col name C (+ i 1) j k))
+ (t i))))
+
+(defun
+ find-non-zero-col-1 (name C i j k n)
+ "Determine if there is a nonzero value among
+ C(i k) C(i k+1) . . . C(i n)
+ C(i+1) k) C(i+1 k+1) . . . C(i+1 n)
+ . . . .
+ . . . .
+ . . . .
+ C(j k) C(j k+1) . . . C(j n)
+ If not, return nil, otherwise return the
+ first, obtained by searching column by column,
+ pair p q, such that C(p q) is nonzero."
+ (declare (xargs :measure (let ((k (nfix k))
+ (n (nfix n)))
+ (if (> k n)
+ 0
+ (- (+ n 1) k)))
+ :guard (and (array2p name C)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (integerp n)
+ (< j (first (dimensions name C)))
+ (< n (second (dimensions name C))))))
+ (let ((k (nfix k))
+ (n (nfix n)))
+ (if (> k n)
+ nil
+ (let ((p (find-non-zero-col name C i j k)))
+ (if p
+ (list p k)
+ (find-non-zero-col-1 name
+ C
+ i
+ j
+ (+ k 1)
+ n))))))
+
+(defun
+ determinant-inverse-loop (A B C D i j k n)
+ "Process columns k thru n,
+ restricted to rows i thru j."
+ (declare (xargs :measure (let ((k (nfix k))
+ (n (nfix n)))
+ (if (> k n)
+ 0
+ (- (+ n 1) k)))
+ :guard (and (array2p '$a A)
+ (array2p '$b B)
+ (array2p '$c C)
+ (acl2-numberp D)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (integerp n)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (>= n 0)
+ (< i (second
+ (dimensions '$a
+ A)))
+ (< i (first
+ (dimensions '$b
+ B)))
+ (< i (first
+ (dimensions '$c
+ C)))
+ (< j (second
+ (dimensions '$a
+ A)))
+ (< j (first
+ (dimensions '$b
+ B)))
+ (< j (first
+ (dimensions '$c
+ C)))
+ (< n (second
+ (dimensions '$c
+ C))))
+ :verify-guards nil))
+ (let ((k (nfix k))
+ (n (nfix n))
+ (i (nfix i))
+ (j (nfix j)))
+ (if (> k n)
+ (mv A B C D)
+ (let
+ ((indices (find-non-zero-col-1 '$C C i j k n)))
+ (if indices
+ (let*
+ ((p (first indices))
+ (q (second indices))
+ (val (aref2 '$C C p q)))
+ (if (= p i)
+ (mv-let
+ (A B C)
+ (zero-column (Ci<-aCi '$A A val i)
+ (Ri<-aRi '$B B (/ val) i)
+ (Ri<-aRi '$C C (/ val) i)
+ i
+ q
+ j)
+ (cond ((= i j)
+ (mv A B C (* val D)))
+ ((= q i)
+ (determinant-inverse-loop A B C
+ (* val D)
+ (+ i 1)
+ j
+ (+ q 1)
+ n))
+ (t
+ (determinant-inverse-loop A B C
+ (* val D)
+ 0
+ j
+ (+ q 1)
+ n))))
+ (mv-let
+ (A B C)
+ (zero-column (Ci<-aCi '$A (Ci<->Cj '$A A i p) val i)
+ (Ri<-aRi '$B (Ri<->Rj '$B B i p)(/ val) i)
+ (Ri<-aRi '$C (Ri<->Rj '$C C i p)(/ val) i)
+ i
+ q
+ j)
+ (cond ((= i j)
+ (mv A B C (* val (- D))))
+ ((= q i)
+ (determinant-inverse-loop A B C
+ (* val (- D))
+ (+ i 1)
+ j
+ (+ q 1)
+ n))
+ (t
+ (determinant-inverse-loop A B C
+ 0
+ (+ i 1)
+ j
+ (+ q 1)
+ n))))))
+ (mv A B C 0))))))
+
+(verify-guards determinant-inverse-loop)
+
+(defun
+ determinant-inverse (M)
+ "Return multiple values A, B, C, and D.
+ If M is a square array, the determinant of
+ M is returned in D. If the determinant is
+ nonzero, then the matrix inverse of M is
+ returned in B."
+ (declare (xargs :guard (and (array2p '$c M)
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims))))))
+ (let ((dims (dimensions '$c M)))
+ (if (mbt (and (alist2p '$c M)
+ (= (first dims)
+ (second dims))))
+ (let ((dim1 (first dims)))
+ (determinant-inverse-loop (compress2 '$A (m-1 dim1))
+ (compress2 '$B (m-1 dim1))
+ (compress2 '$C M)
+ 1 ;; initial value of D
+ 0
+ (- dim1 1)
+ 0
+ (- (second (dimensions '$c M)) 1)))
+ (mv M (/ M) 1 M))))
+
+(defun
+ determinant (M)
+ (declare (xargs :guard (and (array2p '$c M)
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims))))))
+ (mv-let (A B C D)
+ (determinant-inverse M)
+ (declare (ignore A B C))
+ D))
+
+(defun
+ m-/ (M)
+ (declare (xargs :guard (and (array2p '$c M)
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims))))))
+ (mv-let (A B C D)
+ (determinant-inverse M)
+ (declare (ignore A C D))
+ B))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Eventually, we will prove that for square matrices
+;; whenever the determinant is not 0, then m-/
+;; computes the two-sided inverse; and whenever the
+;; determinant is 0 then there is no inverse.
+;; Also it will be proved that non-square matrices
+;; do not have two-sided inverses.
+
+;; Meanwhile the definition of singualar given
+;; immediately below is replaced by the second one
+;; below.
+
+;; (defun
+;; m-singularp (M)
+;; (declare (xargs :guard (array2p '$c M)))
+;; (not (and (mbt (alist2p '$c M))
+;; (let ((dims (dimensions '$c M)))
+;; (= (first dims)
+;; (second dims)))
+;; (= (determinant M) 0))))
+|#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun
+ m-singularp (M)
+ (declare (xargs :guard (array2p '$c M)
+ :verify-guards nil))
+ (not (and (mbt (alist2p '$c M))
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims)))
+ (m-= (m-* M (m-/ M))
+ (m-1 (r M)))
+ (m-= (m-* (m-/ M) M)
+ (m-1 (r M))))))
+
+(defthm
+ non-singular-implies-square
+ (implies (not (m-singularp M))
+ (equal (equal (c M)(r M))
+ t)))
+
+(defthm
+ left-m-*-inverse-of-m-/
+ (implies (not (m-singularp M))
+ (m-= (m-* (m-/ M) M)
+ (m-1 (r M)))))
+
+(defthm
+ right-m-*-inverse-of-m-/
+ (implies (not (m-singularp M))
+ (m-= (m-* M (m-/ M))
+ (m-1 (r M)))))
+
+(defthm
+ dimensions-m-/
+ (implies (and (alist2p name M)
+ (equal (first (dimensions name M))
+ (second (dimensions name M))))
+ (equal (dimensions name (m-/ M))
+ (list (car (dimensions name M))
+ (car (dimensions name M))))))
+
+(defthm
+ alist2p-m-/
+ (implies (and (alist2p name M)
+ (equal (first (dimensions name M))
+ (second (dimensions name M))))
+ (alist2p name (m-/ M))))
+
+(defthm
+ array2p-m-/
+ (implies (and (array2p name M)
+ (equal (first (dimensions name M))
+ (second (dimensions name M))))
+ (array2p name (m-/ M)))
+ :hints (("Goal"
+ :in-theory
+ (disable
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1)
+ :use
+ (:instance
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1
+ (D 1)))))
+
+(defthm
+ matrixp-m-/
+ (implies (and (matrixp (r M)(c M) M)
+ (equal (r M)(c M)))
+ (matrixp (r M)(c M)(m-/ M)))
+ :hints (("Goal"
+ :in-theory
+ (disable
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1)
+ :use
+ (:instance
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1
+ (D 1)
+ (name '$arg)))))
+
+(verify-guards m-singularp)
+
+(in-theory (disable matrixp
+ m-=
+ m-0
+ m-1
+ m-trans
+ m-unary--
+ s-*
+ m-binary-+
+ m-binary-*
+ m-/
+ m-singularp))
+
+(local (in-theory (enable m-singularp)))
+
+(defthm
+ uniqueness-of-m-*-inverse
+ (implies (and (alist2p name X)
+ (not (m-singularp Y))
+ (equal (r X)(r Y))
+ (equal (c X)(c Y))
+ (m-= (m-* X Y)
+ (m-1 (r X))))
+ (m-= X (m-/ Y)))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable
+ right-unity-of-m-1-for-m-*
+ left-unity-of-m-1-for-m-*)
+ :use ((:instance
+ M-=-IMPLIES-EQUAL-M-*-1
+ (M1 (m-* X Y))
+ (M1-equiv (m-1 (r X)))
+ (M2 (m-/ Y)))
+ (:instance
+ right-unity-of-m-1-for-m-*
+ (name '$arg)
+ (M1 X))
+ (:instance
+ left-unity-of-m-1-for-m-*
+ (name '$arg)
+ (M1 (m-/ Y)))))))
+
+(defthm
+ m-/-m-*-lemma
+ (implies (and (not (m-singularp M1))
+ (not (m-singularp M2))
+ (equal (c M1)(r M2)))
+ (m-= (m-* (m-/ M2)(m-* (m-/ M1) M1) M2)
+ (m-1 (r M1))))
+ :rule-classes nil
+ :hints (("Goal"
+ :in-theory (disable
+ ASSOCIATIVITY-OF-M-*
+ left-unity-of-m-1-for-m-*)
+ :use (:instance
+ left-unity-of-m-1-for-m-*
+ (name '$arg)
+ (M1 M2)))))
+
+(defthm
+ Subgoal-8-hack
+ (IMPLIES (AND (ALIST2P '$C M1)
+ (ALIST2P '$C M2)
+ (EQUAL (CADR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M1)))
+ (EQUAL (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2)))
+ (EQUAL (CAR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M2))))
+ (ALIST2P NAME (M-* (M-/ M2)
+ (M-/ M1))))
+ :hints (("Goal"
+ :in-theory (disable ALIST2P-M-*)
+ :use (:instance
+ ALIST2P-M-*
+ (M1 (M-/ M2))
+ (M2 (M-/ M1))
+ (name '$arg)))))
+
+(defthm
+ m-/-m-*
+ (implies (and (not (m-singularp M1))
+ (not (m-singularp M2))
+ (not (m-singularp (m-* M1 M2)))
+ (equal (c M1)(r M2)))
+ (m-= (m-/ (m-* M1 M2))
+ (m-* (m-/ M2)(m-/ M1))))
+ :hints (("Goal"
+ :use ((:instance
+ uniqueness-of-m-*-inverse
+ (X (m-* (m-/ M2)(m-/ M1)))
+ (Y (m-* M1 M2)))
+ m-/-m-*-lemma))))
+
+(defthm
+ m--_m-0
+ (implies (and (integerp m)
+ (> m 0)
+ (integerp n)
+ (> n 0))
+ (m-= (m-- (m-0 m n))
+ (m-0 m n)))
+ :hints (("Goal"
+ :in-theory (disable m-=-s-*-m-0
+ m-=-s-*_-1)
+ :use ((:instance
+ m-=-s-*-m-0
+ (a -1))
+ (:instance
+ m-=-s-*_-1
+ (M (m-0 m n)))))))
+
+(defthm
+ m-=_s-*_m--
+ (implies (alist2p name M)
+ (m-= (s-* a (m-- M))
+ (m-- (s-* a M))))
+ :hints (("Goal"
+ :in-theory (disable
+ associate-scalars-left-s-*)
+ :use ((:instance
+ associate-scalars-left-s-*
+ (a1 -1)
+ (a2 a))
+ (:instance
+ associate-scalars-left-s-*
+ (a1 a)
+ (a2 -1))))))
+
+(defthm
+ distributivity-of-m--_over-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (m-- (m-+ M1 M2))
+ (m-+ (m-- M1)(m-- M2))))
+ :hints (("Goal"
+ :in-theory
+ (disable distributivity-of-s-*-over-m-+)
+ :use (:instance
+ distributivity-of-s-*-over-m-+
+ (a -1)))))
+
diff --git a/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matrix.lisp b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matrix.lisp
new file mode 100644
index 0000000..bc42dc1
--- /dev/null
+++ b/books/workshops/2003/cowles-gamboa-van-baalen_matrix/support/matrix.lisp
@@ -0,0 +1,9871 @@
+; The ACL2 Matrices (Implemented as ACL2 2-D Arrays) Book.
+; Copyright (C) 2002 Ruben Gamboa and John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; Ruben Gamboa and John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+; Summer and Fall 2002.
+; Last modified 13 June 2003.
+
+; ACL2 Version 2.8 alpha (as of May 11 03)
+#|
+ To certify in
+ ACL2 Version 2.8 alpha (as of May 11 03)
+
+(certify-book "matrix"
+ 0
+ t ;;compile-flg
+ )
+|#
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+At UW:
+
+:set-cbd "/home/faculty/cowles/acl2/matrix/" ;;pyramid
+
+:set-cbd "/home/cowles/matrix/" ;; turing
+|#
+
+(in-package "ACL2")
+
+#|
+(local ;;turing
+ (include-book
+ "/home/cowles/acl2-sources/books/arithmetic-2.8/top"))
+
+(local ;;pyramid
+ (include-book
+ "/home/acl2/acl2-2.8/v2-8-alpha-05-11-03/books/arithmetic/top"))
+|#
+
+(local
+ (include-book "../../../../arithmetic/top"))
+
+(include-book "array2")
+
+(include-book "alist2")
+
+(defthm
+ compress211-$arg
+ (implies (syntaxp (not (eq name ''$arg)))
+ (equal (compress211 name l n i j default)
+ (compress211 '$arg l n i j default))))
+
+(defthm
+ compress21-$arg
+ (implies (syntaxp (not (eq name ''$arg)))
+ (equal (compress21 name l n i j default)
+ (compress21 '$arg l n i j default))))
+
+(defthm
+ array2p-$arg-equal-parts
+ (implies (syntaxp (not (eq name ''$arg)))
+ (and (equal (header name l)
+ (header '$arg l))
+ (equal (dimensions name l)
+ (dimensions '$arg l))
+ (equal (maximum-length name l)
+ (maximum-length '$arg l))
+ (equal (default name l)
+ (default '$arg l))
+ (equal (compress2 name l)
+ (compress2 '$arg l))
+ (equal (aref2 name l i j)
+ (aref2 '$arg l i j))
+ (equal (aset2 name l i j val)
+ (aset2 '$arg l i j val)))))
+
+(defthm
+ array2p-$arg
+ (implies (array2p name l)
+ (array2p '$arg l))
+ :rule-classes :forward-chaining)
+
+(defthm
+ not-array2p-arg$
+ (implies (and (not (array2p name l))
+ (symbolp name))
+ (not (array2p '$arg l)))
+ :rule-classes :forward-chaining)
+
+(defthm
+ alist2p-$arg
+ (implies (alist2p name l)
+ (alist2p '$arg l))
+ :rule-classes :forward-chaining)
+
+(defthm
+ not-alist2p-arg$
+ (implies (not (alist2p name l))
+ (not (alist2p '$arg l)))
+ :rule-classes :forward-chaining)
+
+(in-theory (disable alist2p array2p aset2 aref2 compress2 header
+ dimensions maximum-length default))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Boolean test for a matrix:
+
+;; The need for the following constant is explained in
+;; detail later in this book:
+
+;; Search for
+;; ; Ensuring closure of matrix multiplication.
+
+(defconst
+ *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*
+ 46340)
+
+;; To ensure that matrix multiplication is closed, the
+;; matrix can have no more that 46,340 rows and no more
+;; 46,340 columns.
+
+(defun
+ matrixp (m n X)
+ "Determine if X is a m by n matrix."
+ (declare (xargs :guard t))
+ (and (array2p '$arg X)
+ (let ((dims (dimensions '$arg X)))
+ (and (equal m (first dims))
+ (equal n (second dims))))
+ (<= m *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= n *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)))
+
+(defmacro
+ r (M)
+ "Return the number of rows in the matrix M."
+ `(car (dimensions '$arg ,M)))
+
+(defmacro
+ c (M)
+ "Return the number of columns in the matrix M."
+ `(cadr (dimensions '$arg ,M)))
+
+(defthm
+ array2p-matrixp
+ (implies (and (array2p name M)
+ (<= (r M) *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= (c M) *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (matrixp (r M)(c M) M)))
+
+;;;;;;;;;;;;;;;;;;;
+;; Matrix equality:
+
+(defun
+ m-=-row (M1 M2 m n)
+ "Determine if all the following equalities hold:
+ M1(m 0) = M2(m 0), . . . , M1(m n) = M2(m n);
+ ie. determine if the m'th row of M1 matches the
+ m'th row of M2.
+ All entries are treated as numbers."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (car dims1))
+ (< n (cadr dims1))))
+ (let ((dims2 (dimensions '$arg2 M2)))
+ (and (< m (car dims2))
+ (< n (cadr dims2)))))))
+ (if (zp n)
+ (equal (fix (aref2 '$arg1 M1 m 0))
+ (fix (aref2 '$arg2 M2 m 0)))
+ (and (equal (fix (aref2 '$arg1 M1 m n))
+ (fix (aref2 '$arg2 M2 m n)))
+ (m-=-row M1 M2 m (- n 1)))))
+
+(defthm
+ reflexivity-of-m-=-row
+ (m-=-row X X m n))
+
+(defthm
+ symmetry-of-m-=-row
+ (implies (m-=-row M1 M2 m n)
+ (m-=-row M2 M1 m n)))
+
+(defthm
+ transitivity-of-m-=-row
+ (implies (and (m-=-row M1 M2 m n)
+ (m-=-row M2 M3 m n))
+ (m-=-row M1 M3 m n))
+ :rule-classes (:rewrite :forward-chaining))
+
+(defthm
+ m-=-row-compress2
+ (implies (and (alist2p name l)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l)))
+ (< j (cadr (dimensions name l))))
+ (m-=-row (compress2 name l) l i j)))
+
+(defthm
+ m-=-row-remove-compress2-1
+ (implies (and (alist2p name l1)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l1)))
+ (< j (cadr (dimensions name l1))))
+ (equal (m-=-row (compress2 name l1) l2 i j)
+ (m-=-row l1 l2 i j))))
+
+(defthm
+ m-=-row-remove-compress2-2
+ (implies (and (alist2p name l2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l2)))
+ (< j (cadr (dimensions name l2))))
+ (equal (m-=-row l1 (compress2 name l2) i j)
+ (m-=-row l1 l2 i j))))
+
+(defthm
+ m-=-row-fix-aref2
+ (implies (and (m-=-row M1 M2 m n)
+ (integerp n)
+ (integerp j)
+ (<= 0 j)
+ (<= j n))
+ (equal (fix (aref2 name M1 m j))
+ (fix (aref2 name M2 m j))))
+ :rule-classes nil)
+
+(defun
+ m-=-row-1 (M1 M2 m n)
+ "Determine if all the following equalities hold:
+ M1(0 0) = M2(0 0), . . . , M1(0 n) = M2(0 n)
+ . . .
+ . . .
+ . . .
+ M1(m 0) = M2(m 0), . . . , M1(m n) = M2(m n);
+ ie. determine if rows 0 thru m of M1 matches
+ rows 0 thru m of M2.
+ All entries are treated as numbers."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (car dims1))
+ (< n (cadr dims1))))
+ (let ((dims2 (dimensions '$arg2 M2)))
+ (and (< m (car dims2))
+ (< n (cadr dims2)))))))
+ (if (zp m)
+ (m-=-row M1 M2 0 n)
+ (and (m-=-row M1 M2 m n)
+ (m-=-row-1 M1 M2 (- m 1) n))))
+
+(defthm
+ reflexivity-of-m-=-row-1
+ (m-=-row-1 X X m n))
+
+(defthm
+ symmetry-of-m-=-row-1
+ (implies (m-=-row-1 M1 M2 m n)
+ (m-=-row-1 M2 M1 m n)))
+
+(defthm
+ transitivity-of-m-=-row-1
+ (implies (and (m-=-row-1 M1 M2 m n)
+ (m-=-row-1 M2 M3 m n))
+ (m-=-row-1 M1 M3 m n))
+ :rule-classes (:rewrite :forward-chaining))
+
+(defthm
+ m-=-row-1-compress2
+ (implies (and (alist2p name l)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l)))
+ (< j (cadr (dimensions name l))))
+ (m-=-row-1 (compress2 name l) l i j)))
+
+(defthm
+ m-=-row-1-remove-compress2-1
+ (implies (and (alist2p name l1)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l1)))
+ (< j (cadr (dimensions name l1))))
+ (equal (m-=-row-1 (compress2 name l1) l2 i j)
+ (m-=-row-1 l1 l2 i j))))
+
+(defthm
+ m-=-row-1-remove-compress2-2
+ (implies (and (alist2p name l2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l2)))
+ (< j (cadr (dimensions name l2))))
+ (equal (m-=-row-1 l1 (compress2 name l2) i j)
+ (m-=-row-1 l1 l2 i j))))
+
+(defthm
+ m-=-row-1-fix-aref2
+ (implies (and (m-=-row-1 M1 M2 m n)
+ (integerp m)
+ (integerp n)
+ (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j)
+ (<= i m)
+ (<= j n))
+ (equal (fix (aref2 name M1 i j))
+ (fix (aref2 name M2 i j))))
+ :rule-classes nil
+ :hints (("Subgoal *1/2"
+ :use (:instance
+ m-=-row-fix-aref2
+ (m i)))
+ ("Subgoal *1/1"
+ :use (:instance
+ m-=-row-fix-aref2
+ (m 0)))))
+
+(defun
+ m-= (M1 M2)
+ "Determine if the matrices represented by the alists
+ M1 and M2 are equal (as matrices of numbers)."
+ (declare (xargs :guard (and (array2p '$arg1 M1)
+ (array2p '$arg2 M2))))
+ (if (mbt (and (alist2p '$arg1 M1)
+ (alist2p '$arg2 M2)))
+ (let ((dim1 (dimensions '$arg1 M1))
+ (dim2 (dimensions '$arg2 M2)))
+ (if (and (= (first dim1)
+ (first dim2))
+ (= (second dim1)
+ (second dim2)))
+ (m-=-row-1 (compress2 '$arg1 M1)
+ (compress2 '$arg2 M2)
+ (- (first dim1) 1)
+ (- (second dim1) 1))
+ nil))
+ (equal M1 M2)))
+
+(defequiv
+ ;; m-=-is-an-equivalence
+ m-=)
+
+(defthm
+ m-=-compress2
+ (implies (alist2p name l)
+ (m-= (compress2 name l) l)))
+
+(defthm
+ m-=-implies-equal-dims
+ (implies (m-= M1 M2)
+ (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))))
+ :rule-classes nil)
+
+(defcong
+ ;; m-=-implies-equal-alist2p-2
+ m-= equal (alist2p name M) 2
+ :hints (("Goal"
+ :use (:theorem
+ (implies (m-= M M-equiv)
+ (iff (alist2p name M)
+ (alist2p name M-equiv)
+ ))))))
+
+(defthm
+ m-=-fix-aref2
+ (implies (and (m-= M1 M2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name M1)))
+ (< j (cadr (dimensions name M1))))
+ (equal (fix (aref2 name M1 i j))
+ (fix (aref2 name M2 i j))))
+ :rule-classes nil
+ :hints (("Subgoal 3'"
+ :use (:instance
+ m-=-row-1-fix-aref2
+ (name '$arg)
+ (m (+ -1 (car (dimensions '$arg M1)))
+ )
+ (n (+ -1 (cadr (dimensions '$arg M1))
+ ))))
+ ("Subgoal 2'"
+ :use (:instance
+ m-=-row-1-fix-aref2
+ (name '$arg)
+ (m (+ -1 (car (dimensions '$arg M1)))
+ )
+ (n (+ -1 (cadr (dimensions '$arg M1))
+ ))))
+ ("Subgoal 1'"
+ :use (:instance
+ m-=-row-1-fix-aref2
+ (name '$arg)
+ (m (+ -1 (car (dimensions '$arg M1)))
+ )
+ (n (+ -1 (cadr (dimensions '$arg M1))
+ ))))))
+
+;;;;;;;;;;;;;;;
+;; Zero matrix:
+
+(defun
+ m-0 (m n)
+ "Return an alist representing the m by n matrix whose
+ elements are all equal to 0.
+ To use the ACL2 efficient array mechanism to store (m-0 m n),
+ (* m n)) must be stictly less than 2147483647 which is
+ the *MAXIMUM-POSITIVE-32-BIT-INTEGER*."
+ (declare (xargs :guard (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))))
+ (list (list :HEADER
+ :DIMENSIONS (list m n)
+ :MAXIMUM-LENGTH (+ 1 (* m n))
+ :DEFAULT 0
+ :NAME 'zero-matrix)))
+
+(defthm
+ alist2p-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))
+ (alist2p name (m-0 m n)))
+ :hints (("Goal" :in-theory (enable alist2p))))
+
+(defthm
+ array2p-m-0
+ (implies (and (symbolp name)
+ (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0)
+ (< (* m n) *MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-0 m n)))
+ :hints (("Goal" :in-theory (enable array2p))))
+
+(defthm
+ sqrt-*-sqrt-<-sq
+ (implies (and (rationalp x)
+ (rationalp y)
+ (>= x 0)
+ (>= y 0)
+ (<= x 46340)
+ (<= y 46340))
+ (< (* x y) 2147483647))
+ :rule-classes (:rewrite :linear)
+ :hints (("Goal"
+ :use (:instance
+ *-PRESERVES->=-FOR-NONNEGATIVES
+ (x2 x)
+ (y2 y)
+ (x1 46340)
+ (y1 46340)))))
+
+(defthm
+ matrixp-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0)
+ (<= m *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= n *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (matrixp m n (m-0 m n)))
+ :hints (("Goal" :in-theory (enable array2p
+ dimensions
+ header))))
+
+(defthm
+ aref2-m-0
+ (equal (aref2 name (m-0 m n) i j) 0)
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ dimensions-m-0
+ (equal (dimensions name (m-0 m n))(list m n))
+ :hints (("Goal"
+ :in-theory (enable header dimensions))))
+
+(defthm
+ default-m-0
+ (equal (default name (m-0 m n))
+ 0)
+ :hints (("Goal"
+ :in-theory (enable header default))))
+
+(in-theory (disable m-0))
+
+(defthm
+ alist2p-alist2p-m-0
+ (implies (alist2p name1 M)
+ (alist2p name2 (m-0 (car (dimensions
+ '$arg M))
+ (cadr (dimensions
+ '$arg M))))))
+
+(defthm
+ array2p-array2p-m-0
+ (implies (and (array2p name1 M)
+ (symbolp name2))
+ (array2p name2 (m-0 (car (dimensions
+ '$arg M))
+ (cadr (dimensions
+ '$arg M))))))
+
+;;;;;;;;;;;;;;;;;;;
+;; Identity matrix:
+
+(defun
+ m-1a (n)
+ "Return alist of length n of the form
+ ( ((- n 1) . (- n 1)) . 1) . . . ((0 . 0) . 1) )."
+ (declare (xargs :guard (and (integerp n)
+ (>= n 0))
+ :verify-guards nil))
+ (if (zp n)
+ nil
+ (acons (cons (- n 1)(- n 1)) 1 (m-1a (- n 1)))))
+
+(defthm
+ alistp-m-1a
+ (alistp (m-1a n)))
+
+(verify-guards m-1a)
+
+(defthm
+ bounded-integer-alistp2->=
+ (implies (and (bounded-integer-alistp2 l i j)
+ (integerp m)
+ (integerp n)
+ (<= i m)
+ (<= j n))
+ (bounded-integer-alistp2 l m n)))
+
+(defthm
+ bounded-integer-alistp2-m-1a
+ (bounded-integer-alistp2 (m-1a n) n n))
+
+(defthm
+ assoc2-i-i-m-1a
+ (implies (and (integerp i)
+ (integerp n)
+ (>= i 0)
+ (< i n))
+ (and (assoc2 i i (m-1a n))
+ (equal (cdr (assoc2 i i (m-1a n)))
+ 1))))
+
+(defthm
+ assoc2-i-j-m-1a
+ (implies (not (equal i j))
+ (not (assoc2 i j (m-1a n)))))
+
+(defun
+ m-1 (n)
+ "Return an alist representing the n by n identity matrix.
+ To use the ACL2 efficient array mechanism to store (m-1 n),
+ (* n n)) must be stictly less than 2147483647 which is
+ the *MAXIMUM-POSITIVE-32-BIT-INTEGER*."
+ (declare (xargs :guard (and (integerp n)
+ (>= n 0))))
+ (cons (list :HEADER
+ :DIMENSIONS (list n n)
+ :MAXIMUM-LENGTH (+ 1 (* n n))
+ :DEFAULT 0
+ :NAME 'identity-matrix)
+ (m-1a n)))
+
+(defthm
+ alist2p-m-1
+ (implies (and (integerp n)
+ (> n 0))
+ (alist2p name (m-1 n)))
+ :hints (("Goal"
+ :in-theory (enable alist2p))))
+
+(defthm
+ array2p-m-1
+ (implies (and (symbolp name)
+ (integerp n)
+ (> n 0)
+ (< (* n n) *MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-1 n)))
+ :hints (("Goal"
+ :in-theory (enable array2p))))
+
+(defthm
+ matrixp-m-1
+ (implies (and (integerp n)
+ (> n 0)
+ (<= n *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (matrixp n n (m-1 n)))
+ :hints (("Goal"
+ :in-theory (enable array2p dimensions header))))
+
+(defthm
+ aref2-m-1-i-i
+ (implies (and (integerp i)
+ (integerp n)
+ (<= 0 i)
+ (< i n))
+ (equal (aref2 name (m-1 n) i i) 1))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ aref2-m-1-i-j
+ (implies (not (equal i j))
+ (equal (aref2 name (m-1 n) i j) 0))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ dimensions-m-1
+ (equal (dimensions name (m-1 n))(list n n))
+ :hints (("Goal"
+ :in-theory (enable header dimensions))))
+
+(in-theory (disable m-1))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Transpose of a matrix:
+
+(defun
+ m-trans-a (M)
+ (declare (xargs :guard (alistp M)))
+ (if (consp M)
+ (let ((key (caar M))
+ (datum (cdar M)))
+ (if (consp key)
+ (acons (cons (cdr key)
+ (car key))
+ datum
+ (m-trans-a (cdr M)))
+ (m-trans-a (cdr M))))
+ nil))
+
+(defthm
+ alistp-m-trans-a
+ (alistp (m-trans-a M)))
+
+(defthm
+ bounded-integer-alistp2-m-trans-a
+ (implies (bounded-integer-alistp2 l m n)
+ (bounded-integer-alistp2 (m-trans-a l)
+ n
+ m)))
+
+(defthm
+ assoc2-m-trans-a
+ (iff (assoc2 i j (m-trans-a M))
+ (assoc2 j i M)))
+
+(defthm
+ cdr-assoc2-m-trans-a
+ (equal (cdr (assoc2 i j (m-trans-a M)))
+ (cdr (assoc2 j i M))))
+
+(defun
+ m-trans (M)
+ "Return an alist representing the transpose of the matrix
+ represented by the alist M."
+ (declare (xargs :guard (array2p '$arg M)))
+ (cons (list :HEADER
+ :DIMENSIONS (let ((dims (dimensions '$arg M)))
+ (list (cadr dims)(car dims)))
+ :MAXIMUM-LENGTH (maximum-length '$arg M)
+ :DEFAULT (default '$arg M)
+ :NAME 'transpose-matrix)
+ (m-trans-a M)))
+
+(defthm
+ alist2p-m-trans
+ (implies (alist2p name M)
+ (alist2p name (m-trans M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-trans M))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-m-trans
+ (implies (array2p name M)
+ (array2p name (m-trans M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-trans M))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-m-trans
+ (equal (dimensions name (m-trans M))
+ (list (cadr (dimensions name M))
+ (car (dimensions name M))))
+ :hints (("Goal"
+ :in-theory (enable dimensions header))))
+
+(defthm
+ equal-list-dimensions-array2p
+ (implies (array2p name M)
+ (equal (list (car (dimensions name M))
+ (cadr (dimensions name M)))
+ (dimensions name M)))
+ :hints (("Goal"
+ :in-theory (enable array2p dimensions header))))
+
+(defthm
+ aref2-m-trans
+ (equal (aref2 name (m-trans M) i j)
+ (aref2 name M j i))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(in-theory (disable m-trans))
+
+(defthm
+ matrixp-m-trans
+ (implies (matrixp m n X)
+ (matrixp n m (m-trans X))))
+
+(defthm
+ m-=-row-idempotency-of-m-trans
+ (m-=-row (m-trans (m-trans M)) M i j))
+
+(defthm
+ m-=-row-1-idempotency-of-m-trans
+ (m-=-row-1 (m-trans (m-trans M)) M i j))
+
+(defthm
+ array2p-alist2p-$arg2
+ (implies (array2p name M)
+ (alist2p '$arg2 M))
+ :hints (("Goal"
+ :use (:theorem
+ (implies (array2p name M)
+ (array2p '$arg2 M))))))
+
+(defthm
+ idempotency-of-m-trans-alist2p
+ (implies (alist2p name M)
+ (m-= (m-trans (m-trans M)) M)))
+
+(defthm
+ idempotency-of-m-trans-array2p
+ (implies (array2p name M)
+ (m-= (m-trans (m-trans M)) M))
+ :hints (("Goal'"
+ :use (:theorem
+ (implies (array2p '$arg1 M)
+ (alist2p '$arg1
+ (m-trans
+ (m-trans M))))))))
+
+(defthm
+ remove-last-col-m-=-row-1
+ (implies (m-=-row-1 M1 M2 i j)
+ (m-=-row-1 M1 M2 i (- j 1))))
+
+(local
+ (defthm
+ m-=-row-1-m-trans-1
+ (implies (m-=-row-1 (m-trans M1)(m-trans M2) j i)
+ (m-=-row-1 M1 M2 i j))))
+
+(local
+ (defthm
+ m-=-row-1-m-trans-2
+ (implies (m-=-row-1 M1 M2 i j)
+ (m-=-row-1 (m-trans M1)(m-trans M2) j i))
+ :hints (("Goal"
+ :in-theory (disable m-=-row-1-idempotency-of-m-trans)
+ :use ((:instance
+ m-=-row-1-m-trans-1
+ (M1 (m-trans M1))
+ (M2 (m-trans M2))
+ (j i)
+ (i j))
+ (:instance
+ m-=-row-1-idempotency-of-m-trans
+ (M M1))
+ (:instance
+ m-=-row-1-idempotency-of-m-trans
+ (M M2)))))))
+
+(defthm
+ m-=-row-1-m-trans-iff
+ (iff (m-=-row-1 (m-trans M1)(m-trans M2) j i)
+ (m-=-row-1 M1 M2 i j)))
+
+(local
+ (in-theory (disable m-=-row-1-m-trans-1
+ m-=-row-1-m-trans-2)))
+
+(defcong
+ ;; M-=-IMPLIES-M-=-M-TRANS-1
+ m-= m-= (m-trans M) 1)
+
+(defthm
+ m-=-row-1-m-trans-m-0
+ (m-=-row-1 (m-trans (m-0 m n))
+ (m-0 n m)
+ j
+ i))
+
+(defthm
+ m-=-m-trans-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))
+ (m-= (m-trans (m-0 m n))
+ (m-0 n m))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Unary minus of a matrix:
+
+(defun
+ m-unary--a (M)
+ (declare (xargs :guard (alistp M)))
+ (if (consp M)
+ (let ((key (caar M))
+ (datum (cdar M)))
+ (if (consp key)
+ (acons key
+ (- (fix datum))
+ (m-unary--a (cdr M)))
+ (m-unary--a (cdr M))))
+ nil))
+
+(defthm
+ alistp-m-unary--a
+ (alistp (m-unary--a M)))
+
+(defthm
+ bounded-integer-alistp2-m-unary--a
+ (implies (bounded-integer-alistp2 l m n)
+ (bounded-integer-alistp2 (m-unary--a l) m n)))
+
+(defthm
+ assoc2-m-unary--a
+ (iff (assoc2 i j (m-unary--a M))
+ (assoc2 i j M)))
+
+(defthm
+ cdr-assoc2-m-unary--a
+ (implies (assoc2 i j M)
+ (equal (cdr (assoc2 i j (m-unary--a M)))
+ (- (cdr (assoc2 i j M))))))
+
+(defun
+ m-unary-- (M)
+ "Return an alist representing the unary minus of the matrix
+ represented by the alist M."
+ (declare (xargs :guard (array2p '$arg M)))
+ (cons (list :HEADER
+ :DIMENSIONS (dimensions '$arg M)
+ :MAXIMUM-LENGTH (maximum-length '$arg M)
+ :DEFAULT (- (fix (default '$arg M)))
+ :NAME 'unary-minus-matrix)
+ (m-unary--a M)))
+
+(defthm
+ alist2p-m-unary--
+ (implies (alist2p name M)
+ (alist2p name (m-unary-- M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-unary-- M))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-m-unary--
+ (implies (array2p name M)
+ (array2p name (m-unary-- M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-unary-- M))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-m-unary--
+ (equal (dimensions name (m-unary-- M))
+ (dimensions name M))
+ :hints (("Goal"
+ :in-theory (enable array2p dimensions header))))
+
+(defthm
+ aref2-m-unary--
+ (equal (aref2 name (m-unary-- M) i j)
+ (- (aref2 name M i j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(in-theory (disable m-unary--))
+
+(defthm
+ matrixp-m-unary--
+ (implies (matrixp m n X)
+ (matrixp m n (m-unary-- X))))
+
+(defthm
+ m-=-row-idempotency-of-m-unary--
+ (m-=-row (m-unary-- (m-unary-- M)) M i j))
+
+(defthm
+ m-=-row-1-idempotency-of-m-unary--
+ (m-=-row-1 (m-unary-- (m-unary-- M)) M i j))
+
+(defthm
+ idempotency-of-m-unary--_alist2p
+ (implies (alist2p name M)
+ (m-= (m-unary-- (m-unary-- M)) M)))
+
+(defthm
+ array2p-alist2p-$arg1-m-unaray--
+ (implies (array2p name M)
+ (alist2p '$arg1 (m-unary-- (m-unary-- M)))
+ )
+ :hints (("Goal"
+ :use (:theorem
+ (implies (array2p '$arg1 M)
+ (alist2p '$arg1
+ (m-unary--
+ (m-unary-- M))))
+ ))))
+
+(defthm
+ idempotency-of-m-unary--_array2p
+ (implies (array2p name M)
+ (m-= (m-unary-- (m-unary-- M)) M)))
+
+(defthm
+ m-=-row-1-m-unary--
+ (implies (m-=-row-1 M1 M2 i j)
+ (m-=-row-1 (m-unary-- M1)(m-unary-- M2) i j)))
+
+(defcong
+ ;; M-=-IMPLIES-M-=-M-UNARY---1
+ m-= m-= (m-unary-- M) 1)
+
+(defthm
+ m-=-row-1-m-trans-m-unary--
+ (m-=-row-1 (m-trans (m-unary-- M))
+ (m-unary-- (m-trans M))
+ i
+ j))
+
+(defthm
+ m-=-m-trans-m-unary--
+ (implies (alist2p name M)
+ (m-= (m-trans (m-unary-- M))
+ (m-unary-- (m-trans M)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Scalar multiplication of a matrix:
+
+(defun
+ s-*-a (a M)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (alistp M))))
+ (if (consp M)
+ (let ((key (caar M))
+ (datum (cdar M)))
+ (if (consp key)
+ (acons key
+ (* a (fix datum))
+ (s-*-a a (cdr M)))
+ (s-*-a a (cdr M))))
+ nil))
+
+(defthm
+ alistp-s-*-a
+ (alistp (s-*-a a M)))
+
+(defthm
+ bounded-integer-alistp2-s-*-a
+ (implies (bounded-integer-alistp2 l m n)
+ (bounded-integer-alistp2 (s-*-a a l) m n)))
+
+(defthm
+ assoc2-s-*-a
+ (iff (assoc2 i j (s-*-a a M))
+ (assoc2 i j M)))
+
+(defthm
+ cdr-assoc2-s-*-a
+ (implies (assoc2 i j M)
+ (equal (cdr (assoc2 i j (s-*-a a M)))
+ (* a (cdr (assoc2 i j M))))))
+
+(defun
+ s-* (a M)
+ "Return an alist representing the multiplication
+ of the scalar a times the matrix represented by
+ the alist M."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p '$arg M))))
+ (cons (list :HEADER
+ :DIMENSIONS (dimensions '$arg M)
+ :MAXIMUM-LENGTH (maximum-length '$arg M)
+ :DEFAULT (* a (fix (default '$arg M)))
+ :NAME 'scalar-mult-matrix)
+ (s-*-a a M)))
+
+(defthm
+ alist2p-s-*
+ (implies (alist2p name M)
+ (alist2p name (s-* a M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((s-* a M))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-s-*
+ (implies (array2p name M)
+ (array2p name (s-* a M)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((s-* a M))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-s-*
+ (equal (dimensions name (s-* a M))
+ (dimensions name M))
+ :hints (("Goal"
+ :in-theory (enable array2p dimensions header))))
+
+(defthm
+ aref2-s-*
+ (equal (aref2 name (s-* a M) i j)
+ (* a (aref2 name M i j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(in-theory (disable s-*))
+
+(defthm
+ matrixp-s-*
+ (implies (matrixp m n X)
+ (matrixp m n (s-* a X))))
+
+(defthm
+ m-=-row-1-s-*
+ (implies (m-=-row-1 M1 M2 i j)
+ (m-=-row-1 (s-* a M1)(s-* a M2) i j)))
+
+(defcong
+ ;; M-=-IMPLIES-M-=-S-*-2
+ m-= m-= (s-* a M) 2)
+
+(defthm
+ m-=-row-associate-scalars-left-s-*
+ (m-=-row (s-* a1 (s-* a2 M))(s-* (* a1 a2) M) i j))
+
+(defthm
+ m-=-row-1-associate-scalars-left-s-*
+ (m-=-row-1 (s-* a1 (s-* a2 M))(s-* (* a1 a2) M) i j))
+
+(defthm
+ associate-scalars-left-s-*
+ (implies (alist2p name M)
+ (m-= (s-* a1 (s-* a2 M))
+ (s-* (* a1 a2) M))))
+
+(defthm
+ m-=-row-1-s-*-0
+ (m-=-row-1 (s-* 0 M)(m-0 (r M)(c M)) i j))
+
+(defthm
+ m-=-s-*-0
+ (implies (alist2p name M)
+ (m-= (s-* 0 M)(m-0 (r M)(c M)))))
+
+(defthm
+ m-=-row-1-s-*-m-0
+ (m-=-row-1 (s-* a (m-0 m n))(m-0 m n) i j))
+
+(defthm
+ m-=-s-*-m-0
+ (implies (and (integerp m)
+ (integerp n)
+ (> m 0)
+ (> n 0))
+ (m-= (s-* a (m-0 m n))(m-0 m n))))
+
+(defthm
+ m-=-row-1-s-*-1
+ (m-=-row-1 (s-* 1 M) M i j))
+
+(defthm
+ m-=-s-*-1
+ (implies (alist2p name M)
+ (m-= (s-* 1 M) M)))
+
+(defthm
+ m-=-row-1-s-*_-1
+ (m-=-row-1 (s-* -1 M)(m-unary-- M) i j))
+
+(defthm
+ m-=-s-*_-1
+ (implies (alist2p name M)
+ (m-= (s-* -1 M)(m-unary-- M))))
+
+(defthm
+ m-=-row-1-m-trans-s-*
+ (m-=-row-1 (m-trans (s-* s M))
+ (s-* s (m-trans M))
+ i
+ j))
+
+(defthm
+ m-=-m-trans-s-*
+ (implies (alist2p name M)
+ (m-= (m-trans (s-* s M))
+ (s-* s (m-trans M)))))
+
+;;;;;;;;;;;;;;
+;; Matrix sum:
+
+(defun
+ m-binary-+-row (M1 M2 m n)
+ "Return an alist with the following values:
+ M1(m 0)+M2(m 0), . . . , M1(m n)+M2(m n);
+ ie. construct an alist of values representing
+ the vector sum of the m'th row of M1 and the
+ m'th row of M2."
+ (declare (xargs :guard
+ (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions
+ '$arg1 M1)))
+ (and (< m (first dims1))
+ (< n (second dims1))))
+ (let ((dims2 (dimensions
+ '$arg2 M2)))
+ (and (< m (first dims2))
+ (< n (second dims2))))
+ )))
+ (if (zp n)
+ (list (cons (cons m 0)
+ (+ (fix (aref2 '$arg1 M1 m 0))
+ (fix (aref2 '$arg2 M2 m 0)))))
+ (cons (cons (cons m n)
+ (+ (fix (aref2 '$arg1 M1 m n))
+ (fix (aref2 '$arg2 M2 m n))))
+ (m-binary-+-row M1 M2 m (- n 1)))))
+
+(defthm
+ m-binary-+-row-remove-compress2-1
+ (implies (and (alist2p name l1)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l1)))
+ (< j (cadr (dimensions name l1))))
+ (equal (m-binary-+-row (compress2 name l1) l2 i j)
+ (m-binary-+-row l1 l2 i j))))
+
+(defthm
+ m-binary-+-row-remove-compress2-2
+ (implies (and (alist2p name l2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l2)))
+ (< j (cadr (dimensions name l2))))
+ (equal (m-binary-+-row l1 (compress2 name l2) i j)
+ (m-binary-+-row l1 l2 i j))))
+
+(defthm
+ m-=-row-implies-equal-m-binary-+-row-1
+ (implies (m-=-row M1 M2 m n)
+ (equal (m-binary-+-row M1 M3 m n)
+ (m-binary-+-row M2 M3 m n))))
+
+(defthm
+ m-=-row-implies-equal-m-binary-+-row-2
+ (implies (m-=-row M2 M3 m n)
+ (equal (m-binary-+-row M1 M2 m n)
+ (m-binary-+-row M1 M3 m n))))
+
+(defthm
+ assoc2-m-binary-+-row
+ (implies (and (integerp n)
+ (integerp j)
+ (>= j 0)
+ (<= j n))
+ (assoc2 m j (m-binary-+-row M1 M2 m n))))
+
+(defthm
+ assoc2=nil-m-binary-+-row
+ (implies (not (equal i m))
+ (equal (assoc2 i j (m-binary-+-row M1 M2 m n))
+ nil)))
+
+(defthm
+ cdr-assoc2-m-binary-+-row
+ (implies (and (integerp n)
+ (integerp j)
+ (>= j 0)
+ (<= j n))
+ (equal (cdr (assoc2 m j (m-binary-+-row M1 M2 m n)))
+ (+ (aref2 '$arg1 M1 m j)
+ (aref2 '$arg2 M2 m j)))))
+
+(defun
+ m-binary-+-row-1 (M1 M2 m n)
+ "Return an alist with all the following values:
+ M1(0 0)+M2(0 0), . . . , M1(0 n)+M2(0 n)
+ . . .
+ . . .
+ . . .
+ M1(m 0)+M2(m 0), . . . , M1(m n)+M2(m n);
+ ie. construct an alist of values representing
+ the vector sum of rows 0 thru m of M1 with
+ the corresponding rows 0 thru m of M2."
+ (declare (xargs :guard
+ (and (integerp m)
+ (>= m 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions
+ '$arg1 M1)))
+ (and (< m (first dims1))
+ (< n (second dims1))))
+ (let ((dims2 (dimensions
+ '$arg2 M2)))
+ (and (< m (first dims2))
+ (< n (second dims2))))
+ )))
+ (if (zp m)
+ (m-binary-+-row M1 M2 0 n)
+ (append (m-binary-+-row M1 M2 m n)
+ (m-binary-+-row-1 M1 M2 (- m 1) n))))
+
+(defthm
+ alistp-m-binary-+-row-1
+ (alistp (m-binary-+-row-1 M1 M2 m n)))
+
+(defthm
+ bounded-integerp-alistp2-m-binary-+-row-1
+ (implies (and (integerp m)
+ (integerp n)
+ (>= i 0)
+ (>= j 0)
+ (< i m)
+ (< j n))
+ (bounded-integer-alistp2 (m-binary-+-row-1 M1 M2 i j)
+ m
+ n)))
+
+(defthm
+ m-binary-+-row-1-remove-compress2-1
+ (implies (and (alist2p name l1)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l1)))
+ (< j (cadr (dimensions name l1))))
+ (equal (m-binary-+-row-1 (compress2 name l1) l2 i j)
+ (m-binary-+-row-1 l1 l2 i j))))
+
+(defthm
+ m-binary-+-row-1-remove-compress2-2
+ (implies (and (alist2p name l2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name l2)))
+ (< j (cadr (dimensions name l2))))
+ (equal (m-binary-+-row-1 l1 (compress2 name l2) i j)
+ (m-binary-+-row-1 l1 l2 i j))))
+
+(defthm
+ m-=-row-1-implies-equal-m-binary-+-row-1-1
+ (implies (m-=-row-1 M1 M2 m n)
+ (equal (m-binary-+-row-1 M1 M3 m n)
+ (m-binary-+-row-1 M2 M3 m n))))
+
+(defthm
+ m-=-row-1-implies-equal-m-binary-+-row-1-2
+ (implies (m-=-row-1 M2 M3 m n)
+ (equal (m-binary-+-row-1 M1 M2 m n)
+ (m-binary-+-row-1 M1 M3 m n))))
+
+(defthm
+ assoc2-m-binary-+-row-1
+ (implies (and (integerp m)
+ (integerp n)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (<= i m)
+ (<= j n))
+ (assoc2 i j (m-binary-+-row-1 M1 M2 m n))))
+
+(defthm
+ assoc2=nil-m-binary-+-row-1
+ (implies (and (>= m 0)
+ (> i m))
+ (equal (assoc2 i j (m-binary-+-row-1 M1 M2 m n))
+ nil)))
+
+(local
+ (defthm
+ assoc2-append
+ (equal (assoc2 i j (append L1 L2))
+ (if (assoc2 i j L1)
+ (assoc2 i j L1)
+ (assoc2 i j L2)))))
+
+(local
+ (defthm
+ cdr-assoc2-m-binary-+-row-1-lemma
+ (implies (and (equal (cdr (assoc2 i j
+ (m-binary-+-row-1 M1 M2
+ (+ -1 m) n)))
+ (+ (aref2 '$arg M1 i j)
+ (aref2 '$arg M2 i j)))
+ (integerp j)
+ (<= 0 j)
+ (<= j n))
+ (equal (cdr (assoc2 i j
+ (append (m-binary-+-row M1 M2 m n)
+ (m-binary-+-row-1 M1 M2
+ (+ -1 m) n))))
+ (+ (aref2 '$arg M1 i j)
+ (aref2 '$arg M2 i j))))))
+
+(local (in-theory (disable assoc2-append)))
+
+(defthm
+ cdr-assoc2-m-binary-+-row-1
+ (implies (and (integerp m)
+ (integerp n)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (<= i m)
+ (<= j n))
+ (equal (cdr (assoc2 i j (m-binary-+-row-1 M1 M2 m n)))
+ (+ (aref2 '$arg1 M1 i j)
+ (aref2 '$arg2 M2 i j)))))
+
+(local (in-theory (disable cdr-assoc2-m-binary-+-row-1-lemma)))
+
+(defun
+ m-binary-+ (M1 M2)
+ "Return an alist representing the matrix sum
+ of the matrices represented by the alists M1
+ and M2. This is done by adding a header to an
+ alist containing the appropriate values."
+ (declare (xargs :guard
+ (and (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dim1 (dimensions '$arg1
+ M1))
+ (dim2 (dimensions '$arg2
+ M2)))
+ (and
+ (= (first dim1)
+ (first dim2))
+ (= (second dim1)
+ (second dim2)))))
+ ))
+ (let* ((dim1 (dimensions '$arg1 M1))
+ (dim2 (dimensions '$arg2 M2))
+ (dim11 (first dim1))
+ (dim12 (second dim1))
+ (dim21 (first dim2))
+ (dim22 (second dim2)))
+ (if (mbt (and (alist2p '$arg1 M1)
+ (alist2p '$arg2 M2)
+ (= dim11 dim21)
+ (= dim12 dim22)))
+ (cons (list :HEADER
+ :DIMENSIONS (list dim11 dim12)
+ :MAXIMUM-LENGTH
+ (+ 1 (* dim11 dim12))
+ :DEFAULT 0
+ :NAME 'matrix-sum)
+ (m-binary-+-row-1 (compress2 '$arg1 M1)
+ (compress2 '$arg2 M2)
+ (- dim11 1)
+ (- dim12 1)))
+ (+ M1 M2))))
+
+(defmacro
+ m-+ (&rest rst)
+ (if rst
+ (if (cdr rst)
+ (xxxjoin 'm-binary-+ rst)
+ (car rst))
+ 0))
+
+(add-binop m-+ m-binary-+)
+
+(defthm
+ alist2p-m-+
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (alist2p name (m-+ M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-+ M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions))))
+
+(defthm
+ array2p-m-+
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (array2p name (m-+ M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-+ M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ array2p-m-+-1
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (array2p name (m-+ M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-+ M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+
+ equal-list-dimensions-array2p)
+ :use ((:instance
+ equal-list-dimensions-array2p
+ (M M1))
+ (:instance
+ equal-list-dimensions-array2p
+ (M M2))))))
+
+(defthm
+ dimensions-m-+-alist2p
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (equal (dimensions name (m-+ M1 M2))
+ (list (car (dimensions name M1))
+ (cadr (dimensions name M1)))))
+ :hints (("Goal"
+ :in-theory (enable alist2p dimensions
+ header))))
+
+(defthm
+ dimensions-m-+-array2p
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (equal (dimensions name (m-+ M1 M2))
+ (dimensions name M1)))
+ :hints (("Goal"
+ :in-theory (disable
+ equal-list-dimensions-array2p
+ dimensions-m-+-alist2p)
+ :use ((:instance
+ equal-list-dimensions-array2p
+ (M M1))
+ dimensions-m-+-alist2p))))
+
+(defthm
+ matrixp-m-+
+ (implies (and (matrixp m n X1)
+ (matrixp m n X2))
+ (matrixp m n (m-+ X1 X2)))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ default-m-+-alist2p
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2))))
+ (equal (default name (m-+ M1 M2)) 0))
+ :hints (("Goal"
+ :in-theory (enable alist2p default
+ header))))
+
+(defthm
+ default-m-+-array2p
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (equal (default name (m-+ M1 M2)) 0))
+ :hints (("Goal"
+ :in-theory (enable array2p default header))))
+
+(defthm
+ maximum-length-m-+
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (dimensions name M1)
+ (dimensions name M2)))
+ (equal (maximum-length name (m-+ M1 M2))
+ (+ 1 (* (car (dimensions name M1))
+ (cadr (dimensions name M1))))))
+ :hints (("Goal"
+ :in-theory (enable array2p maximum-length header))))
+
+(defthm
+ aref2-m-+
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (first (dimensions name M1))
+ (first (dimensions name M2)))
+ (equal (second (dimensions name M1))
+ (second (dimensions name M2)))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (car (dimensions name M1)))
+ (< j (cadr (dimensions name M1))))
+ (equal (aref2 name (m-+ M1 M2) i j)
+ (+ (aref2 name M1 i j)
+ (aref2 name M2 i j))))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-+-1
+ m-= equal (M-+ M1 M2) 1)
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-+-2
+ m-= equal (M-+ M1 M2) 2)
+
+(defthm
+ commutativity-of-m-binary-+-row
+ (equal (m-binary-+-row M1 M2 m n)
+ (m-binary-+-row M2 M1 m n)))
+
+(defthm
+ commutativity-of-m-binary-+-row-1
+ (equal (m-binary-+-row-1 M1 M2 m n)
+ (m-binary-+-row-1 M2 M1 m n)))
+
+(defthm
+ commutativity-of-m-+
+ (equal (m-+ M1 M2)
+ (m-+ M2 M1)))
+
+(defthm
+ aref2-cons
+ (equal (aref2 name (cons (cons (cons i j) val) lst) m n)
+ (if (and (equal i m)
+ (equal j n))
+ val
+ (aref2 name lst m n)))
+ :hints (("Goal"
+ :in-theory (enable aref2))))
+
+(defthm
+ aref2-cons-move-header
+ (equal (aref2 name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (cons (cons (cons i j) val) lst))
+ m
+ n)
+ (if (and (equal i m)
+ (equal j n))
+ val
+ (aref2 name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ m
+ n)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ m-binary-+-row-remove-last
+ (implies (and (>= i 0)
+ (> n i))
+ (equal (m-binary-+-row
+ M1
+ (cons (cons (cons m n) val) M2)
+ m
+ i)
+ (m-binary-+-row M1
+ M2
+ m
+ i))))
+
+(defthm
+ associativity-of-m-binary-+-row
+ (equal (m-binary-+-row (m-binary-+-row M1 M2 m n)
+ M3
+ m
+ n)
+ (m-binary-+-row M1
+ (m-binary-+-row M2 M3 m n)
+ m
+ n)))
+
+(in-theory (disable commutativity-of-m-binary-+-row
+ commutativity-of-m-binary-+-row-1))
+
+(in-theory (disable associativity-of-m-binary-+-row))
+
+(defthm
+ m-binary-+-row-append-1
+ (equal (m-binary-+-row (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ M3
+ m
+ n)
+ (m-binary-+-row (m-binary-+-row M1 M2 m n)
+ M3
+ m
+ n)))
+
+(defthm
+ m-binary-+-row-append-2
+ (equal (m-binary-+-row M1
+ (append (m-binary-+-row M2
+ M3
+ m
+ n)
+ lst)
+ m
+ n)
+ (m-binary-+-row M1
+ (m-binary-+-row M2 M3 m n)
+ m
+ n)))
+
+(defthm
+ m-binary-+-row-cons-1
+ (implies (> m i)
+ (equal (m-binary-+-row
+ (cons (cons (cons m n) val) lst)
+ M1
+ i
+ j)
+ (m-binary-+-row lst M1 i j))))
+
+(defthm
+ m-binary-+-row-cons-1-a
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (m-binary-+-row
+ (cons (cons (cons m n) val) lst)
+ M1
+ i
+ j)
+ (m-binary-+-row lst M1 i j))))
+
+(defthm
+ m-binary-+-row-cons-1-a-header
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (m-binary-+-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (cons (cons (cons m n) val) lst))
+ M3
+ i
+ j)
+ (m-binary-+-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ i
+ j))))
+
+(defthm
+ m-binary-+-row-cons-2
+ (implies (> m i)
+ (equal (m-binary-+-row
+ M1
+ (cons (cons (cons m n) val) lst)
+ i
+ j)
+ (m-binary-+-row M1 lst i j))))
+
+(defthm
+ m-binary-+-row-cons-2-a-header
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (m-binary-+-row
+ M1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (cons (cons (cons m n) val) lst))
+ i
+ j)
+ (m-binary-+-row
+ M1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ i
+ j))))
+
+(defthm
+ aref2-append-m-binary-+-row
+ (implies (and (> m i))
+ (equal (aref2 name (append (m-binary-+-row M1 M2 m j)
+ lst)
+ i n)
+ (aref2 name lst i n))))
+
+(defthm
+ aref2-append-m-binary-+-row-header
+ (implies (and (> m i))
+ (equal (aref2
+ name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1 M2 m j)
+ lst))
+ i
+ n)
+ (aref2
+ name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ i
+ n))))
+
+(defthm
+ m-binary-+-row-append-3
+ (implies (> m i)
+ (equal (m-binary-+-row (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ M3
+ i
+ n)
+ (m-binary-+-row lst
+ M3
+ i
+ n))))
+
+(defthm
+ m-binary-+-row-append-3-header
+ (implies (> m i)
+ (equal (m-binary-+-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ M3
+ i
+ n)
+ (m-binary-+-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ i
+ n))))
+
+(defthm
+ m-binary-+-row-append-4
+ (implies (> m i)
+ (equal (m-binary-+-row M3
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ i
+ n)
+ (m-binary-+-row M3
+ lst
+ i
+ n))))
+
+(defthm
+ m-binary-+-row-append-4-header
+ (implies (> m i)
+ (equal (m-binary-+-row
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ i
+ n)
+ (m-binary-+-row
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ i
+ n))))
+
+(defthm
+ m-binary-+-row-1-append-1
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-binary-+-row-1 (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ M3
+ j
+ n)
+ (m-binary-+-row-1 lst
+ M3
+ j
+ n))))
+
+(defthm
+ m-binary-+-row-1-append-1-header
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-binary-+-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ M3
+ j
+ n)
+ (m-binary-+-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ j
+ n))))
+
+(defthm
+ m-binary-+-row-1-append-2
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-binary-+-row-1 M1
+ (append (m-binary-+-row M2
+ M3
+ m
+ n)
+ lst)
+ j
+ n)
+ (m-binary-+-row-1 M1
+ lst
+ j
+ n))))
+
+(defthm
+ m-binary-+-row-1-append-2-header
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-binary-+-row-1
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ j
+ n)
+ (m-binary-+-row-1
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ j
+ n))))
+
+(in-theory (enable associativity-of-m-binary-+-row))
+
+(defthm
+ associativity-of-m-binary-+-row-1
+ (equal (m-binary-+-row-1 (m-binary-+-row-1 M1 M2 m n) M3 m n)
+ (m-binary-+-row-1 M1 (m-binary-+-row-1 M2 M3 m n) m n)))
+
+(defthm
+ dimensions-header
+ (equal (dimensions name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst))
+ dims)
+ :hints (("Goal"
+ :in-theory (enable header dimensions))))
+
+(defthm
+ default-header
+ (equal (default name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst))
+ default)
+ :hints (("Goal"
+ :in-theory (enable header default))))
+
+(defthm
+ alist2p-m-binary-+-header
+ (implies (and (alist2p name1 M1)
+ (alist2p name2 M2)
+ (equal (first (dimensions '$arg M1))
+ (first (dimensions '$arg M2)))
+ (equal (second (dimensions '$arg M1))
+ (second (dimensions '$arg M2))
+ ))
+ (alist2p name
+ (cons (list :HEADER
+ :DIMENSIONS
+ (list
+ (first
+ (DIMENSIONS '$ARG
+ M1))
+ (second
+ (dimensions '$arg
+ M1)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1))))
+ :DEFAULT 0
+ :NAME 'MATRIX-SUM)
+ (m-binary-+-row-1 M1
+ M2
+ (+ -1
+ (car (dimensions
+ '$arg M1)))
+ (+ -1
+ (cadr (dimensions
+ '$arg M1)))
+ ))))
+ :hints (("Goal"
+ :use alist2p-m-+)))
+
+(defthm
+ array2p-m-binary-+-header
+ (implies (and (array2p name1 M1)
+ (array2p name2 M2)
+ (equal (dimensions '$arg M1)
+ (dimensions '$arg M2))
+ (symbolp name))
+ (array2p name
+ (cons (list :HEADER
+ :DIMENSIONS (DIMENSIONS '$ARG M1)
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1))))
+ :DEFAULT 0
+ :NAME 'MATRIX-SUM)
+ (m-binary-+-row-1 M1
+ M2
+ (+ -1
+ (car (dimensions
+ '$arg M1)))
+ (+ -1
+ (cadr (dimensions
+ '$arg M1)))
+ ))))
+ :hints (("Goal"
+ :use array2p-m-+)))
+
+(defthm
+ aref2-m-binary-+-row-1-remove-header-alist2p
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j)
+ (< i (car (dimensions name M1)))
+ (< j (cadr (dimensions name M1))))
+ (equal (aref2 name
+ (cons (list :HEADER
+ :DIMENSIONS
+ (list (first
+ (DIMENSIONS '$ARG
+ M1))
+ (second
+ (dimensions '$arg
+ M1)))
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ (+ -1
+ (car (dimensions
+ '$arg M1)))
+ (+ -1
+ (cadr (dimensions
+ '$arg M1)))))
+ i j)
+ (aref2 name (m-binary-+-row-1 M1
+ M2
+ (+ -1
+ (car (dimensions
+ name M1)))
+ (+ -1
+ (cadr (dimensions
+ name M1))))
+ i
+ j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ aref2-m-binary-+-row-1-remove-header-array2p
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j)
+ (< i (car (dimensions name M1)))
+ (< j (cadr (dimensions name M1))))
+ (equal (aref2 name
+ (cons (list :HEADER
+ :DIMENSIONS (DIMENSIONS '$ARG M1)
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ (+ -1
+ (car (dimensions
+ '$arg M1)))
+ (+ -1
+ (cadr (dimensions
+ '$arg M1)))))
+ i j)
+ (aref2 name (m-binary-+-row-1 M1
+ M2
+ (+ -1
+ (car (dimensions
+ name M1)))
+ (+ -1
+ (cadr (dimensions
+ name M1))))
+ i
+ j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defthm
+ m-binary-+-row-append-1-remove-header
+ (equal (m-binary-+-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1 M2 m n)
+ lst))
+ M3
+ m
+ n)
+ (m-binary-+-row (m-binary-+-row M1 M2 m n)
+ M3
+ m
+ n))
+ :hints (("Goal"
+ :in-theory
+ (disable
+ ASSOCIATIVITY-OF-M-BINARY-+-ROW))))
+
+(defthm
+ m-binary-+-row-append-2-remove-header
+ (equal (m-binary-+-row M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1 M2 m n)
+ lst))
+ m
+ n)
+ (m-binary-+-row M3
+ (m-binary-+-row M1 M2 m n)
+ m
+ n))
+ :hints (("Goal"
+ :in-theory (disable ASSOCIATIVITY-OF-M-BINARY-+-ROW))))
+
+(defthm
+ m-binary-+-row-remove-header-1
+ (equal (m-binary-+-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row M1 M2 m n))
+ M3
+ m
+ n)
+ (m-binary-+-row (m-binary-+-row M1 M2 m n)
+ M3
+ m
+ n))
+ :hints (("Goal"
+ :in-theory (disable ASSOCIATIVITY-OF-M-BINARY-+-ROW))))
+
+(defthm
+ m-binary-+-row-remove-header-2
+ (equal (m-binary-+-row M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row M1 M2 m n))
+ m
+ n)
+ (m-binary-+-row M3
+ (m-binary-+-row M1 M2 m n)
+ m
+ n))
+ :hints (("Goal"
+ :in-theory (disable ASSOCIATIVITY-OF-M-BINARY-+-ROW))))
+
+(defthm
+ m-binary-+-row-1-remove-header-1
+ (equal (m-binary-+-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ m
+ n))
+ M3
+ m
+ n)
+ (m-binary-+-row-1
+ (m-binary-+-row-1 M1
+ M2
+ m
+ n)
+ M3
+ m
+ n))
+ :hints (("Goal"
+ :in-theory (disable associativity-of-m-binary-+-row
+ associativity-of-m-binary-+-row-1))))
+
+(defthm
+ m-binary-+-row-1-remove-header-2
+ (equal (m-binary-+-row-1
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ m
+ n))
+ m
+ n)
+ (m-binary-+-row-1
+ M3
+ (m-binary-+-row-1 M1
+ M2
+ m
+ n)
+ m
+ n))
+ :hints (("Goal"
+ :in-theory (disable associativity-of-m-binary-+-row
+ associativity-of-m-binary-+-row-1))))
+
+(defthm
+ alist2p-m-binary-+-header-hack
+ (IMPLIES (AND (ALIST2P '$ARG1 M2)
+ (ALIST2P '$ARG2 M3)
+ (EQUAL (CAR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M2)))
+ (EQUAL (CADR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2)))
+ (EQUAL (CAR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M3)))
+ (EQUAL (CADR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M3))))
+ (ALIST2P '$ARG2
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1 M2 M3 (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1)))))))
+ :hints (("Goal"
+ :in-theory (disable alist2p-m-binary-+-header)
+ :use (:instance
+ alist2p-m-binary-+-header
+ (M1 M2)
+ (M2 M3)))))
+
+(defthm
+ m-binary-+-row-1-remove-compress2-2-hack
+ (IMPLIES
+ (AND (ALIST2P '$ARG1 M2)
+ (ALIST2P '$ARG2 M3)
+ (EQUAL (CAR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M2)))
+ (EQUAL (CADR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2)))
+ (EQUAL (CAR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M3)))
+ (EQUAL (CADR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M3))))
+ (EQUAL
+ (M-BINARY-+-ROW-1
+ M1
+ (M-BINARY-+-ROW-1 M2 M3 (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1))))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1))))
+ (M-BINARY-+-ROW-1
+ M1
+ (COMPRESS2
+ '$ARG
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1 M2 M3 (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1))))))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1))))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+-row-1-remove-compress2-2
+ alist2p-m-binary-+-header-hack)
+ :use ((:instance
+ m-binary-+-row-1-remove-compress2-2
+ (l1 M1)
+ (name '$arg)
+ (l2 (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1 M2 M3 (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1))))))
+ (i (+ -1 (CAR (DIMENSIONS '$ARG M1))))
+ (j (+ -1 (CADR (DIMENSIONS '$ARG M1)))))
+ alist2p-m-binary-+-header-hack))))
+
+(defthm
+ associativity-of-m-+
+ (equal (m-+ (m-+ M1 M2) M3)
+ (m-+ M1 M2 M3))
+ :hints (("Goal"
+ :in-theory (disable commutativity-of-m-+))))
+
+(defthm
+ m-=-row-cons-1-a
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (m-=-row (cons (cons (cons m n) val) lst)
+ M1
+ i
+ j)
+ (m-=-row lst M1 i j))))
+
+(defthm
+ m-=-row-cons-2-a
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (m-=-row M1
+ (cons (cons (cons m n) val) lst)
+ i
+ j)
+ (m-=-row M1 lst i j))))
+
+(defthm
+ m-=-row-cons-1-a-header
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (m-=-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (cons (cons (cons m n) val) lst))
+ M3
+ i
+ j)
+ (m-=-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ i
+ j))))
+
+(defthm
+ m-=-row-cons-2-a-header
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (m-=-row
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (cons (cons (cons m n) val) lst))
+ i
+ j)
+ (m-=-row
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ i
+ j))))
+
+(defthm
+ m-=-row-m-binary-+-row-append-1
+ (equal (m-=-row (append (m-binary-+-row M1 M2 m n)
+ lst)
+ M3
+ m
+ n)
+ (m-=-row (m-binary-+-row M1 M2 m n)
+ M3
+ m
+ n)))
+
+(defthm
+ m-=-row-m-binary-+-row-append-2
+ (equal (m-=-row M3
+ (append (m-binary-+-row M1 M2 m n)
+ lst)
+ m
+ n)
+ (m-=-row M3
+ (m-binary-+-row M1 M2 m n)
+ m
+ n)))
+
+(defthm
+ m-=-row-m-binary-+-row-append-1-remove-header
+ (equal (m-=-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1 M2 m n)
+ lst))
+ M3
+ m
+ n)
+ (m-=-row (m-binary-+-row M1 M2 m n)
+ M3
+ m
+ n)))
+
+(defthm
+ m-=-row-m-binary-+-row-append-2-remove-header
+ (equal (m-=-row M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1 M2 m n)
+ lst))
+ m
+ n)
+ (m-=-row M3
+ (m-binary-+-row M1 M2 m n)
+ m
+ n)))
+
+(defthm
+ m-=-row-m-binary-+-row-remove-header-1
+ (equal (m-=-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row M1 M2 m n))
+ M3
+ m
+ n)
+ (m-=-row (m-binary-+-row M1 M2 m n)
+ M3
+ m
+ n)))
+
+(defthm
+ m-=-row-m-binary-+-row-remove-header-2
+ (equal (m-=-row M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row M1 M2 m n))
+ m
+ n)
+ (m-=-row m3
+ (m-binary-+-row M1 M2 m n)
+ m
+ n)))
+
+(defthm
+ m-=-row-m-binary-+-row-append-3
+ (implies (> m i)
+ (equal (m-=-row (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ M3
+ i
+ n)
+ (m-=-row lst
+ M3
+ i
+ n))))
+
+(defthm
+ m-=-row-m-binary-+-row-append-4
+ (implies (> m i)
+ (equal (m-=-row M3
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ i
+ n)
+ (m-=-row M3
+ lst
+ i
+ n))))
+
+(defthm
+ m-=-row-m-binary-+-row-append-3-header
+ (implies (> m i)
+ (equal (m-=-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ M3
+ i
+ n)
+ (m-=-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ i
+ n))))
+
+(defthm
+ m-=-row-m-binary-+-row-append-4-header
+ (implies (> m i)
+ (equal (m-=-row
+ m3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ i
+ n)
+ (m-=-row
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ i
+ n))))
+
+(defthm
+ m-=-row-1-m-binary-+-row-append-1
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1 (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ M3
+ j
+ n)
+ (m-=-row-1 lst
+ M3
+ j
+ n))))
+
+(defthm
+ m-=-row-1-m-binary-+-row-append-2
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1 M3
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst)
+ j
+ n)
+ (m-=-row-1 M3
+ lst
+ j
+ n))))
+
+(defthm
+ m-=-row-1-m-binary-+-row-append-1-header
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ M3
+ j
+ n)
+ (m-=-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ j
+ n))))
+
+(defthm
+ m-=-row-1-m-binary-+-row-append-2-header
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-+-row M1
+ M2
+ m
+ n)
+ lst))
+ j
+ n)
+ (m-=-row-1
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ j
+ n))))
+
+(defthm
+ m-=-row-1-m-binary-+-row-1-remove-header-1
+ (equal (m-=-row-1 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ m
+ n))
+ M3
+ m
+ n)
+ (m-=-row-1 (m-binary-+-row-1 M1 M2 m n)
+ M3
+ m
+ n)))
+
+(defthm
+ m-=-row-1-m-binary-+-row-1-remove-header-2
+ (equal (m-=-row-1 M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ m
+ n))
+ m
+ n)
+ (m-=-row-1 M3
+ (m-binary-+-row-1 M1 M2 m n)
+ m
+ n)))
+
+(defthm
+ m-=-row-1-m-binary-+-row-1-m-0
+ (m-=-row-1 (m-binary-+-row-1 M1
+ (m-0 m n)
+ i
+ j)
+ M1
+ i
+ j))
+
+(defthm
+ alist2p-m-0-hack
+ (IMPLIES (ALIST2P NAME M)
+ (ALIST2P '$ARG1
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1 M
+ (M-0 (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable alist2p-m-+)
+ :use (:instance
+ alist2p-m-+
+ (M1 M)
+ (M2 (M-0 (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (name '$arg)))))
+
+(defthm
+ ALIST2P-M-BINARY-+-HEADER-m-0-hack
+ (implies (alist2p '$arg M)
+ (ALIST2P '$ARG
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1 M
+ (M-0 (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable ALIST2P-M-BINARY-+-HEADER)
+ :use (:instance
+ ALIST2P-M-BINARY-+-HEADER
+ (name1 '$arg)
+ (name2 '$arg)
+ (M1 M)
+ (M2 (M-0 (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ M-=-ROW-1-REMOVE-COMPRESS2-1-m-0-hack
+ (IMPLIES (ALIST2P NAME M)
+ (M-=-ROW-1
+ (COMPRESS2 '$ARG
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1 M
+ (M-0 (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M))))))
+ M
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M))))))
+
+(defthm
+ right-m-+-unicity-of-m-0
+ (implies (alist2p name M)
+ (m-= (m-+ M (m-0 (car (dimensions name M))
+ (cadr (dimensions name M))))
+ M)))
+
+(defthm
+ left-m-+-unicity-of-m-0
+ (implies (alist2p name M)
+ (m-= (m-+ (m-0 (car (dimensions name M))
+ (cadr (dimensions name M)))
+ M)
+ M)))
+
+(defmacro
+ m-- (x &optional (y 'nil binary-casep))
+ (if binary-casep
+ `(m-binary-+ ,x (m-unary-- ,y))
+ `(m-unary-- ,x)))
+
+(add-macro-alias m-- m-unary--)
+
+(add-invisible-fns m-binary-+ m-unary--)
+(add-invisible-fns m-unary-- m-unary--)
+
+(defthm
+ m-=-row-1-m-binary-+-row-1-m-unary--
+ (m-=-row-1 (m-binary-+-row-1 M1
+ (m-unary-- M1)
+ i
+ j)
+ (m-0 m n)
+ i
+ j))
+
+(defthm
+ left-m-+-inverse-of-m--
+ (implies (alist2p name M)
+ (m-= (m-+ (m-- M) M)
+ (m-0 (car (dimensions name M))
+ (cadr (dimensions name M))))))
+
+(defthm
+ right-m-+-inverse-of-m--
+ (implies (alist2p name M)
+ (m-= (m-+ M (m-- M))
+ (m-0 (car (dimensions name M))
+ (cadr (dimensions name M))))))
+
+(defthm
+ m-=-row-distributivity-of-s-*-over-+
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M))
+ (< j (c M)))
+ (m-=-row (s-* (+ a b) M)
+ (m-+ (s-* a M)(s-* b m))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ m-=-row-1-distributivity-of-s-*-over-+
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M))
+ (< j (c M)))
+ (m-=-row-1 (s-* (+ a b) M)
+ (m-+ (s-* a M)(s-* b m))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ distributivity-of-s-*-over-+
+ (implies (alist2p name M)
+ (m-= (s-* (+ a b) M)
+ (m-+ (s-* a M)(s-* b m))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+
+ alist2p-m-+)
+ :use ((:instance
+ alist2p-m-+
+ (M1 (s-* a M))
+ (M2 (s-* b M)))))))
+
+(defthm
+ m-=-row-distributivity-of-s-*-over-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M1)))
+ (m-=-row (s-* a (m-+ M1 M2))
+ (m-+ (s-* a M1)(s-* a M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ m-=-row-1-distributivity-of-s-*-over-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M1)))
+ (m-=-row-1 (s-* a (m-+ M1 M2))
+ (m-+ (s-* a M1)(s-* a M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ distributivity-of-s-*-over-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (s-* a (m-+ M1 M2))
+ (m-+ (s-* a M1)(s-* a M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+
+ alist2p-s-*)
+ :use ((:instance
+ alist2p-s-*
+ (M (m-binary-+ M1 M2)))
+ (:instance
+ alist2p-s-*
+ (M M1))
+ (:instance
+ alist2p-s-*
+ (M M2))
+ (:instance
+ alist2p-m-+
+ (M1 (s-* a M1))
+ (M2 (s-* a M2)))))))
+
+(defthm
+ m-=-row-m-trans-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (c M1))
+ (< j (r M1)))
+ (m-=-row (m-trans (m-+ M1 M2))
+ (m-+ (m-trans M1)(m-trans M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ m-=-row-1-m-trans-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (c M1))
+ (< j (r M1)))
+ (m-=-row-1 (m-trans (m-+ M1 M2))
+ (m-+ (m-trans M1)(m-trans M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))))
+
+(defthm
+ m-trans-m-+
+ (implies (and (equal (car (dimensions name M1))
+ (car (dimensions name M2)))
+ (equal (cadr (dimensions name M1))
+ (cadr (dimensions name M2)))
+ (alist2p name M1)
+ (alist2p name M2))
+ (m-= (m-trans (m-+ M1 M2))
+ (m-+ (m-trans M1)(m-trans M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-+))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-+
+ alist2p-m-trans)
+ :use (:instance
+ alist2p-m-trans
+ (name '$arg)
+ (M (m-+ M1 M2))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-+
+ alist2p-m-+)
+ :use (:instance
+ alist2p-m-+
+ (name '$arg)
+ (M1 (m-trans M1))
+ (M2 (m-trans M2))))))
+
+;;;;;;;;;;;;;;;;;;
+;; Matrix product:
+
+(defun
+ dot (M1 M2 i j k)
+ "Return the dot product
+ (M1 i 0)*(M2 0 k) + . . . + (M1 i j)*(M2 j k)."
+ (declare (xargs :guard (and (integerp i)
+ (>= i 0)
+ (integerp j)
+ (>= j 0)
+ (integerp k)
+ (>= k 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< i (first dims1))
+ (< j (second dims1))))
+ (let ((dims2 (dimensions '$arg1 M2)))
+ (and (< j (first dims2))
+ (< k (second dims2)))))))
+ (if (zp j)
+ (* (fix (aref2 '$arg1 M1 i 0))
+ (fix (aref2 '$arg2 M2 0 k)))
+ (+ (* (fix (aref2 '$arg1 M1 i j))
+ (fix (aref2 '$arg2 M2 j k)))
+ (dot M1 M2 i (- j 1) k))))
+
+(defthm
+ dot-remove-compress2-1
+ (implies (and (alist2p name l1)
+ (integerp i)
+ (>= i 0)
+ (< i (car (dimensions name l1)))
+ (< j (cadr (dimensions name l1))))
+ (equal (dot (compress2 name l1) l2 i j k)
+ (dot l1 l2 i j k))))
+
+(defthm
+ dot-remove-compress2-2
+ (implies (and (alist2p name l2)
+ (integerp k)
+ (>= k 0)
+ (< j (car (dimensions name l2)))
+ (< k (cadr (dimensions name l2))))
+ (equal (dot l1 (compress2 name l2) i j k)
+ (dot l1 l2 i j k))))
+
+(defthm
+ m-=-row-1-implies-equal-dot-2
+ (implies (and (m-=-row-1 M2 M3 n p)
+ (integerp p)
+ (integerp j)
+ (>= j 0)
+ (>= p j))
+ (equal (dot M1 M2 m n j)
+ (dot M1 M3 m n j)))
+ :hints (("Goal"
+ :do-not '(generalize)
+ :in-theory (disable LEFT-CANCELLATION-FOR-*))))
+
+(defun
+ m-binary-*-row (M1 M2 m j n)
+ "Return an alist with the following values:
+ (dot M1 M2 m j 0), . . . , (dot M1 M2 m j n);
+ ie. construct an alist of values representing
+ the vector of dot products of the m'th row of M1
+ with columns 0 thru n of M2."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp j)
+ (>= j 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (first dims1))
+ (< j (second dims1))))
+ (let ((dims2 (dimensions '$arg1 M2)))
+ (and (< j (first dims2))
+ (< n (second dims2)))))))
+ (if (zp n)
+ (list (cons (cons m 0)
+ (dot M1 M2 m j 0)))
+ (cons (cons (cons m n)
+ (dot M1 M2 m j n))
+ (m-binary-*-row M1 M2 m j (- n 1)))))
+
+(defthm
+ m-binary-*-row-remove-compress2-1
+ (implies (and (alist2p name l1)
+ (integerp i)
+ (>= i 0)
+ (< i (car (dimensions name l1)))
+ (< j (cadr (dimensions name l1))))
+ (equal (m-binary-*-row (compress2 name l1) l2 i j k)
+ (m-binary-*-row l1 l2 i j k))))
+
+(defthm
+ m-binary-*-row-remove-compress2-2
+ (implies (and (alist2p name l2)
+ (integerp k)
+ (>= k 0)
+ (< j (car (dimensions name l2)))
+ (< k (cadr (dimensions name l2))))
+ (equal (m-binary-*-row l1 (compress2 name l2) i j k)
+ (m-binary-*-row l1 l2 i j k))))
+
+(defthm
+ m-=-row-implies-equal-m-binary-*-row-1
+ (implies (m-=-row M1 M2 m n)
+ (equal (m-binary-*-row M1 M3 m n p)
+ (m-binary-*-row M2 M3 m n p))))
+
+(defthm
+ m-=row-1-implies-equal-m-binary-*-row-2
+ (implies (and (m-=-row-1 M2 M3 n p)
+ (integerp p)
+ (>= p 0))
+ (equal (m-binary-*-row M1 M2 m n p)
+ (m-binary-*-row M1 M3 m n p))))
+
+(defthm
+ assoc2-m-binary-*-row
+ (implies (and (integerp p)
+ (integerp j)
+ (>= j 0)
+ (<= j p))
+ (assoc2 m j (m-binary-*-row M1 M2 m n p))))
+
+(defthm
+ assoc2=nil-m-binary-*-row
+ (implies (not (equal i m))
+ (equal (assoc2 i j (m-binary-*-row M1 M2 m n p))
+ nil)))
+
+(defthm
+ cdr-assoc2-m-binary-*-row
+ (implies (and (integerp p)
+ (integerp j)
+ (>= j 0)
+ (<= j p))
+ (equal (cdr (assoc2 m j (m-binary-*-row M1 M2 m n p)))
+ (dot M1 M2 m n j))))
+
+(defun
+ m-binary-*-row-1 (M1 M2 m j n)
+ "Return an alist with all the following values:
+ (dot M1 M2 0 j 0), . . . , (dot M1 M2 0 j n)
+ . . .
+ . . .
+ . . .
+ (dot M1 M2 m j 0), . . . , (dot M1 M2 m j n)."
+ (declare (xargs :guard (and (integerp m)
+ (>= m 0)
+ (integerp j)
+ (>= j 0)
+ (integerp n)
+ (>= n 0)
+ (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (let ((dims1 (dimensions '$arg1 M1)))
+ (and (< m (first dims1))
+ (< j (second dims1))))
+ (let ((dims2 (dimensions '$arg1 M2)))
+ (and (< j (first dims2))
+ (< n (second dims2)))))))
+ (if (zp m)
+ (m-binary-*-row M1 M2 0 j n)
+ (append (m-binary-*-row M1 M2 m j n)
+ (m-binary-*-row-1 M1 M2 (- m 1) j n))))
+
+(defthm
+ alistp-m-binary-*-row-1
+ (alistp (m-binary-*-row-1 M1 M2 m n p)))
+
+(defthm
+ bounded-integerp-alistp2-m-binary-*-row-1
+ (implies (and (integerp m)
+ (integerp n)
+ (>= i 0)
+ (>= k 0)
+ (< i m)
+ (< k n))
+ (bounded-integer-alistp2 (m-binary-*-row-1 M1 M2 i j k)
+ m
+ n)))
+
+(defthm
+ m-binary-*-row-1-remove-compress2-1
+ (implies (and (alist2p name l1)
+ (integerp i)
+ (>= i 0)
+ (< i (car (dimensions name l1)))
+ (< j (cadr (dimensions name l1))))
+ (equal (m-binary-*-row-1 (compress2 name l1) l2 i j k)
+ (m-binary-*-row-1 l1 l2 i j k))))
+
+(defthm
+ m-binary-*-row-1-remove-compress2-2
+ (implies (and (alist2p name l2)
+ (integerp k)
+ (>= k 0)
+ (< j (car (dimensions name l2)))
+ (< k (cadr (dimensions name l2))))
+ (equal (m-binary-*-row-1 l1 (compress2 name l2) i j k)
+ (m-binary-*-row-1 l1 l2 i j k))))
+
+(defthm
+ m-=-row-1-implies-equal-m-binary-*-row-1-1
+ (implies (m-=-row-1 M1 M2 m n)
+ (equal (m-binary-*-row-1 M1 M3 m n p)
+ (m-binary-*-row-1 M2 M3 m n p))))
+
+(defthm
+ m-=-row-1-implies-equal-m-binary-*-row-1-2
+ (implies (and (m-=-row-1 M2 M3 n p)
+ (integerp p)
+ (>= p 0))
+ (equal (m-binary-*-row-1 M1 M2 m n p)
+ (m-binary-*-row-1 M1 M3 m n p))))
+
+(defthm
+ assoc2-m-binary-*-row-1
+ (implies (and (integerp m)
+ (integerp p)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (<= i m)
+ (<= j p))
+ (assoc2 i j (m-binary-*-row-1 M1 M2 m n p))))
+
+(defthm
+ assoc2=nil-m-binary-*-row-1
+ (implies (and (>= m 0)
+ (> i m))
+ (equal (assoc2 i j (m-binary-*-row-1 M1 M2 m n p))
+ nil)))
+
+(local (in-theory (enable assoc2-append)))
+
+(local
+ (defthm
+ cdr-assoc2-m-binary-*-row-1-lemma
+ (implies (and (equal (cdr (assoc2 i
+ j
+ (m-binary-*-row-1 M1
+ M2
+ (+ -1 m)
+ n
+ p)))
+ (dot M1 M2 i n j))
+ (integerp j)
+ (<= 0 j)
+ (<= j p))
+ (equal (cdr (assoc2 i
+ j
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ (m-binary-*-row-1 M1
+ M2
+ (+ -1 m)
+ n
+ p))))
+ (dot M1 M2 i n j)))))
+
+(local (in-theory (disable assoc2-append)))
+
+(defthm
+ cdr-assoc2-m-binary-*-row-1
+ (implies (and (integerp m)
+ (integerp i)
+ (integerp j)
+ (integerp p)
+ (>= i 0)
+ (>= j 0)
+ (<= i m)
+ (<= j p))
+ (equal (cdr (assoc2 i j (m-binary-*-row-1 M1 M2 m n p)))
+ (dot M1 M2 i n j))))
+
+(local (in-theory (disable cdr-assoc2-m-binary-*-row-1-lemma)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Ensuring closure of matrix multiplication.
+
+; Let dim1 be the number of rows and dim2 be the number of columns
+; in an ACL2 two dimensional array. The product, dim1*dim2, is
+; required to fit into 32 bits so that some compilers can lay down
+; faster code. Thus, dim1*dim2 <= maximum-positive-32-bit-integer
+; = 2^31 - 1
+; = 2,147,483,647.
+
+; This restriction on the size of dim1*dim2 means that matrices
+; representable by ACL2 arrays are NOT closed under matrix
+; multiplication, even when the product is mathematically defined.
+; To illustrate, suppose dim1*dim2 is required to be no larger than
+; 20; M1 is a matrix with 5 rows and 2 columns; and M2 is a matrix
+; with 2 rows and 5 columns. Then M1 and M2 would both be
+; representable and their product, M1 * M2, would be mathematically
+; defined, but not representable (since 25 > 20).
+
+; Furthermore, when there are more than two matrices involved in a
+; matrix multiplication, the final product may be both mathematically
+; defined and representable by an ACL2 array, but yet not
+; computable in ACL2. Let's illustrate by extending the example given
+; above with M1 and M2. Suppose M0 is a matrix with 2 rows and 5
+; colums. Then the product (M0 * M1) * M2 is mathematically defined,
+; representable in ACL2, and computable in ACL2 (since both partial
+; products (M0 * M1) and (M0 * M1) * M2 are representable in ACL2).
+; But the product M0 * (M1 * M2) is mathematically defined,
+; representable in ACL2, but NOT computable in ACL2 (since the
+; partial product (M1 * M2) is NOT representable in ACL2).
+
+; One way to prevent this last problem and also ensure closure for
+; matrix multiplication is to require that each of dim1 and dim2
+; be less than or equal to 46,340 which is the integer square root
+; of 2,147,483,647, the maximum-positive-32-bit-integer. Then
+; the product of dim1*dim2 is guarenteed to be less than the
+; the maximum-positive-32-bit-integer. Futhermore, with this stronger
+; restriction, if the product M1 * . . . * Mn is both mathematically
+; defined and representable in ACL2, then, for any way of
+; parenthesizing this product, all the partial products are also
+; mathematically defined and representable in ACL2.
+
+; Thus, for matrix multiplication, it is required that both the
+; number of rows and the number of columns be less than or equal
+; to 46,340.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun m-binary-* (M1 M2)
+ "Return an alist representing the matrix product
+ of the matrices represented by the alists M1
+ and M2. This is done by adding a header to an
+ alist containing the appropriate values."
+ (declare (xargs :guard (and (array2p '$arg1 M1)
+ (array2p '$arg2 M2)
+ (= (second (dimensions '$arg1 M1))
+ (first (dimensions '$arg2 M2))))))
+ (let* ((dim1 (dimensions '$arg1 M1))
+ (dim2 (dimensions '$arg2 M2))
+ (dim11 (first dim1))
+ (dim12 (second dim1))
+ (dim21 (first dim2))
+ (dim22 (second dim2)))
+ (if (mbt (and (alist2p '$arg1 M1)
+ (alist2p '$arg2 M2)
+ (= dim12 dim21)))
+ (cons (list :HEADER
+ :DIMENSIONS
+ (list dim11 dim22)
+ :MAXIMUM-LENGTH
+ (+ 1 (* dim11 dim22))
+ :DEFAULT 0
+ :NAME 'matrix-product)
+ (m-binary-*-row-1 (compress2 '$arg1 M1)
+ (compress2 '$arg2 M2)
+ (- dim11 1)
+ (- dim12 1)
+ (- dim22 1)))
+ (* M1 M2))))
+
+(defmacro
+ m-* (&rest rst)
+ (if rst
+ (if (cdr rst)
+ (xxxjoin 'm-binary-* rst)
+ (car rst))
+ 1))
+
+(add-binop m-* m-binary-*)
+
+(defthm
+ alist2p-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (alist2p name (m-* M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable alist2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ array2p-m-*-1
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2)))
+ (< (* (first (dimensions name M1))
+ (second (dimensions name M2)))
+ *MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-* M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ array2p-m-*
+ (implies (and (array2p name M1)
+ (array2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2)))
+ (<= (first (dimensions name M1))
+ *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (<= (second (dimensions name M2))
+ *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ (array2p name (m-* M1 M2)))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (enable array2p header
+ dimensions
+ maximum-length))))
+
+(defthm
+ dimensions-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (equal (dimensions name (m-* M1 M2))
+ (list (first (dimensions name M1))
+ (second (dimensions name M2)))))
+ :hints (("Goal"
+ :in-theory (enable alist2p dimensions header))))
+
+(defthm
+ matrixp-m-*
+ (implies (and (matrixp m n X1)
+ (matrixp n p X2))
+ (matrixp m p (m-* X1 X2)))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ default-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (equal (default name (m-* M1 M2))
+ 0))
+ :hints (("Goal"
+ :in-theory (enable alist2p default header))))
+
+(defthm
+ maximum-length-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2))))
+ (equal (maximum-length name (m-* M1 M2))
+ (+ 1 (* (first (dimensions name M1))
+ (second (dimensions name M2))))))
+ :hints (("Goal"
+ :in-theory (enable alist2p maximum-length header))))
+
+(defthm
+ aref2-m-*
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (second (dimensions name M1))
+ (first (dimensions name M2)))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M1)))
+ (< j (second (dimensions name M2))))
+ (equal (aref2 name (m-* M1 M2) i j)
+ (dot M1
+ M2
+ i
+ (+ -1 (second (dimensions name M1)))
+ j)))
+ :hints (("Goal"
+ :in-theory (enable aref2 header default))))
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-*-1
+ m-= equal (M-* M1 M2) 1)
+
+(defcong
+ ;; M-=-IMPLIES-EQUAL-M-*-2
+ m-= equal (M-* M1 M2) 2)
+
+(defthm
+ m-=-row-m-binary-*-row-append-1
+ (equal (m-=-row (append (m-binary-*-row M1 M2 m n p)
+ lst)
+ M3
+ m
+ p)
+ (m-=-row (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p)))
+
+(defthm
+ m-=-row-m-binary-*-row-append-2
+ (equal (m-=-row M3
+ (append (m-binary-*-row M1 M2 m n p)
+ lst)
+ m
+ p)
+ (m-=-row M3
+ (m-binary-*-row M1 M2 m n p)
+ m
+ p)))
+
+(defthm
+ m-=-row-m-binary-*-row-append-1-remove-header
+ (equal (m-=-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1 M2 m n p)
+ lst))
+ M3
+ m
+ p)
+ (m-=-row (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p)))
+
+(defthm
+ m-=-row-m-binary-*-row-append-2-remove-header
+ (equal (m-=-row M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1 M2 m n p)
+ lst))
+ m
+ p)
+ (m-=-row M3
+ (m-binary-*-row M1 M2 m n p)
+ m
+ p)))
+
+(defthm
+ m-=-row-m-binary-*-row-remove-header-1
+ (equal (m-=-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row M1 M2 m n p))
+ M3
+ m
+ p)
+ (m-=-row (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p)))
+
+(defthm
+ m-=-row-m-binary-*-row-remove-header-2
+ (equal (m-=-row M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row M1 M2 m n p))
+ m
+ p)
+ (m-=-row m3
+ (m-binary-*-row M1 M2 m n p)
+ m
+ p)))
+
+(defthm
+ aref2-append-m-binary-*-row
+ (implies (and (> m i))
+ (equal (aref2 name (append (m-binary-*-row M1 M2 m j k)
+ lst)
+ i n)
+ (aref2 name lst i n))))
+
+(defthm
+ aref2-append-m-binary-*-row-header
+ (implies (and (> m i))
+ (equal (aref2
+ name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1 M2 m j k)
+ lst))
+ i
+ n)
+ (aref2
+ name
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ i
+ n))))
+
+(defthm
+ m-=-row-m-binary-*-row-append-3
+ (implies (> m i)
+ (equal (m-=-row (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst)
+ M3
+ i
+ p)
+ (m-=-row lst
+ M3
+ i
+ p))))
+
+(defthm
+ m-=-row-m-binary-*-row-append-4
+ (implies (> m i)
+ (equal (m-=-row M3
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst)
+ i
+ p)
+ (m-=-row M3
+ lst
+ i
+ p))))
+
+(defthm
+ m-=-row-m-binary-*-row-append-3-header
+ (implies (> m i)
+ (equal (m-=-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ M3
+ i
+ p)
+ (m-=-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ i
+ p))))
+
+(defthm
+ m-=-row-m-binary-*-row-append-4-header
+ (implies (> m i)
+ (equal (m-=-row
+ m3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ i
+ p)
+ (m-=-row
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ i
+ p))))
+
+(defthm
+ m-=-row-1-m-binary-*-row-append-1
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1 (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst)
+ M3
+ j
+ p)
+ (m-=-row-1 lst
+ M3
+ j
+ p))))
+
+(defthm
+ m-=-row-1-m-binary-*-row-append-2
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1 M3
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst)
+ j
+ p)
+ (m-=-row-1 M3
+ lst
+ j
+ p))))
+
+(defthm
+ m-=-row-1-m-binary-*-row-append-1-header
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ M3
+ j
+ p)
+ (m-=-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ j
+ p))))
+
+(defthm
+ m-=-row-1-m-binary-*-row-append-2-header
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-=-row-1
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ j
+ p)
+ (m-=-row-1
+ M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ j
+ p))))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-remove-header-1
+ (equal (m-=-row-1 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M1
+ M2
+ m
+ n
+ p))
+ M3
+ m
+ p)
+ (m-=-row-1 (m-binary-*-row-1 M1 M2 m n p)
+ M3
+ m
+ p)))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-remove-header-2
+ (equal (m-=-row-1 M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M1
+ M2
+ m
+ n
+ p))
+ m
+ p)
+ (m-=-row-1 M3
+ (m-binary-*-row-1 M1 M2 m n p)
+ m
+ p)))
+
+(defthm
+ dot-m-0-1
+ (equal (dot (m-0 m n) M1 i j k)
+ 0))
+
+(defthm
+ dot-m-0-2
+ (equal (dot M1 (m-0 m n) i j k)
+ 0))
+
+(defthm
+ m-=-row-m-binary-*-row-m-0-1
+ (m-=-row (m-binary-*-row (m-0 m n)
+ M1
+ i
+ j
+ k)
+ (m-0 m p)
+ i
+ k))
+
+(defthm
+ m-=-row-m-binary-*-row-m-0-2
+ (m-=-row (m-binary-*-row M1
+ (m-0 n p)
+ i
+ j
+ k)
+ (m-0 m p)
+ i
+ k))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-m-0-1
+ (m-=-row-1 (m-binary-*-row-1 (m-0 m n)
+ M1
+ i
+ j
+ k)
+ (m-0 m p)
+ i
+ k))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-m-0-2
+ (m-=-row-1 (m-binary-*-row-1 M1
+ (m-0 n p)
+ i
+ j
+ k)
+ (m-0 m p)
+ i
+ k))
+
+(defthm
+ alist2p-m-binary-*-row-1-header-m-0-hack-1
+ (implies (and (ALIST2P NAME M1)
+ (INTEGERP M)
+ (< 0 M))
+ (ALIST2P name1
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST M (CADR (DIMENSIONS '$ARG M1)))
+ :MAXIMUM-LENGTH
+ (+ 1 (* M (CADR (DIMENSIONS '$ARG M1))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 (M-0 M (CAR (DIMENSIONS '$ARG M1)))
+ M1
+ (+ -1 M)
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1)))))))
+ :hints (("Goal"
+ :in-theory (disable Alist2P-M-*)
+ :use (:instance
+ Alist2P-M-*
+ (M1 (m-0 m (first (dimensions name M1))))
+ (M2 M1)))))
+
+(defthm
+ left-nullity-of-m-0-for-m-*
+ (implies (and (alist2p name M1)
+ (integerp m)
+ (> m 0))
+ (m-= (m-* (m-0 m (first (dimensions name M1)))
+ M1)
+ (m-0 m (second (dimensions name M1))))))
+
+(defthm
+ alist2p-m-binary-*-row-1-header-m-0-hack-2
+ (implies (and (ALIST2P NAME M1)
+ (INTEGERP p)
+ (< 0 p))
+ (ALIST2P name1
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1)) P)
+ :MAXIMUM-LENGTH
+ (+ 1 (* P (CAR (DIMENSIONS '$ARG M1))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 M1 (M-0 (CADR (DIMENSIONS '$ARG M1)) P)
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1)))
+ (+ -1 P)))))
+ :hints (("Goal"
+ :in-theory (disable Alist2P-M-*)
+ :use (:instance
+ Alist2P-M-*
+ (M2 (M-0 (CADR (DIMENSIONS '$ARG M1)) P))))))
+
+(defthm
+ right-nullity-of-m-0-for-m-*
+ (implies (and (alist2p name M1)
+ (integerp p)
+ (> p 0))
+ (m-= (m-* M1
+ (m-0 (second (dimensions name M1))
+ p))
+ (m-0 (first (dimensions name M1))
+ p))))
+
+(defthm
+ aref2-m-1
+ (implies (and (integerp i)
+ (integerp n)
+ (<= 0 i)
+ (< i n))
+ (equal (aref2 name (m-1 n) i j)
+ (if (equal i j)
+ 1
+ 0))))
+
+(defthm
+ dot-m-1-1
+ (implies (and (integerp i)
+ (integerp j)
+ (integerp m)
+ (>= i 0)
+ (>= j 0)
+ (> m i))
+ (equal (dot (m-1 m) M1 i j k)
+ (if (<= i j)
+ (fix (aref2 '$arg M1 i k))
+ 0))))
+
+(defthm
+ dot-m-1-2
+ (implies (and (integerp j)
+ (integerp k)
+ (integerp m)
+ (>= j 0)
+ (>= k 0)
+ (> m j))
+ (equal (dot M1 (m-1 m) i j k)
+ (if (<= k j)
+ (fix (aref2 '$arg M1 i k))
+ 0))))
+
+(defthm
+ m-=-row-m-binary-*-row-m-1-1
+ (implies (and (integerp i)
+ (integerp j)
+ (integerp m)
+ (>= i 0)
+ (>= j i)
+ (> m i))
+ (m-=-row (m-binary-*-row (m-1 m)
+ M1
+ i
+ j
+ k)
+ M1
+ i
+ k)))
+
+(defthm
+ m-=-row-m-binary-*-row-m-1-2
+ (implies (and (integerp j)
+ (integerp k)
+ (integerp m)
+ (>= j k)
+ (>= k 0)
+ (> m j))
+ (m-=-row (m-binary-*-row M1
+ (m-1 m)
+ i
+ j
+ k)
+ M1
+ i
+ k)))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-m-1-1
+ (implies (and (integerp i)
+ (integerp j)
+ (integerp m)
+ (>= i 0)
+ (>= j i)
+ (> m i))
+ (m-=-row-1 (m-binary-*-row-1 (m-1 m)
+ M1
+ i
+ j
+ k)
+ M1
+ i
+ k)))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-m-1-2
+ (implies (and (integerp j)
+ (integerp k)
+ (integerp m)
+ (>= j k)
+ (>= k 0)
+ (> m j))
+ (m-=-row-1 (m-binary-*-row-1 M1
+ (m-1 m)
+ i
+ j
+ k)
+ M1
+ i
+ k)))
+
+(defthm
+ alist2p-m-binary-*-row-1-header-m-1-hack-1
+ (IMPLIES (ALIST2P NAME M1)
+ (ALIST2P name1
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 (M-1 (CAR (DIMENSIONS '$ARG M1)))
+ M1
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1)))))))
+ :hints (("Goal"
+ :in-theory (disable Alist2P-M-*)
+ :use (:instance
+ Alist2P-M-*
+ (M1 (m-1 (first (dimensions name M1))))
+ (M2 M1)))))
+
+
+(defthm
+ left-unity-of-m-1-for-m-*
+ (implies (alist2p name M1)
+ (m-= (m-* (m-1 (first (dimensions name M1)))
+ M1)
+ M1)))
+
+(defthm
+ alist2p-m-binary-*-row-1-header-m-1-hack-2
+ (IMPLIES (ALIST2P NAME M1)
+ (ALIST2P name1
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M1))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 M1 (M-1 (CADR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M1)))))))
+ :hints (("Goal"
+ :in-theory (disable Alist2P-M-*)
+ :use (:instance
+ Alist2P-M-*
+ (M2 (m-1 (second (dimensions name M1))))))))
+
+(defthm
+ right-unity-of-m-1-for-m-*
+ (implies (alist2p name M1)
+ (m-= (m-* M1
+ (m-1 (second (dimensions name M1))))
+ M1)))
+
+(defthm
+ dot-cons-1
+ (implies (and (>= p 0)
+ (> j p))
+ (equal (dot (cons (cons (cons m j) val)
+ lst)
+ M3
+ m
+ p
+ q)
+ (dot lst
+ M3
+ m
+ p
+ q))))
+
+(defthm
+ dot-cons-header-1
+ (implies (and (>= p 0)
+ (> j p))
+ (equal (dot (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (cons (cons (cons m j) val)
+ lst))
+ M3
+ m
+ p
+ q)
+ (dot (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ m
+ p
+ q))))
+
+(defthm
+ dot-cons-m-binary-*-row-append-1
+ (implies (> j p)
+ (equal (dot (cons (cons (cons m j) val)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ M3
+ m
+ p
+ q)
+ (dot (cons (cons (cons m j) val)
+ (m-binary-*-row M1
+ M2
+ m
+ n
+ p))
+ M3
+ m
+ p
+ q))))
+
+(defthm
+ dot-m-binary-*-row-append-1
+ (equal (dot (append (m-binary-*-row M1 M2 m n p)
+ lst)
+ M3
+ m
+ p
+ q)
+ (dot (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p
+ q)))
+
+(defthm
+ dot-m-binary-*-row-append-3
+ (implies (> m i)
+ (equal (dot (append (m-binary-*-row M1 M2 m n p)
+ lst)
+ M3
+ i
+ p
+ q)
+ (dot lst
+ M3
+ i
+ p
+ q))))
+
+(defthm
+ dot-m-binary-*-row-append-3-header
+ (implies (> m i)
+ (equal (dot
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ M3
+ i
+ p
+ q)
+ (dot
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ i
+ p
+ q))))
+
+(defthm
+ dot-m-binary-*-row-append-remove-header-1
+ (equal (dot (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1 M2 m n p)
+ lst))
+ M3
+ m
+ p
+ q)
+ (dot (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p
+ q)))
+
+(defthm
+ dot-m-binary-*-row-remove-header-1
+ (equal (dot (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row M1 M2 m n p))
+ M3
+ m
+ p
+ q)
+ (dot (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p
+ q)))
+
+(defthm
+ m-binary-*-row-m-binary-*-row-append-1
+ (equal (m-binary-*-row (append (m-binary-*-row M1 M2 m n p)
+ lst)
+ M3
+ m
+ p
+ q)
+ (m-binary-*-row (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p
+ q)))
+
+(defthm
+ m-binary-*-row-m-binary-*-row-append-1-remove-header
+ (equal (m-binary-*-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1 M2 m n p)
+ lst))
+ M3
+ m
+ p
+ q)
+ (m-binary-*-row (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p
+ q)))
+
+(defthm
+ m-binary-*-row-m-binary-*-row-remove-header-1
+ (equal (m-binary-*-row (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row M1 M2 m n p))
+ M3
+ m
+ p
+ q)
+ (m-binary-*-row (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p
+ q)))
+
+(defthm
+ m-binary-*-row-m-binary-*-row-append-3
+ (implies (> m i)
+ (equal (m-binary-*-row (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst)
+ M3
+ i
+ p
+ q)
+ (m-binary-*-row lst
+ M3
+ i
+ p
+ q))))
+
+(defthm
+ m-binary-*-row-m-binary-*-row-append-3-header
+ (implies (> m i)
+ (equal (m-binary-*-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ M3
+ i
+ p
+ q)
+ (m-binary-*-row
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ i
+ p
+ q))))
+
+(defthm
+ m-binary-*-row-1-m-binary-*-row-append-1
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-binary-*-row-1 (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst)
+ M3
+ j
+ p
+ q)
+ (m-binary-*-row-1 lst
+ M3
+ j
+ p
+ q))))
+
+(defthm
+ m-binary-*-row-1-m-binary-*-row-append-1-header
+ (implies (and (>= j 0)
+ (< j m))
+ (equal (m-binary-*-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (append (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ lst))
+ M3
+ j
+ p
+ q)
+ (m-binary-*-row-1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ lst)
+ M3
+ j
+ p
+ q))))
+
+(defthm
+ m-binary-*-row-1-m-binary-*-row-1-remove-header-1
+ (equal (m-binary-*-row-1 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M1
+ M2
+ m
+ n
+ p))
+ M3
+ m
+ p
+ q)
+ (m-binary-*-row-1 (m-binary-*-row-1 M1 M2 m n p)
+ M3
+ m
+ p
+ q)))
+
+(defthm
+ m-binary-*-row-1-m-binary-*-row-1-remove-header-2
+ (implies (and (integerp q)
+ (>= q 0))
+ (equal (m-binary-*-row-1 M3
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH
+ max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M1
+ M2
+ n
+ p
+ q))
+ m
+ n
+ q)
+ (m-binary-*-row-1 M3
+ (m-binary-*-row-1 M1 M2 n p q)
+ m
+ n
+ q)))
+ :hints (("Goal"
+ :use (:instance
+ m-=-row-1-implies-equal-m-binary-*-row-1-2
+ (M1 M3)
+ (M2 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH
+ max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M1
+ M2
+ n
+ p
+ q)))
+ (M3 (m-binary-*-row-1 M1 M2 n p q))
+ (p q)))))
+
+(defthm
+ aref2-m-binary-*-row-lemma
+ (implies (and (>= q i)
+ (integerp q)
+ (integerp i)
+ (>= i j))
+ (equal (aref2 name (m-binary-*-row M2 M3 n p q) n j)
+ (aref2 name (m-binary-*-row M2 M3 n p i) n j)))
+ :rule-classes nil)
+
+(defthm
+ aref2-m-binary-*-row
+ (implies (and (> q i)
+ (integerp q)
+ (integerp i)
+ (>= i j))
+ (equal (aref2 name (m-binary-*-row M2 M3 n p q) n j)
+ (aref2 name (m-binary-*-row M2 M3 n p i) n j)))
+ :hints (("Goal"
+ :use aref2-m-binary-*-row-lemma)))
+
+(defthm
+ m-=-row-m-binary-*-row-q>i
+ (implies (and (integerp q)
+ (integerp i)
+ (>= i 0)
+ (> q i))
+ (m-=-row (m-binary-*-row M2 M3 n p q)
+ (m-binary-*-row M2 M3 n p i)
+ n
+ i)))
+
+(defthm
+ m-=-row-implies-m-=-row-q>i-lemma
+ (implies (and (m-=-row M1 M2 n q)
+ (integerp q)
+ (integerp i)
+ (>= q i))
+ (m-=-row M1 M2 n i))
+ :rule-classes nil)
+
+(defthm
+ m-=-row-implies-m-=-row-q>i
+ (implies (and (m-=-row M1 M2 n q)
+ (integerp q)
+ (integerp i)
+ (> q i))
+ (m-=-row M1 M2 n i))
+ :hints (("Goal"
+ :use m-=-row-implies-m-=-row-q>i-lemma)))
+
+(defthm
+ m-=-row-append-m-binary-*-row-q>i
+ (implies (and (integerp q)
+ (integerp i)
+ (> q i))
+ (m-=-row (append (m-binary-*-row M2 M3 n p q)
+ lst)
+ (m-binary-*-row M2 M3 n p q)
+ n
+ i))
+ :hints (("Goal"
+ :in-theory (disable m-=-row-implies-m-=-row-q>i)
+ :use (:instance
+ m-=-row-implies-m-=-row-q>i
+ (M1 (append (m-binary-*-row M2 M3 n p q)
+ lst))
+ (M2 (m-binary-*-row M2 M3 n p q))))))
+
+(defthm
+ m-=-row-append-m-binary-*-row-q>i-1
+ (implies (and (integerp q)
+ (integerp i)
+ (>= i 0)
+ (> q i))
+ (m-=-row (append (m-binary-*-row M2 M3 n p q)
+ lst)
+ (m-binary-*-row M2 M3 n p i)
+ n
+ i))
+ :hints (("Goal"
+ :in-theory (disable TRANSITIVITY-OF-M-=-ROW)
+ :use (:instance
+ TRANSITIVITY-OF-M-=-ROW
+ (M1 (append (m-binary-*-row M2 M3 n p q)
+ lst))
+ (M2 (m-binary-*-row M2 M3 n p q))
+ (M3 (m-binary-*-row M2 M3 n p i))
+ (m n)
+ (n i)))))
+
+(defthm
+ m-=-row-m-binary-*-row-1-q>i
+ (implies (and (> q i)
+ (integerp n)
+ (integerp q)
+ (integerp i)
+ (>= n 0)
+ (>= i 0))
+ (m-=-row (m-binary-*-row-1 M2 M3 n p q)
+ (m-binary-*-row-1 M2 M3 n p i)
+ n
+ i)))
+
+(defthm
+ m-=-row-1-implies-m-=-row
+ (implies (and (m-=-row-1 M1 M2 n q)
+ (integerp n)
+ (>= n 0))
+ (m-=-row M1 M2 n q)))
+
+(defthm
+ m-=-row-1-implies-m-=-row-q>i
+ (implies (and (m-=-row-1 M1 M2 n q)
+ (integerp q)
+ (integerp i)
+ (> q i)
+ (integerp n)
+ (>= n 0))
+ (m-=-row M1 M2 n i))
+ :hints (("Goal"
+ :use m-=-row-implies-m-=-row-q>i)))
+
+(defthm
+ m-=-row-1-implies-m-=-row-1-q>i
+ (implies (and (m-=-row-1 M1 M2 n q)
+ (integerp q)
+ (integerp i)
+ (> q i)
+ (integerp n)
+ (>= n 0))
+ (m-=-row-1 M1 M2 n i)))
+
+(defthm
+ m-=-row-1-append-m-binary-*-row-n>j
+ (implies (and (>= j 0)
+ (> n j))
+ (m-=-row-1 (append (m-binary-*-row M2
+ M3
+ n
+ p
+ q)
+ lst)
+ lst
+ j
+ q)))
+
+(defthm
+ m-=-row-1-append-m-binary-*-row-n>j-q>i
+ (implies (and (m-=-row-1 lst1 lst2 j i)
+ (>= j 0)
+ (> n j))
+ (m-=-row-1 (append (m-binary-*-row M2
+ M3
+ n
+ p
+ q)
+ lst1)
+ lst2
+ j
+ i)))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-q>i
+ (implies (and (> q i)
+ (integerp q)
+ (integerp i)
+ (>= i 0))
+ (m-=-row-1 (m-binary-*-row-1 M2 M3 n p q)
+ (m-binary-*-row-1 M2 M3 n p i)
+ n
+ i)))
+
+(defthm
+ m-binary-*-row-m-binary-*-row-1-q>i
+ (implies (and (integerp q)
+ (integerp i)
+ (>= i 0)
+ (> q i))
+ (equal (m-binary-*-row M1
+ (m-binary-*-row-1 M2
+ M3
+ n
+ p
+ q)
+ m
+ n
+ i)
+ (m-binary-*-row M1
+ (m-binary-*-row-1 M2
+ M3
+ n
+ p
+ i)
+ m
+ n
+ i)))
+ :hints (("Goal"
+ :in-theory (disable
+ m-=row-1-implies-equal-m-binary-*-row-2)
+ :use (:instance
+ m-=row-1-implies-equal-m-binary-*-row-2
+ (M2 (m-binary-*-row-1 M2 M3 n p q))
+ (M3 (m-binary-*-row-1 M2 M3 n p i))
+ (p i)))))
+
+(defthm
+ m-=-row-implies-equal-m-binary-*-row
+ (implies (m-=-row (m-binary-*-row M1 M2 m n q)
+ (m-binary-*-row M3 M4 m p q)
+ m
+ q)
+ (equal (m-binary-*-row M1 M2 m n q)
+ (m-binary-*-row M3 M4 m p q))))
+
+(defthm
+ m-=-row-1-implies-equal-m-binary-*-row-1
+ (implies (m-=-row-1 (m-binary-*-row-1 M1 M2 m n q)
+ (m-binary-*-row-1 M3 M4 m p q)
+ m
+ q)
+ (equal (m-binary-*-row-1 M1 M2 m n q)
+ (m-binary-*-row-1 M3 M4 m p q))))
+
+(defthm
+ aref2-append-m-binary-*-row-1
+ (implies (and (integerp q)
+ (>= q 0))
+ (equal (aref2 name
+ (append (m-binary-*-row M2
+ M3
+ n
+ p
+ q)
+ lst)
+ n
+ q)
+ (aref2 name
+ (m-binary-*-row M2
+ M3
+ n
+ p
+ q)
+ n
+ q))))
+
+(defthm
+ dot-append-m-binary-*-row
+ (implies (and (>= j 0)
+ (> n j))
+ (equal (dot M1
+ (append (m-binary-*-row M2
+ M3
+ n
+ p
+ q)
+ lst)
+ m
+ j
+ q)
+ (dot M1
+ lst
+ m
+ j
+ q))))
+
+(defthm
+ aref2-m-binary-*-row-0
+ (implies (and (integerp q)
+ (>= q 0))
+ (equal (aref2 name
+ (m-binary-*-row M2 M3 n 0 q)
+ n
+ q)
+ (* (aref2 name M2 n 0)
+ (aref2 name M3 0 q)))))
+
+(defthm
+ dot-m-binary-*-row-1-0
+ (implies (and (integerp q)
+ (>= q 0))
+ (equal (dot M1
+ (m-binary-*-row-1 M2
+ M3
+ n
+ 0
+ q)
+ m
+ n
+ q)
+ (* (aref2 name M3 0 q)
+ (dot M1 M2 m n 0)))))
+
+(defthm
+ aref2-m-binary-*-row-p>0
+ (implies (and (integerp p)
+ (integerp q)
+ (> p 0)
+ (>= q 0))
+ (equal (+ (* (aref2 name M2 n p)
+ (aref2 name M3 p q))
+ (aref2 name
+ (m-binary-*-row M2
+ M3
+ n
+ (+ -1 p)
+ q)
+ n
+ q))
+ (aref2 name
+ (m-binary-*-row M2 M3 n p q)
+ n
+ q))))
+
+(defthm
+ dot-m-binary-*-row-1-p>0
+ (implies (and (integerp n)
+ (integerp p)
+ (integerp q)
+ (>= n 0)
+ (> p 0)
+ (>= q 0))
+ (equal (+ (* (aref2 name M3 p q)
+ (dot M1 M2 m n p))
+ (dot M1
+ (m-binary-*-row-1 M2
+ M3
+ n
+ (+ -1 p)
+ q)
+ m
+ n
+ q))
+ (dot M1
+ (m-binary-*-row-1 M2
+ M3
+ n
+ p
+ q)
+ m
+ n
+ q)))
+ :hints (("Subgoal *1/4"
+ :in-theory (disable
+ aref2-m-binary-*-row-p>0)
+ :use aref2-m-binary-*-row-p>0)
+ ("Subgoal *1/1"
+ :do-not '(generalize))))
+
+(defthm
+ dot-m-binary-*-row-associativity
+ (implies (and (integerp n)
+ (integerp p)
+ (integerp q)
+ (>= n 0)
+ (>= p 0)
+ (>= q 0))
+ (equal (dot (m-binary-*-row M1 M2 m n p)
+ M3
+ m
+ p
+ q)
+ (dot M1
+ (m-binary-*-row-1 M2 M3 n p q)
+ m
+ n
+ q)))
+ :hints (("Subgoal *1/4.1"
+ :in-theory (disable dot-m-binary-*-row-1-p>0)
+ :use dot-m-binary-*-row-1-p>0)))
+
+(defthm
+ m-=-row-m-binary-*-row-associativity
+ (implies (and (integerp n)
+ (integerp p)
+ (integerp q)
+ (>= n 0)
+ (>= p 0)
+ (>= q 0))
+ (m-=-row (m-binary-*-row (m-binary-*-row M1
+ M2
+ m
+ n
+ p)
+ M3
+ m
+ p
+ q)
+ (m-binary-*-row M1
+ (m-binary-*-row-1
+ M2
+ M3
+ n
+ p
+ q)
+ m
+ n
+ q)
+ m
+ q)))
+
+(defthm
+ m-=-row-1-m-binary-*-row-1-associativity
+ (implies
+ (and (integerp n)
+ (integerp p)
+ (integerp q)
+ (>= n 0)
+ (>= p 0)
+ (>= q 0))
+ (m-=-row-1 (m-binary-*-row-1 (m-binary-*-row-1 M1
+ M2
+ m
+ n
+ p)
+ M3
+ m
+ p
+ q)
+ (m-binary-*-row-1 M1
+ (m-binary-*-row-1 M2
+ M3
+ n
+ p
+ q)
+ m
+ n
+ q)
+ m
+ q)))
+
+(defthm
+ m-binary-*-row-1-associativity
+ (implies
+ (and (integerp n)
+ (integerp p)
+ (integerp q)
+ (>= n 0)
+ (>= p 0)
+ (>= q 0))
+ (equal (m-binary-*-row-1 (m-binary-*-row-1 M1
+ M2
+ m
+ n
+ p)
+ M3
+ m
+ p
+ q)
+ (m-binary-*-row-1 M1
+ (m-binary-*-row-1 M2
+ M3
+ n
+ p
+ q)
+ m
+ n
+ q)))
+ :hints (("Goal"
+ :in-theory
+ (disable
+ m-=-row-1-implies-equal-m-binary-*-row-1)
+ :use
+ (:instance
+ m-=-row-1-implies-equal-m-binary-*-row-1
+ (M1 (m-binary-*-row-1 M1 M2 m n p))
+ (M2 M3)
+ (M3 M1)
+ (M4 (m-binary-*-row-1 M2 M3 n p q))
+ (n p)
+ (p n)))))
+
+(defthm
+ alist2p-m-binary-*-row-1-header-hack-1
+ (IMPLIES (AND (ALIST2P '$ARG1 M1)
+ (ALIST2P '$ARG2 M2)
+ (EQUAL (CADR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M2)))
+ (EQUAL (CADR (DIMENSIONS '$ARG M2))
+ (CAR (DIMENSIONS '$ARG M3))))
+ (ALIST2P name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M3)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M3))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 M1
+ M2
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M3)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ alist2p-m-binary-*-row-1-header-hack-2
+ (IMPLIES (AND (ALIST2P '$ARG1 M2)
+ (ALIST2P '$ARG2 M3)
+ (EQUAL (CADR (DIMENSIONS '$ARG M1))
+ (CAR (DIMENSIONS '$ARG M2)))
+ (EQUAL (CADR (DIMENSIONS '$ARG M2))
+ (CAR (DIMENSIONS '$ARG M3))))
+ (ALIST2P name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M2))
+ (CADR (DIMENSIONS '$ARG M3)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M2))
+ (CADR (DIMENSIONS '$ARG M3))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 M2
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M3)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M3)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ associativity-of-m-*
+ (equal (m-* (m-* M1 M2) M3)
+ (m-* M1 M2 M3)))
+
+(defthm
+ m-binary-*-row-1-m-binary-+-row-1-remove-header-1
+ (equal (m-binary-*-row-1 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ i
+ j))
+ M3
+ i
+ j
+ k)
+ (m-binary-*-row-1 (m-binary-+-row-1 M1 M2 i j)
+ M3
+ i
+ j
+ k))
+ :hints (("Goal"
+ :use (:instance
+ m-=-row-1-implies-equal-m-binary-*-row-1-1
+ (M1 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M1
+ M2
+ i
+ j)))
+ (M2 (m-binary-+-row-1 M1 M2 i j))
+ (m i)
+ (n j)
+ (p k)))))
+
+(defthm
+ m-binary-*-row-1-m-binary-+-row-1-remove-header-2
+ (implies (and (integerp k)
+ (>= k 0))
+ (equal (m-binary-*-row-1 M1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M2
+ M3
+ j
+ k))
+ i
+ j
+ k)
+ (m-binary-*-row-1 M1
+ (m-binary-+-row-1 M2
+ M3
+ j
+ k)
+ i
+ j
+ k)))
+ :hints (("Goal"
+ :use (:instance
+ m-=-row-1-implies-equal-m-binary-*-row-1-2
+ (M2 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-+-row-1 M2
+ M3
+ j
+ k)))
+ (M3 (m-binary-+-row-1 M2
+ M3
+ j
+ k))
+ (n j)
+ (p k)
+ (m i)))))
+
+(defthm
+ m-binary-+-row-1-m-binary-*-row-1-remove-header-1
+ (equal (m-binary-+-row-1 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M1
+ M2
+ i
+ j
+ k))
+ M3
+ i
+ k)
+ (m-binary-+-row-1 (m-binary-*-row-1 M1 M2 i j k)
+ M3
+ i
+ k))
+ :hints (("Goal"
+ :use (:instance
+ m-=-row-1-implies-equal-m-binary-+-row-1-1
+ (M1 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M1
+ M2
+ i
+ j
+ k)))
+ (M2 (m-binary-*-row-1 M1 M2 i j k))
+ (m i)
+ (n k)))))
+
+(defthm
+ m-binary-+-row-1-m-binary-*-row-1-remove-header-2
+ (equal (m-binary-+-row-1 M1
+ (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M2
+ M3
+ i
+ j
+ k))
+ i
+ k)
+ (m-binary-+-row-1 M1
+ (m-binary-*-row-1 M2 M3 i j k)
+ i
+ k))
+ :hints (("Goal"
+ :use (:instance
+ m-=-row-1-implies-equal-m-binary-+-row-1-2
+ (M2 (cons (list :HEADER
+ :DIMENSIONS dims
+ :MAXIMUM-LENGTH max-length
+ :DEFAULT default
+ :NAME name1)
+ (m-binary-*-row-1 M2
+ M3
+ i
+ j
+ k)))
+ (M3 (m-binary-*-row-1 M2 M3 i j k))
+ (m i)
+ (n k)))))
+
+(defthm
+ distributivity-aref2-m-binary-+-row
+ (implies (and (integerp k)
+ (>= k 0))
+ (equal (* x
+ (aref2 '$arg
+ (m-binary-+-row M2
+ M3
+ j
+ k)
+ j
+ k))
+ (+ (* x (aref2 '$arg M2 j k))
+ (* x (aref2 '$arg M3 j k))))))
+
+(defthm
+ aref2-append-m-binary-+-row-a
+ (implies (and (integerp k)
+ (>= k 0))
+ (equal (aref2 '$arg (append (m-binary-+-row M2 M3 j k)
+ lst)
+ j
+ k)
+ (aref2 '$arg (m-binary-+-row M2 M3 j k) j k))))
+
+(defthm
+ aref2-append-m-binary-+-row-b
+ (implies (and (integerp k)
+ (>= k 0)
+ (integerp k1)
+ (< k k1))
+ (equal (aref2 '$arg (append (m-binary-+-row M2 M3 j k1)
+ lst)
+ j
+ k)
+ (aref2 '$arg (m-binary-+-row M2 M3 j k) j k))))
+
+(defthm
+ dot-remove-cons
+ (implies (and (>= l 0)
+ (< l j))
+ (equal (dot M1
+ (cons (cons (cons j k) val) lst)
+ i
+ l
+ k)
+ (dot M1 lst i l k))))
+
+(defthm
+ dot-remove-cons-1
+ (implies (< k k1)
+ (equal (dot M1
+ (cons (cons (cons j k1) val) lst)
+ i
+ l
+ k)
+ (dot M1 lst i l k))))
+
+(defthm
+ dot-append-m-binary-+-row
+ (implies (and (>= l 0)
+ (< l j))
+ (equal (dot M1
+ (append (m-binary-+-row M2 M3 j k1)
+ lst)
+ i
+ l
+ k)
+ (dot M1 lst i l k))))
+
+(defthm
+ dot-m-binary-+-row-1
+ (implies (and (integerp k)
+ (>= k 0))
+ (equal (dot M1
+ (m-binary-+-row-1 M2 M3 j k)
+ i
+ j
+ k)
+ (+ (dot M1 M2 i j k)
+ (dot M1 M3 i j k)))))
+
+(defthm
+ dot-m-binary-+-row-1-a
+ (implies (and (< k k1)
+ (integerp k)
+ (>= k 0)
+ (integerp k1))
+ (equal (dot M1
+ (m-binary-+-row-1 M2 M3 j k1)
+ i
+ j
+ k)
+ (+ (dot M1 M2 i j k)
+ (dot M1 M3 i j k))))
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(defthm
+ dot-m-binary-+-row-1-b
+ (implies (and (<= k k1)
+ (integerp k)
+ (>= k 0)
+ (integerp k1))
+ (equal (dot M1
+ (m-binary-+-row-1 M2 M3 j k1)
+ i
+ j
+ k)
+ (+ (dot M1 M2 i j k)
+ (dot M1 M3 i j k))))
+ :hints (("Goal"
+ :cases ((< k k1)))))
+
+(defthm
+ m-binary-*-row-remove-cons
+ (implies (and (>= l 0)
+ (< l j))
+ (equal (m-binary-*-row M1
+ (cons (cons (cons j k1) val) lst)
+ i
+ l
+ k)
+ (m-binary-*-row M1 lst i l k))))
+
+(defthm
+ m-binary-*-row-remove-cons-1
+ (implies (and (>= k 0)
+ (< k k1))
+ (equal (m-binary-*-row M1
+ (cons (cons (cons j k1) val) lst)
+ i
+ j
+ k)
+ (m-binary-*-row M1 lst i j k))))
+
+(defthm
+ distributivity-m-binary-*-append-row-m-binary-+-row
+ (implies (and (integerp j)
+ (integerp k)
+ (>= j 0)
+ (>= l 0)
+ (>= k l))
+ (equal (m-binary-*-row M1
+ (append (m-binary-+-row M2 M3 j l)
+ (m-binary-+-row-1 M2 M3 (+ -1 j) k))
+ i
+ j
+ l)
+ (m-binary-+-row (m-binary-*-row M1 M2 i j l)
+ (m-binary-*-row M1 M3 i j l)
+ i
+ l))))
+
+(defthm
+ distributivity-m-binary-*-row-m-binary-+-row-case-j=0
+ (equal (m-binary-*-row M1
+ (m-binary-+-row M2 M3 0 k)
+ i
+ 0
+ k)
+ (m-binary-+-row (m-binary-*-row M1 M2 i 0 k)
+ (m-binary-*-row M1 M3 i 0 k)
+ i
+ k)))
+
+(defthm
+ distributivity-m-binary-*-row-m-binary-+-row-a
+ (implies (and (integerp k)
+ (<= l k)
+ (>= l 0))
+ (equal (m-binary-*-row M1
+ (m-binary-+-row-1 M2 M3 j k)
+ i
+ j
+ l)
+ (m-binary-+-row (m-binary-*-row M1 M2 i j l)
+ (m-binary-*-row M1 M3 i j l)
+ i
+ l))))
+
+(defthm
+ distributivity-m-binary-*-row-m-binary-+-row
+ (equal (m-binary-*-row M1
+ (m-binary-+-row-1 M2 M3 j k)
+ i
+ j
+ k)
+ (m-binary-+-row (m-binary-*-row M1 M2 i j k)
+ (m-binary-*-row M1 M3 i j k)
+ i
+ k)))
+
+(defthm
+ m-binary-+-row-1-remove-cons-1
+ (implies (and (>= i1 0)
+ (< i1 i))
+ (equal (m-binary-+-row-1 (cons (cons (cons i j) val)
+ lst1)
+ lst2
+ i1
+ j)
+ (m-binary-+-row-1 lst1
+ lst2
+ i1
+ j))))
+
+(defthm
+ m-binary-+-row-1-remove-cons-2
+ (implies (and (>= i1 0)
+ (< i1 i))
+ (equal (m-binary-+-row-1 lst1
+ (cons (cons (cons i j) val)
+ lst2)
+ i1
+ j)
+ (m-binary-+-row-1 lst1
+ lst2
+ i1
+ j))))
+
+(defthm
+ m-binary-+-row-remove-append-1
+ (equal (m-binary-+-row (append (m-binary-*-row M1 M2 i j k)
+ lst1)
+ lst2
+ i
+ k)
+ (m-binary-+-row (m-binary-*-row M1 M2 i j k)
+ lst2
+ i
+ k)))
+
+(defthm
+ m-binary-+-row-remove-append-2
+ (equal (m-binary-+-row lst1
+ (append (m-binary-*-row M1 M2 i j k)
+ lst2)
+ i
+ k)
+ (m-binary-+-row lst1
+ (m-binary-*-row M1 M2 i j k)
+ i
+ k)))
+
+(defthm
+ m-binary-+-row-remove-append-1a
+ (implies (< i1 i)
+ (equal (m-binary-+-row (append (m-binary-*-row M1 M2 i j k)
+ lst1)
+ lst2
+ i1
+ k)
+ (m-binary-+-row lst1
+ lst2
+ i1
+ k))))
+
+(defthm
+ m-binary-+-row-remove-append-2a
+ (implies (< i1 i)
+ (equal (m-binary-+-row lst1
+ (append (m-binary-*-row M1 M2 i j k)
+ lst2)
+ i1
+ k)
+ (m-binary-+-row lst1
+ lst2
+ i1
+ k))))
+
+(defthm
+ m-binary-+-row-1-remove-append-1a
+ (implies (and (> i 0)
+ (< i1 i))
+ (equal (m-binary-+-row-1 (append (m-binary-*-row M1 M2 i j k)
+ lst1)
+ lst2
+ i1
+ k)
+ (m-binary-+-row-1 lst1
+ lst2
+ i1
+ k))))
+
+(defthm
+ m-binary-+-row-1-remove-append-1b
+ (implies (and (> i 0)
+ (< i1 i))
+ (equal (m-binary-+-row-1 lst1
+ (append (m-binary-*-row M1 M2 i j k)
+ lst2)
+ i1
+ k)
+ (m-binary-+-row-1 lst1
+ lst2
+ i1
+ k))))
+
+(defthm
+ left-distributivity-m-binary-*-row-1-m-binary-+-row-1
+ (equal (m-binary-*-row-1 M1
+ (m-binary-+-row-1 M2
+ M3
+ j
+ k)
+ i
+ j
+ k)
+ (m-binary-+-row-1 (m-binary-*-row-1 M1
+ M2
+ i
+ j
+ k)
+ (m-binary-*-row-1 M1
+ M3
+ i
+ j
+ k)
+ i
+ k)))
+
+(defthm
+ alist2p-header-m-binary-*-row-1-crock
+ (IMPLIES (AND (ALIST2P name1 M1)
+ (ALIST2P name2 M2))
+ (ALIST2P name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 M1
+ M2
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ alist2p-header-m-binary-*-row-1-crock-1
+ (IMPLIES (AND (ALIST2P name1 M1)
+ (ALIST2P name2 M2))
+ (ALIST2P name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-+-ROW-1
+ (M-BINARY-*-ROW-1 M1
+ M2
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2))))
+ (M-BINARY-*-ROW-1 M1
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2))))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ alist2p-header-m-binary-*-row-1-crock-2
+ (IMPLIES (AND (ALIST2P name1 M1)
+ (ALIST2P name2 M2))
+ (ALIST2P name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1
+ (M-BINARY-*-ROW-1 M1
+ M2
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2))))
+ (M-BINARY-*-ROW-1 M1
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2))))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ alist2p-header-m-binary-*-row-1-crock-3
+ (IMPLIES (AND (ALIST2P name1 M1)
+ (ALIST2P name2 M2))
+ (ALIST2P name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M2))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-*-ROW-1 M1
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M2)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M2)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ left-distributivity-of-m-*-over-m-+
+ (m-= (m-* M1 (m-+ M2 M3))
+ (m-+ (m-* M1 M2)
+ (m-* M1 M3))))
+
+(defthm
+ right-dot-m-binary-+-row
+ (equal (dot (m-binary-+-row M1
+ M2
+ i
+ j)
+ M3
+ i
+ j
+ k)
+ (+ (dot M1 M3 i j k)
+ (dot M2 M3 i j k))))
+
+(defthm
+ right-distributivity-m-binary-*-row-m-binary-+-row
+ (equal (m-binary-*-row (m-binary-+-row M1
+ M2
+ i
+ j)
+ M3
+ i
+ j
+ k)
+ (m-binary-+-row (m-binary-*-row M1
+ M3
+ i
+ j
+ k)
+ (m-binary-*-row M2
+ M3
+ i
+ j
+ k)
+ i
+ k)))
+
+(defthm
+ dot-m-binary-+-row-remove-append
+ (equal (dot (append (m-binary-+-row M1
+ M2
+ i
+ j)
+ lst)
+ M3
+ i
+ j
+ k)
+ (dot (m-binary-+-row M1
+ M2
+ i
+ j)
+ M3
+ i
+ j
+ k)))
+
+(defthm
+ dot-m-binary-+-row-remove-append-a
+ (implies (> i i1)
+ (equal (dot (append (m-binary-+-row M1
+ M2
+ i
+ j)
+ lst)
+ M3
+ i1
+ j
+ k)
+ (dot lst
+ M3
+ i1
+ j
+ k))))
+
+(defthm
+ m-binary-*-row-m-binary-+-row-remove-append
+ (equal (m-binary-*-row (append (m-binary-+-row M1
+ M2
+ i
+ j)
+ lst)
+ M3
+ i
+ j
+ k)
+ (m-binary-+-row (m-binary-*-row M1
+ M3
+ i
+ j
+ k)
+ (m-binary-*-row M2
+ M3
+ i
+ j
+ k)
+ i
+ k)))
+
+(defthm
+ m-binary-*-row-m-binary-+-row-remove-append-a
+ (implies (> i i1)
+ (equal (m-binary-*-row (append (m-binary-+-row M1
+ M2
+ i
+ j)
+ lst)
+ M3
+ i1
+ j
+ k)
+ (m-binary-*-row lst
+ M3
+ i1
+ j
+ k))))
+
+(defthm
+ m-binary-*-row-1-m-binary-+-row-remove-append-a
+ (implies (and (>= i1 0)
+ (> i i1))
+ (equal (m-binary-*-row-1 (append (m-binary-+-row M1
+ M2
+ i
+ j)
+ lst)
+ M3
+ i1
+ j
+ k)
+ (m-binary-*-row-1 lst
+ M3
+ i1
+ j
+ k))))
+
+(defthm
+ right-distributivity-m-binary-*-row-1-m-binary-+-row-1
+ (equal (m-binary-*-row-1 (m-binary-+-row-1 M1
+ M2
+ i
+ j)
+ M3
+ i
+ j
+ k)
+ (m-binary-+-row-1 (m-binary-*-row-1 M1
+ M3
+ i
+ j
+ k)
+ (m-binary-*-row-1 M2
+ M3
+ i
+ j
+ k)
+ i
+ k)))
+
+(defthm
+ alist2p-header-m-binary-*-row-1-crock-4
+ (IMPLIES (AND (ALIST2P name1 M1)
+ (ALIST2P name2 M3))
+ (ALIST2P name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M3)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M3))))
+ '(:DEFAULT 0 :NAME MATRIX-PRODUCT))
+ (M-BINARY-+-ROW-1
+ (M-BINARY-*-ROW-1 M1
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M3)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M3))))
+ (M-BINARY-*-ROW-1 M2
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M3)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M3))))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M3)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ alist2p-header-m-binary-*-row-1-crock-5
+ (IMPLIES (AND (ALIST2P name1 M1)
+ (ALIST2P name2 M3))
+ (ALIST2p name
+ (CONS (LIST* :HEADER :DIMENSIONS
+ (LIST (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M3)))
+ :MAXIMUM-LENGTH
+ (+ 1
+ (* (CAR (DIMENSIONS '$ARG M1))
+ (CADR (DIMENSIONS '$ARG M3))))
+ '(:DEFAULT 0 :NAME MATRIX-SUM))
+ (M-BINARY-+-ROW-1
+ (M-BINARY-*-ROW-1 M1
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M3)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M3))))
+ (M-BINARY-*-ROW-1 M2
+ M3
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CAR (DIMENSIONS '$ARG M3)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M3))))
+ (+ -1 (CAR (DIMENSIONS '$ARG M1)))
+ (+ -1 (CADR (DIMENSIONS '$ARG M3)))))))
+ :HINTS (("Goal"
+ :IN-THEORY (ENABLE Alist2P HEADER DIMENSIONS MAXIMUM-LENGTH))))
+
+(defthm
+ right-distributivity-of-m-*-over-m-+
+ (m-= (m-* (m-+ M1 M2) M3)
+ (m-+ (m-* M1 M3)
+ (m-* M2 M3))))
+
+(defthm
+ m-=-row-1-m-trans-m-1
+ (implies (and (integerp n)
+ (< i n))
+ (m-=-row-1 (m-trans (m-1 n))
+ (m-1 n)
+ i
+ j)))
+
+(defthm
+ m-=-m-trans-m-1
+ (implies (and (integerp n)
+ (> n 0))
+ (m-= (m-trans (m-1 n))
+ (m-1 n))))
+
+(defthm
+ dot-s-*-left=*-dot
+ (equal (dot (s-* a M1)
+ M2
+ i
+ k
+ j)
+ (* a (dot M1
+ M2
+ i
+ k
+ j))))
+
+(defthm
+ dot-s-*-right=*-dot
+ (equal (dot M1
+ (s-* a M2)
+ i
+ k
+ j)
+ (* a (dot M1
+ M2
+ i
+ k
+ j))))
+
+(defthm
+ m-=-row-m-*-s-*-left
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M2)))
+ (m-=-row (m-* (s-* a M1) M2)
+ (s-* a (m-* M1 M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ m-=-row-m-*-s-*-right
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M2)))
+ (m-=-row (m-* M1 (s-* a M2))
+ (s-* a (m-* M1 M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ m-=-row-1-m-*-s-*-left
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M2)))
+ (m-=-row-1 (m-* (s-* a M1) M2)
+ (s-* a (m-* M1 M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ m-=-row-1-m-*-s-*-right
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M2)))
+ (m-=-row-1 (m-* M1 (s-* a M2))
+ (s-* a (m-* M1 M2))
+ i
+ j))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ m-*-s-*-left
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2)))
+ (m-= (m-* (s-* a M1) M2)
+ (s-* a (m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-*
+ alist2p-m-*)
+ :use (:instance
+ alist2p-m-*
+ (name '$arg)
+ (M1 (s-* a M1))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-*
+ alist2p-s-*)
+ :use (:instance
+ alist2p-s-*
+ (name '$arg)
+ (M (m-* M1 M2))))))
+
+(defthm
+ m-*-s-*-right
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2)))
+ (m-= (m-* M1 (s-* a M2))
+ (s-* a (m-* M1 M2))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-*
+ alist2p-m-*)
+ :use (:instance
+ alist2p-m-*
+ (name '$arg)
+ (M2 (s-* a M2))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-*
+ alist2p-s-*)
+ :use (:instance
+ alist2p-s-*
+ (name '$arg)
+ (M (m-* M1 M2))))))
+
+(defthm
+ dot-m-trans-m-trans
+ (equal (dot (m-trans M2)
+ (m-trans M1)
+ j
+ k
+ i)
+ (dot M1
+ M2
+ i
+ k
+ j)))
+
+(defthm
+ m-=-row-m-trans-m-*=m-*-m-trans
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M2)))
+ (m-=-row (m-trans (m-* M1 M2))
+ (m-* (m-trans M2)(m-trans M1))
+ j
+ i))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ m-=-row-1-m-trans-m-*=m-*-m-trans
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2))
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (r M1))
+ (< j (c M2)))
+ (m-=-row-1 (m-trans (m-* M1 M2))
+ (m-* (m-trans M2)(m-trans M1))
+ j
+ i))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))))
+
+(defthm
+ m-trans-m-*=m-*-m-trans
+ (implies (and (alist2p name M1)
+ (alist2p name M2)
+ (equal (c M1)(r M2)))
+ (m-= (m-trans (m-* M1 M2))
+ (m-* (m-trans M2)(m-trans M1))))
+ :hints (("Goal"
+ :in-theory (disable m-binary-*))
+ ("Subgoal 2"
+ :in-theory (disable m-binary-*
+ alist2p-m-trans)
+ :use (:instance
+ alist2p-m-trans
+ (name '$arg)
+ (M (m-* M1 M2))))
+ ("Subgoal 1"
+ :in-theory (disable m-binary-*
+ alist2p-m-*)
+ :use (:instance
+ alist2p-m-*
+ (name '$arg)
+ (M1 (m-trans M2))
+ (M2 (m-trans M1))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Row and column operations on ACL2 arrays:
+
+(defthm
+ Ri<->Rj-loop-guard-hack
+ (IMPLIES (AND (< K (CADR (DIMENSIONS '$ARG M)))
+ (< I (CAR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 I)
+ (INTEGERP I)
+ (integerp k)
+ (ARRAY2P '$ARG M)
+ (SYMBOLP NAME))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ M
+ I
+ K
+ (AREF2 '$ARG M J K))))
+ :hints (("Goal"
+ :in-theory (disable ARRAY2P-ASET2)
+ :use (:instance
+ ARRAY2P-ASET2
+ (L M)
+ (j k)
+ (val (AREF2 '$ARG M J K))))))
+
+(defthm
+ Ri<->Rj-loop-guard-hack-1
+ (IMPLIES (AND (< K (CADR (DIMENSIONS '$ARG M)))
+ (< J (CAR (DIMENSIONS '$ARG M)))
+ (< I (CAR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP J)
+ (INTEGERP I)
+ (integerp k)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ (ASET2 '$ARG
+ M
+ I
+ K
+ (AREF2 '$ARG M J K))
+ J
+ K
+ (AREF2 '$ARG M I K))))
+ :hints (("Goal"
+ :in-theory (disable ARRAY2P-ASET2)
+ :use (:instance
+ ARRAY2P-ASET2
+ (L (ASET2 '$ARG
+ M
+ I
+ K
+ (AREF2 '$ARG M J K)))
+ (i j)
+ (j k)
+ (val (AREF2 '$ARG M I K))))))
+
+(defun
+ Ri<->Rj-loop (name M i j k)
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims))
+ (dims2 (second dims)))
+ (and (< i dims1)
+ (< j dims1)
+ (< k dims2))))))
+ (if (zp k)
+ (let ((temp (aref2 name M i 0)))
+ (aset2 name
+ (aset2 name
+ M
+ i
+ 0
+ (aref2 name
+ M
+ j
+ 0))
+ j
+ 0
+ temp))
+ (Ri<->Rj-loop name
+ (let ((temp (aref2 name M i k)))
+ (aset2 name
+ (aset2 name
+ M
+ i
+ k
+ (aref2 name
+ M
+ j
+ k))
+ j
+ k
+ temp))
+ i
+ j
+ (- k 1))))
+
+(defun
+ Ri<->Rj (name M i j)
+ "Return the result of interchanging
+ row i and row j in array M."
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims)))
+ (and (< i dims1)
+ (< j dims1))))))
+ (Ri<->Rj-loop name
+ M
+ i
+ j
+ (- (second (dimensions name M)) 1)))
+
+(defthm
+ Ci<->Cj-loop-guard-hack
+ (IMPLIES (AND (< K (CAR (DIMENSIONS '$ARG M)))
+ (< I (CADR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 I)
+ (INTEGERP I)
+ (integerp k)
+ (ARRAY2P '$ARG M)
+ (SYMBOLP NAME))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ M
+ K
+ I
+ (AREF2 '$ARG M K J))))
+ :hints (("Goal"
+ :in-theory (disable ARRAY2P-ASET2)
+ :use (:instance
+ ARRAY2P-ASET2
+ (L M)
+ (i k)
+ (j i)
+ (val (AREF2 '$ARG M K j))))))
+
+(defthm
+ Ci<->Cj-loop-guard-hack-1
+ (IMPLIES (AND (< K (CAR (DIMENSIONS '$ARG M)))
+ (< J (CADR (DIMENSIONS '$ARG M)))
+ (< I (CADR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP J)
+ (INTEGERP I)
+ (integerp k)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ (ASET2 '$ARG
+ M
+ K
+ I
+ (AREF2 '$ARG M K J))
+ K
+ J
+ (AREF2 '$ARG M K I))))
+ :hints (("Goal"
+ :in-theory (disable ARRAY2P-ASET2)
+ :use (:instance
+ ARRAY2P-ASET2
+ (L (ASET2 '$ARG
+ M
+ K
+ I
+ (AREF2 '$ARG M K J)))
+ (i k)
+ (val (AREF2 '$ARG M K i))))))
+
+(defun
+ Ci<->Cj-loop (name M i j k)
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2)
+ (< k dims1))))))
+ (if (zp k)
+ (let ((temp (aref2 name M 0 i)))
+ (aset2 name
+ (aset2 name
+ M
+ 0
+ i
+ (aref2 name
+ M
+ 0
+ j))
+ 0
+ j
+ temp))
+ (Ci<->Cj-loop name
+ (let ((temp (aref2 name M k i)))
+ (aset2 name
+ (aset2 name
+ M
+ k
+ i
+ (aref2 name
+ M
+ k
+ j))
+ k
+ j
+ temp))
+ i
+ j
+ (- k 1))))
+
+(defun
+ Ci<->Cj (name M i j)
+ "Return the result of interchanging
+ column i and column j in array M."
+ (declare (xargs :guard (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2))))))
+ (Ci<->Cj-loop name
+ M
+ i
+ j
+ (- (first (dimensions name M)) 1)))
+
+(defthm
+ Ri<-aRi-loop-guard-hack
+ (IMPLIES (AND (< K (CADR (DIMENSIONS '$ARG M)))
+ (< I (CAR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 I)
+ (INTEGERP I)
+ (integerp k)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME (ASET2 '$ARG M I K 0)))
+ :hints (("Goal"
+ :in-theory (disable array2p-aset2)
+ :use (:instance
+ array2p-aset2
+ (L M)
+ (j k)
+ (val 0)))))
+
+(defthm
+ Ri<-aRi-loop-guard-hack-1
+ (IMPLIES (AND (< K (CADR (DIMENSIONS '$ARG M)))
+ (< I (CAR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 I)
+ (integerp k)
+ (INTEGERP I)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ M
+ I
+ K
+ (* A (AREF2 '$ARG M I K)))))
+ :hints (("Goal"
+ :in-theory (disable array2p-aset2)
+ :use (:instance
+ array2p-aset2
+ (L M)
+ (j k)
+ (val (* A (AREF2 '$ARG M I K)))))))
+
+(defun
+ Ri<-aRi-loop (name M a i k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp k)
+ (>= i 0)
+ (>= k 0)
+ (let ((dims (dimensions name M)))
+ (and (< i (first dims))
+ (< k (second dims)))))))
+ (if (zp k)
+ (aset2 name
+ M
+ i
+ 0
+ (* a (fix (aref2 name
+ M
+ i
+ 0))))
+ (Ri<-aRi-loop name
+ (aset2 name
+ M
+ i
+ k
+ (* a (fix (aref2 name
+ M
+ i
+ k))))
+ a
+ i
+ (- k 1))))
+
+(defun
+ Ri<-aRi (name M a i)
+ "Return the result of replacing each element,
+ Mij, in row i of array M, with (* a Mij)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M))))))
+ (Ri<-aRi-loop name
+ M
+ a
+ i
+ (- (second (dimensions name M)) 1)))
+
+(defun
+ Ci<-aCi-loop (name M a i k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp k)
+ (>= i 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< k dims1))))))
+
+ (if (zp k)
+ (aset2 name
+ M
+ 0
+ i
+ (* a (fix (aref2 name
+ M
+ 0
+ i))))
+ (Ci<-aCi-loop name
+ (aset2 name
+ M
+ k
+ i
+ (* a (fix (aref2 name
+ M
+ k
+ i))))
+ a
+ i
+ (- k 1))))
+
+(defun
+ Ci<-aCi (name M a i)
+ "Return the result of replacing each element,
+ Mji, in column i of array M, with (* a Mji)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M))))))
+ (Ci<-aCi-loop name
+ M
+ a
+ i
+ (- (first (dimensions name M)) 1)))
+
+(defthm
+ Rj<-aRi+Rj-loop-guard-hack
+ (IMPLIES (AND (< K (CADR (DIMENSIONS '$ARG M)))
+ (< J (CAR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 J)
+ (INTEGERP J)
+ (integerp k)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ M
+ J
+ K
+ (* A (AREF2 '$ARG M I K)))))
+ :hints (("Goal"
+ :in-theory (disable array2p-aset2)
+ :use (:instance
+ array2p-aset2
+ (L M)
+ (i j)
+ (j k)
+ (val (* A (AREF2 '$ARG M I K)))))))
+
+(defthm
+ Rj<-aRi+Rj-loop-guard-hack-1
+ (IMPLIES (AND (< K (CADR (DIMENSIONS '$ARG M)))
+ (< J (CAR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 J)
+ (INTEGERP J)
+ (integerp k)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ M
+ J
+ K
+ (+ (AREF2 '$ARG M J K)
+ (* A (AREF2 '$ARG M I K))))))
+ :hints (("Goal"
+ :in-theory (disable array2p-aset2)
+ :use (:instance
+ array2p-aset2
+ (L M)
+ (i j)
+ (j k)
+ (val (+ (AREF2 '$ARG M J K)
+ (* A (AREF2 '$ARG M I K))))))))
+
+(defun
+ Rj<-aRi+Rj-loop (name M a i j k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims)))
+ (and (< i dims1)
+ (< j dims1)
+ (< k (second dims)))))))
+ (if (zp k)
+ (aset2 name
+ M
+ j
+ 0
+ (+ (* a (fix (aref2 name
+ M
+ i
+ 0)))
+ (fix (aref2 name
+ M
+ j
+ 0))))
+ (Rj<-aRi+Rj-loop name
+ (aset2 name
+ M
+ j
+ k
+ (+ (* a (fix (aref2 name
+ M
+ i
+ k)))
+ (fix (aref2 name
+ M
+ j
+ k))))
+ a
+ i
+ j
+ (- k 1))))
+
+(defun
+ Rj<-aRi+Rj (name M a i j)
+ "Return the result of replacing each element,
+ Mjk, in row j of matrix M, with (+ (* a Mik) Mjk)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims1 (first dims)))
+ (and (< i dims1)
+ (< j dims1))))))
+ (Rj<-aRi+Rj-loop name
+ M
+ a
+ i
+ j
+ (- (second (dimensions name M)) 1)))
+
+(defthm
+ Cj<-aCi+Cj-loop-guard-hack
+ (IMPLIES (AND (< K (CAR (DIMENSIONS '$ARG M)))
+ (< J (CADR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 J)
+ (INTEGERP J)
+ (integerp k)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ M
+ K
+ J
+ (* A (AREF2 '$ARG M K I)))))
+ :hints (("Goal"
+ :in-theory (disable array2p-aset2)
+ :use (:instance
+ array2p-aset2
+ (L M)
+ (i k)
+ (val (* A (AREF2 '$ARG M K i)))))))
+
+(defthm
+ Cj<-aCi+Cj-loop-guard-hack-1
+ (IMPLIES (AND (< K (CAR (DIMENSIONS '$ARG M)))
+ (< J (CADR (DIMENSIONS '$ARG M)))
+ (< I (CADR (DIMENSIONS '$ARG M)))
+ (<= 0 K)
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP J)
+ (INTEGERP I)
+ (integerp k)
+ (ARRAY2P NAME M))
+ (ARRAY2P NAME
+ (ASET2 '$ARG
+ M
+ K
+ J
+ (+ (AREF2 '$ARG M K J)
+ (* A (AREF2 '$ARG M K I))))))
+ :hints (("Goal"
+ :in-theory (disable array2p-aset2)
+ :use (:instance
+ array2p-aset2
+ (L M)
+ (i k)
+ (val (+ (AREF2 '$ARG M K j)
+ (* A (AREF2 '$ARG M K i))))))))
+
+(defun
+ Cj<-aCi+Cj-loop (name M a i j k)
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (let* ((dims (dimensions name M))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2)
+ (< k (first dims)))))))
+ (if (zp k)
+ (aset2 name
+ M
+ 0
+ j
+ (+ (* a (fix (aref2 name
+ M
+ 0
+ i)))
+ (fix (aref2 name
+ M
+ 0
+ j))))
+ (Cj<-aCi+Cj-loop name
+ (aset2 name
+ M
+ k
+ j
+ (+ (* a (fix (aref2 name
+ M
+ k
+ i)))
+ (fix (aref2 name
+ M
+ k
+ j))))
+ a
+ i
+ j
+ (- k 1))))
+
+(defun
+ Cj<-aCi+Cj (name M a i j)
+ "Return the result of replacing each element,
+ Mkj, in column j of matrix M, with (+ (* a Mki)
+ Mkj)."
+ (declare (xargs :guard (and (acl2-numberp a)
+ (array2p name M)
+ (integerp i)
+ (integerp j)
+ (/= i j)
+ (>= i 0)
+ (>= j 0)
+ (let* ((dims (dimensions name M))
+ (dims2 (second dims)))
+ (and (< i dims2)
+ (< j dims2))))))
+
+ (Cj<-aCi+Cj-loop name
+ M
+ a
+ i
+ j
+ (- (first (dimensions name M)) 1)))
+
+(local (in-theory (disable ARRAY2P-$ARG-EQUAL-PARTS)))
+
+(defthm
+ Ri<->Rj-loop-equal-parts
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M)))
+ (< j (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (and (equal (header name (Ri<->Rj-loop name M i j k))
+ (header name M))
+ (equal (dimensions name (Ri<->Rj-loop name M i j k))
+ (dimensions name M))
+ (equal (maximum-length name
+ (Ri<->Rj-loop name M i j k))
+ (maximum-length name M))
+ (equal (default name (Ri<->Rj-loop name M i j k))
+ (default name M)))))
+
+(defthm
+ Ci<->Cj-loop-equal-parts
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (second (dimensions name M)))
+ (< j (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (and (equal (header name (Ci<->Cj-loop name M i j k))
+ (header name M))
+ (equal (dimensions name (Ci<->Cj-loop name M i j k))
+ (dimensions name M))
+ (equal (maximum-length name
+ (Ci<->Cj-loop name M i j k))
+ (maximum-length name M))
+ (equal (default name (Ci<->Cj-loop name M i j k))
+ (default name M)))))
+
+(defthm
+ Ri<-aRi-loop-equal-parts
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (and (equal (header name (Ri<-aRi-loop name M a i k))
+ (header name M))
+ (equal (dimensions name (Ri<-aRi-loop name M a i k))
+ (dimensions name M))
+ (equal (maximum-length name
+ (Ri<-aRi-loop name M a i k))
+ (maximum-length name M))
+ (equal (default name (Ri<-aRi-loop name M a i k))
+ (default name M)))))
+
+(defthm
+ Ci<-aCi-loop-equal-parts
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (and (equal (header name (Ci<-aCi-loop name M a i k))
+ (header name M))
+ (equal (dimensions name (Ci<-aCi-loop name M a i k))
+ (dimensions name M))
+ (equal (maximum-length name
+ (Ci<-aCi-loop name M a i k))
+ (maximum-length name M))
+ (equal (default name (Ci<-aCi-loop name M a i k))
+ (default name M)))))
+
+(defthm
+ Rj<-aRi+Rj-loop-equal-parts
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (and (equal (header name
+ (Rj<-aRi+Rj-loop name M a i j k))
+ (header name M))
+ (equal (dimensions name
+ (Rj<-aRi+Rj-loop name M a i j k))
+ (dimensions name M))
+ (equal (maximum-length name
+ (Rj<-aRi+Rj-loop name M a i j k))
+ (maximum-length name M))
+ (equal (default name (Rj<-aRi+Rj-loop name M a i j k))
+ (default name M)))))
+
+(defthm
+ Cj<-aCi+Cj-loop-equal-parts
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (and (equal (header name
+ (Cj<-aCi+Cj-loop name M a i j k))
+ (header name M))
+ (equal (dimensions name
+ (Cj<-aCi+Cj-loop name M a i j k))
+ (dimensions name M))
+ (equal (maximum-length name
+ (Cj<-aCi+Cj-loop name M a i j k))
+ (maximum-length name M))
+ (equal (default name (Cj<-aCi+Cj-loop name M a i j k))
+ (default name M)))))
+
+(defthm
+ alist2p-Ri<->Rj-loop
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M)))
+ (< j (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (alist2p name (Ri<->Rj-loop name M i j k))))
+
+(defthm
+ array2p-Ri<->Rj-loop
+ (implies (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M)))
+ (< j (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (array2p name (Ri<->Rj-loop name M i j k))))
+
+(defthm
+ alist2p-Ci<->Cj-loop
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (second (dimensions name M)))
+ (< j (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (alist2p name (Ci<->Cj-loop name M i j k))))
+
+(defthm
+ array2p-Ci<->Cj-loop
+ (implies (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (second (dimensions name M)))
+ (< j (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (array2p name (Ci<->Cj-loop name M i j k))))
+
+(defthm
+ alist2p-Ri<-aRi-loop
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (alist2p name (Ri<-aRi-loop name M a i k))))
+
+(defthm
+ array2p-Ri<-aRi-loop
+ (implies (and (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (array2p name (Ri<-aRi-loop name M a i k))))
+
+(defthm
+ alist2p-Ci<-aCi-loop
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (alist2p name (Ci<-aCi-loop name M a i k))))
+
+(defthm
+ array2p-Ci<-aCi-loop
+ (implies (and (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (array2p name (Ci<-aCi-loop name M a i k))))
+
+(defthm
+ alist2p-Rj<-aRi+Rj-loop
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (alist2p name (Rj<-aRi+Rj-loop name M a i j k))))
+
+(defthm
+ array2p-Rj<-aRi+Rj-loop
+ (implies (and (array2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (first (dimensions name M)))
+ (< k (second (dimensions name M))))
+ (array2p name (Rj<-aRi+Rj-loop name M a i j k))))
+
+(defthm
+ alist2p-Cj<-aCi+Cj-loop
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (alist2p name (Cj<-aCi+Cj-loop name M a i j k))))
+
+(defthm
+ array2p-Cj<-aCi+Cj-loop
+ (implies (and (array2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (second (dimensions name M)))
+ (< k (first (dimensions name M))))
+ (array2p name (Cj<-aCi+Cj-loop name M a i j k))))
+
+(local (in-theory (enable ARRAY2P-$ARG-EQUAL-PARTS)))
+
+(defthm
+ dimensions-Ri<->Rj
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M)))
+ (< j (first (dimensions name M))))
+ (equal (dimensions name (Ri<->Rj name M i j))
+ (dimensions name M))))
+
+(defthm
+ dimensions-Ci<->Cj
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (second (dimensions name M)))
+ (< j (second (dimensions name M))))
+ (equal (dimensions name (Ci<->Cj name M i j))
+ (dimensions name M))))
+
+(defthm
+ dimensions-Ri<-aRi
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M))))
+ (equal (dimensions name (Ri<-aRi name M a i))
+ (dimensions name M))))
+
+(defthm
+ dimensions-Ci<-aCi
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M))))
+ (equal (dimensions name (Ci<-aCi name M a i))
+ (dimensions name M))))
+
+(defthm
+ dimensions-Rj<-aRi+Rj
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (first (dimensions name M))))
+ (equal (dimensions name (Rj<-aRi+Rj name M a i j))
+ (dimensions name M))))
+
+(defthm
+ dimensions-Cj<-aCi+Cj
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (second (dimensions name M))))
+ (equal (dimensions name (Cj<-aCi+Cj name M a i j))
+ (dimensions name M))))
+
+(defthm
+ alist2p-Ri<->Rj
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M)))
+ (< j (first (dimensions name M))))
+ (alist2p name (Ri<->Rj name M i j))))
+
+(defthm
+ array2p-Ri<->Rj
+ (implies (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (first (dimensions name M)))
+ (< j (first (dimensions name M))))
+ (array2p name (Ri<->Rj name M i j))))
+
+(defthm
+ alist2p-Ci<->Cj
+ (implies (and (alist2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (second (dimensions name M)))
+ (< j (second (dimensions name M))))
+ (alist2p name (Ci<->Cj name M i j))))
+
+(defthm
+ array2p-Ci<->Cj
+ (implies (and (array2p name M)
+ (integerp i)
+ (integerp j)
+ (>= i 0)
+ (>= j 0)
+ (< i (second (dimensions name M)))
+ (< j (second (dimensions name M))))
+ (array2p name (Ci<->Cj name M i j))))
+
+(defthm
+ alist2p-Ri<-aRi
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M))))
+ (alist2p name (Ri<-aRi name M a i))))
+
+(defthm
+ array2p-Ri<-aRi
+ (implies (and (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (first (dimensions name M))))
+ (array2p name (Ri<-aRi name M a i))))
+
+(defthm
+ alist2p-Ci<-aCi
+ (implies (and (alist2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M))))
+ (alist2p name (Ci<-aCi name M a i))))
+
+(defthm
+ array2p-Ci<-aCi
+ (implies (and (array2p name M)
+ (integerp i)
+ (>= i 0)
+ (< i (second (dimensions name M))))
+ (array2p name (Ci<-aCi name M a i))))
+
+(defthm
+ alist2p-Rj<-aRi+Rj
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (first (dimensions name M))))
+ (alist2p name (Rj<-aRi+Rj name M a i j))))
+
+(defthm
+ array2p-Rj<-aRi+Rj
+ (implies (and (array2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (first (dimensions name M))))
+ (array2p name (Rj<-aRi+Rj name M a i j))))
+
+(defthm
+ alist2p-Cj<-aCi+Cj
+ (implies (and (alist2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (second (dimensions name M))))
+ (alist2p name (Cj<-aCi+Cj name M a i j))))
+
+(defthm
+ array2p-Cj<-aCi+Cj
+ (implies (and (array2p name M)
+ (integerp j)
+ (>= j 0)
+ (< j (second (dimensions name M))))
+ (array2p name (Cj<-aCi+Cj name M a i j))))
+
+(in-theory (disable Ri<->Rj
+ Ci<->Cj
+ Ri<-aRi
+ Ci<-aCi
+ Rj<-aRi+Rj
+ Cj<-aCi+Cj))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Matrix inverse and determinant:
+
+;; Description of algorithm for computing the
+;; inverse and determinant.
+
+;; Input a square matrix M.
+
+;; let A <- I
+;; B <- I
+;; C <- M
+;; D <- 1
+
+;; Row reduce C to I.
+;; Apply same row operations to B.
+;; Multiply A successively on right by
+;; inverse of same row operations.
+;; (Done with equivalent column operations.)
+;; Modify D according to column operations on A.
+;; Ci<->Cj: D <- -1 * D
+;; Ci<-aCi: D <- a * D
+;; Cj<-aCi+Cj: D <- D
+
+;; Invariants
+;; A * B = I
+;; B * M = C
+;; D = determinant of A
+
+;; After termination
+;; A = left inverse of B
+;; B = left inverse of M (because C contains I
+;; after termination)
+
+;; Prove that after termination A = M:
+;; A = A * I = A * (B * M)
+;; = (A * B) * M = I * M = M
+
+;; Thus B is both left and right inverse of M
+;; and D is the determinant of M.
+
+;; Inverse row operations:
+;; (Ri<->Rj)^(-1) = Ri<->Rj
+;; (Ri<-aRi)^(-1) = Ri<-(/a)Ri
+;; (Rj<-aRi+Rj)^(-1) = Rj<-(-a)Ri+Rj
+
+;; Equivalent row and column operations as
+;; applied to identity matrix: I
+;; Ri<->Rj(I) = Ci<->Cj(I)
+;; Ri<-aRi(I) = Ci<-aCi(I)
+;; Rj<-aRi+Rj(I) = Ci<-aCj+Ci(I)
+
+;; Row operation applied to M is the same as
+;; multiplying M on the LEFT by the result
+;; of applying the same operation to I.
+
+;; Column operation applied to M is the same as
+;; multiplying M on the RIGHT by the result
+;; of applying the same operation to I.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun
+ zero-column (A B C i1 j i)
+ "For k = i downto 0,
+ when k differs from i1 and (aref2 '$C C k j) is a nonzero number then
+ replace column i1 in A with (aref2 '$C C k j) * column k + column i1,
+ replace row k in B with (- (aref2 '$C C k j)) * row i1 + row k,
+ replace row k in C with (- (aref2 '$C C k j)) * row i1 + row k.
+ When (aref2 '$C C i1 j) = 1, then all other entries in the jth
+ column of C are modified to 0."
+ (declare (xargs :guard (and (array2p '$a A)
+ (array2p '$b B)
+ (array2p '$c C)
+ (integerp i)
+ (>= i 0)
+ (integerp i1)
+ (>= i1 0)
+ (integerp j)
+ (>= j 0)
+ (< i (second
+ (dimensions '$a
+ A)))
+ (< i (first
+ (dimensions '$b
+ B)))
+ (< i (first
+ (dimensions '$c
+ C)))
+ (< i1 (second
+ (dimensions '$a
+ A)))
+ (< i1 (first
+ (dimensions '$b
+ B)))
+ (< i1 (first
+ (dimensions '$c
+ C)))
+ (< j (second
+ (dimensions '$c
+ C))))))
+ (if (zp i)
+ (if (not (zp i1))
+ (let ((val (fix (aref2 '$C C 0 j))))
+ (if (= val 0)
+ (mv A B C)
+ (mv (Cj<-aCi+Cj '$A A val 0 i1)
+ (Rj<-aRi+Rj '$B B (- val) i1 0)
+ (Rj<-aRi+Rj '$C C (- val) i1 0))))
+ (mv A B C))
+ (if (not (equal i i1))
+ (let ((val (fix (aref2 '$C C i j))))
+ (if (= val 0)
+ (zero-column A B C i1 j (- i 1))
+ (zero-column (Cj<-aCi+Cj '$A A val i i1)
+ (Rj<-aRi+Rj '$B B (- val) i1 i)
+ (Rj<-aRi+Rj '$C C (- val) i1 i)
+ i1
+ j
+ (- i 1))))
+ (zero-column A B C i1 j (- i 1)))))
+
+(defthm
+ dimensions-RJ<-ARI+RJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP J)
+ (>= J 0)
+ (< J (FIRST (DIMENSIONS NAME M))))
+ (EQUAL (DIMENSIONS NAME (RJ<-ARI+RJ NAME1 M A I J))
+ (DIMENSIONS NAME M)))
+ :hints (("Goal"
+ :in-theory (disable dimensions-RJ<-ARI+RJ)
+ :use (:instance
+ dimensions-RJ<-ARI+RJ
+ (name name1)))))
+
+(DEFTHM
+ DIMENSIONS-CJ<-ACI+CJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP J)
+ (>= J 0)
+ (< J (SECOND (DIMENSIONS NAME M))))
+ (EQUAL (DIMENSIONS NAME (CJ<-ACI+CJ NAME1 M A I J))
+ (DIMENSIONS NAME M)))
+ :hints (("Goal"
+ :in-theory (disable dimensions-CJ<-ACI+CJ)
+ :use (:instance
+ dimensions-CJ<-ACI+CJ
+ (name name1)))))
+
+(DEFTHM
+ ALIST2P-RJ<-ARI+RJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP J)
+ (>= J 0)
+ (< J (FIRST (DIMENSIONS NAME M))))
+ (ALIST2P NAME (RJ<-ARI+RJ NAME1 M A I J)))
+ :hints (("Goal"
+ :in-theory (disable ALIST2P-RJ<-ARI+RJ)
+ :use (:instance
+ ALIST2P-RJ<-ARI+RJ
+ (name name1)))))
+
+(DEFTHM
+ ALIST2P-CJ<-ACI+CJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP J)
+ (>= J 0)
+ (< J (SECOND (DIMENSIONS NAME M))))
+ (ALIST2P NAME (CJ<-ACI+CJ NAME1 M A I J)))
+ :hints (("Goal"
+ :in-theory (disable ALIST2P-CJ<-ACI+CJ)
+ :use (:instance
+ ALIST2P-CJ<-ACI+CJ
+ (name name1)))))
+
+(DEFTHM
+ ARRAY2P-RJ<-ARI+RJ-1
+ (IMPLIES (AND (symbolp name1)
+ (ARRAY2P NAME M)
+ (INTEGERP J)
+ (>= J 0)
+ (< J (FIRST (DIMENSIONS NAME M))))
+ (ARRAY2P NAME (RJ<-ARI+RJ NAME1 M A I J)))
+ :hints (("Goal"
+ :in-theory (disable Array2P-RJ<-ARI+RJ)
+ :use (:instance
+ Array2P-RJ<-ARI+RJ
+ (name name1)))))
+
+(DEFTHM
+ ARRAY2P-CJ<-ACI+CJ-1
+ (IMPLIES (AND (symbolp name1)
+ (ARRAY2P NAME M)
+ (INTEGERP J)
+ (>= J 0)
+ (< J (SECOND (DIMENSIONS NAME M))))
+ (ARRAY2P NAME (CJ<-ACI+CJ NAME1 M A I J)))
+ :hints (("Goal"
+ :in-theory (disable Array2P-CJ<-ACI+CJ)
+ :use (:instance
+ Array2P-CJ<-ACI+CJ
+ (name name1)))))
+
+(defthm
+ dimensions-zero-column-A
+ (implies (and (alist2p name A)
+ (integerp i1)
+ (>= i1 0)
+ (< i1 (second (dimensions name A))))
+ (equal (dimensions name (car (zero-column A B C i1 j i)))
+ (dimensions name A))))
+
+(defthm
+ alist2p-zero-column-A
+ (implies (and (alist2p name A)
+ (integerp i1)
+ (>= i1 0)
+ (< i1 (second (dimensions name A))))
+ (alist2p name (car (zero-column A B C i1 j i)))))
+
+(defthm
+ array2p-zero-column-A
+ (implies (and (array2p name A)
+ (integerp i1)
+ (>= i1 0)
+ (< i1 (second (dimensions name A))))
+ (array2p name (car (zero-column A B C i1 j i)))))
+
+(defthm
+ dimensions-zero-column-B
+ (implies (and (alist2p name B)
+ (< i (first (dimensions name B))))
+ (equal (dimensions name (cadr (zero-column A B C i1 j i)))
+ (dimensions name B))))
+
+(defthm
+ alist2p-zero-column-B
+ (implies (and (alist2p name B)
+ (< i (first (dimensions name B))))
+ (alist2p name (cadr (zero-column A B C i1 j i)))))
+
+(defthm
+ array2p-zero-column-B
+ (implies (and (array2p name B)
+ (< i (first (dimensions name B))))
+ (array2p name (cadr (zero-column A B C i1 j i)))))
+
+(defthm
+ dimensions-zero-column-C
+ (implies (and (alist2p name C)
+ (< i (first (dimensions name C))))
+ (equal (dimensions name (caddr (zero-column A B C i1 j i)))
+ (dimensions name C))))
+
+(defthm
+ alist2p-zero-column-C
+ (implies (and (alist2p name C)
+ (< i (first (dimensions name C))))
+ (alist2p name (caddr (zero-column A B C i1 j i)))))
+
+(defthm
+ array2p-zero-column-C
+ (implies (and (array2p name C)
+ (< i (first (dimensions name C))))
+ (array2p name (caddr (zero-column A B C i1 j i)))))
+
+(defun
+ find-non-zero-col (name C i j k)
+ "Determine if there is a nonzero value among
+ C(i k), C(i+1) k), . . . , C(j k).
+ If not, return nil, otherwise return the
+ first n such that C(n k) is nonzero."
+ (declare (xargs :measure (let ((i (nfix i))
+ (j (nfix j)))
+ (if (> i j)
+ 0
+ (- (+ j 1) i)))
+ :guard (and (array2p name C)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (>= k 0)
+ (< j (first
+ (dimensions name
+ C)))
+ (< k (second
+ (dimensions name
+ C))))))
+ (let ((i (nfix i))
+ (j (nfix j)))
+ (cond ((> i j) nil)
+ ((zerop (fix (aref2 name C i k)))
+ (find-non-zero-col name C (+ i 1) j k))
+ (t i))))
+
+(defthm
+ find-non-zero-col-inequality
+ (implies (>= j 0)
+ (<= (find-non-zero-col name C i j k)
+ j))
+ :rule-classes (:rewrite :linear))
+
+(defthm
+ find-non-zero-col-inequality-1
+ (implies (and (find-non-zero-col name C i j k)
+ (integerp i))
+ (>= (find-non-zero-col name C i j k)
+ i))
+ :rule-classes (:rewrite :linear))
+
+(defthm
+ aref2-find-non-zero-col
+ (implies (find-non-zero-col name C i j k)
+ (and (acl2-numberp
+ (aref2 name
+ C
+ (find-non-zero-col name
+ C
+ i
+ j
+ k)
+ k))
+ (not (equal
+ (aref2 name
+ C
+ (find-non-zero-col name
+ C
+ i
+ j
+ k)
+ k)
+ 0))))
+ :rule-classes :type-prescription)
+
+(defun
+ find-non-zero-col-1 (name C i j k n)
+ "Determine if there is a nonzero value among
+ C(i k) C(i k+1) . . . C(i n)
+ C(i+1) k) C(i+1 k+1) . . . C(i+1 n)
+ . . . .
+ . . . .
+ . . . .
+ C(j k) C(j k+1) . . . C(j n)
+ If not, return nil, otherwise return the
+ first, obtained by searching column by column,
+ pair p q, such that C(p q) is nonzero."
+ (declare (xargs :measure (let ((k (nfix k))
+ (n (nfix n)))
+ (if (> k n)
+ 0
+ (- (+ n 1) k)))
+ :guard (and (array2p name C)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (integerp n)
+ (< j (first (dimensions name C)))
+ (< n (second (dimensions name C))))))
+ (let ((k (nfix k))
+ (n (nfix n)))
+ (if (> k n)
+ nil
+ (let ((p (find-non-zero-col name C i j k)))
+ (if p
+ (list p k)
+ (find-non-zero-col-1 name
+ C
+ i
+ j
+ (+ k 1)
+ n))))))
+
+(defthm
+ natp-car-find-non-zero-col-1
+ (implies (find-non-zero-col-1 name C i j k n)
+ (and (integerp (car (find-non-zero-col-1 name C i j k n)))
+ (>= (car (find-non-zero-col-1 name C i j k n)) 0)))
+ :rule-classes :type-prescription)
+
+(defthm
+ natp-cadr-find-non-zero-col-1
+ (implies (find-non-zero-col-1 name C i j k n)
+ (and (integerp (cadr (find-non-zero-col-1 name C i j k n)))
+ (>= (cadr (find-non-zero-col-1 name C i j k n)) 0)))
+ :rule-classes :type-prescription)
+
+(defthm
+ find-non-zero-col-1-inequality
+ (implies (>= j 0)
+ (<= (first (find-non-zero-col-1 name C i j k n))
+ j))
+ :rule-classes (:rewrite :linear))
+
+(defthm
+ find-non-zero-col-1-inequality-1
+ (implies (and (find-non-zero-col-1 name C i j k n)
+ (integerp i))
+ (>= (first (find-non-zero-col-1 name C i j k n))
+ i))
+ :rule-classes (:rewrite :linear))
+
+(defthm
+ find-non-zero-col-1-inequality-2
+ (implies (and (>= n 0))
+ (<= (second (find-non-zero-col-1 name C i j k n))
+ n))
+ :rule-classes (:rewrite :linear))
+
+(defthm
+ find-non-zero-col-1-inequality-3
+ (implies (and (find-non-zero-col-1 name C i j k n)
+ (integerp k))
+ (>= (second (find-non-zero-col-1 name C i j k n))
+ k))
+ :rule-classes (:rewrite :linear))
+
+(defthm
+ type-aref2-find-non-zero-col-1
+ (implies (find-non-zero-col-1 name1 C i j k n)
+ (and (acl2-numberp
+ (aref2 name
+ C
+ (car
+ (find-non-zero-col-1 name1
+ C
+ i
+ j
+ k
+ n))
+ (cadr
+ (find-non-zero-col-1 name1
+ C
+ i
+ j
+ k
+ n))))
+ (not
+ (equal
+ (aref2 name
+ C
+ (car
+ (find-non-zero-col-1 name1
+ C
+ i
+ j
+ k
+ n))
+ (cadr
+ (find-non-zero-col-1 name1
+ C
+ i
+ j
+ k
+ n)))
+ 0))))
+ :rule-classes :type-prescription
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(DEFTHM
+ DIMENSIONS-RI<-ARI-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (>= I 0)
+ (< I (FIRST (DIMENSIONS NAME M))))
+ (EQUAL (DIMENSIONS NAME (RI<-ARI NAME1 M A I))
+ (DIMENSIONS NAME M)))
+ :hints (("Goal"
+ :in-theory (disable DIMENSIONS-RI<-ARI)
+ :use (:instance
+ DIMENSIONS-RI<-ARI
+ (name name1)))))
+
+(DEFTHM
+ DIMENSIONS-CI<-ACI-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (>= I 0)
+ (< I (SECOND (DIMENSIONS NAME M))))
+ (EQUAL (DIMENSIONS NAME (CI<-ACI NAME1 M A I))
+ (DIMENSIONS NAME M)))
+ :hints (("Goal"
+ :in-theory (disable DIMENSIONS-CI<-ACI)
+ :use (:instance
+ DIMENSIONS-CI<-ACI
+ (name name1)))))
+
+(DEFTHM
+ DIMENSIONS-RI<->RJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (INTEGERP J)
+ (>= I 0)
+ (>= J 0)
+ (< I (FIRST (DIMENSIONS NAME M)))
+ (< J (FIRST (DIMENSIONS NAME M))))
+ (EQUAL (DIMENSIONS NAME (RI<->RJ NAME1 M I J))
+ (DIMENSIONS NAME M)))
+ :hints (("Goal"
+ :in-theory (disable DIMENSIONS-RI<->RJ)
+ :use (:instance
+ DIMENSIONS-RI<->RJ
+ (name name1)))))
+
+(DEFTHM
+ DIMENSIONS-CI<->CJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (INTEGERP J)
+ (>= I 0)
+ (>= J 0)
+ (< I (SECOND (DIMENSIONS NAME M)))
+ (< J (SECOND (DIMENSIONS NAME M))))
+ (EQUAL (DIMENSIONS NAME (CI<->CJ NAME1 M I J))
+ (DIMENSIONS NAME M)))
+ :hints (("Goal"
+ :in-theory (disable DIMENSIONS-CI<->CJ)
+ :use (:instance
+ DIMENSIONS-CI<->CJ
+ (name name1)))))
+
+(defthm
+ lemma-32-hack
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< (+ 1 I)
+ (CADR
+ (DIMENSIONS
+ '$a
+ (CAR (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :rule-classes nil)
+
+(defthm
+ lemma-32-hack-1
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< (+ 1 I)
+ (CADR
+ (DIMENSIONS
+ '$arg
+ (CAR (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-32-hack)))
+
+(defthm
+ lemma-23-hack
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP J)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CADR
+ (DIMENSIONS
+ '$A
+ (CAR (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :rule-classes nil)
+
+(defthm
+ lemma-23-hack-1
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP J)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CADR
+ (DIMENSIONS
+ '$arg
+ (CAR (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-23-hack)))
+
+(defthm
+ lemma-19-hack
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CADR
+ (DIMENSIONS '$A
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)))))
+ :rule-classes nil)
+
+(defthm
+ lemma-19-hack-1
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CADR
+ (DIMENSIONS '$Arg
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-19-hack)))
+
+(defthm
+ lemma-18-hack
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< I
+ (CAR (DIMENSIONS
+ '$B
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)))))
+ :rule-classes nil)
+
+(defthm
+ lemma-18-hack-1
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< I
+ (CAR (DIMENSIONS
+ '$arg
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-18-hack)))
+
+(defthm
+ lemma-16-hack
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CAR
+ (DIMENSIONS
+ '$b
+ (CADR
+ (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :rule-classes nil)
+
+(defthm
+ lemma-16-hack-1
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CAR
+ (DIMENSIONS
+ '$arg
+ (CADR
+ (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-16-hack)))
+
+(defthm
+ lemma-15-hack
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CAR (DIMENSIONS
+ '$b
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)))))
+ :rule-classes nil)
+
+(defthm
+ lemma-15-hack-1
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< J
+ (CAR (DIMENSIONS
+ '$arg
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-15-hack)))
+
+(defthm
+ lemma-15-crock
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< I
+ (CADR
+ (DIMENSIONS '$a
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)))))
+ :rule-classes nil)
+
+(defthm
+ lemma-15-crock-1
+ (IMPLIES (AND (< J (CADR (DIMENSIONS '$ARG A)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$A A)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< I
+ (CADR
+ (DIMENSIONS '$arg
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-15-crock)))
+
+(defthm
+ lemma-10-hack
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< (+ 1 I)
+ (CAR
+ (DIMENSIONS
+ '$b
+ (CADR
+ (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :rule-classes nil)
+
+(defthm
+ lemma-10-hack-1
+ (IMPLIES (AND (< J (CAR (DIMENSIONS '$ARG B)))
+ (<= 0 J)
+ (<= 0 I)
+ (INTEGERP I)
+ (ARRAY2P '$B B)
+ (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (NOT (EQUAL (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I)))
+ (< (+ 1 I)
+ (CAR
+ (DIMENSIONS
+ '$arg
+ (CADR
+ (ZERO-COLUMN
+ (CI<-ACI '$A
+ (CI<->CJ '$A
+ A
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ I)
+ (RI<-ARI '$B
+ (RI<->RJ '$B
+ B
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ (RI<-ARI '$C
+ (RI<->RJ '$C
+ C
+ I
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N)))
+ (/ (AREF2 '$ARG
+ C
+ (CAR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))))
+ I)
+ I
+ (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ J))))))
+ :hints (("Goal"
+ :in-theory (disable NATP-CAR-FIND-NON-ZERO-COL-1)
+ :use lemma-10-hack)))
+
+(defthm
+ lemma-1-hack
+ (IMPLIES (AND (FIND-NON-ZERO-COL-1 '$C C I J K N)
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (<= 0 J)
+ (INTEGERP J)
+ (ARRAY2P '$C C)
+ (NOT (EQUAL I J))
+ (EQUAL (CADR (FIND-NON-ZERO-COL-1 '$C C I J K N))
+ I))
+ (< (+ 1 I) (CAR (DIMENSIONS '$ARG C)))))
+
+(defun
+ determinant-inverse-loop (A B C D i j k n)
+ "Process columns k thru n,
+ restricted to rows i thru j."
+ (declare (xargs :measure (let ((k (nfix k))
+ (n (nfix n)))
+ (if (> k n)
+ 0
+ (- (+ n 1) k)))
+ :guard (and (array2p '$a A)
+ (array2p '$b B)
+ (array2p '$c C)
+ (acl2-numberp D)
+ (integerp i)
+ (integerp j)
+ (integerp k)
+ (integerp n)
+ (>= i 0)
+ (>= j 0)
+ (>= k 0)
+ (>= n 0)
+ (< i (second
+ (dimensions '$a
+ A)))
+ (< i (first
+ (dimensions '$b
+ B)))
+ (< i (first
+ (dimensions '$c
+ C)))
+ (< j (second
+ (dimensions '$a
+ A)))
+ (< j (first
+ (dimensions '$b
+ B)))
+ (< j (first
+ (dimensions '$c
+ C)))
+ (< n (second
+ (dimensions '$c
+ C))))
+ :verify-guards nil))
+ (let ((k (nfix k))
+ (n (nfix n))
+ (i (nfix i))
+ (j (nfix j)))
+ (if (> k n)
+ (mv A B C D)
+ (let
+ ((indices (find-non-zero-col-1 '$C C i j k n)))
+ (if indices
+ (let*
+ ((p (first indices))
+ (q (second indices))
+ (val (aref2 '$C C p q)))
+ (if (= p i)
+ (mv-let
+ (A B C)
+ (zero-column (Ci<-aCi '$A A val i)
+ (Ri<-aRi '$B B (/ val) i)
+ (Ri<-aRi '$C C (/ val) i)
+ i
+ q
+ j)
+ (cond ((= i j)
+ (mv A B C (* val D)))
+ ((= q i)
+ (determinant-inverse-loop A B C
+ (* val D)
+ (+ i 1)
+ j
+ (+ q 1)
+ n))
+ (t
+ (determinant-inverse-loop A B C
+ (* val D)
+ 0
+ j
+ (+ q 1)
+ n))))
+ (mv-let
+ (A B C)
+ (zero-column (Ci<-aCi '$A (Ci<->Cj '$A A i p) val i)
+ (Ri<-aRi '$B (Ri<->Rj '$B B i p)(/ val) i)
+ (Ri<-aRi '$C (Ri<->Rj '$C C i p)(/ val) i)
+ i
+ q
+ j)
+ (cond ((= i j)
+ (mv A B C (* val (- D))))
+ ((= q i)
+ (determinant-inverse-loop A B C
+ (* val (- D))
+ (+ i 1)
+ j
+ (+ q 1)
+ n))
+ (t
+ (determinant-inverse-loop A B C
+ 0
+ (+ i 1)
+ j
+ (+ q 1)
+ n))))))
+ (mv A B C 0))))))
+
+(defthm
+ mv-nth-1
+ (equal (mv-nth 1 L)
+ (cadr L)))
+
+(defthm
+ mv-nth-2
+ (equal (mv-nth 2 L)
+ (caddr L)))
+
+(verify-guards determinant-inverse-loop)
+
+(defthm
+ sq-array2p-m-1
+ (IMPLIES (AND (EQUAL (CAR (DIMENSIONS name M))
+ (CADR (DIMENSIONS name M)))
+ (ARRAY2P name M))
+ (ARRAY2P name
+ (M-1 (CAR (DIMENSIONS name M)))))
+ :hints (("Goal"
+ :use (:theorem
+ (implies (array2p name M)
+ (< (* (first (dimensions name M))
+ (second (dimensions name M)))
+ *MAXIMUM-POSITIVE-32-BIT-INTEGER*))))))
+
+(defthm
+ sq-array2p-m-1-a
+ (IMPLIES (AND (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (ARRAY2P name1 M)
+ (symbolp name))
+ (ARRAY2P name
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ :hints (("Goal"
+ :in-theory (disable sq-array2p-m-1)
+ :use sq-array2p-m-1)))
+
+(defthm
+ sq-array2p-compress2
+ (IMPLIES (AND (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (ARRAY2P name M)
+ (symbolp name1))
+ (ARRAY2P name1
+ (COMPRESS2 name2
+ (M-1 (CAR (DIMENSIONS '$ARG M))))))
+ :hints (("Goal"
+ :in-theory (disable ARRAY2P-COMPRESS2)
+ :use (:instance
+ ARRAY2P-COMPRESS2
+ (L (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (name name1)))))
+
+(defun
+ determinant-inverse (M)
+ "Return multiple values A, B, C, and D.
+ If M is a square array, the determinant of
+ M is returned in D. If the determinant is
+ nonzero, then the matrix inverse of M is
+ returned in B."
+ (declare (xargs :guard (and (array2p '$c M)
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims))))))
+ (let ((dims (dimensions '$c M)))
+ (if (mbt (and (alist2p '$c M)
+ (= (first dims)
+ (second dims))))
+ (let ((dim1 (first dims)))
+ (determinant-inverse-loop (compress2 '$A (m-1 dim1))
+ (compress2 '$B (m-1 dim1))
+ (compress2 '$C M)
+ 1 ;; initial value of D
+ 0
+ (- dim1 1)
+ 0
+ (- (second (dimensions '$c M)) 1)))
+ (mv M (/ M) 1 M))))
+
+(defun
+ determinant (M)
+ (declare (xargs :guard (and (array2p '$c M)
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims))))))
+ (mv-let (A B C D)
+ (determinant-inverse M)
+ (declare (ignore A B C))
+ D))
+
+(defun
+ m-/ (M)
+ (declare (xargs :guard (and (array2p '$c M)
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims))))))
+ (mv-let (A B C D)
+ (determinant-inverse M)
+ (declare (ignore A C D))
+ B))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Eventually, we will prove that for square matrices
+;; whenever the determinant is not 0, then m-/
+;; computes the two-sided inverse; and whenever the
+;; determinant is 0 then there is no inverse.
+;; Also it will be proved that non-square matrices
+;; do not have two-sided inverses.
+
+;; Meanwhile the definition of singualar given
+;; immediately below is replaced by the second one
+;; below.
+
+;; (defun
+;; m-singularp (M)
+;; (declare (xargs :guard (array2p '$c M)))
+;; (not (and (mbt (alist2p '$c M))
+;; (let ((dims (dimensions '$c M)))
+;; (= (first dims)
+;; (second dims)))
+;; (= (determinant M) 0))))
+|#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun
+ m-singularp (M)
+ (declare (xargs :guard (array2p '$c M)
+ :verify-guards nil))
+ (not (and (mbt (alist2p '$c M))
+ (let ((dims (dimensions '$c M)))
+ (= (first dims)
+ (second dims)))
+ (m-= (m-* M (m-/ M))
+ (m-1 (r M)))
+ (m-= (m-* (m-/ M) M)
+ (m-1 (r M))))))
+
+(defthm
+ non-singular-implies-square
+ (implies (not (m-singularp M))
+ (equal (equal (c M)(r M))
+ t)))
+
+(defthm
+ left-m-*-inverse-of-m-/
+ (implies (not (m-singularp M))
+ (m-= (m-* (m-/ M) M)
+ (m-1 (r M)))))
+
+(defthm
+ right-m-*-inverse-of-m-/
+ (implies (not (m-singularp M))
+ (m-= (m-* M (m-/ M))
+ (m-1 (r M)))))
+
+(DEFTHM
+ ALIST2P-CI<->CJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (INTEGERP J)
+ (>= I 0)
+ (>= J 0)
+ (< I (SECOND (DIMENSIONS NAME M)))
+ (< J (SECOND (DIMENSIONS NAME M))))
+ (ALIST2P NAME (CI<->CJ NAME1 M I J)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE alist2p-CI<->CJ)
+ :USE (:INSTANCE
+ alist2p-CI<->CJ
+ (NAME NAME1)))))
+
+(DEFTHM
+ Array2P-CI<->CJ-1
+ (IMPLIES (AND (symbolp name1)
+ (Array2P NAME M)
+ (INTEGERP I)
+ (INTEGERP J)
+ (>= I 0)
+ (>= J 0)
+ (< I (SECOND (DIMENSIONS NAME M)))
+ (< J (SECOND (DIMENSIONS NAME M))))
+ (Array2P NAME (CI<->CJ NAME1 M I J)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE array2p-CI<->CJ)
+ :USE (:INSTANCE
+ array2p-CI<->CJ
+ (NAME NAME1)))))
+
+(DEFTHM
+ ALIST2P-RI<->RJ-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (INTEGERP J)
+ (>= I 0)
+ (>= J 0)
+ (< I (FIRST (DIMENSIONS NAME M)))
+ (< J (FIRST (DIMENSIONS NAME M))))
+ (ALIST2P NAME (RI<->RJ NAME1 M I J)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE alist2p-RI<->RJ)
+ :USE (:INSTANCE
+ alist2p-RI<->RJ
+ (NAME NAME1)))))
+
+(DEFTHM
+ Array2P-RI<->RJ-1
+ (IMPLIES (AND (symbolp name1)
+ (Array2P NAME M)
+ (INTEGERP I)
+ (INTEGERP J)
+ (>= I 0)
+ (>= J 0)
+ (< I (FIRST (DIMENSIONS NAME M)))
+ (< J (FIRST (DIMENSIONS NAME M))))
+ (Array2P NAME (RI<->RJ NAME1 M I J)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE array2p-RI<->RJ)
+ :USE (:INSTANCE
+ array2p-RI<->RJ
+ (NAME NAME1)))))
+
+(DEFTHM
+ ALIST2P-RI<-ARI-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (>= I 0)
+ (< I (FIRST (DIMENSIONS NAME M))))
+ (ALIST2P NAME (RI<-ARI NAME1 M A I)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE alist2p-RI<-ARI)
+ :USE (:INSTANCE
+ alist2p-RI<-ARI
+ (NAME NAME1)))))
+
+(DEFTHM
+ Array2P-RI<-ARI-1
+ (IMPLIES (AND (symbolp name1)
+ (Array2P NAME M)
+ (INTEGERP I)
+ (>= I 0)
+ (< I (FIRST (DIMENSIONS NAME M))))
+ (Array2P NAME (RI<-ARI NAME1 M A I)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE array2p-RI<-ARI)
+ :USE (:INSTANCE
+ array2p-RI<-ARI
+ (NAME NAME1)))))
+
+(DEFTHM
+ ALIST2P-CI<-ACI-1
+ (IMPLIES (AND (ALIST2P NAME M)
+ (INTEGERP I)
+ (>= I 0)
+ (< I (second (DIMENSIONS NAME M))))
+ (ALIST2P NAME (CI<-ACI NAME1 M A I)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE alist2p-CI<-ACI)
+ :USE (:INSTANCE
+ alist2p-CI<-ACI
+ (NAME NAME1)))))
+
+(DEFTHM
+ Array2P-CI<-ACI-1
+ (IMPLIES (AND (symbolp name1)
+ (Array2P NAME M)
+ (INTEGERP I)
+ (>= I 0)
+ (< I (second (DIMENSIONS NAME M))))
+ (Array2P NAME (CI<-ACI NAME1 M A I)))
+ :HINTS (("Goal"
+ :IN-THEORY (DISABLE array2p-CI<-ACI)
+ :USE (:INSTANCE
+ array2p-CI<-ACI
+ (NAME NAME1)))))
+
+(defthm
+ array2p-alist2p-1
+ (implies (and (array2p name1 L)
+ (symbolp name))
+ (alist2p name L))
+ :hints (("Goal"
+ :in-theory (disable array2p-alist2p)
+ :use array2p-alist2p)))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-A
+ (IMPLIES (AND (Alist2P '$A A)
+ (Alist2P '$B B)
+ (Alist2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (EQUAL (DIMENSIONS
+ name
+ (CAR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N)))
+ (DIMENSIONS name A))))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-B
+ (IMPLIES (AND (Alist2P '$A A)
+ (Alist2P '$B B)
+ (Alist2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (EQUAL (DIMENSIONS
+ name
+ (CADR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N)))
+ (DIMENSIONS name B))))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-C
+ (IMPLIES (AND (Alist2P '$A A)
+ (Alist2P '$B B)
+ (Alist2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (EQUAL (DIMENSIONS
+ name
+ (CADDR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N)))
+ (DIMENSIONS name C))))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-A
+ (IMPLIES (AND (Alist2P '$A A)
+ (Alist2P '$B B)
+ (Alist2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (alist2p '$a (CAR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N))))
+
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-B
+ (IMPLIES (AND (Alist2P '$A A)
+ (Alist2P '$B B)
+ (Alist2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (alist2p '$b (CAdR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N))))
+
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-C
+ (IMPLIES (AND (Alist2P '$A A)
+ (Alist2P '$B B)
+ (Alist2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (alist2p '$C (CAddR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N))))
+
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-A
+ (IMPLIES (AND (Array2P '$A A)
+ (Array2P '$B B)
+ (Array2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (array2p '$a (CAR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N))))
+
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-B
+ (IMPLIES (AND (Array2P '$A A)
+ (Array2P '$B B)
+ (Array2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (array2p '$b (CAdR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N))))
+
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-C
+ (IMPLIES (AND (Array2P '$A A)
+ (Array2P '$B B)
+ (Array2P '$C C)
+ (INTEGERP I)
+ (INTEGERP J)
+ (INTEGERP K)
+ (INTEGERP N)
+ (<= 0 I)
+ (<= 0 J)
+ (<= 0 K)
+ (<= 0 N)
+ (< I (CADR (DIMENSIONS '$ARG A)))
+ (< I (CAR (DIMENSIONS '$ARG B)))
+ (< I (CAR (DIMENSIONS '$ARG C)))
+ (< J (CADR (DIMENSIONS '$ARG A)))
+ (< J (CAR (DIMENSIONS '$ARG B)))
+ (< J (CAR (DIMENSIONS '$ARG C)))
+ (< N (CADR (DIMENSIONS '$ARG C))))
+ (array2p '$C (CAddR (DETERMINANT-INVERSE-LOOP A
+ B
+ C
+ D
+ I
+ J
+ K
+ N))))
+
+ :hints (("Goal"
+ :do-not '(generalize))))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-A
+ (IMPLIES (ALIST2P '$C M)
+ (EQUAL (DIMENSIONS
+ '$ARG
+ (CAR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M))))))
+ (LIST (CAR (DIMENSIONS '$ARG M))
+ (CAR (DIMENSIONS '$ARG M)))))
+ :hints (("Goal"
+ :in-theory (disable dimensions-DETERMINANT-INVERSE-LOOP-A)
+ :use (:instance
+ dimensions-DETERMINANT-INVERSE-LOOP-A
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-A-1
+ (IMPLIES (and (ALIST2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (EQUAL (DIMENSIONS
+ '$ARG
+ (CAR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M))))))
+ (LIST (CAR (DIMENSIONS '$ARG M))
+ (CAR (DIMENSIONS '$ARG M)))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-A)
+ :use
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-A)))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-B
+ (IMPLIES (ALIST2P '$C M)
+ (EQUAL (DIMENSIONS
+ '$ARG
+ (CAdR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M))))))
+ (LIST (CAR (DIMENSIONS '$ARG M))
+ (CAR (DIMENSIONS '$ARG M)))))
+ :hints (("Goal"
+ :in-theory (disable dimensions-DETERMINANT-INVERSE-LOOP-B)
+ :use (:instance
+ dimensions-DETERMINANT-INVERSE-LOOP-B
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1
+ (IMPLIES (and (ALIST2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (EQUAL (DIMENSIONS
+ '$ARG
+ (CAdR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M))))))
+ (LIST (CAR (DIMENSIONS '$ARG M))
+ (CAR (DIMENSIONS '$ARG M)))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-B)
+ :use
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-B)))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-C
+ (IMPLIES (ALIST2P '$C M)
+ (EQUAL (DIMENSIONS
+ '$ARG
+ (CAddR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR
+ (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1
+ (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M))))))
+ (dimensions '$arg M)))
+ :hints (("Goal"
+ :in-theory (disable dimensions-DETERMINANT-INVERSE-LOOP-c)
+ :use (:instance
+ dimensions-DETERMINANT-INVERSE-LOOP-c
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-C-1
+ (IMPLIES (and (ALIST2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (EQUAL (DIMENSIONS
+ '$ARG
+ (CAddR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR
+ (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1
+ (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M))))))
+ (dimensions '$arg M)))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-C)
+ :use
+ dimensions-DETERMINANT-INVERSE-LOOP-COMPRESS2-C)))
+
+(defthm
+ dimensions-m-/
+ (implies (and (alist2p name M)
+ (equal (first (dimensions name M))
+ (second (dimensions name M))))
+ (equal (dimensions name (m-/ M))
+ (list (car (dimensions name M))
+ (car (dimensions name M))))))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A
+ (IMPLIES (ALIST2P '$C M)
+ (alist2p name
+ (CAR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable alist2p-DETERMINANT-INVERSE-LOOP-A)
+ :use (:instance
+ alist2p-DETERMINANT-INVERSE-LOOP-A
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A-1
+ (IMPLIES (and (ALIST2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (alist2p name
+ (CAR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A)
+ :use
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A)))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B
+ (IMPLIES (ALIST2P '$C M)
+ (alist2p name
+ (CAdR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable alist2p-DETERMINANT-INVERSE-LOOP-B)
+ :use (:instance
+ alist2p-DETERMINANT-INVERSE-LOOP-B
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1
+ (IMPLIES (and (ALIST2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (alist2p name
+ (CAdR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B)
+ :use
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B)))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C
+ (IMPLIES (ALIST2P '$C M)
+ (alist2p name
+ (CAddR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR
+ (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1
+ (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable alist2p-DETERMINANT-INVERSE-LOOP-c)
+ :use (:instance
+ alist2p-DETERMINANT-INVERSE-LOOP-c
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C-1
+ (IMPLIES (and (ALIST2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (alist2p name
+ (CAddR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR
+ (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1
+ (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C)
+ :use
+ alist2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C)))
+
+(defthm
+ alist2p-m-/
+ (implies (and (alist2p name M)
+ (equal (first (dimensions name M))
+ (second (dimensions name M))))
+ (alist2p name (m-/ M))))
+
+(defTHM
+ ARRAY2P-COMPRESS2-1
+ (IMPLIES (ARRAY2P NAME L)
+ (ARRAY2P NAME (COMPRESS2 NAME1 L))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A
+ (IMPLIES (and (Array2P '$C M)
+ (< (* (CAR (DIMENSIONS '$ARG M))
+ (CAR (DIMENSIONS '$ARG M)))
+ *MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (symbolp name))
+ (array2p name
+ (CAR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable array2p-DETERMINANT-INVERSE-LOOP-A)
+ :use (:instance
+ array2p-DETERMINANT-INVERSE-LOOP-A
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ array2p-rewrite-linear-1
+ (implies (array2p name M)
+ (< (* (CAR (DIMENSIONS name M))
+ (CAdR (DIMENSIONS name M)))
+ *MAXIMUM-POSITIVE-32-BIT-INTEGER*))
+ :rule-classes (:rewrite :linear))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A-1
+ (IMPLIES (and (Array2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (symbolp name))
+ (array2p name
+ (CAR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A
+ array2p-rewrite-linear-1)
+ :use
+ (array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-A
+ (:instance
+ array2p-rewrite-linear-1
+ (name '$arg))))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B
+ (IMPLIES (and (Array2P '$C M)
+ (< (* (CAR (DIMENSIONS '$ARG M))
+ (CAR (DIMENSIONS '$ARG M)))
+ *MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (symbolp name))
+ (array2p name
+ (CAdR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable array2p-DETERMINANT-INVERSE-LOOP-B)
+ :use (:instance
+ array2p-DETERMINANT-INVERSE-LOOP-B
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1
+ (IMPLIES (and (Array2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (symbolp name))
+ (array2p name
+ (CAdR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B
+ array2p-rewrite-linear-1)
+ :use
+ (array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B
+ (:instance
+ array2p-rewrite-linear-1
+ (name '$arg))))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C
+ (IMPLIES (and (Array2P '$C M)
+ (< (* (CAR (DIMENSIONS '$ARG M))
+ (CAR (DIMENSIONS '$ARG M)))
+ *MAXIMUM-POSITIVE-32-BIT-INTEGER*)
+ (symbolp name))
+ (array2p name
+ (CAddR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR
+ (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1
+ (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAdR (DIMENSIONS '$ARG M)))))))
+ :hints (("Goal"
+ :in-theory (disable array2p-DETERMINANT-INVERSE-LOOP-c)
+ :use (:instance
+ array2p-DETERMINANT-INVERSE-LOOP-c
+ (A (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (B (COMPRESS2 '$ARG
+ (M-1 (CAR (DIMENSIONS '$ARG M)))))
+ (C (COMPRESS2 '$ARG M))
+ (i 0)
+ (j (+ -1 (CAR (DIMENSIONS '$ARG M))))
+ (k 0)
+ (n (+ -1 (CAdR (DIMENSIONS '$ARG M))))))))
+
+(defthm
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C-1
+ (IMPLIES (and (Array2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M)))
+ (symbolp name))
+ (array2p name
+ (CAddR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2
+ '$ARG
+ (M-1 (CAR
+ (DIMENSIONS '$ARG M))))
+ (COMPRESS2
+ '$ARG
+ (M-1
+ (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ D
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1
+ (CAR (DIMENSIONS '$ARG M)))))))
+ :hints
+ (("Goal"
+ :in-theory
+ (disable
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C
+ array2p-rewrite-linear-1)
+ :use
+ (array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-C
+ (:instance
+ array2p-rewrite-linear-1
+ (name '$arg))))))
+
+(defthm
+ array2p-m-/
+ (implies (and (array2p name M)
+ (equal (first (dimensions name M))
+ (second (dimensions name M))))
+ (array2p name (m-/ M)))
+ :hints (("Goal"
+ :in-theory
+ (disable
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1)
+ :use
+ (:instance
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1
+ (D 1)))))
+
+(defthm
+ matrixp-m-/
+ (implies (and (matrixp (r M)(c M) M)
+ (equal (r M)(c M)))
+ (matrixp (r M)(c M)(m-/ M)))
+ :hints (("Goal"
+ :in-theory
+ (disable
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1)
+ :use
+ (:instance
+ array2p-DETERMINANT-INVERSE-LOOP-COMPRESS2-B-1
+ (D 1)
+ (name '$arg)))))
+
+(in-theory (disable m-binary-*
+ m-=))
+
+(defthm
+ Subgoal-7-hack
+ (IMPLIES (AND (ARRAY2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (ARRAY2P '$ARG1
+ (M-* M
+ (CADR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ 1
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M))))))))
+ :hints (("Goal"
+ :in-theory (disable ARRAY2P-M-*-1
+ array2p-rewrite-linear-1)
+ :use ((:instance
+ ARRAY2P-M-*-1
+ (name '$arg)
+ (M1 M)
+ (M2 (CADR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ 1
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))))))
+ (:instance
+ array2p-rewrite-linear-1
+ (name '$arg))))))
+
+(defthm
+ Subgoal-3-hack
+ (IMPLIES (AND (ARRAY2P '$C M)
+ (EQUAL (CAR (DIMENSIONS '$ARG M))
+ (CADR (DIMENSIONS '$ARG M))))
+ (ARRAY2P '$ARG1
+ (M-* (CADR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ 1
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))))
+ M)))
+ :hints (("Goal"
+ :in-theory (disable ARRAY2P-M-*-1
+ array2p-rewrite-linear-1)
+ :use ((:instance
+ ARRAY2P-M-*-1
+ (name '$arg)
+ (M2 M)
+ (M1 (CADR
+ (DETERMINANT-INVERSE-LOOP
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG (M-1 (CAR (DIMENSIONS '$ARG M))))
+ (COMPRESS2 '$ARG M)
+ 1
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))
+ 0
+ (+ -1 (CAR (DIMENSIONS '$ARG M)))))))
+ (:instance
+ array2p-rewrite-linear-1
+ (name '$arg))))))
+
+(verify-guards m-singularp)
+
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.pdf.gz b/books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.pdf.gz
new file mode 100644
index 0000000..c08cf9c
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.ps.gz b/books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.ps.gz
new file mode 100644
index 0000000..20d5b8b
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/kalman-slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/kalman.pdf.gz b/books/workshops/2003/gamboa-cowles-van-baalen/kalman.pdf.gz
new file mode 100644
index 0000000..2e28acc
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/kalman.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/kalman.ps.gz b/books/workshops/2003/gamboa-cowles-van-baalen/kalman.ps.gz
new file mode 100644
index 0000000..0e04272
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/kalman.ps.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/certify.lsp b/books/workshops/2003/gamboa-cowles-van-baalen/support/certify.lsp
new file mode 100644
index 0000000..0d046a8
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/certify.lsp
@@ -0,0 +1,18 @@
+;;; Run this script to certify all the books. But first, certify matalg in
+;;; ../../cowles-gamboa-van-baalen_matrix/support/.
+
+(certify-book "linalg" 0)
+
+:u
+
+(ld "defpkg.lisp")
+
+(certify-book "kalman-defs" 1)
+
+:u
+
+(certify-book "kalman-proof" 1 t :skip-proofs-okp t :defaxioms-okp t)
+
+:u
+
+(certify-book "kalman-demo" 1 t :skip-proofs-okp t :defaxioms-okp t)
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/defpkg.lsp b/books/workshops/2003/gamboa-cowles-van-baalen/support/defpkg.lsp
new file mode 100644
index 0000000..bd06d48
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/defpkg.lsp
@@ -0,0 +1,4 @@
+(defpkg "KALMAN"
+ (union-eq *acl2-exports*
+ *common-lisp-symbols-from-main-lisp-package*))
+
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.acl2 b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.acl2
new file mode 100644
index 0000000..3392efc
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.acl2
@@ -0,0 +1,4 @@
+(value :q)
+(lp)
+(ld "defpkg.lsp")
+(certify-book "kalman-defs" ? t)
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.lisp b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.lisp
new file mode 100644
index 0000000..4ff1815
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-defs.lisp
@@ -0,0 +1,805 @@
+; The ACL2 Matrix Algebra Book. Summary of definitions and algebra in matrix.lisp.
+; Copyright (C) 2002 Ruben Gamboa and John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; Ruben Gamboa and John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+; Summer and Fall 2002.
+
+#|
+ To certify in ACL2 Version 2.6:
+
+ (ld ;; Newline to fool dependency scanner
+ "defpkg.lisp")
+ (certify-book "kalman-defs" 1)
+
+|#
+
+(in-package "KALMAN")
+
+(include-book "linalg")
+
+ (set-ignore-ok :warn)
+ (set-irrelevant-formals-ok :warn)
+
+(defmacro m-id (n)
+ `(acl2::m-1 ,n))
+
+(defmacro m-zero (m n)
+ `(acl2::m-0 ,m ,n))
+
+(defmacro m-matrixp (m n a)
+ `(acl2::matrixp ,m ,n ,a))
+
+(defmacro l (a)
+ `(acl2::r ,a))
+
+(defmacro c (a)
+ `(acl2::c ,a))
+
+(defmacro m-+ (a b)
+ `(acl2::m-+ ,a ,b))
+
+(defmacro m-- (a b)
+ `(acl2::m-- ,a ,b))
+
+(defmacro m-unary-- (a)
+ `(acl2::m-- ,a))
+
+(defmacro m-* (a b)
+ `(acl2::m-* ,a ,b))
+
+(defmacro s-* (k a)
+ `(acl2::s-* ,k ,a))
+
+(defmacro m-inv (a)
+ `(acl2::m-/ ,a))
+
+(defmacro m-trans (a)
+ `(acl2::m-trans ,a))
+
+(defmacro m-singular (a)
+ `(acl2::m-singularp ,a))
+
+(defmacro m-= (a b)
+ `(acl2::m-= ,a ,b))
+
+(defmacro m-dim-p (n)
+ `(acl2::m-dim-p ,n))
+
+(in-theory (disable acl2::m-1 acl2::m-0 acl2::matrixp acl2::m-binary-+
+ acl2::m-unary-- acl2::m-binary-* acl2::s-* acl2::m-/ acl2::m-trans
+ acl2::m-singularp acl2::m-=))
+
+(encapsulate
+ (((x-0) => *) ; initial value of x
+ ((phi *) => *) ; steps through an iteration of x
+ ((ww *) => *) ; iteration step noise
+ ((q *) => *) ; covariance of step noise
+ ((h *) => *) ; matrix transforming observable to x
+ ((v *) => *) ; observation noise
+ ((r *) => *) ; covariance of observation noise
+ ((xhatmin-0) => *) ; initial guess for best estimate of x
+ ((pminus-0) => *) ; initial guess for covariance of estimate
+ ((n) => *) ; dimension of x
+ ((m) => *) ; dimension of y
+ ((m-mean *) => *) ; mean of an expression
+ )
+
+
+ (set-ignore-ok :warn)
+ (set-irrelevant-formals-ok :warn)
+
+ (local
+ (defun n ()
+ 1))
+
+ (local
+ (defun m ()
+ 1))
+
+; Addition by Matt K. April 2016 to accommodate addition of type-set bit for
+; the set {1}.
+ (local (in-theory (disable (:t n) (:t m))))
+
+ (local
+ (defun phi (k)
+ (m-id (n))))
+
+ (defthm matrix-phi
+ (m-matrixp (n) (n) (phi k)))
+
+ (defthm numrows-cols-phi
+ (and (equal (l (phi k)) (n))
+ (equal (c (phi k)) (n)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n (n))
+ (acl2::p (phi k)))))))
+ (local
+ (defun ww (k)
+ (m-zero (n) 1)))
+
+ (defthm matrix-w
+ (m-matrixp (n) 1 (ww k)))
+
+ (defthm numrows-cols-w
+ (and (equal (l (ww k)) (n))
+ (equal (c (ww k)) 1))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n 1)
+ (acl2::p (ww k)))))))
+
+ (local
+ (defun q (k)
+ (m-zero (n) (n))))
+
+ (defthm matrix-q
+ (m-matrixp (n) (n) (q k)))
+
+ (defthm numrows-cols-q
+ (and (equal (l (q k)) (n))
+ (equal (c (q k)) (n)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n (n))
+ (acl2::p (q k)))))))
+
+ (local
+ (defun x-0 ()
+ (m-zero (n) 1)))
+
+ (local (in-theory (disable (x-0))))
+
+ (defthm matrix-x-0
+ (m-matrixp (n) 1 (x-0)))
+
+ (defthm numrows-cols-x-0
+ (and (equal (l (x-0)) (n))
+ (equal (c (x-0)) 1))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n 1)
+ (acl2::p (x-0)))))))
+
+ (defun x (k)
+ (if (zp k)
+ (x-0)
+ (m-+ (m-* (phi (1- k)) (x (1- k)))
+ (ww (1- k)))))
+
+ (defthm matrix-x
+ (m-matrixp (n) 1 (x k)))
+
+ (defthm numrows-cols-x
+ (and (equal (l (x k)) (n))
+ (equal (c (x k)) 1))
+ :hints (("Goal"
+ :use ((:instance matrix-x)
+ (:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n 1)
+ (acl2::p (x k)))))))
+
+ (local
+ (defun mean-x (k)
+ (x k)))
+
+ (local
+ (defun h (k)
+ (m-zero (m) (n))))
+
+ (defthm matrix-h
+ (m-matrixp (m) (n) (h k)))
+
+ (defthm numrows-cols-h
+ (and (equal (l (h k)) (m))
+ (equal (c (h k)) (n)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (m))
+ (acl2::n (n))
+ (acl2::p (h k)))))))
+
+ (local
+ (defun v (k)
+ (m-zero (m) 1)))
+
+ (defthm matrix-v
+ (m-matrixp (m) 1 (v k)))
+
+ (defthm numrows-cols-v
+ (and (equal (l (v k)) (m))
+ (equal (c (v k)) 1))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (m))
+ (acl2::n 1)
+ (acl2::p (v k)))))))
+
+ (defun z (k)
+ (m-+ (m-* (h k) (x k))
+ (v k)))
+
+ (local (defthm matrix-x-1 (ACL2::MATRIXP 1 1 (X K))))
+
+ (defthm matrix-z
+ (m-matrixp (m) 1 (z k)))
+
+ (defthm numrows-cols-z
+ (and (equal (l (z k)) (m))
+ (equal (c (z k)) 1))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (m))
+ (acl2::n 1)
+ (acl2::p (z k)))))))
+
+ (local
+ (defun r (k)
+ (m-zero (m) (m))))
+
+ (defthm matrix-r
+ (m-matrixp (m) (m) (r k)))
+
+ (defthm numrows-cols-r
+ (and (equal (l (r k)) (m))
+ (equal (c (r k)) (m)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (m))
+ (acl2::n (m))
+ (acl2::p (r k)))))))
+ (local
+ (defun xhatmin-0 ()
+ (x 0)))
+
+ (defthm matrix-xhatmin-0
+ (m-matrixp (n) 1 (xhatmin-0))
+ :hints (("Goal"
+ :expand ((xhatmin-0))
+ :in-theory (disable (x) (xhatmin-0)))))
+
+ (defthm numrows-cols-xhatmin-0
+ (and (equal (l (xhatmin-0)) (n))
+ (equal (c (xhatmin-0)) 1))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n 1)
+ (acl2::p (xhatmin-0)))
+ (:instance matrix-xhatmin-0)))))
+
+ (local
+ (defun pminus-0 ()
+ (m-zero (n) (n))))
+
+ (defthm matrix-pminus-0
+ (m-matrixp (n) (n) (pminus-0))
+ :hints (("Goal"
+ :expand ((pminus-0))
+ :in-theory (disable (pminus-0)))))
+
+ (defthm numrows-cols-pminus-0
+ (and (equal (l (pminus-0)) (n))
+ (equal (c (pminus-0)) (n)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n (n))
+ (acl2::p (pminus-0)))
+ (:instance matrix-pminus-0)))))
+ (local
+ (defun m-mean (m-expr)
+ m-expr))
+
+ (defthm matrix-mean
+ (implies (m-matrixp m n m-expr)
+ (m-matrixp m n (m-mean m-expr))))
+
+ (defthm numrows-cols-mean
+ (and (equal (l (m-mean m-expr)) (l m-expr))
+ (equal (c (m-mean m-expr)) (c m-expr))))
+
+ (defcong
+ m-= m-= (m-mean x) 1)
+
+ (defthm mean-trans
+ (equal (m-mean (m-trans p))
+ (m-trans (m-mean p))))
+
+ (defthm mean-+
+ (implies (and (equal (l p) (l q))
+ (equal (c p) (c q)))
+ (equal (m-mean (m-+ p q))
+ (m-+ (m-mean p) (m-mean q)))))
+
+ (defthm mean-*
+ (implies (equal (c p) (l q))
+ (equal (m-mean (m-* p q))
+ (m-* (m-mean p) (m-mean q)))))
+
+ (defthm mean-unary--
+ (equal (m-mean (m-unary-- p))
+ (m-unary-- (m-mean p))))
+
+ (defthm mean-delete
+ (equal (m-mean p)
+ p))
+
+ (defthm mean-of-v-vtrans
+ (m-= (m-mean (m-* (v k) (m-trans (v k))))
+ (r k)))
+
+ (defthm mean-of-w-wtrans
+ (m-= (m-mean (m-* (ww k) (m-trans (ww k))))
+ (q k)))
+
+ (defmacro pminus-body (k)
+ `(if (zp ,k)
+ (pminus-0)
+ (m-+ (m-* (phi (1- ,k))
+ (m-* (pplus (1- ,k))
+ (m-trans (phi (1- ,k)))))
+ (q (1- ,k)))))
+
+ (defmacro gain-body (k)
+ `(m-* (pminus-body ,k)
+ (m-* (m-trans (h ,k))
+ (m-inv (m-+ (m-* (h ,k)
+ (m-* (pminus-body ,k)
+ (m-trans (h ,k))))
+ (r ,k))))))
+
+ (defun pplus (k)
+;;; Legacy doc string replaced Nov. 2014 by auto-generated defxdoc form
+;;; see defxdoc form towards in the last part of this file.
+; ":Doc-Section ACL2::Programming
+;
+; estimate of error covariance~/~/
+; "
+ (if (zp k)
+ (m-* (m-- (m-id (l (x k)))
+ (m-* (m-* (pminus-0)
+ (m-* (m-trans (h k))
+ (m-inv (m-+ (m-* (h k)
+ (m-* (pminus-0)
+ (m-trans (h k))))
+ (r k)))))
+ (h k)))
+ (pminus-0))
+ (m-* (m-- (m-id (l (x k)))
+ (m-* (gain-body k)
+ (h k)))
+ (pminus-body k))))
+
+ (defun pminus (k)
+;;; Legacy doc string replaced Nov. 2014 by auto-generated defxdoc form
+;;; see defxdoc form towards in the last part of this file.
+; ":Doc-Section ACL2::Programming
+;
+; a priori estimate of error covariance~/~/
+; "
+ (pminus-body k))
+
+ (defun gain (k)
+;;; Legacy doc string replaced Nov. 2014 by auto-generated defxdoc form
+;;; see defxdoc form towards in the last part of this file.
+; ":Doc-Section ACL2::Programming
+;
+; Kalman gain modifies observation residual to get better estimate of x~/~/
+; "
+ (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-inv (m-+ (m-* (h k)
+ (m-* (pminus k)
+ (m-trans (h k))))
+ (r k))))))
+
+
+
+ (defthm pplus-recdef
+ (implies (and (integerp k)
+ (<= 0 k))
+ (equal (pplus k)
+ (m-* (m-- (m-id (l (x k)))
+ (m-* (gain k)
+ (h k)))
+ (pminus k))))
+ :hints (("Goal"
+ :in-theory (disable x (x)
+ h (h)
+ phi (phi)
+ q (q)
+ r (r)
+ (pminus) (pplus) (gain))))
+ :rule-classes ((:definition
+ :clique (pplus pminus gain)
+ :controller-alist ((pplus t)
+ (pminus t)
+ (gain t)))))
+
+ (defthm pminus-recdef
+ (implies (and (integerp k)
+ (< 0 k))
+ (equal (pminus k)
+ (m-+ (m-* (phi (1- k))
+ (m-* (pplus (1- k))
+ (m-trans (phi (1- k)))))
+ (q (1- k)))))
+ :hints (("Goal"
+ :in-theory (disable x (x)
+ h (h)
+ phi (phi)
+ q (q)
+ r (r)
+ pplus-recdef (pminus) (pplus) (gain))))
+ :rule-classes ((:definition
+ :clique (pplus pminus gain)
+ :controller-alist ((pplus t)
+ (pminus t)
+ (gain t)))))
+
+ (defthm gain-recdef
+ (implies (and (integerp k)
+ (<= 0 k))
+ (equal (gain k)
+ (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-inv (m-+ (m-* (h k)
+ (m-* (pminus k)
+ (m-trans (h k))))
+ (r k)))))))
+ :hints (("Goal"
+ :in-theory (disable x (x)
+ h (h)
+ phi (phi)
+ q (q)
+ r (r)
+ pplus-recdef (pminus) (pplus) (gain))))
+ :rule-classes ((:definition
+ :clique (pplus pminus gain)
+ :controller-alist ((pplus t)
+ (pminus t)
+ (gain t)))))
+
+ (in-theory (disable (:definition pminus)
+ (:definition pplus)
+ (:definition gain)))
+
+ (defmacro xhat-body (k)
+ `(m-+ (xhatmin ,k)
+ (m-* (gain ,k)
+ (m-- (z ,k)
+ (m-* (h ,k) (xhatmin ,k))))))
+
+ (defun xhatmin (k)
+;;; Legacy doc string replaced Nov. 2014 by auto-generated defxdoc form
+;;; see defxdoc form towards in the last part of this file.
+; ":Doc-Section ACL2::Programming
+;
+; estimate of x(k) before seeing measurement z(k)~/~/
+; "
+ (if (zp k)
+ (xhatmin-0)
+ (m-* (phi (1- k)) (xhat-body (1- k)))))
+
+ (defun xhat (k)
+;;; Legacy doc string replaced Nov. 2014 by auto-generated defxdoc form
+;;; see defxdoc form towards in the last part of this file.
+; ":Doc-Section ACL2::Programming
+;
+; estimate of x(k) using measurement z(k)~/~/
+; "
+ (xhat-body k))
+
+ (defthm xhatmin-recdef
+ (implies (and (integerp k)
+ (< 0 k))
+ (equal (xhatmin k)
+ (m-* (phi (1- k)) (xhat (1- k)))))
+ :rule-classes ((:definition
+ :clique (xhat xhatmin)
+ :controller-alist ((xhat t)
+ (xhatmin t)))))
+
+
+ (in-theory (disable (:definition xhatmin)))
+
+ (defthm dim-p-m
+ (m-dim-p (m)))
+
+ (defthm dim-p-n
+ (m-dim-p (n)))
+
+ (local (in-theory (disable n (n)
+ m (m)
+ (x)
+ (xhatmin-0)
+ (pminus-0))))
+
+ (encapsulate
+ ()
+
+ (local
+ (defthm lemma-1
+ (implies (zp k)
+ (m-matrixp (n) 1 (xhatmin k)))
+ :hints (("Goal"
+; :With directives added 3/13/06 by Matt Kaufmann for after v2-9-4.
+ :expand ((:with xhatmin (xhatmin k)) (n))))))
+
+ (local
+ (defthm lemma-2
+ (implies (and (not (zp k))
+ (m-matrixp (n) 1 (xhat (1- k))))
+ (m-matrixp (n) 1 (xhatmin k)))))
+
+ (defthm lemma-2-5
+ (acl2::matrixp (m) (m) (acl2::m-/ (ACL2::M-BINARY-+ (ACL2::M-0 (M) (M))
+ (ACL2::M-0 (M) (M)))))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-inv
+ (acl2::P (ACL2::M-BINARY-+ (ACL2::M-0 (M) (M))
+ (ACL2::M-0 (M) (M))))
+ (acl2::n (m))))
+ :in-theory (disable acl2::matrix-inv))))
+
+ (local
+ (defthm lemma-3
+ (implies (zp k)
+ (m-matrixp (n) (n) (pplus k)))
+ :hints (("Goal"
+; :With directives added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ :expand ((:with pplus (pplus k)))))))
+
+ (local
+ (defthm lemma-4
+ (implies (and (not (zp k))
+ (m-matrixp (n) (m) (gain k))
+ (m-matrixp (n) (n) (pminus k)))
+ (m-matrixp (n) (n) (pplus k)))))
+
+ (local
+ (defthm lemma-5
+ (implies (zp k)
+ (m-matrixp (n) (n) (pminus k)))
+ :hints (("Goal"
+; :With directives added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ :expand ((:with pminus (pminus k)))
+ :in-theory (disable gain-recdef pplus-recdef pminus-recdef)))))
+
+ (local
+ (defthm lemma-6
+ (implies (and (not (zp k))
+ (or (zp (1- k))
+ (and (m-matrixp (n) (m) (gain (1- k)))
+ (m-matrixp (n) (n) (pminus (1- k))))))
+ (m-matrixp (n) (n) (pminus k)))
+ :hints (("Goal"
+ :expand ((pminus k))
+ :in-theory (disable gain-recdef pplus-recdef pminus-recdef))
+ ("Subgoal 2"
+ :use ((:instance lemma-3 (k (1- k))))
+ :in-theory (disable lemma-3 pplus-recdef))
+ ("Subgoal 1"
+ :use ((:instance lemma-4 (k (1- k))))
+ :in-theory (disable lemma-4)))))
+
+ (local
+ (defun natural-induction (k)
+ (if (zp k)
+ 1
+ (1+ (natural-induction (1- k))))))
+
+ (local
+ (defthm matrix-gain-pminus
+ (and (m-matrixp (n) (n) (pminus k))
+ (m-matrixp (n) (m) (gain k)))
+ :hints (("Goal"
+ :induct (natural-induction k))
+ ("Subgoal *1/2"
+ :use ((:instance lemma-6))
+ :in-theory (disable lemma-6 gain-recdef pminus-recdef))
+; :With directives added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2'''"
+ :expand ((:with gain (gain k))))
+ ("Subgoal *1/1"
+ :expand ((:with gain (gain k))))
+ ("Subgoal *1/1'"
+ :use ((:instance lemma-5))
+ :in-theory (disable lemma-5)))))
+
+ (defthm matrix-gain
+ (m-matrixp (n) (m) (gain k)))
+
+ (defthm numrows-cols-gain
+ (and (equal (l (gain k)) (n))
+ (equal (c (gain k)) (m)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n (m))
+ (acl2::p (gain k)))))))
+
+
+ (defthm matrix-pminus
+ (m-matrixp (n) (n) (pminus k)))
+
+ (defthm numrows-cols-pminus
+ (and (equal (l (pminus k)) (n))
+ (equal (c (pminus k)) (n)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n (n))
+ (acl2::p (pminus k)))))))
+
+ (defthm matrix-pplus
+ (m-matrixp (n) (n) (pplus k))
+ :hints (("Goal"
+ :use ((:instance lemma-3)
+ (:instance lemma-4)
+ (:instance matrix-gain-pminus))
+ :in-theory nil)))
+
+ (defthm numrows-cols-pplus
+ (and (equal (l (pplus k)) (n))
+ (equal (c (pplus k)) (n)))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n (n))
+ (acl2::p (pplus k)))))))
+
+
+ (local
+ (defthm lemma-7
+ (implies (zp k)
+ (m-matrixp (n) 1 (xhat k)))
+ :hints (("Goal" :do-not-induct t
+ :expand ((xhat k)))
+ ("Goal'"
+ :use ((:instance lemma-1))
+ :in-theory (disable lemma-1)))))
+
+ (local
+ (defthm lemma-8
+ (implies (and (not (zp k))
+ (m-matrixp (n) 1 (xhat (1- k))))
+ (m-matrixp (n) 1 (xhat k)))
+ :hints (("Goal" :do-not-induct t
+ :in-theory (disable xhatmin-recdef gain-recdef))
+ ("Goal'"
+ :use ((:instance lemma-2))
+ :in-theory (disable xhatmin-recdef gain-recdef lemma-2))
+ ("Goal''"
+ :expand ((xhat k))))))
+
+
+ (defthm matrix-xhat
+ (m-matrixp (n) 1 (xhat k))
+ :hints (("Goal"
+ :induct (natural-induction k))
+ ("Subgoal *1/2"
+ :by (:instance lemma-8))
+ ("Subgoal *1/1"
+ :by (:instance lemma-7))))
+
+ (defthm numrows-cols-xhat
+ (and (equal (l (xhat k)) (n))
+ (equal (c (xhat k)) 1))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n 1)
+ (acl2::p (xhat k)))))))
+
+ (defthm matrix-xhatmin
+ (m-matrixp (n) 1 (xhatmin k))
+ :hints (("Goal"
+ :use ((:instance lemma-1)
+ (:instance lemma-2)
+ (:instance matrix-xhat (k (1- k))))
+ :in-theory nil)))
+
+ (defthm numrows-cols-xhatmin
+ (and (equal (l (xhatmin k)) (n))
+ (equal (c (xhatmin k)) 1))
+ :hints (("Goal"
+ :use ((:instance acl2::matrix-p-numrows-cols
+ (acl2::m (n))
+ (acl2::n 1)
+ (acl2::p (xhatmin k)))))))
+ )
+
+ (defthm mean-of-x-xhatmin*vtrans
+ (m-= (m-mean (m-* (m-+ (x k)
+ (m-unary-- (xhatmin k)))
+ (m-trans (v k))))
+ (m-zero (n) (m))))
+
+ (defthm mean-of-v*trans-of-x-xhatmin
+ (m-= (m-mean (m-* (v k)
+ (m-trans (m-+ (x k)
+ (m-unary-- (xhatmin k))))))
+ (m-zero (m) (n))))
+
+ (defthm mean-of-x-xhat*wtrans
+ (m-= (m-mean (m-* (m-+ (x k)
+ (m-unary-- (xhat k)))
+ (m-trans (ww k))))
+ (m-zero (n) (n))))
+
+ (defthm mean-of-w*trans-of-x-xhat
+ (m-= (m-mean (m-* (ww k)
+ (m-trans (m-+ (x k)
+ (m-unary-- (xhat k))))))
+ (m-zero (n) (n))))
+
+ (defthm pminus-0-def
+ (m-= (pminus-0)
+ (m-mean (m-* (m-- (x 0) (xhatmin-0))
+ (m-trans (m-- (x 0) (xhatmin-0))))))
+ :hints (("Goal"
+ :in-theory (disable (pminus-0)
+ (x)
+ (xhatmin-0)))))
+
+ )
+
+(in-theory (disable mean-* mean-delete))
+
+; The forms below were initially generated automatically from
+; legacy documentation strings in this file.
+
+(include-book "xdoc/top" :dir :system)
+(defmacro defxdoc (&rest args)
+ `(acl2::defxdoc ,@args))
+
+(defxdoc kalman::gain
+ :parents (programming)
+ :short "Kalman gain modifies observation residual to get better estimate of x"
+ :long "")
+
+(defxdoc kalman::pminus
+ :parents (programming)
+ :short "A priori estimate of error covariance"
+ :long "")
+
+(defxdoc kalman::pplus
+ :parents (programming)
+ :short "Estimate of error covariance"
+ :long "")
+
+(defxdoc kalman::xhat
+ :parents (programming)
+ :short "Estimate of x(k) using measurement z(k)"
+ :long "")
+
+(defxdoc kalman::xhatmin
+ :parents (programming)
+ :short "Estimate of x(k) before seeing measurement z(k)"
+ :long "")
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.acl2 b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.acl2
new file mode 100644
index 0000000..84d673b
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.acl2
@@ -0,0 +1,4 @@
+(in-package "ACL2")
+(ld "defpkg.lsp")
+; cert-flags: ? t :skip-proofs-okp t :defaxioms-okp t
+(certify-book "kalman-demo" ? t :skip-proofs-okp t :defaxioms-okp t)
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.lisp b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.lisp
new file mode 100644
index 0000000..4c7b869
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-demo.lisp
@@ -0,0 +1,161 @@
+; The ACL2 Matrix Algebra Book. Summary of definitions and algebra in matrix.lisp.
+; Copyright (C) 2002 Ruben Gamboa and John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; Ruben Gamboa and John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+; Summer and Fall 2002.
+; Last modified 1 November 2002.
+
+#|
+ To certify in ACL2 Version 2.6
+
+ (ld ;; Newline to fool dependency scanner
+ "defpkg.lsp")
+ (certify-book "kalman-demo" 1)
+|#
+
+(in-package "KALMAN")
+
+(include-book "kalman-proof")
+
+(defun kalman-loop-body (xhatmin-prev pminus-prev k)
+ (let* ((gain (m-* pminus-prev
+ (m-* (m-trans (h k))
+ (m-inv (m-+ (m-* (h k)
+ (m-* pminus-prev
+ (m-trans (h k))))
+ (r k))))))
+ (xhat (m-+ xhatmin-prev
+ (m-* gain
+ (m-- (z k)
+ (m-* (h k) xhatmin-prev)))))
+ (pplus (m-* (m-- (m-id (n))
+ (m-* gain (h k)))
+ pminus-prev))
+ (xhatmin (m-* (phi k) xhat))
+ (pminus (m-+ (m-* (phi k)
+ (m-* pplus
+ (m-trans (phi k))))
+ (q k))))
+ (mv gain xhat pplus xhatmin pminus)))
+
+(encapsulate
+ ()
+
+ (local
+ (defthm lemma-1
+ (implies (and (integerp k)
+ (<= 0 k)
+ (equal xhatmin-prev (xhatmin k))
+ (equal pminus-prev (pminus k)))
+ (mv-let (gain xhat pplus xhatmin pminus)
+ (kalman-loop-body xhatmin-prev pminus-prev k)
+ (declare (ignore xhat pplus xhatmin pminus))
+ (equal gain (gain k))))
+ :hints (("Goal"
+ :in-theory (disable acl2::*-+-right acl2::*-+-left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+)))))
+
+ (local
+ (defthm lemma-2
+ (implies (and (integerp k)
+ (<= 0 k)
+ (equal xhatmin-prev (xhatmin k))
+ (equal pminus-prev (pminus k)))
+ (mv-let (gain xhat pplus xhatmin pminus)
+ (kalman-loop-body xhatmin-prev pminus-prev k)
+ (declare (ignore gain pplus xhatmin pminus))
+ (equal xhat (xhat k))))
+ :hints (("Goal"
+ :in-theory (disable acl2::*-+-right acl2::*-+-left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+)))))
+
+ (local
+ (defthm lemma-3
+ (implies (and (integerp k)
+ (<= 0 k)
+ (equal xhatmin-prev (xhatmin k))
+ (equal pminus-prev (pminus k)))
+ (mv-let (gain xhat pplus xhatmin pminus)
+ (kalman-loop-body xhatmin-prev pminus-prev k)
+ (declare (ignore gain xhat xhatmin pminus))
+ (equal pplus (pplus k))))
+ :hints (("Goal"
+ :in-theory (disable pplus-as-mean
+ acl2::*-+-right acl2::*-+-left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+)))))
+
+ (local
+ (defthm lemma-4
+ (implies (and (integerp k)
+ (<= 0 k)
+ (equal xhatmin-prev (xhatmin k))
+ (equal pminus-prev (pminus k)))
+ (mv-let (gain xhat pplus xhatmin pminus)
+ (kalman-loop-body xhatmin-prev pminus-prev k)
+ (declare (ignore gain xhat pplus pminus))
+ (equal xhatmin (xhatmin (1+ k)))))
+ :hints (("Goal"
+ :in-theory (disable acl2::*-+-right acl2::*-+-left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+)))))
+
+ (local
+ (defthm lemma-5
+ (implies (and (integerp k)
+ (<= 0 k)
+ (equal xhatmin-prev (xhatmin k))
+ (equal pminus-prev (pminus k)))
+ (mv-let (gain xhat pplus xhatmin pminus)
+ (kalman-loop-body xhatmin-prev pminus-prev k)
+ (declare (ignore gain xhat pplus xhatmin))
+ (equal pminus (pminus (1+ k)))))
+ :hints (("Goal"
+ :in-theory (disable pplus-as-mean
+ pminus-as-mean
+ pminus-as-mean-almost
+ acl2::*-+-right acl2::*-+-left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+)))))
+
+ (defthm kalman-loop-invariant
+ (implies (and (integerp k)
+ (<= 0 k)
+ (equal xhatmin-prev (xhatmin k))
+ (equal pminus-prev (pminus k)))
+ (mv-let (gain xhat pplus xhatmin pminus)
+ (kalman-loop-body xhatmin-prev pminus-prev k)
+ (and (equal gain (gain k))
+ (equal xhat (xhat k))
+ (equal pplus (pplus k))
+ (equal xhatmin (xhatmin (1+ k)))
+ (equal pminus (pminus (1+ k))))))
+ :hints (("Goal"
+ :use ((:instance lemma-1)
+ (:instance lemma-2)
+ (:instance lemma-3)
+ (:instance lemma-4)
+ (:instance lemma-5)))))
+ )
+
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.acl2 b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.acl2
new file mode 100644
index 0000000..e197566
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.acl2
@@ -0,0 +1,4 @@
+(in-package "ACL2")
+(ld "defpkg.lsp")
+; cert-flags: ? t :skip-proofs-okp t :defaxioms-okp t
+(certify-book "kalman-proof" ? t :skip-proofs-okp t :defaxioms-okp t)
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.lisp b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.lisp
new file mode 100644
index 0000000..dc81da3
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/kalman-proof.lisp
@@ -0,0 +1,2271 @@
+; The ACL2 Matrix Algebra Book. Summary of definitions and algebra in matrix.lisp.
+; Copyright (C) 2002 Ruben Gamboa and John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; Ruben Gamboa and John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+; Summer and Fall 2002.
+; Last modified 1 November 2002.
+
+#|
+ To certify in ACL2 Version 2.6
+
+ (ld ;; Newline to fool dependency scanner
+ "defpkg.lsp")
+ (certify-book "kalman-proof" 1)
+|#
+
+(in-package "KALMAN")
+
+(include-book "kalman-defs")
+
+(defmacro enable-disable (enable-list disable-list)
+ (list 'union-theories
+ (cons 'disable disable-list)
+ `(quote ,enable-list)))
+
+(defstub best-estimate-of-x (*) => *)
+
+(defun best-prior-estimate-of-x (k)
+ (if (zp k)
+ (xhatmin k)
+ (m-* (phi (1- k))
+ (best-estimate-of-x (1- k)))))
+
+(defun result-form (y Xp k)
+ (m-+ Xp
+ (m-* y
+ (m-- (z k)
+ (m-* (h k)
+ Xp)))))
+
+(defun result-form-derivative (y Xp k)
+ (m-+ (s-* 2 (m-mean (m-* (m-- Xp (x k))
+ (m-trans (m-- (z k)
+ (m-* (h k) Xp))))))
+ (s-* 2 (m-* y
+ (m-mean (m-* (m-- (z k)
+ (m-* (h k) Xp))
+ (m-trans (m-- (z k)
+ (m-* (h k) Xp)))))))))
+
+(defaxiom best-estimate-of-x-def
+ (implies (and (m-= (best-prior-estimate-of-x k) Xp)
+ (m-= (result-form-derivative y Xp k) (m-zero (n) (m))))
+ (m-= (best-estimate-of-x k)
+ (result-form y Xp k))))
+
+(skip-proofs
+ (defthm non-singular-gain-component
+ (not (m-singular (m-mean (m-* (m-+ (z k)
+ (m-unary-- (m-* (h k) (xhatmin k))))
+ (m-+ (m-trans (z k))
+ (m-unary-- (m-* (m-trans (xhatmin k))
+ (m-trans (h k)))))))))))
+
+(skip-proofs
+ (defthm non-singular-gain-component-2
+ (not (m-singular (m-+ (r k) (m-* (h k) (m-* (pminus k) (m-trans (h k)))))))))
+
+(defthm pminus-as-mean-case-0
+ (implies (= k 0)
+ (m-= (pminus k)
+ (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k)))))))
+ :hints (("Goal"
+ :expand ((pminus k))
+ :in-theory (enable-disable (pminus xhatmin)
+ (x ; added by Matt K. for v2-8, 7/31/03
+ (pminus) (xhatmin))))))
+
+(encapsulate
+ ()
+
+ (local
+ (defthm lemma-1
+ (implies (and (integerp k)
+ (< 0 k))
+ (equal (m-- (x k) (xhatmin k))
+ (m-- (m-+ (m-* (phi (1- k)) (x (1- k)))
+ (ww (1- k)))
+ (m-* (phi (1- k))
+ (xhat (1- k))))))
+ :hints (("Goal" :do-not-induct t
+ :in-theory (disable xhat)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-2
+ (implies (and (integerp k)
+ (< 0 k))
+ (equal (m-- (x k) (xhatmin k))
+ (m-+ (m-* (phi (1- k))
+ (m-- (x (1- k))
+ (xhat (1- k))))
+ (ww (1- k)))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-1)
+ (:instance (:theorem
+ (implies (and (m-matrixp (l phi) (c phi) phi)
+ (m-matrixp (l x) (c x) x)
+ (m-matrixp (l xhat) (c xhat) xhat)
+ (m-matrixp (l ww) (c x) ww)
+ (equal (c phi) (l x))
+ (equal (l phi) (l ww))
+ (equal (c x) (c ww))
+ (equal (c phi) (l xhat))
+ (equal (c x) (c xhat))
+ (equal (l x) (l xhat)))
+ (equal (m-- (m-+ (m-* phi x)
+ ww)
+ (m-* phi xhat))
+ (m-+ (m-* phi (m-- x xhat))
+ ww))))
+ (phi (phi (1- k)))
+ (x (x (1- k)))
+ (ww (ww (1- k)))
+ (xhat (xhat (1- k))))))
+ ("Subgoal 2'" :in-theory nil))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-3a
+ (implies (and (m-matrixp (l a) (c a) a)
+ (m-matrixp (l b) (c b) b)
+ (equal (l a) (l b))
+ (equal (c a) (c b)))
+ (m-= (m-* (m-+ a b)
+ (m-trans (m-+ a b)))
+ (m-+ (m-* a (m-trans a))
+ (m-+ (m-* a (m-trans b))
+ (m-+ (m-* b (m-trans a))
+ (m-* b (m-trans b)))))))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-3b-1
+ (implies (and (m-= (m-* (m-+ (m-* phi (m-+ x (m-unary-- xhat))) ww)
+ (m-trans (m-+ (m-* phi (m-+ x (m-unary-- xhat))) ww)))
+ (m-+ (m-* phi
+ (m-* (m-+ x (m-unary-- xhat))
+ (m-trans (m-* phi
+ (m-+ x
+ (m-unary-- xhat))))))
+ (m-+ (m-* phi (m-* (m-+ x (m-unary-- xhat))
+ (m-trans ww)))
+ (m-+ (m-* ww
+ (m-trans (m-* phi
+ (m-+ x
+ (m-unary-- xhat)))))
+ (m-* ww (m-trans ww))))))
+ (m-matrixp (l x) (c x) x)
+ (m-matrixp (l xhat) (c xhat) xhat)
+ (m-matrixp (l phi) (c phi) phi)
+ (m-matrixp (l ww) (c ww) ww)
+ (equal (l phi) (l ww))
+ (equal (c x) (c ww))
+ (equal (c phi) (l x))
+ (equal (c ww) (c xhat))
+ (equal (l x) (l xhat)))
+ (m-= (m-* (m-+ (m-* phi (m-+ x (m-unary-- xhat))) ww)
+ (m-trans (m-+ (m-* phi (m-+ x (m-unary-- xhat))) ww)))
+ (m-+ (m-* phi (m-* (m-+ x (m-unary-- xhat))
+ (m-* (m-trans (m-+ x (m-unary-- xhat)))
+ (m-trans phi))))
+ (m-+ (m-* phi (m-* (m-+ x (m-unary-- xhat)) (m-trans ww)))
+ (m-+ (m-* ww (m-* (m-trans (m-+ x (m-unary-- xhat)))
+ (m-trans phi)))
+ (m-* ww (m-trans ww)))))))
+ :hints (("Goal"
+ :use ((:instance acl2::trans-*
+ (acl2::p phi)
+ (acl2::q (m-- x xhat))))
+ :in-theory (disable acl2::trans-*
+ acl2::*-+-right
+ acl2::*-+-left)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-3b
+ (implies (and (m-matrixp (l x) (c x) x)
+ (m-matrixp (l xhat) (c xhat) xhat)
+ (m-matrixp (l phi) (c phi) phi)
+ (m-matrixp (l ww) (c ww) ww)
+ (equal (c phi) (l x))
+ (equal (l phi) (l ww))
+ (equal (c x) (c ww))
+ (equal (c phi) (l xhat))
+ (equal (c x) (c xhat))
+ (equal (l x) (l xhat)))
+ (m-= (m-* (m-+ (m-* phi (m-- x xhat)) ww)
+ (m-trans (m-+ (m-* phi (m-- x xhat)) ww)))
+ (m-+ (m-* (m-* phi (m-- x xhat)) (m-* (m-trans (m-- x xhat))
+ (m-trans phi)))
+ (m-+ (m-* (m-* phi (m-- x xhat)) (m-trans ww))
+ (m-+ (m-* ww (m-* (m-trans (m-- x xhat))
+ (m-trans phi)))
+ (m-* ww (m-trans ww)))))))
+ :hints (("Goal"
+ :use ((:instance lemma-3a
+ (a (m-* phi (m-- x xhat)))
+ (b ww))))
+ ("Goal''"
+ :use ((:instance lemma-3b-1))
+ :in-theory (disable acl2::trans-*
+ acl2::*-+-right
+ acl2::*-+-left)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-3
+ (m-= (m-* (m-+ (m-* (phi (1- k)) (m-- (x (1- k)) (xhat (1- k))))
+ (ww (1- k)))
+ (m-trans (m-+ (m-* (phi (1- k))
+ (m-- (x (1- k)) (xhat (1- k))))
+ (ww (1- k)))))
+ (m-+ (m-* (m-* (phi (1- k))
+ (m-- (x (1- k)) (xhat (1- k))))
+ (m-* (m-trans (m-- (x (1- k)) (xhat (1- k))))
+ (m-trans (phi (1- k)))))
+ (m-+ (m-* (m-* (phi (1- k))
+ (m-- (x (1- k)) (xhat (1- k))))
+ (m-trans (ww (1- k))))
+ (m-+ (m-* (ww (1- k))
+ (m-* (m-trans (m-- (x (1- k))
+ (xhat (1- k))))
+ (m-trans (phi (1- k)))))
+ (m-* (ww (1- k)) (m-trans (ww (1- k))))))))
+ :hints (("Goal"
+ :use ((:instance lemma-3b
+ (phi (phi (1- k)))
+ (x (x (1- k)))
+ (ww (ww (1- k)))
+ (xhat (xhat (1- k)))))))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-4a
+ (m-= (M-MEAN
+ (ACL2::M-BINARY-* (PHI (+ -1 K))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X (+ -1 K))
+ (ACL2::M-UNARY-- (XHAT (+ -1 K))))
+ (ACL2::M-TRANS (WW (+ -1 K))))))
+ (m-zero (n) (n)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance mean-*
+ (p (phi (+ -1 k)))
+ (q (m-* (m-+ (x (+ -1 k))
+ (m-unary-- (xhat (+ -1 k))))
+ (m-trans (ww (+ -1 k))))))
+ (:instance mean-of-x-xhat*wtrans
+ (k (1- k))))
+ :in-theory (disable xhat z
+ acl2::*-+-right
+ mean-of-x-xhat*wtrans)))))
+
+ (local
+ (defthm lemma-4b
+ (m-= (M-MEAN
+ (ACL2::M-BINARY-* (WW (+ -1 K))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X (+ -1 K)))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHAT (+ -1 K)))))
+ (ACL2::M-TRANS (PHI (+ -1 K))))))
+ (m-zero (n) (n)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance mean-*
+ (p (m-* (ww (+ -1 k))
+ (m-+ (m-trans (x (+ -1 k)))
+ (m-unary-- (m-trans (xhat (+ -1 k)))))))
+ (q (m-trans (phi (+ -1 k)))))
+ (:instance mean-of-w*trans-of-x-xhat
+ (k (1- k))))
+ :in-theory (disable xhat z
+ acl2::*-+-right
+ mean-of-w*trans-of-x-xhat)))))
+
+
+ (local
+ (defthm lemma-4c
+ (m-= (M-MEAN
+ (ACL2::M-BINARY-* (PHI (+ -1 K))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X (+ -1 K))
+ (ACL2::M-UNARY-- (XHAT (+ -1 K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X (+ -1 K)))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHAT (+ -1 K)))))
+ (ACL2::M-TRANS (PHI (+ -1 K)))))))
+ (m-* (m-* (phi (1- k))
+ (m-mean (m-* (m-+ (x (+ -1 k))
+ (m-unary-- (xhat (+ -1 k))))
+ (m-trans (m-+ (x (+ -1 k))
+ (m-unary-- (xhat (+ -1 k))))))))
+ (m-trans (phi (1- k)))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance mean-*
+ (p (m-* (phi (1- k))
+ (m-* (m-+ (x (+ -1 k))
+ (m-unary-- (xhat (+ -1 k))))
+ (m-trans (m-+ (x (+ -1 k))
+ (m-unary-- (xhat (+ -1 k))))))))
+ (q (m-trans (phi (+ -1 k)))))
+ (:instance mean-*
+ (p (phi (+ -1 k)))
+ (q (m-* (m-+ (x (+ -1 k))
+ (m-unary-- (xhat (+ -1 k))))
+ (m-trans (m-+ (x (+ -1 k))
+ (m-unary-- (xhat (+ -1 k))))))))
+ (:instance mean-delete
+ (p (phi (1- k)))))
+ :in-theory (disable xhat z acl2::*-+-right)))))
+
+ (local
+ (defthm lemma-4-1
+ (acl2::m-=
+ (m-mean
+ (acl2::m-binary-+
+ (acl2::m-binary-*
+ (phi (+ -1 k))
+ (acl2::m-binary-*
+ (acl2::m-binary-+ (x (+ -1 k))
+ (acl2::m-unary-- (xhat (+ -1 k))))
+ (acl2::m-binary-*
+ (acl2::m-binary-+ (acl2::m-trans (x (+ -1 k)))
+ (acl2::m-unary-- (acl2::m-trans (xhat (+ -1 k)))))
+ (acl2::m-trans (phi (+ -1 k))))))
+ (acl2::m-binary-+
+ (acl2::m-binary-*
+ (phi (+ -1 k))
+ (acl2::m-binary-* (acl2::m-binary-+ (x (+ -1 k))
+ (acl2::m-unary-- (xhat (+ -1 k))))
+ (acl2::m-trans (ww (+ -1 k)))))
+ (acl2::m-binary-+
+ (acl2::m-binary-* (ww (+ -1 k))
+ (acl2::m-trans (ww (+ -1 k))))
+ (acl2::m-binary-*
+ (ww (+ -1 k))
+ (acl2::m-binary-*
+ (acl2::m-binary-+ (acl2::m-trans (x (+ -1 k)))
+ (acl2::m-unary-- (acl2::m-trans (xhat (+ -1 k)))))
+ (acl2::m-trans (phi (+ -1 k)))))))))
+ (acl2::m-binary-+
+ (q (+ -1 k))
+ (acl2::m-binary-*
+ (phi (+ -1 k))
+ (acl2::m-binary-*
+ (m-mean
+ (acl2::m-binary-*
+ (acl2::m-binary-+ (x (+ -1 k))
+ (acl2::m-unary-- (xhat (+ -1 k))))
+ (acl2::m-binary-+ (acl2::m-trans (x (+ -1 k)))
+ (acl2::m-unary-- (acl2::m-trans (xhat (+ -1 k)))))))
+ (acl2::m-trans (phi (+ -1 k)))))))
+ :hints (("Goal" :in-theory (disable acl2::*-+-right
+ acl2::*---right
+ acl2::*-+-left
+ acl2::*---left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+
+ xhat x z xhatmin-recdef gain-recdef)))))
+
+ (local
+ (defthm lemma-4
+ (m-= (m-mean (m-* (m-+ (m-* (phi (1- k)) (m-- (x (1- k)) (xhat (1- k))))
+ (ww (1- k)))
+ (m-trans (m-+ (m-* (phi (1- k))
+ (m-- (x (1- k)) (xhat (1- k))))
+ (ww (1- k))))))
+ (m-+ (m-* (m-* (phi (1- k))
+ (m-mean (m-* (m-- (x (1- k)) (xhat (1- k)))
+ (m-trans (m-- (x (1- k)) (xhat (1- k)))))))
+ (m-trans (phi (1- k))))
+ (q (1- k))))
+ :hints (("Goal"
+ :use ((:instance lemma-3))
+ :in-theory nil)
+ ("Goal'"
+ :use ((:theorem (m-=
+ (m-mean
+ (m-+ (m-* (m-* (phi (+ -1 k))
+ (m-- (x (+ -1 k)) (xhat (+ -1 k))))
+ (m-* (m-trans (m-- (x (+ -1 k)) (xhat (+ -1 k))))
+ (m-trans (phi (+ -1 k)))))
+ (m-+ (m-* (m-* (phi (+ -1 k))
+ (m-- (x (+ -1 k)) (xhat (+ -1 k))))
+ (m-trans (ww (+ -1 k))))
+ (m-+ (m-* (ww (+ -1 k))
+ (m-* (m-trans (m-- (x (+ -1 k)) (xhat (+ -1 k))))
+ (m-trans (phi (+ -1 k)))))
+ (m-* (ww (+ -1 k))
+ (m-trans (ww (+ -1 k))))))))
+ (m-+ (m-* (m-* (phi (+ -1 k))
+ (m-mean (m-* (m-- (x (+ -1 k)) (xhat (+ -1 k)))
+ (m-trans (m-- (x (+ -1 k)) (xhat (+ -1 k)))))))
+ (m-trans (phi (+ -1 k))))
+ (q (+ -1 k))))))
+ :in-theory (disable acl2::*-+-right
+ acl2::*---right
+ acl2::*-+-left
+ acl2::*---left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+
+ acl2::commutativity-2-of-m-+
+ xhat
+ x
+ z
+ xhatmin-recdef
+ gain-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-5
+ (implies (and (integerp k)
+ (< 0 k))
+ (m-= (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k)))))
+ (m-+ (m-* (m-* (phi (1- k))
+ (m-mean (m-* (m-- (x (1- k)) (xhat (1- k)))
+ (m-trans (m-- (x (1- k)) (xhat (1- k)))))))
+ (m-trans (phi (1- k))))
+ (q (1- k)))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-2)
+ (:instance lemma-4))
+ :in-theory (disable x xhat xhatmin-recdef
+ acl2::*-+-right
+ acl2::*---right
+ acl2::*-+-left
+ acl2::*---left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+
+ acl2::commutativity-2-of-m-+)))
+ :rule-classes nil))
+
+ (defthm pminus-as-mean-almost
+ (implies (and (integerp k)
+ (< 0 k)
+ (m-= (pplus (1- k))
+ (m-mean (m-* (m-- (x (1- k))
+ (xhat (1- k)))
+ (m-trans (m-- (x (1- k))
+ (xhat (1- k))))))))
+ (m-= (pminus k)
+ (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k)))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-5))
+ :in-theory (disable x xhat xhatmin
+ gain-recdef pplus-recdef xhatmin-recdef
+ acl2::*-+-right
+ acl2::*---right
+ acl2::*-+-left
+ acl2::*---left
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::left-distributivity-of-m-*-over-m-+
+ acl2::commutativity-2-of-m-+))))
+ )
+
+(defthm matrix-*-trans
+ (implies (and (equal m (l x))
+ (equal n (l x))
+ (m-matrixp m n x))
+ (m-matrixp m n (m-* x (m-trans x)))))
+
+(defthm id-*-x-useful
+ (implies (and (equal (l p) n)
+ (m-matrixp (l p) (c p) p))
+ (m-= (m-* (m-id n) p) p))
+ :hints (("Goal"
+ :use ((:instance acl2::id-*-x
+ (acl2::n (l p))
+ (acl2::n2 (c p))
+ (acl2::p p)))
+ :in-theory (disable acl2::id-*-x))))
+
+(defthm x-*-id-useful
+ (implies (and (equal (c p) n)
+ (m-matrixp (l p) (c p) p))
+ (m-= (m-* p (m-id n)) p))
+ :hints (("Goal"
+ :use ((:instance acl2::x-*-id
+ (acl2::m (l p))
+ (acl2::n (c p))
+ (acl2::p p)))
+ :in-theory (disable acl2::x-*-id))))
+
+(encapsulate
+ ()
+
+ (local
+ (defthm lemma-1
+ (m-= (m-- (x k) (xhat k))
+ (m-- (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-- (x k) (xhatmin k)))
+ (m-* (gain k)
+ (v k))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance acl2::id-*-x
+ (acl2::p (x k))
+ (acl2::n (n))
+ (acl2::n2 1))
+ (:instance acl2::id-*-x
+ (acl2::p (xhatmin k))
+ (acl2::n (n))
+ (acl2::n2 1)))
+ :in-theory (disable acl2::id-*-x)))
+ :rule-classes nil))
+
+
+ (local
+ (defthm lemma-2a
+ (implies (and (equal (l a) (l b))
+ (equal (c a) (c b))
+ (m-matrixp (l b) (c b) b)
+ (m-matrixp (l a) (c a) a))
+ (m-= (m-* (m-- a b)
+ (m-trans (m-- a b)))
+ (m-+ (m-* a (m-trans a))
+ (m-+ (m-unary-- (m-* a (m-trans b)))
+ (m-+ (m-unary-- (m-* b (m-trans a)))
+ (m-* b (m-trans b)))))))
+ :hints (("Goal"
+ :use ((:instance acl2::unary---unary--
+ (acl2::p (m-* b (m-trans b)))))
+ :in-theory (disable acl2::unary---unary--)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-2
+ (m-= (m-* (m-- (x k) (xhat k))
+ (m-trans (m-- (x k) (xhat k))))
+ (m-+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k))))
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (m-+ (m-unary-- (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (m-* (m-- (x k) (xhatmin k))
+ (m-trans (v k)))
+ (m-trans (gain k)))))
+ (m-+ (m-unary-- (m-* (gain k)
+ (m-* (m-* (v k)
+ (m-trans (m-- (x k) (xhatmin k))))
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k)))))))
+ (m-* (gain k)
+ (m-* (m-* (v k)
+ (m-trans (v k)))
+ (m-trans (gain k))))))))
+ :hints (("Goal"
+ :use ((:instance lemma-1)
+ (:instance lemma-2a
+ (a (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-- (x k) (xhatmin k))))
+ (b (m-* (gain k)
+ (v k)))))
+ :in-theory (disable x xhat xhatmin
+ gain-recdef pplus-recdef xhatmin-recdef
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))
+ :rule-classes nil))
+
+
+ (local
+ (defthm lemma-3a1
+ (and (equal (l (m-- (x k) (xhatmin k))) (n))
+ (equal (c (m-- (m-id (n)) (m-* (gain k) (h k)))) (n)))))
+
+ (local
+ (defthm lemma-3a
+ (m-= (m-mean (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k)))))
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k)))))))
+ :hints (("Goal"
+ :use ((:instance mean-*
+ (p (m-- (m-id (n))
+ (m-* (gain k) (h k))))
+ (q (m-* (m-- (x k) (xhatmin k))
+ (m-* (m-trans (m-- (x k) (xhatmin k)))
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))))
+ (:instance mean-*
+ (p (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k)))))
+ (q (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (:instance mean-delete
+ (p (m-id (n))))
+ (:instance mean-delete
+ (p (m-* (gain k) (h k)))))
+ :in-theory (disable x xhatmin gain gain-recdef
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ;acl2::trans-* acl2::trans-+ acl2::trans---
+ )))))
+
+ (local
+ (defthm lemma-3b
+ (m-= (m-mean (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K)))))))
+ (m-zero (n) (n)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance mean-*
+ (p (m-- (m-id (n))
+ (m-* (gain k) (h k))))
+ (q (m-* (m-* (m-- (x k) (xhatmin k))
+ (m-trans (v k)))
+ (m-trans (gain k)))))
+ (:instance mean-*
+ (p (m-* (m-- (x k) (xhatmin k))
+ (m-trans (v k))))
+ (q (m-trans (gain k))))
+ (:instance mean-of-x-xhatmin*vtrans))
+ :in-theory (disable mean-of-x-xhatmin*vtrans
+ mean-+
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ )))))
+
+ (local
+ (defthm lemma-3c
+ (m-= (M-MEAN
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K))))))))))
+
+
+ (m-zero (n) (n)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance mean-*
+ (p (gain k))
+ (q (m-* (m-* (v k)
+ (m-trans (m-- (x k) (xhatmin k))))
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k)))))))
+ (:instance mean-*
+ (p (m-* (v k)
+ (m-trans (m-- (x k) (xhatmin k)))))
+ (q (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (:instance mean-of-v*trans-of-x-xhatmin))
+ :in-theory (disable mean-of-v*trans-of-x-xhatmin
+ mean-+
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ )))))
+
+
+ (local
+ (defthm lemma-3d
+ (equal (m-mean (m-* (gain k)
+ (m-* (v k)
+ (m-* (m-trans (v k))
+ (m-trans (gain k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))
+ :hints (("Goal"
+ :use ((:instance mean-*
+ (p (gain k))
+ (q (m-* (m-* (v k)
+ (m-trans (v k)))
+ (m-trans (gain k)))))
+ (:instance mean-*
+ (p (m-* (v k)
+ (m-trans (v k))))
+ (q (m-trans (gain k))))
+ (:instance mean-delete
+ (p (gain k))))
+ :in-theory (disable gain gain-recdef)))))
+
+
+
+
+ (local
+ (defthm lemma-3e
+
+ (EQUAL
+ (CAR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-* (V K)
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K)))))))
+ (CAR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K))))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))))))
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef x xhat xhatmin
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+ (local
+ (defthm lemma-3f
+
+ (EQUAL
+ (CADR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-* (V K)
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K)))))))
+ (CADR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K))))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))))))
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef x xhat xhatmin
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+ (local
+ (defthm lemma-3g
+
+ (EQUAL
+ (CAR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K))))))))
+ (CAR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K))))))))))))
+
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef x xhat xhatmin
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+ (local
+ (defthm lemma-3h
+
+ (EQUAL
+ (CADR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K))))))))
+ (CADR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K))))))))))))
+
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef x xhat xhatmin
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+ (local
+ (defthm lemma-3i
+
+ (EQUAL
+ (CAR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))))
+ (CAR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))))
+
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef x xhat xhatmin
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+ (local
+ (defthm lemma-3j
+
+ (EQUAL
+ (CADR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))))
+ (CADR
+ (DIMENSIONS
+ 'ACL2::$ARG
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))))
+
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef x xhat xhatmin
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+
+
+ (local
+ (defthm lemma-3k
+
+ (ACL2::M-=
+ (ACL2::M-BINARY-+
+ (ACL2::M-0 (N) (N))
+ (ACL2::M-BINARY-+
+ (ACL2::M-0 (N) (N))
+ (ACL2::M-BINARY-+
+ (ACL2::M-BINARY-* (GAIN K)
+ (ACL2::M-BINARY-* (R K)
+ (ACL2::M-TRANS (GAIN K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (M-MEAN
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-TRANS (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K))))))
+ (ACL2::M-TRANS
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K)
+ (H K))))))))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-BINARY-* (GAIN K)
+ (ACL2::M-BINARY-* (R K)
+ (ACL2::M-TRANS (GAIN K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (M-MEAN
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef x xhat xhatmin
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+
+ (local
+ (DEFTHM
+ lemma-3l
+ (ACL2::M-=
+ (M-MEAN
+ (ACL2::M-BINARY-+
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-* (V K)
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K)))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-* (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (V K))
+ (ACL2::M-TRANS (GAIN K))))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-*
+ (GAIN K)
+ (ACL2::M-BINARY-*
+ (V K)
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY--
+ (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K))))))))))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-BINARY-* (GAIN K)
+ (ACL2::M-BINARY-* (R K)
+ (ACL2::M-TRANS (GAIN K))))
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (GAIN K) (H K))))
+ (ACL2::M-BINARY-*
+ (M-MEAN
+ (ACL2::M-BINARY-*
+ (ACL2::M-BINARY-+ (X K)
+ (ACL2::M-UNARY-- (XHATMIN K)))
+ (ACL2::M-BINARY-+ (ACL2::M-TRANS (X K))
+ (ACL2::M-UNARY-- (ACL2::M-TRANS (XHATMIN K))))))
+ (ACL2::M-BINARY-+
+ (ACL2::M-1 (N))
+ (ACL2::M-UNARY-- (ACL2::M-BINARY-* (ACL2::M-TRANS (H K))
+ (ACL2::M-TRANS (GAIN K)))))))))
+ :INSTRUCTIONS
+ ((:DV 1)
+ (:REWRITE MEAN-+)
+ (:CHANGE-GOAL NIL T)
+ (:USE LEMMA-3E)
+ (:USE LEMMA-3F)
+ (:DV 1)
+ (:REWRITE LEMMA-3D)
+ :NX (:REWRITE MEAN-+)
+ (:CHANGE-GOAL NIL T)
+ (:USE LEMMA-3G)
+ (:USE LEMMA-3H)
+ (:DV 1)
+ (:REWRITE LEMMA-3B)
+ :NX (:REWRITE MEAN-+)
+ (:CHANGE-GOAL NIL T)
+ (:USE LEMMA-3I)
+ (:USE LEMMA-3J)
+ (:DV 1)
+ (:REWRITE LEMMA-3C)
+ :NX (:REWRITE LEMMA-3A)
+ :TOP (:DV 1)
+ (:REWRITE ACL2::COMMUTATIVITY-2-OF-M-+)
+ (:DIVE 2) ; changed by Matt K. for v2-9 due to proof-builder DV fix for binops
+ (:REWRITE ACL2::COMMUTATIVITY-2-OF-M-+)
+ :TOP (:USE LEMMA-3K))))
+
+ (local
+ (defthm lemma-3
+ (m-= (m-mean (m-* (m-- (x k) (xhat k))
+ (m-trans (m-- (x k) (xhat k)))))
+ (m-+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k)))))
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k))))))
+ :hints (("Goal"
+ :use ((:instance lemma-2))
+ :in-theory (disable x xhat xhatmin
+ gain-recdef pplus-recdef xhatmin-recdef
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ))
+ ("Goal'4'"
+ :by (:instance lemma-3l)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-4
+ (m-= (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (pminus k)
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (m-+ (pminus k)
+ (m-+ (m-unary-- (m-* (gain k) (m-* (h k) (pminus k))))
+ (m-+ (m-unary-- (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-trans (gain k)))))
+ (m-* (gain k)
+ (m-* (h k)
+ (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-trans (gain k))))))))))
+ :hints (("Goal" :do-not-induct t
+ :in-theory (disable gain gain-recdef
+ pminus pminus-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-5
+ (m-= (m-+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (pminus k)
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))
+ (m-+ (pminus k)
+ (m-+ (m-unary-- (m-* (gain k) (m-* (h k) (pminus k))))
+ (m-+ (m-unary-- (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-trans (gain k)))))
+ (m-+ (m-* (gain k)
+ (m-* (h k)
+ (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-trans (gain k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-4))
+ :in-theory (disable gain gain-recdef
+ pminus pminus-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-6
+ (m-= (m-+ (m-* (gain k)
+ (m-* (h k)
+ (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-trans (gain k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))
+ (m-* (gain k)
+ (m-* (m-+ (m-* (h k) (m-* (pminus k) (m-trans (h k))))
+ (r k))
+ (m-trans (gain k)))))
+ :hints (("Goal"
+ :in-theory (disable gain gain-recdef pminus pminus-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-7a
+ (implies (and (not (m-singular x))
+ (m-matrixp (l x) (c x) x)
+ (m-matrixp (l y) (c y) y)
+ (equal (c v) (l w))
+ (equal (c w) (l x))
+ (equal (c x) (l y)))
+ (m-= (m-* v
+ (m-* w
+ (m-* (m-inv x)
+ (m-* x y))))
+ (m-* v (m-* w y))))
+ :hints (("Goal"
+ :use ((:instance acl2::assoc-*
+ (acl2::p (m-inv x))
+ (acl2::q x)
+ (acl2::r y))
+ (:instance acl2::inv-*-x
+ (acl2::p x)))
+ :in-theory (disable acl2::assoc-*
+ acl2::inv-*-x))
+ ("Goal'4'"
+ :in-theory (enable acl2::assoc-*)))))
+
+ (local
+ (defthm lemma-7
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-+ (m-* (gain k)
+ (m-* (h k)
+ (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-trans (gain k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))
+ (m-* (pminus k)
+ (m-* (m-trans (h k)) (m-trans (gain k))))))
+ :hints (("Goal"
+ :use ((:instance lemma-6))
+ :in-theory (disable gain pminus pminus-recdef
+ acl2::assoc-*
+ acl2::comm-+
+ ACL2::*-+-RIGHT
+ ACL2::*---RIGHT
+ ACL2::*-+-left
+ ACL2::*---left
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::left-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ acl2::COMMUTATIVITY-2-OF-M-+
+ ))
+ ("Goal'''"
+ :use (:theorem
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-* (gain k)
+ (m-* (m-+ (m-* (h k)
+ (m-* (pminus k) (m-trans (h k))))
+ (r k))
+ (m-trans (gain k))))
+ (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-trans (gain k))))))))
+ ("Subgoal 1"
+ :in-theory (disable gain pminus pminus-recdef
+ ;acl2::comm-+
+ ACL2::*-+-RIGHT
+ ACL2::*---RIGHT
+ ACL2::*-+-left
+ ACL2::*---left
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::left-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ acl2::COMMUTATIVITY-2-OF-M-+
+ ))
+ )
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-8
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (pminus k)
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))
+ (m-- (pminus k)
+ (m-* (gain k) (m-* (h k) (pminus k))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-5)
+ (:instance lemma-6)
+ (:instance lemma-7))
+ :in-theory (disable gain gain-recdef
+ pminus pminus-recdef
+ acl2::assoc-*
+ acl2::comm-+
+ ACL2::*-+-RIGHT
+ ACL2::*---RIGHT
+ ACL2::*-+-left
+ ACL2::*---left
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::left-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ acl2::COMMUTATIVITY-2-OF-M-+
+ acl2::trans-*
+ acl2::trans-+
+ acl2::trans---))
+ ("Goal'7'"
+ :by (:theorem
+ (m-= (m-+ (pminus k)
+ (m-+ (m-unary-- (m-* (gain k) (m-* (h k) (pminus k))))
+ (m-zero (n) (n))))
+ (m-- (pminus k)
+ (m-* (gain k)
+ (m-* (h k) (pminus k))))))
+ :in-theory (disable pminus pminus-recdef gain gain-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-9-for-lemma-10
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (pminus k)
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))
+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (pminus k))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-8))
+ :in-theory (disable pminus pminus-recdef gain gain-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm lemma-10
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-+ (m-* (m-- (m-id (n))
+ (m-* (gain k) (h k)))
+ (m-* (pminus k)
+ (m-trans (m-- (m-id (n))
+ (m-* (gain k) (h k))))))
+ (m-* (gain k)
+ (m-* (r k)
+ (m-trans (gain k)))))
+ (pplus k)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-9-for-lemma-10))
+ :in-theory (disable pminus pminus-recdef gain gain-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm pplus-as-mean-case-0
+ (implies (equal k 0)
+ (m-= (pplus k)
+ (m-mean (m-* (m-- (x k) (xhat k))
+ (m-trans (m-- (x k) (xhat k)))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-3)
+ (:instance lemma-10)
+ (:instance pminus-as-mean-case-0))
+ :in-theory (disable pminus pminus-recdef gain gain-recdef)))
+ :rule-classes nil))
+
+ (local
+ (defthm pplus-as-mean-almost
+ (implies (and (integerp k)
+ (< 0 k)
+ (m-= (pplus (1- k))
+ (m-mean (m-* (m-- (x (1- k))
+ (xhat (1- k)))
+ (m-trans (m-- (x (1- k))
+ (xhat (1- k))))))))
+ (m-= (pplus k)
+ (m-mean (m-* (m-- (x k) (xhat k))
+ (m-trans (m-- (x k) (xhat k)))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-3)
+ (:instance lemma-10)
+ (:instance pminus-as-mean-almost))
+ :in-theory (disable gain gain-recdef
+ pminus pminus-recdef
+ acl2::assoc-*
+ acl2::comm-+
+ ACL2::*-+-RIGHT
+ ACL2::*---RIGHT
+ ACL2::*-+-left
+ ACL2::*---left
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::left-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ acl2::COMMUTATIVITY-2-OF-M-+
+ acl2::trans-*
+ acl2::trans-+
+ acl2::trans---)))
+ :rule-classes nil))
+
+ (local
+ (defun natural-induction (n)
+ (if (zp n)
+ 0
+ (1+ (natural-induction (1- n))))))
+
+ (defthm pplus-as-mean
+ (implies (and (integerp k)
+ (<= 0 k))
+ (m-= (pplus k)
+ (m-mean (m-* (m-- (x k) (xhat k))
+ (m-trans (m-- (x k) (xhat k)))))))
+ :hints (("Goal"
+ :induct (natural-induction k))
+ ("Subgoal *1/2"
+ :use ((:instance pplus-as-mean-almost)))
+ ("Subgoal *1/1"
+ :use ((:instance pplus-as-mean-case-0)))
+ ))
+
+ )
+
+(defthm pminus-as-mean
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (pminus k)
+ (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (x k) (xhatmin k)))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance pminus-as-mean-almost)
+ (:instance pplus-as-mean (k (1- k))))
+ :in-theory (disable pminus-as-mean-almost pplus-as-mean
+ x xhat xhatmin
+ gain-recdef pplus-recdef xhatmin-recdef
+ (pminus) (x) (xhatmin)))))
+
+(encapsulate
+ ()
+
+ (local
+ (encapsulate
+ ()
+
+ (local
+ (defthm lemma-0-1
+ (implies (and (m-matrixp (l y) (c y) y)
+ (m-matrixp (l z) (c z) z)
+ (equal (c x) (l y))
+ (equal (c y) (l z)))
+ (equal (m-* x (m-mean (m-* y z)))
+ (m-mean (m-* (m-* x y) z))))
+ :hints (("Goal"
+ :use ((:instance mean-*
+ (p x)
+ (q (m-* y z)))
+ (:instance mean-delete
+ (p x)))))))
+
+ (local
+ (defthm lemma-0-2
+ (implies (and (m-matrixp (l x) (c x) x)
+ (m-matrixp (l y) (c y) y)
+ (equal (c x) (l y))
+ (equal (c y) (l z)))
+ (equal (m-* (m-mean (m-* x y)) z)
+ (m-mean (m-* x (m-* y z)))))
+ :hints (("Goal"
+ :use ((:instance mean-*
+ (p (m-* x y))
+ (q z))
+ (:instance mean-delete
+ (p z)))))))
+
+ (defthm lemma-0
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-* (pminus k) (m-trans (h k)))
+ (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k))))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance pminus-as-mean))
+ :in-theory (disable pplus-as-mean pminus-as-mean))))
+
+
+ (defthm lemma-1
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-* (h k) (m-* (pminus k) (m-trans (h k))))
+ (m-mean (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))))))
+ ))
+
+ (local
+ (encapsulate
+ ()
+
+ (local
+ (defthm lemma-2-1
+ (equal (l (m-* (v k) (m-trans (v k))))
+ (l (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))))))
+
+ (local
+ (defthm lemma-2-2
+ (equal (c (m-* (v k) (m-trans (v k))))
+ (c (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))))))
+
+ (defthm lemma-2
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-+ (m-* (h k)
+ (m-* (pminus k) (m-trans (h k))))
+ (m-mean (m-* (v k) (m-trans (v k)))))
+ (m-mean (m-+ (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))
+ (m-* (v k) (m-trans (v k)))))))
+ :hints (("Goal" :do-not-induct t
+ :in-theory '(lemma-1 mean-+ lemma-2-1 lemma-2-2
+ acl2::m-=-implies-equal-m-+-1))))
+
+ ))
+
+ (local
+ (defthm lemma-3
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-+ (m-* (h k)
+ (m-* (pminus k)
+ (m-trans (h k))))
+ (r k))
+ (m-mean (m-+ (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))
+ (m-* (v k) (m-trans (v k)))))))
+ :hints (("Goal"
+ :use ((:instance mean-of-v-vtrans)
+ (:instance lemma-2))
+ :in-theory '(acl2::m-=-implies-equal-m-+-2)))))
+
+ (local
+ (encapsulate
+ nil
+
+ (local
+ (defthm lemma-4-1
+ (implies (and (m-matrixp (l a) (c a) a)
+ (m-matrixp (l b) (c b) b)
+ (equal (l a) (l b))
+ (equal (c a) (c b)))
+ (m-= (m-mean (m-* (m-+ a b) (m-trans (m-+ a b))))
+ (m-+ (m-mean (m-* a (m-trans a)))
+ (m-+ (m-mean (m-* a (m-trans b)))
+ (m-+ (m-mean (m-* b (m-trans a)))
+ (m-mean (m-* b (m-trans b))))))))))
+
+ (local
+ (defthm lemma-4-2
+ (m-= (m-mean (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (v k))))
+ (m-zero (m) (m)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance mean-of-x-xhatmin*vtrans)
+ (:instance acl2::x-*-zero
+ (acl2::p (h k))
+ (acl2::m (n))
+ (acl2::n (m)))
+ (:instance acl2::*-+-right
+ (acl2::p (h k))
+ (acl2::q (m-* (x k) (m-trans (v k))))
+ (acl2::r (m-* (m-unary-- (xhatmin k))
+ (m-trans (v k)))))
+ (:instance mean-*
+ (p (h k))
+ (q (m-* (m-- (x k) (xhatmin k))
+ (m-trans (v k)))))
+ (:instance mean-delete
+ (p (h k))))
+ :in-theory (disable mean-of-x-xhatmin*vtrans
+ acl2::x-*-zero
+ acl2::*-+-right)))))
+
+ (local
+ (defthm lemma-4-3
+ (m-= (m-mean (m-* (v k)
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k))))))
+ (m-zero (m) (m)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance mean-of-v*trans-of-x-xhatmin)
+ (:instance acl2::zero-*-x
+ (acl2::p (m-trans (h k)))
+ (acl2::m (m))
+ (acl2::n (n)))
+ (:instance mean-*
+ (p (m-* (v k)
+ (m-trans (m-- (x k) (xhatmin k)))))
+ (q (m-trans (h k))))
+ (:instance mean-delete
+ (p (m-trans (h k)))))
+ :in-theory (disable mean-of-v*trans-of-x-xhatmin
+ acl2::*-+-left
+ acl2::*-+-right
+ acl2::*---left
+ acl2::*---right
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ acl2::x-*-zero))
+ ("Goal'7'"
+ :use ((:theorem
+ (IMPLIES (m-= (m-mean (m-* (v k)
+ (m-* (m-- (m-trans (x k))
+ (m-trans (xhatmin k)))
+ (m-trans (h k)))))
+ (m-* (m-zero (m) (n))
+ (m-trans (h k))))
+ (m-= (m-mean (m-* (v k)
+ (m-- (m-* (m-trans (x k))
+ (m-trans (h k)))
+ (m-* (m-trans (xhatmin k))
+ (m-trans (h k))))))
+ (m-zero (m) (m)))))))
+ ("Subgoal 1"
+ :in-theory (enable acl2::*-+-left)))))
+
+ (defthm lemma-4
+ (m-= (m-mean (m-* (m-+ (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (v k))
+ (m-trans (m-+ (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (v k)))))
+ (m-mean (m-+ (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))
+ (m-* (v k) (m-trans (v k))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-4-1
+ (a (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k))))
+ (b (v k))))
+ :in-theory (disable lemma-4-1
+ xhatmin-recdef
+ mean-of-v-vtrans
+ mean-unary--
+ acl2::trans-*
+ acl2::trans-+
+ acl2::assoc-*
+ acl2::assoc-+
+ acl2::comm-+
+ acl2::*-+-left
+ acl2::*---left
+ ))))
+ ))
+
+ (local
+ (encapsulate
+ ()
+
+ (local
+ (defthm lemma-5-1
+ (implies (and (equal (l a) (l b))
+ (equal (c a) (c b))
+ (equal (l b) (l c))
+ (equal (c b) (c c)))
+ (m-= (m-+ b (m-+ a c))
+ (m-+ a (m-+ b c))))
+ :hints (("Goal"
+ :use ((:instance acl2::assoc-+
+ (acl2::p b)
+ (acl2::q a)
+ (acl2::r c))
+ (:instance acl2::assoc-+
+ (acl2::p a)
+ (acl2::q b)
+ (acl2::r c)))
+ :in-theory (disable acl2::assoc-+)))))
+
+ (defthm lemma-5
+ (m-= (m-+ (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (v k))
+ (m-- (z k) (m-* (h k) (xhatmin k))))
+ :hints (("Goal" :do-not-induct t)))
+ ))
+
+ (local
+ (defthm lemma-6
+ (m-= (m-mean (m-* (m-- (z k) (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (z k) (m-* (h k) (xhatmin k))))))
+ (m-mean (m-+ (m-* (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))
+ (m-* (v k) (m-trans (v k))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-4)
+ (:instance lemma-5))
+ :in-theory (disable lemma-4
+ lemma-5
+ z
+ xhatmin
+ x
+ mean-+
+ acl2::assoc-+
+ acl2::comm-+
+ acl2::commutativity-2-of-m-+
+ acl2::trans-*
+ acl2::trans-+
+ acl2::trans---
+ acl2::*-+-left
+ acl2::*-+-right
+ acl2::*---left
+ acl2::*---right
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+ (local
+ (defthm lemma-7
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (m-+ (m-* (h k)
+ (m-* (pminus k)
+ (m-trans (h k))))
+ (r k))
+ (m-mean (m-* (m-- (z k) (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (z k) (m-* (h k) (xhatmin k))))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-3)
+ (:instance lemma-6))
+ :in-theory (disable lemma-3
+ lemma-6
+ z
+ xhatmin
+ x
+ mean-+
+ acl2::assoc-+
+ acl2::comm-+
+ acl2::commutativity-2-of-m-+
+ acl2::trans-*
+ acl2::trans-+
+ acl2::trans---
+ acl2::*-+-left
+ acl2::*-+-right
+ acl2::*---left
+ acl2::*---right
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+)))))
+
+ (local
+ (defthm lemma-8
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (s-* 2 (m-* (gain k)
+ (m-mean (m-* (m-- (z k)
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (z k)
+ (m-* (h k) (xhatmin k))))))))
+ (s-* 2 (m-* (pminus k) (m-trans (h k))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-7)
+ (:instance gain-recdef))
+ :in-theory (disable lemma-0 lemma-1 lemma-3 lemma-7
+ gain-recdef
+ z
+ acl2::*-+-right
+ acl2::*-+-left
+ acl2::*---right
+ acl2::*---left
+ acl2::assoc-+
+ acl2::comm-+
+ acl2::left-distributivity-of-m-*-over-m-+
+ acl2::right-distributivity-of-m-*-over-m-+
+ pminus-as-mean))
+ ("Goal'5'"
+ :by (:theorem
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (s-* 2 (m-* (pminus k)
+ (m-* (m-trans (h k))
+ (m-* (m-inv (m-+
+ (m-* (h k)
+ (m-* (pminus k)
+ (m-trans (h k))))
+ (r k)))
+ (m-+
+ (m-* (h k)
+ (m-* (pminus k)
+ (m-trans (h k))))
+ (r k))))))
+ (s-* 2
+ (m-* (pminus k)
+ (m-trans (h k))))))))
+ ("Goal'6'"
+ :use ((:instance acl2::inv-*-x
+ (acl2::p (m-+ (r k)
+ (m-* (h k)
+ (m-* (pminus k)
+ (m-trans (h k))))))))
+ :in-theory (disable lemma-0 lemma-1 lemma-3 lemma-7
+ z
+ acl2::inv-*-x
+ acl2::*-+-left
+ acl2::*-+-right
+ acl2::*---left
+ acl2::*---right
+ acl2::assoc-*
+ acl2::assoc-+
+ ;acl2::comm-+
+ acl2::k-*---p
+ acl2::k-*-x-+-y
+ mean-+
+ mean-of-v-vtrans
+ mean-unary--
+ acl2::trans-*
+ acl2::trans-+
+ acl2::unary---+
+ pminus-as-mean)))))
+
+ (local
+ (defthm lemma-9
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (s-* 2 (m-* (gain k)
+ (m-mean (m-* (m-- (z k)
+ (m-* (h k) (xhatmin k)))
+ (m-trans (m-- (z k)
+ (m-* (h k) (xhatmin k))))))))
+ (s-* 2 (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-0)
+ (:instance lemma-8))
+ :in-theory (disable lemma-0 lemma-8
+ gain gain-recdef
+ z
+ xhatmin
+ x
+ )
+ ))))
+
+ (local
+ (encapsulate
+ ()
+
+ (local
+ (defthm lemma-10-1
+ (implies (and (equal (l a) (l b))
+ (equal (c a) (c b))
+ (equal (l b) (l c))
+ (equal (c b) (c c)))
+ (m-= (m-+ b (m-+ a c))
+ (m-+ a (m-+ b c))))
+ :hints (("Goal"
+ :use ((:instance acl2::assoc-+
+ (acl2::p b)
+ (acl2::q a)
+ (acl2::r c))
+ (:instance acl2::assoc-+
+ (acl2::p a)
+ (acl2::q b)
+ (acl2::r c)))
+ :in-theory (disable acl2::assoc-+)))))
+
+ (local
+ (defthm lemma-10-2
+ (equal (m-- (z k) (m-* (h k) (xhatmin k)))
+ (m-+ (m-* (h k) (m-- (x k) (xhatmin k))) (v k)))
+ :hints (("Goal" :do-not-induct t))
+ ))
+
+ (local
+ (defthm lemma-10-3
+ (m-= (m-trans (m-- (z k) (m-* (h k) (xhatmin k))))
+ (m-+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k))))
+ (m-trans (v k))))
+ :hints (("Goal" :do-not-induct t))))
+
+ (local
+ (defthm lemma-10-4
+ (m-= (m-mean (m-* (m-- (xhatmin k) (x k))
+ (m-trans (m-- (z k)
+ (m-* (h k) (xhatmin k))))))
+ (m-mean (m-* (m-- (xhatmin k) (x k))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k)))))))
+ :hints (("Goal" :do-not-induct t
+ :in-theory (disable MEAN-UNARY--
+ z
+ mean-+
+ acl2::trans---
+ acl2::trans-+
+ acl2::trans-*
+ lemma-10-1
+ lemma-10-2
+ acl2::*-+-left
+ acl2::*---left
+ acl2::*-+-right
+ acl2::*---right
+ acl2::left-distributivity-of-m-*-over-m-+
+ acl2::right-distributivity-of-m-*-over-m-+
+ acl2::comm-+
+ ))
+
+
+ ("Goal'"
+ :use ((:instance acl2::*-+-right
+ (acl2::p (M-- (XHATMIN K) (X K)))
+ (acl2::q (M-TRANS (M-- (M-* (H K) (X K))
+ (M-* (H K) (XHATMIN K)))))
+ (acl2::r (M-TRANS (V K)))))
+ :in-theory (disable z
+ MEAN-UNARY--
+ mean-+
+ acl2::trans---
+ acl2::trans-+
+ acl2::trans-*
+ acl2::*-+-right
+ acl2::*---right
+ acl2::*-+-left
+ acl2::*---left
+ acl2::comm-+
+ acl2::left-distributivity-of-m-*-over-m-+
+ acl2::right-distributivity-of-m-*-over-m-+
+ ))
+
+ ("Goal'5'"
+ :by (:theorem
+ (m-=
+ (m-mean (m-+ (m-* (m-+ (xhatmin k) (m-unary-- (x k)))
+ (m-trans (m-+ (m-* (h k) (x k))
+ (m-unary-- (m-* (h k) (xhatmin k))))))
+ (m-* (m-+ (xhatmin k) (m-unary-- (x k)))
+ (m-trans (v k)))))
+ (m-mean (m-* (m-+ (xhatmin k) (m-unary-- (x k)))
+ (m-trans (m-+ (m-* (h k) (x k))
+ (m-unary-- (m-* (h k) (xhatmin k))))))))))
+ ("Goal'6'"
+ :use ((:instance mean-of-x-xhatmin*vtrans)
+ (:instance mean-unary--
+ (p (m-* (m-+ (x k)
+ (m-unary-- (xhatmin k)))
+ (m-trans (v k)))))
+ (:theorem (m-= (m-unary-- (m-* (m-+ (x k)
+ (m-unary-- (xhatmin k)))
+ (m-trans (v k))))
+ (m-* (m-+ (xhatmin k) (m-unary-- (x k)))
+ (m-trans (v k))))))
+ :in-theory (disable mean-of-x-xhatmin*vtrans
+ mean-unary--))
+
+ ("Subgoal 2"
+ :use ((:instance M-=-IMPLIES-M-=-M-MEAN-1
+ (x (m-* (m-- (xhatmin k) (x k))
+ (m-trans (v k))))
+ (x-equiv (m-unary-- (m-* (m-- (x k) (xhatmin k))
+ (m-trans (v k))))))
+ )
+ :in-theory (disable mean-of-x-xhatmin*vtrans
+ mean-unary--
+ lemma-10-1
+ acl2::*-+-left
+ acl2::*-+-right
+ acl2::*---left
+ acl2::*---right
+ ;acl2::comm-+
+ acl2::trans-*
+ acl2::trans-+
+ acl2::trans---
+ acl2::left-distributivity-of-m-*-over-m-+
+ acl2::right-distributivity-of-m-*-over-m-+
+ (:congruence M-=-IMPLIES-M-=-M-MEAN-1)
+ ))
+ )))
+
+ (local
+ (defthm lemma-10-5
+ (implies (and (m-matrixp (l a) (c a) a)
+ (m-matrixp (l b) (c b) b)
+ (equal (l a) (l b))
+ (equal (c a) (c b)))
+ (m-= (m-- b a)
+ (m-unary-- (m-- a b))))))
+
+
+ (local
+ (defthm lemma-10-6
+ (implies (and (m-matrixp (l a) (c a) a)
+ (m-matrixp (l b) (c b) b)
+ (m-matrixp (l c) (c c) c)
+ (equal (l a) (l b))
+ (equal (c a) (c b))
+ (equal (c b) (l c)))
+ (m-= (m-unary-- (m-mean (m-* (m-- a b) c)))
+ (m-mean (m-* (m-- b a) c))))
+ :hints (("Goal"
+ :use ((:instance lemma-10-5)
+ (:instance M-=-IMPLIES-M-=-M-MEAN-1
+ (x (ACL2::M-BINARY-* (ACL2::M-BINARY-+ B (ACL2::M-UNARY-- A))
+ C))
+ (x-equiv (m-* (m-unary-- (m-- a b)) c)))
+ )
+ :in-theory (disable lemma-10-5 acl2::unary---+ acl2::assoc-+
+ m-=-implies-m-=-m-mean-1))
+ ("Goal'4'"
+ :by (:theorem
+ (implies
+ (and (acl2::matrixp (car (dimensions 'acl2::$arg a))
+ (car (dimensions 'acl2::$arg c))
+ a)
+ (acl2::matrixp (car (dimensions 'acl2::$arg a))
+ (car (dimensions 'acl2::$arg c))
+ b)
+ (acl2::matrixp (car (dimensions 'acl2::$arg c))
+ (cadr (dimensions 'acl2::$arg c))
+ c))
+ (acl2::m-=
+ (acl2::m-unary--
+ (m-mean (acl2::m-binary-* (acl2::m-binary-+ a (acl2::m-unary-- b))
+ c)))
+ (m-mean (acl2::m-binary-*
+ (acl2::m-unary-- (acl2::m-binary-+ a (acl2::m-unary-- b)))
+ c)))))
+ :in-theory (disable lemma-10-5 acl2::unary---+ acl2::assoc-+)))))
+
+ (defthm lemma-10
+ (m-= (m-mean (m-* (m-- (xhatmin k) (x k))
+ (m-trans (m-- (z k)
+ (m-* (h k) (xhatmin k))))))
+ (m-unary-- (m-mean (m-* (m-- (x k) (xhatmin k))
+ (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k))))))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-10-4)
+ (:instance lemma-10-6
+ (a (xhatmin k))
+ (b (x k))
+ (c (m-trans (m-- (m-* (h k) (x k))
+ (m-* (h k) (xhatmin k))))))
+ )
+ :in-theory (disable lemma-10-2
+ lemma-10-3
+ lemma-10-4
+ lemma-10-5
+ lemma-10-6
+ z
+ mean-unary--
+ acl2::*---left
+ acl2::*---right
+ acl2::*-+-left
+ acl2::*-+-right
+ acl2::unary---+
+ acl2::trans-*
+ acl2::trans-+
+ acl2::trans---
+ acl2::comm-+
+ acl2::assoc-+
+ ACL2::LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ ACL2::right-DISTRIBUTIVITY-OF-M-*-OVER-M-+
+ mean-+))))
+ ))
+
+ (defthm gain-minimizes-error
+ (implies (and (integerp k) (<= 0 k))
+ (m-= (result-form-derivative (gain k) (xhatmin k) k)
+ (m-zero (n) (m))))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance lemma-9)
+ (:instance lemma-10)
+ (:instance gain-recdef))
+ :in-theory (disable lemma-9
+ lemma-10
+ lemma-0
+ lemma-1
+ lemma-3
+ lemma-6
+ lemma-7
+ lemma-8
+ gain-recdef
+ xhatmin-recdef
+ acl2::assoc-+
+ acl2::*-+-left
+ acl2::*-+-right
+ acl2::*---left
+ acl2::*---right
+ acl2::assoc-*
+ acl2::comm-+
+ z
+ acl2::trans-*
+ acl2::trans-+
+ acl2::trans---
+ pminus-recdef
+ ;MINUS-AS-PLUS-INVERSE
+ ))))
+ )
+
+(defthm xhatmin=best-prior-almost
+ (implies (m-= (xhat (1- k))
+ (best-estimate-of-x (1- k)))
+ (m-= (xhatmin k)
+ (best-prior-estimate-of-x k)))
+ :hints (("Goal" :do-not-induct t
+ :in-theory (disable xhat z)))
+ :rule-classes nil)
+
+(local
+ (defun natural-induction (k)
+ (if (zp k)
+ 1
+ (1+ (natural-induction (1- k))))))
+
+(defthm result-form-=-xhat
+ (equal (result-form (gain k) (xhatmin k) k)
+ (xhat k)))
+
+(defthm xhat=best-estimate
+ (implies (and (integerp k)
+ (<= 0 k))
+ (m-= (xhat k)
+ (best-estimate-of-x k)))
+ :hints (("Goal"
+ :induct (natural-induction k))
+ ("Subgoal *1/2"
+ :use ((:instance xhatmin=best-prior-almost)
+ (:instance best-estimate-of-x-def
+ (y (gain k))
+ (Xp (xhatmin k)))
+ (:instance gain-minimizes-error))
+ :in-theory (disable xhat))
+ ("Subgoal *1/1"
+ :use ((:instance best-estimate-of-x-def
+ (y (gain 0))
+ (Xp (xhatmin 0))
+ (k 0)))
+ :in-theory (disable gain-recdef
+ (best-prior-estimate-of-x)
+ (xhatmin)
+ (gain)))
+ )
+ :rule-classes nil)
+
+(defthm xhatmin=best-prior
+ (implies (and (integerp k)
+ (<= 0 k))
+ (m-= (xhatmin k)
+ (best-prior-estimate-of-x k)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance xhatmin=best-prior-almost)
+ (:instance xhat=best-estimate (k (1- k))))
+ :in-theory '(best-prior-estimate-of-x zp)))
+ :rule-classes nil)
+
diff --git a/books/workshops/2003/gamboa-cowles-van-baalen/support/linalg.lisp b/books/workshops/2003/gamboa-cowles-van-baalen/support/linalg.lisp
new file mode 100644
index 0000000..a9c648e
--- /dev/null
+++ b/books/workshops/2003/gamboa-cowles-van-baalen/support/linalg.lisp
@@ -0,0 +1,1079 @@
+; The ACL2 Linear Algebra Book.
+; Copyright (C) 2002 Ruben Gamboa and John R. Cowles, University of Wyoming
+
+; This book is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+
+; This book is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+
+; You should have received a copy of the GNU General Public License
+; along with this book; if not, write to the Free Software
+; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+; Written by:
+; Ruben Gamboa and John Cowles
+; Department of Computer Science
+; University of Wyoming
+; Laramie, WY 82071-3682 U.S.A.
+
+; Summer and Fall 2002.
+; Last modified 16 June 2003.
+#|
+ To certify in
+ ACL2 Version 2.8 alpha (as of May 11 03)
+
+(certify-book "linalg"
+ 0
+ nil ;;compile-flg
+ )
+|#
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Date: Mon, 23 Sep 2002 12:22:26 -0600
+From: Ruben Gamboa <ruben@cs.uwyo.edu>
+To: cowles@cs.uwyo.edu
+Subject: linear algebra
+|#
+#|
+~ruben/home/projects/kalman/linalg.lisp
+|#
+#|
+ (ld ;; Newline to fool dependency scanner
+ "defpkg.lsp")
+ (certify-book "linalg" 1)
+|#
+#|
+(in-package "KALMAN")
+|#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+At UW:
+
+:set-cbd "/home/faculty/cowles/acl2/matrix/" ;;pyramid
+
+:set-cbd "/home/cowles/matrix/" ;; turing
+|#
+
+(in-package "ACL2")
+
+#|
+(include-book ;;turing
+ "/home/cowles/acl2-sources/books/arithmetic-2.8/top")
+
+(include-book ;;pyramid
+ "/home/acl2/acl2-2.8/v2-8-alpha-05-11-03/books/arithmetic/top")
+|#
+
+(include-book "../../../../arithmetic/top")
+
+(include-book "../../cowles-gamboa-van-baalen_matrix/support/matalg")
+
+(ADD-BINOP M-+ M-BINARY-+)
+(ADD-MACRO-ALIAS M-- M-UNARY--)
+(ADD-BINOP M-* M-BINARY-*)
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (encapsulate
+;; ((m-matrixp (m n x) t) ;; (matrixp (m n x) t)
+;; (l (x) t) ;; (r (x) t)
+;; (c (x) t)
+;; (m-* (x y) t)
+;; (s-* (k x) t)
+;; (m-+ (x y) t)
+;; (m-- (x y) t) ;; macro for both matrix
+;; (m-unary-- (x) t) ;; unary and binary minus
+;; (m-trans (x) t)
+;; (m-zero (m n) t) ;; (m-0 (m n) t)
+;; (m-id (n) t) ;; (m-1 (n) t)
+;; (m-singular (x) t) ;; (m-singularp (x) t)
+;; (m-inv (x) t)) ;; (m-/ (x) t)
+;; ;; (m-= (M N) t)
+
+;; (local (defun m-matrixp (m n x)
+;; (and (consp x)
+;; (equal (car x) m)
+;; (equal (cadr x) n)
+;; (acl2-numberp (caddr x))
+;; (equal (cdddr x) nil))))
+;; (local (defun l (x) (car x)))
+;; (local (defun c (x) (cadr x)))
+;; (local (defun m-* (x y) (list (car x) (cadr y) (* (caddr x) (caddr y)))))
+;; (local (defun s-* (x y) (list (car y) (cadr y) (* x (caddr y)))))
+;; (local (defun m-+ (x y) (list (car x) (cadr x) (+ (caddr x) (caddr y)))))
+;; (local (defun m-- (x y) (list (car x) (cadr x) (- (caddr x) (caddr y)))))
+;; (local (defun m-unary-- (x) (list (car x) (cadr x) (- (caddr x)))))
+;; (local (defun m-trans (x) (list (cadr x) (car x) (fix (caddr x)))))
+;; (local (defun m-zero (l c) (list l c 0)))
+;; (local (defun m-id (l) (list l l 1)))
+;; (local (defun m-singular (x) (or (not (equal (car x) (cadr x)))
+;; (equal (caddr x) 0))))
+;; (local (defun m-inv (x) (list (car x) (cadr x) (/ (caddr x)))))
+|#
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-p-numrows-cols
+;; (implies (m-matrixp m n p)
+;; (and (equal (l p) m)
+;; (equal (c p) n))))
+|#
+
+(defthm matrix-p-numrows-cols
+ (implies (matrixp m n p)
+ (and (equal (r p) m)
+ (equal (c p) n)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-zero
+;; (m-matrixp m n (m-zero m n)))
+|#
+
+(defabbrev
+ m-dim-p (n)
+ "Determine if n is a legal matrix dimension."
+ (and (integerp n)
+ (> n 0)
+ (<= n *INT-SQRT-MAXIMUM-POSITIVE-32-BIT-INTEGER*)))
+
+(defthm matrix-zero
+ (implies (and (m-dim-p m)
+ (m-dim-p n))
+ (matrixp m n (m-0 m n))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-id
+;; (m-matrixp n n (m-id n)))
+|#
+
+(defthm matrix-id
+ (implies (m-dim-p n)
+ (matrixp n n (m-1 n))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-trans
+;; (implies (and (equal (l p) m)
+;; (equal (c p) n))
+;; (m-matrixp n m (m-trans p))))
+|#
+
+(defthm matrix-trans
+ (implies (matrixp m n P)
+ (matrixp n m (m-trans P))))
+
+(in-theory (disable MATRIXP-M-TRANS))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-inv
+;; (implies (and (equal (l p) n)
+;; (equal (c p) n)
+;; (not (m-singular p)))
+;; (m-matrixp n n (m-inv p))))
+|#
+
+(defthm matrix-inv
+ (implies (and (matrixp (r P)(c P) P)
+ (equal (r P) n)
+ (equal (c P) n))
+ (matrixp n n (m-/ P)))
+ :hints (("Goal"
+ :use (:instance
+ matrixp-m-/
+ (M P)))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-*
+;; (implies (and (equal (l p) m)
+;; (equal (c p) (l q))
+;; (equal (c q) n))
+;; (m-matrixp m n (m-* p q))))
+|#
+
+(defthm matrix-*
+ (implies (and (matrixp m (c P) P)
+ (matrixp (r Q) n Q)
+ (equal (c P)(r Q)))
+ (matrixp m n (m-* P Q))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-s*
+;; (implies (and (equal (l p) m)
+;; (equal (c p) n))
+;; (m-matrixp m n (s-* k p))))
+|#
+
+(defthm matrix-s*
+ (implies (matrixp m n P)
+ (matrixp m n (s-* k p))))
+
+(in-theory (disable MATRIXP-S-*))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-+
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q))
+;; (equal (l p) m)
+;; (equal (c p) n))
+;; (m-matrixp m n (m-+ p q))))
+|#
+
+(defthm matrix-+
+ (implies (and (matrixp m n P)
+ (matrixp m n Q))
+ (matrixp m n (m-+ P Q))))
+
+(in-theory (disable MATRIXP-M-+))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix--
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q))
+;; (equal (l p) m)
+;; (equal (c p) n))
+;; (m-matrixp m n (m-- p q))))
+|#
+
+(defthm matrix--
+ (implies (and (matrixp m n P)
+ (matrixp m n Q))
+ (matrixp m n (m-- P Q))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm matrix-unary--
+;; (implies (and (equal (l p) m)
+;; (equal (c p) n))
+;; (m-matrixp m n (m-unary-- p))))
+|#
+
+(defthm matrix-unary--
+ (implies (matrixp m n P)
+ (matrixp m n (m-- P))))
+
+(in-theory (disable MATRIXP-M-UNARY--))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-zero
+;; (equal (l (m-zero m n)) m))
+|#
+
+(defthm numrows-zero
+ (equal (r (m-0 m n)) m))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-zero
+;; (equal (c (m-zero m n)) n))
+|#
+
+(defthm numcols-zero
+ (equal (c (m-0 m n)) n))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm zero-*-x
+;; (implies (equal (l p) n)
+;; (equal (m-* (m-zero m n) p)
+;; (m-zero m (c p)))))
+|#
+
+(defthm zero-*-x
+ (implies (and (matrixp (r P)(c P) P)
+ (integerp m)
+ (> m 0)
+ (equal (r P) n))
+ (m-= (m-* (m-0 m n) P)
+ (m-0 m (c P))))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm x-*-zero
+;; (implies (equal (c p) m)
+;; (equal (m-* p (m-zero m n))
+;; (m-zero (l p) n))))
+|#
+
+(defthm x-*-zero
+ (implies (and (matrixp (r P)(c P) P)
+ (integerp n)
+ (> n 0)
+ (equal (c P) m))
+ (m-= (m-* P (m-0 m n))
+ (m-0 (r P) n)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm unary---zero
+;; (equal (m-unary-- (m-zero m n))
+;; (m-zero m n)))
+|#
+
+(defthm unary---zero
+ (implies (and (integerp m)
+ (> m 0)
+ (integerp n)
+ (> n 0))
+ (m-= (m-- (m-0 m n))
+ (m-0 m n))))
+
+(in-theory (disable m--_m-0))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm zero-+-x
+;; (implies (and (equal (l p) m)
+;; (equal (c p) n)
+;; (m-matrixp m n p))
+;; (equal (m-+ (m-zero m n) p) p)))
+|#
+
+(defthm zero-+-x
+ (implies (matrixp m n P)
+ (m-= (m-+ (m-0 m n) P) P))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm x-+---x
+;; (equal (m-+ p (m-unary-- p))
+;; (m-zero (l p) (c p))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm x-+---x
+ (implies (matrixp (r P)(c P) P)
+ (m-= (m-+ P (m-- P))
+ (m-0 (r P) (c P))))
+ :hints (("Goal"
+ :in-theory (disable
+ right-m-+-inverse-of-m--)
+ :use (:instance
+ right-m-+-inverse-of-m--
+ (M P)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm -x-+-x
+;; (equal (m-+ (m-unary-- p) p)
+;; (m-zero (l p) (c p))))
+|#
+
+(defthm -x-+-x
+ (implies (matrixp (r P)(c P) P)
+ (m-= (m-+ (m-- P) P)
+ (m-0 (r P) (c P)))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm scalar-*-zero
+;; (equal (s-* k (m-zero m n))
+;; (m-zero m n)))
+|#
+
+(defthm scalar-*-zero
+ (implies (and (integerp m)
+ (> m 0)
+ (integerp n)
+ (> n 0))
+ (m-= (s-* k (m-0 m n))
+ (m-0 m n))))
+
+(in-theory (disable M-=-S-*-M-0))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm zero-trans
+;; (equal (m-trans (m-zero m n))
+;; (m-zero n m)))
+|#
+
+(defthm zero-trans
+ (implies (and (integerp m)
+ (> m 0)
+ (integerp n)
+ (> n 0))
+ (m-= (m-trans (m-0 m n))
+ (m-0 n m))))
+
+(in-theory (disable M-=-M-TRANS-M-0))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-id
+;; (equal (l (m-id n)) n))
+|#
+
+(defthm numrows-id
+ (equal (r (m-1 n)) n))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-id
+;; (equal (c (m-id n)) n))
+|#
+
+(defthm numcols-id
+ (equal (c (m-1 n)) n))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm id-*-x
+;; (implies (m-matrixp n n2 p)
+;; (equal (m-* (m-id n) p) p)))
+|#
+
+(defthm id-*-x
+ (implies (matrixp n n2 P)
+ (m-= (m-* (m-1 n) P) P))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm x-*-id
+;; (implies (m-matrixp m n p)
+;; (equal (m-* p (m-id n)) p)))
+|#
+
+(defthm x-*-id
+ (implies (matrixp m n P)
+ (m-= (m-* P (m-1 n)) P))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm id-trans
+;; (equal (m-trans (m-id n))
+;; (m-id n)))
+|#
+
+(defthm id-trans
+ (implies (and (integerp n)
+ (> n 0))
+ (m-= (m-trans (m-1 n))
+ (m-1 n))))
+
+(in-theory (disable M-=-M-TRANS-M-1))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-*
+;; (implies (equal (c p) (l q))
+;; (equal (l (m-* p q))
+;; (l p))))
+|#
+
+(defthm numrows-*
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (c P) (r Q)))
+ (equal (r (m-* P Q))
+ (r P)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-*
+;; (implies (equal (c p) (l q))
+;; (equal (c (m-* p q))
+;; (c q))))
+|#
+
+(defthm numcols-*
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (c P) (r Q)))
+ (equal (c (m-* P Q))
+ (c Q)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm assoc-*
+;; (implies (and (equal (c p) (l q))
+;; (equal (c q) (l r)))
+;; (equal (m-* (m-* p q) r)
+;; (m-* p (m-* q r)))))
+|#
+
+(defthm assoc-*
+ (implies (and (equal (c p) (r q))
+ (equal (c q) (r r)))
+ (m-= (m-* (m-* P Q) R)
+ (m-* P (m-* Q R))))
+ :rule-classes ((:rewrite
+ :corollary
+ (equal (m-* (m-* P Q) R)
+ (m-* P (m-* Q R))))))
+
+(in-theory (disable ASSOCIATIVITY-OF-M-*))
+
+#|;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-s*
+;; (equal (l (s-* k p))
+;; (l p)))
+|#
+
+(defthm numrows-s*
+ (equal (r (s-* k P))
+ (r P)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-s*
+;; (equal (c (s-* k p))
+;; (c p)))
+|#
+
+(defthm numcols-s*
+ (equal (c (s-* k P))
+ (c p)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm k-*-x-*-y
+;; (implies (equal (c p) (l q))
+;; (equal (m-* (s-* n p) q)
+;; (s-* n (m-* p q)))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm k-*-x-*-y
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (c P) (r Q)))
+ (m-= (m-* (s-* n P) Q)
+ (s-* n (m-* P Q))))
+ :hints (("Goal"
+ :in-theory (disable m-*-s-*-left)
+ :use (:instance
+ m-*-s-*-left
+ (M1 P)
+ (M2 Q)
+ (a n)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm x-*-k-*-y
+;; (implies (equal (c p) (l q))
+;; (equal (m-* p (s-* n q))
+;; (s-* n (m-* p q)))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm x-*-k-*-y
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (c P) (r Q)))
+ (m-= (m-* P (s-* n Q))
+ (s-* n (m-* P Q))))
+ :hints (("Goal"
+ :in-theory (disable m-*-s-*-right)
+ :use (:instance
+ m-*-s-*-right
+ (M1 P)
+ (M2 Q)
+ (a n)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-+
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q)))
+;; (equal (l (m-+ p q))
+;; (l p))))
+|#
+
+(defthm numrows-+
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (r P) (r Q))
+ (equal (c P) (c Q)))
+ (equal (r (m-+ P Q))
+ (r P)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-+
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q)))
+;; (equal (c (m-+ p q))
+;; (c p))))
+|#
+
+(defthm numcols-+
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (r P) (r Q))
+ (equal (c P) (c Q)))
+ (equal (c (m-+ P Q))
+ (c P)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm assoc-+
+;; (implies (and (equal (l p) (l q))
+;; (equal (l q) (l r))
+;; (equal (c p) (c q))
+;; (equal (c q) (c r)))
+;; (equal (m-+ (m-+ p q) r)
+;; (m-+ p (m-+ q r)))))
+|#
+
+(defthm assoc-+
+ (implies (and (equal (r P) (r Q))
+ (equal (r Q) (r R))
+ (equal (c P) (c Q))
+ (equal (c Q) (c R)))
+ (m-= (m-+ (m-+ P Q) R)
+ (m-+ P (m-+ Q R))))
+ :rule-classes ((:rewrite
+ :corollary
+ (equal (m-+ (m-+ P Q) R)
+ (m-+ P (m-+ Q R))))))
+
+(in-theory (disable ASSOCIATIVITY-OF-M-+))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm comm-+
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q)))
+;; (equal (m-+ p q)
+;; (m-+ q p))))
+|#
+
+(defthm comm-+
+ (implies (and (equal (r P) (r Q))
+ (equal (c P) (c Q)))
+ (m-= (m-+ P Q)
+ (m-+ Q P)))
+ :rule-classes ((:rewrite
+ :corollary
+ (equal (m-+ P Q)
+ (m-+ Q P)))))
+
+(in-theory (disable COMMUTATIVITY-OF-M-+))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm x-+-x
+;; (equal (m-+ p p)
+;; (s-* 2 p)))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm x-+-x
+ (implies (matrixp (r P)(c P) P)
+ (m-= (m-+ P P)
+ (s-* 2 P)))
+ :hints (("Goal"
+ :in-theory (disable double-m-+-s-*)
+ :use (:instance
+ double-m-+-s-*
+ (M P)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm k-*-x-+-y
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q)))
+;; (equal (s-* n (m-+ p q))
+;; (m-+ (s-* n p)
+;; (s-* n q)))))
+|#
+
+(defthm k-*-x-+-y
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (r P) (r Q))
+ (equal (c P) (c Q)))
+ (m-= (s-* n (m-+ P Q))
+ (m-+ (s-* n P)
+ (s-* n Q))))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm *-+-right
+;; (implies (and (equal (l q) (l r))
+;; (equal (c q) (c r))
+;; (equal (c p) (l q)))
+;; (equal (m-* p (m-+ q r))
+;; (m-+ (m-* p q)
+;; (m-* p r)))))
+|#
+
+(defthm *-+-right
+ (implies (and (equal (r Q) (r R))
+ (equal (c Q) (c R))
+ (equal (c P) (r Q)))
+ (m-= (m-* P (m-+ Q R))
+ (m-+ (m-* P Q)
+ (m-* P R))))
+ :rule-classes ((:rewrite
+ :corollary
+ (m-= (m-* P (m-+ Q R))
+ (m-+ (m-* P Q)
+ (m-* P R))))))
+
+(in-theory
+ (disable LEFT-DISTRIBUTIVITY-OF-M-*-OVER-M-+))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm *-+-left
+;; (implies (and (equal (l q) (l r))
+;; (equal (c q) (c r))
+;; (equal (c q) (l p)))
+;; (equal (m-* (m-+ q r) p)
+;; (m-+ (m-* q p)
+;; (m-* r p)))))
+|#
+
+(defthm *-+-left
+ (implies (and (equal (r Q) (r R))
+ (equal (c Q) (c R))
+ (equal (c Q) (r P)))
+ (m-= (m-* (m-+ Q R) P)
+ (m-+ (m-* Q P)
+ (m-* R P))))
+ :rule-classes ((:rewrite
+ :corollary
+ (m-= (m-* (m-+ Q R) P)
+ (m-+ (m-* Q P)
+ (m-* R P))))))
+
+(in-theory
+ (disable RIGHT-DISTRIBUTIVITY-OF-M-*-OVER-M-+))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm minus-as-plus-inverse
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q)))
+;; (equal (m-- p q)
+;; (m-+ p (m-unary-- q)))))
+|#
+
+; Matt K., after v4-2:
+; Commenting out the following rule, which rewrites a term to itself!
+; -- Well, instead, given the comment below, I'll just make it not be a rewrite
+; rule.
+(defthm minus-as-plus-inverse
+ (equal (m-- P Q)
+ (m-+ P (m-unary-- Q)))
+ :rule-classes nil)
+
+;; m-- is a macro that expands into the second term of the
+;; above equality. So the equality above expands into a special
+;; case of the reflexivity of equal.
+; Matt K. mod: See comment above for why I'm commenting this out.
+; (in-theory (disable minus-as-plus-inverse))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm k-*---p
+;; (equal (s-* n (m-unary-- p))
+;; (m-unary-- (s-* n p))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm k-*---p
+ (implies (matrixp (r P)(c P) P)
+ (m-= (s-* n (m-- P))
+ (m-- (s-* n P))))
+ :hints (("Goal"
+ :in-theory (disable m-=_s-*_m--)
+ :use (:instance
+ m-=_s-*_m--
+ (M P)
+ (a n)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-unary--
+;; (equal (l (m-unary-- p))
+;; (l p)))
+|#
+
+(defthm numrows-unary--
+ (equal (r (m-- P))
+ (r P)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-unary--
+;; (equal (c (m-unary-- p))
+;; (c p)))
+|#
+
+(defthm numcols-unary--
+ (equal (c (m-- P))
+ (c P)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm unary---unary--
+;; (implies (m-matrixp m n p)
+;; (equal (m-unary-- (m-unary-- p))
+;; p)))
+|#
+
+(defthm unary---unary--
+ (implies (matrixp (r P)(c P) P)
+ (m-= (m-- (m-- P))
+ P))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm unary---+
+;; (equal (m-unary-- (m-+ p q))
+;; (m-+ (m-unary-- p) (m-unary-- q))))
+|#
+
+(defthm unary---+
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (r P)(r Q))
+ (equal (c P)(c Q)))
+ (m-= (m-- (m-+ P Q))
+ (m-+ (m-- P)(m-- Q))))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm *---left
+;; (equal (m-* (m-unary-- p) q)
+;; (m-unary-- (m-* p q))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm *---left
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (c P)(r Q)))
+ (m-= (m-* (m-- P) Q)
+ (m-- (m-* P Q))))
+ :hints (("Goal"
+ :in-theory (disable M-*-M--_LEFT)
+ :use (:instance
+ M-*-M--_LEFT
+ (M1 P)
+ (M2 Q)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm *---right
+;; (equal (m-* p (m-unary-- q))
+;; (m-unary-- (m-* p q))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm *---right
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (c P)(r Q)))
+ (m-= (m-* P (m-- Q))
+ (m-- (m-* P Q))))
+ :hints (("Goal"
+ :in-theory (disable M-*-M--_right)
+ :use (:instance
+ M-*-M--_right
+ (M1 P)
+ (M2 Q)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-trans
+;; (equal (l (m-trans p)) (c p)))
+|#
+
+(defthm numrows-trans
+ (equal (r (m-trans P))(c P)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-trans
+;; (equal (c (m-trans p)) (l p)))
+|#
+
+(defthm numcols-trans
+ (equal (c (m-trans P))(r P)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm trans-*-scalar
+;; (equal (m-trans (s-* n p))
+;; (s-* n (m-trans p))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm trans-*-scalar
+ (implies (matrixp (r P)(c P) P)
+ (m-= (m-trans (s-* n P))
+ (s-* n (m-trans P))))
+ :hints (("Goal"
+ :in-theory (disable M-=-M-TRANS-S-*)
+ :use (:instance
+ M-=-M-TRANS-S-*
+ (s n)
+ (M P)
+ (name '$arg)))))
+
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm trans---
+;; (equal (m-trans (m-unary-- p))
+;; (m-unary-- (m-trans p))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm trans---
+ (implies (matrixp (r P)(c P) P)
+ (m-= (m-trans (m-- P))
+ (m-- (m-trans P))))
+ :hints (("Goal"
+ :in-theory (disable M-=-M-TRANS-M-UNARY--)
+ :use (:instance
+ M-=-M-TRANS-M-UNARY--
+ (M P)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm trans-trans
+;; (implies (m-matrixp m n p)
+;; (equal (m-trans (m-trans p))
+;; p)))
+|#
+
+(defthm trans-trans
+ (implies (matrixp (r P)(c P) P)
+ (m-= (m-trans (m-trans P))
+ P))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm trans-+
+;; (implies (and (equal (l p) (l q))
+;; (equal (c p) (c q)))
+;; (equal (m-trans (m-+ p q))
+;; (m-+ (m-trans p) (m-trans q)))))
+|#
+
+(defthm trans-+
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (r P)(r Q))
+ (equal (c P)(c Q)))
+ (m-= (m-trans (m-+ P Q))
+ (m-+ (m-trans P)(m-trans Q))))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm trans-*
+;; (implies (equal (c p) (l q))
+;; (equal (m-trans (m-* p q))
+;; (m-* (m-trans q) (m-trans p)))))
+|#
+
+(local (in-theory (enable matrixp)))
+
+(defthm trans-*
+ (implies (and (matrixp (r P)(c P) P)
+ (matrixp (r Q)(c Q) Q)
+ (equal (c P)(r Q)))
+ (m-= (m-trans (m-* P Q))
+ (m-* (m-trans Q)(m-trans P))))
+ :hints (("Goal"
+ :in-theory (disable
+ M-TRANS-M-*=M-*-M-TRANS)
+ :use (:instance
+ M-TRANS-M-*=M-*-M-TRANS
+ (M1 P)
+ (M2 Q)
+ (name '$arg)))))
+
+(local (in-theory (disable matrixp)))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numrows-inv
+;; (implies (equal (c p) (l p))
+;; (equal (l (m-inv p)) (l p))))
+|#
+
+(defthm numrows-inv
+ (implies (and (matrixp (r P)(c P) P)
+ (equal (c P) (r P)))
+ (equal (r (m-/ P)) (r P)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm numcols-inv
+;; (implies (equal (c p) (l p))
+;; (equal (c (m-inv p)) (c p))))
+|#
+
+(defthm numcols-inv
+ (implies (and (matrixp (r P)(c P) P)
+ (equal (c P) (r P)))
+ (equal (c (m-/ P)) (c P)))
+ :hints (("Goal"
+ :in-theory (enable matrixp))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm non-singulars-are-square
+;; (implies (not (m-singular p))
+;; (equal (c p) (l p))))
+|#
+
+(defthm non-singulars-are-square
+ (implies (not (m-singularp P))
+ (equal (c P)(r P))))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm inv-*-x
+;; (implies (and (m-matrixp m n p)
+;; (not (m-singular p)))
+;; (equal (m-* (m-inv p) p)
+;; (m-id (l p)))))
+|#
+
+(defthm inv-*-x
+ (implies (not (m-singularp P))
+ (m-= (m-* (m-/ P) P)
+ (m-1 (r P)))))
+
+(in-theory (disable LEFT-M-*-INVERSE-OF-M-/))
+
+#|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; (defthm x-*-inv
+;; (implies (and (m-matrixp m n p)
+;; (not (m-singular p)))
+;; (equal (m-* p (m-inv p))
+;; (m-id (l p)))))
+|#
+
+(defthm x-*-inv
+ (implies (not (m-singularp P))
+ (m-= (m-* P (m-/ P))
+ (m-1 (r P)))))
+
+(in-theory (disable RIGHT-M-*-INVERSE-OF-M-/))
+
+;; )
diff --git a/books/workshops/2003/gamboa-patterson/polymorphism.pdf.gz b/books/workshops/2003/gamboa-patterson/polymorphism.pdf.gz
new file mode 100644
index 0000000..1de82ab
--- /dev/null
+++ b/books/workshops/2003/gamboa-patterson/polymorphism.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa-patterson/polymorphism.ps.gz b/books/workshops/2003/gamboa-patterson/polymorphism.ps.gz
new file mode 100644
index 0000000..17a27e0
--- /dev/null
+++ b/books/workshops/2003/gamboa-patterson/polymorphism.ps.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa-patterson/slides.pdf.gz b/books/workshops/2003/gamboa-patterson/slides.pdf.gz
new file mode 100644
index 0000000..9b6e9ea
--- /dev/null
+++ b/books/workshops/2003/gamboa-patterson/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa_lit-programming/litproofs.pdf.gz b/books/workshops/2003/gamboa_lit-programming/litproofs.pdf.gz
new file mode 100644
index 0000000..b2c03e2
--- /dev/null
+++ b/books/workshops/2003/gamboa_lit-programming/litproofs.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa_lit-programming/litproofs.ps.gz b/books/workshops/2003/gamboa_lit-programming/litproofs.ps.gz
new file mode 100644
index 0000000..30d9530
--- /dev/null
+++ b/books/workshops/2003/gamboa_lit-programming/litproofs.ps.gz
Binary files differ
diff --git a/books/workshops/2003/gamboa_lit-programming/slides.pdf.gz b/books/workshops/2003/gamboa_lit-programming/slides.pdf.gz
new file mode 100644
index 0000000..608dcb1
--- /dev/null
+++ b/books/workshops/2003/gamboa_lit-programming/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/greve-wilding-vanfleet/deps.lisp b/books/workshops/2003/greve-wilding-vanfleet/deps.lisp
new file mode 100644
index 0000000..a7a4dfe
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/deps.lisp
@@ -0,0 +1,8 @@
+;; Silly file to trick cert.pl into including the right books.
+
+(in-package "ACL2")
+
+#||
+; Seems to be needed; see support/make-consistency-test.lisp.
+(include-book "data-structures/set-theory" :dir :system)
+||#
diff --git a/books/workshops/2003/greve-wilding-vanfleet/security-policy.pdf.gz b/books/workshops/2003/greve-wilding-vanfleet/security-policy.pdf.gz
new file mode 100644
index 0000000..216dcb4
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/security-policy.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/greve-wilding-vanfleet/security-policy.ps.gz b/books/workshops/2003/greve-wilding-vanfleet/security-policy.ps.gz
new file mode 100644
index 0000000..c3df955
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/security-policy.ps.gz
Binary files differ
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/.gitignore b/books/workshops/2003/greve-wilding-vanfleet/support/.gitignore
new file mode 100644
index 0000000..3a06756
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/.gitignore
@@ -0,0 +1,3 @@
+make.lisp
+consistency-test.lisp
+consistency-test-passed.lisp
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/Makefile b/books/workshops/2003/greve-wilding-vanfleet/support/Makefile
new file mode 100644
index 0000000..3be5d36
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/Makefile
@@ -0,0 +1,45 @@
+include ../../../../Makefile-generic
+BOOKS = firewallworks
+
+# Avoid provisional certification since we are not using Makefile-deps,
+# which is because there is a generated .lisp file.
+override ACL2_PCERT =
+
+separation.cert: separation.lisp
+
+firewallspec.cert: separation.cert firewallspec.lisp
+
+consistency-test.lisp: separation.lisp firewallspec.lisp firewallworks.lisp make-consistency-test.lisp
+ rm -f make.lisp
+ rm -f consistency-test.lisp
+ echo "(value :q)" > make.lisp
+ echo "(load \"make-consistency-test.lisp\")" >> make.lisp
+ echo "(make-test \"consistency-test.lisp\")" >> make.lisp
+# Deleted by Matt K., May 2006, to avoid STATE warning in CMUCL.
+# echo '(acl2::value :q)' >> make.lisp
+ echo '(acl2::exit-lisp)' >> make.lisp
+ $(ACL2) < make.lisp > consistency.out
+
+## This book will be certified if the axioms are proved consistent
+consistency-test-passed.cert: consistency-test.lisp
+ rm -f make.lisp
+ rm -f consistency-test-passed.lisp
+ rm -f consistency-test-passed.cert
+ echo "(in-package \"ACL2\")" >> consistency-test-passed.lisp
+ echo "(value :q) (lp)" > make.lisp
+ echo "(ld \"consistency-test.lisp\" :ld-error-triples t :ld-error-action :error)" >> make.lisp
+ echo '(acl2::value :q)' >> make.lisp
+ echo '(acl2::exit-lisp)' >> make.lisp
+ $(ACL2) < make.lisp > consistency-test-passed.out
+
+## This book will be certified if the axioms are proved consistent
+compatible.cert: compatible.lisp separation.cert
+
+## Note: this will fail if the consistency-check is not passed, or the compatibility
+## test did not work
+firewallworks.cert: firewallspec.cert firewallworks.lisp consistency-test-passed.cert compatible.cert
+
+newclean:
+ rm -f consistency-test.lisp make.lisp consistency-test-passed.lisp
+
+clean: newclean
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/cert_pl_exclude b/books/workshops/2003/greve-wilding-vanfleet/support/cert_pl_exclude
new file mode 100644
index 0000000..833501d
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/cert_pl_exclude
@@ -0,0 +1,2 @@
+This directory has a custom Makefile, so it is excluded from
+certification based on cert.pl.
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/compatible.acl2 b/books/workshops/2003/greve-wilding-vanfleet/support/compatible.acl2
new file mode 100644
index 0000000..178d743
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/compatible.acl2
@@ -0,0 +1,4 @@
+(value :q)
+(lp)
+(include-book "separation")
+(certify-book "compatible" ? t)
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/compatible.lisp b/books/workshops/2003/greve-wilding-vanfleet/support/compatible.lisp
new file mode 100644
index 0000000..6217937
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/compatible.lisp
@@ -0,0 +1,87 @@
+(in-package "ACL2")
+
+;; This file demonstrates that our notion of separation implies the
+;; "standard" notion presented to us by Vanfleet and derived from
+;; previous work. These separation notions are: infiltration,
+;; exfiltration, and mediation.
+;;
+;; Matt July 2002
+
+;; Requires:
+;; (include-book "separation")
+
+(defthm subsetp-intersection-equal
+ (and
+ (subsetp (intersection-equal a b) a)
+ (subsetp (intersection-equal a b) b)))
+
+(defthm member-selectlist-means
+ (implies
+ (and
+ (equal (selectlist l l1) (selectlist l l2))
+ (member x l))
+ (iff (equal (select x l1) (select x l2)) t))
+ :rule-classes :forward-chaining)
+
+(defthm selectlist-subset
+ (implies
+ (and
+ (equal (selectlist y l1) (selectlist y l2))
+ (subsetp x y))
+ (iff (equal (selectlist x l1) (selectlist x l2)) t)))
+
+(defthm infiltration
+ (implies
+ (and
+ (equal (current st1) (current st2))
+ (equal (selectlist (segs (current st1)) st1)
+ (selectlist (segs (current st2)) st2))
+ (member x (segs (current st1))))
+ (equal (select x (next st1))
+ (select x (next st2))))
+ :hints (("goal" :use (:instance separation (seg x)))))
+
+;; Our initial version of exfiltration was quite strong: the segment
+;; in question was unchanged assuming that the current partition had
+;; no dia segments. This version using these functions would be
+;; something like:
+
+;(defthm exfiltration
+; (implies
+; (not (intersection-equal (dia y) (segs (current st))))
+; (equal (select y (next st))
+; (select y st)))
+; :hints (("goal" :use (:instance separation (seg y)))))
+
+;; Unfortunately, this formulation forecloses the possibility of
+;; free-running counters, interrupt handlers, etc. that change the
+;; state of y in a way not dependant on the current partition. This
+;; kind of behavior ought to be allowed by this formalization, so we
+;; weaken it somewhat.
+
+; Matt K., after v4-2:
+; Commenting out the following rule, which rewrites a term to itself!
+#||
+(defthm exfiltration
+ (implies
+ (and
+ (equal (current st1) (current st2))
+ (not (intersection-equal (dia y) (segs (current st1)))))
+ (equal (select y (next st2))
+ (select y (next st2))))
+ :hints (("goal" :use (:instance separation (seg y)))))
+||#
+
+(defthm mediation
+ (implies
+ (and
+ (equal (current st1) (current st2))
+ (equal (selectlist (segs (current st1)) st1)
+ (selectlist (segs (current st2)) st2))
+ (equal (select x st1) (select x st2)))
+ (equal (select x (next st1)) (select x (next st2))))
+ :hints (("goal" :use (:instance separation (seg x)))))
+
+
+
+
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.acl2 b/books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.acl2
new file mode 100644
index 0000000..e6aab8a
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.acl2
@@ -0,0 +1,4 @@
+(value :q)
+(lp)
+(include-book "separation")
+(certify-book "firewallspec" ? t)
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.lisp b/books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.lisp
new file mode 100644
index 0000000..0dc35f0
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/firewallspec.lisp
@@ -0,0 +1,120 @@
+(in-package "ACL2")
+
+;; Essay on formalizing "black" data.
+
+;; This file introduces some concepts useful in specifying a firewall.
+;; It was not immediately obvious how to formalize the correct
+;; operation of a firewall. What makes it difficult is describing
+;; what it means for data not to contain sensitive information. We
+;; introduce the notion of "black", which is a predicate on a segment
+;; name and a system state. The intended interpretation is that black
+;; segments do not contain sensitive information that requires
+;; protection.
+
+;; Mostly we leave "black" unspecified. However, we assume that it
+;; has the following properties:
+
+;; 1. If all segments in a system are black, then after the system
+;; progresses one step each segment is black. (No "spontaneous
+;; generation".)
+
+;; 2. There exists a function "scrub" that modifies a segment so
+;; that it is black.
+
+;; 3. Elements of system state that are not associated with the
+;; segment are irrelevant in deciding whether a segment is black.
+
+;; Is this approach to modeling reasonable? Assume that each byte of
+;; the system has associated with it a "black" bit that tells whether
+;; the byte is cleared. Any operation that produces data sets the
+;; result's black bit to the "and" of all the input black bits.
+
+;; Axiom one holds, since any operation will set black bits if every
+;; segment in the system has its black bits set. Note that
+;; applications are not modeled at this level, but it is worth
+;; considering whether this framework could model something like a
+;; decryption algorithm. Note that decryption requires keys or
+;; algorithms that would not be considered "black" in this framework,
+;; so this axiom would not be inconsistent with such models.
+
+;; Axiom two holds since one can "scrub" a data segment by zeroizing
+;; all the data and setting the black bits. (Of course, not under
+;; user control.)
+
+;; Axiom three holds since it is straightforward to tell if a segment
+;; is black by checking all its black bits.
+
+(encapsulate
+;; BLACK
+;; input: segment name, machine state
+;; output: boolean indicating whether segment is cleared
+
+ (((black * *) => *)
+
+;; SCRUB
+;; input: segment name, machine state
+;; output machine state in which segment is cleared and other
+;; segments are untouched
+
+ ((scrub * *) => *)
+)
+
+;; A "black" segment contains no sensitive information
+(local (defun black (segname st) (declare (ignore segname) (ignore st)) t))
+
+;; A list of segments is all black
+(defun blacklist (segnames st)
+ (if (consp segnames)
+ (and
+ (black (car segnames) st)
+ (blacklist (cdr segnames) st))
+ t))
+
+;; A segment to be "scrubbed"
+(local (defun scrub (seg st) (declare (ignore seg)) st))
+
+;; A list of segments to be "scrubbed"
+(defun scrublist (segs st)
+ (if (consp segs)
+ (scrublist (cdr segs) (scrub (car segs) st))
+ st))
+
+(defthm scrub-commutative
+ (equal
+ (scrub seg1 (scrub seg2 st))
+ (scrub seg2 (scrub seg1 st))))
+
+(defthm segment-scrub-different
+ (implies (not (equal seg1 seg2))
+ (equal (select seg1 (scrub seg2 st))
+ (select seg1 st))))
+(defthm black-scrub
+ (equal
+ (black seg1 (scrub seg2 st))
+ (or
+ (equal seg1 seg2)
+ (black seg1 st))))
+
+(defthm current-scrub
+ (equal
+ (current (scrub seg st))
+ (current st)))
+
+;; If every segment is black, then after one step an arbitrary segment
+;; is black
+(defthm spontaneous-generation
+ (implies
+ (blacklist (segslist (allparts)) st)
+ (black seg (next st))))
+
+;; Only the contents of a segment determine its blackness
+(defthm black-function-of-segment
+ (implies
+ (equal (select x st1) (select x st2))
+ (equal (black x st1) (black x st2)))
+ :rule-classes nil)
+
+)
+
+
+
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.acl2 b/books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.acl2
new file mode 100644
index 0000000..e977fb1
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.acl2
@@ -0,0 +1,12 @@
+(in-package "ACL2")
+(include-book "firewallspec")
+
+;; [Jared] BOZO wtf...?
+
+(include-book "consistency-test-passed" :uncertified-okp nil)
+:u
+(include-book "compatible" :uncertified-okp nil)
+:u
+
+; cert-flags: ? t :defaxioms-okp t
+(certify-book "firewallworks" ? t :defaxioms-okp t)
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.lisp b/books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.lisp
new file mode 100644
index 0000000..64c7279
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/firewallworks.lisp
@@ -0,0 +1,340 @@
+(in-package "ACL2")
+
+;; (include-book "firewallspec")
+
+;; Firewall works
+
+;; We formalize a particular firewall system and use the separation
+;; axiom to show that it works. We use the notion of "black" data to
+;; describe what is and what is not cleared.
+
+;; We introduce the firewall system using three axioms.
+
+;; Note about the axioms consistency
+;; ---------------------------------
+;; We would like to show that the axioms we've added here are
+;; consistent with the axioms added using encapsulate. Although doing
+;; this does not guarantee that we've axiomitized things properly,
+;; since it's a check on our axioms we'd like to do it.
+;; Unfortunately, there seems to be no way to accomplish this
+;; conveniently using ACL2 2.6.
+
+;; So, we do it manually, using code written to work with a Makefile.
+;; The makefile is arranged so that if these axioms are inconsistent
+;; with the axioms added previously, then an error occurs. We use the
+;; witnesses introduced by the encapsulate, which is not the most
+;; robust way to do this since it requires foresight when introducing
+;; the encapsulates and may limit their use. (Better to have a
+;; mechanism that allows a new witness to be introduced when the
+;; consistency check is being accomplished.)
+
+;; We would of course prefer ACL2 to support doing this, and we have
+;; suggested this to the ACL2 authors and others.
+
+;; b, and f are partitions. Their names are meant to suggest "black"
+;; and "firewall".
+(defaxiom allparts-includes
+ (and
+ (member 'b (allparts))
+ (member 'f (allparts))))
+
+;; When the system is executing partition f, the contents of memory
+;; segment "outbox" does not unblacken
+(defaxiom firewall-blackens
+ (implies
+ (and
+ (equal (current st) 'f)
+ (black 'outbox st))
+ (black 'outbox (next st))))
+
+;; If there is a segment in partition B that is writable from a
+;; segment in a non-B partition, then it is called "outbox" and it is
+;; only writable from segments that are in partition F and not in
+;; partition B.
+(defaxiom dia-setup
+ (implies
+ (and
+ (member seg1 (dia seg2))
+ (member seg2 (segs 'b))
+ (member seg1 (segs p))
+ (not (equal p 'b)))
+ (and
+ (equal seg2 'outbox)
+ (equal p 'f)
+ (not (member seg1 (segs 'b)))))
+ :rule-classes nil)
+
+;; Some of the recursive functions we have introduced were added in
+;; the scope of an encapsulate. ACL2 will not allow us to use their
+;; recursive structure in inductive proofs, because we might have done
+;; something fishy. We now provide ACL2 some recursive functions to
+;; guide its choice of induction schemes on a few of these functions.
+
+(defun scrublist-induct (segs st)
+ (if (consp segs)
+ (scrublist-induct (cdr segs) (scrub (car segs) st))
+ st))
+
+(defthm scrublist-induction-scheme
+ t
+ :rule-classes ((:induction :pattern (scrublist segs st)
+ :scheme (scrublist-induct segs st))))
+
+(defthm blacklist-induction-scheme
+ t
+ :rule-classes ((:induction :pattern (blacklist segs st)
+ :scheme (len segs))))
+
+(defun run-induct (st n)
+ (if (zp n) st (run-induct (next st) (1- n))))
+
+(defthm run-induction-scheme
+ t
+ :rule-classes ((:induction :pattern (run st n)
+ :scheme (run-induct st n))))
+
+;; We introduce some underlying useful theorems about our functions
+
+(defthm remains-black-after-scrublist
+ (implies
+ (black seg st)
+ (black seg (scrublist segs st))))
+
+(defthm black-scrublist
+ (iff
+ (black x (scrublist list st))
+ (or
+ (member x list)
+ (black x st))))
+
+(defthm scrublist-scrub
+ (equal
+ (scrublist list (scrub x st))
+ (scrub x (scrublist list st))))
+
+(defthm blacklist-scrub
+ (implies
+ (blacklist x list)
+ (blacklist x (scrub y list))))
+
+;; Scrubbing the non-black elements yields a system state with all
+;; black elements
+(defthm scrub-nonblack-means-black
+ (implies
+ (blacklist y st)
+ (blacklist x (scrublist (set-difference-equal x y) st))))
+
+; [Removed by Matt K. to handle changes to member, assoc, etc. after ACL2 4.2.]
+; (defthm member-equal-is-member
+; (equal (member-equal a l) (member a l)))
+
+(defthm intersection-equal-dia-b-segs-f-helper
+ (implies
+ (and
+ (member x (segs 'b))
+ (not (equal x 'outbox))
+ (subsetp z (dia x)))
+ (equal (intersection-equal z (segs 'f)) nil))
+ :hints
+ (("Subgoal *1/3'4'" :use (:instance dia-setup (seg1 z1) (seg2 x) (p 'f))))
+ :rule-classes nil)
+
+(defthm subsetp-append
+ (subsetp x (append a x)))
+
+(defthm subsetp-x-x
+ (subsetp x x)
+ :hints (("goal" :use (:instance subsetp-append (a nil))
+ :in-theory (disable subsetp-append))))
+
+(defthm intersection-equal-dia-b-segs-f
+ (implies
+ (and
+ (member x (segs 'b))
+ (not (equal x 'outbox)))
+ (equal (intersection-equal (dia x) (segs 'f)) nil))
+ :hints (("goal" :use (:instance intersection-equal-dia-b-segs-f-helper
+ (z (dia x))))))
+
+(defthm select-scrublist
+ (implies
+ (not (member a l))
+ (equal (select a (scrublist l st))
+ (select a st))))
+
+(defthm current-scrublist
+ (equal
+ (current (scrublist segs st))
+ (current st)))
+
+(defthm selectlist-scrublist
+ (implies
+ (equal (intersection-equal x y) nil)
+ (equal
+ (selectlist x (scrublist y st))
+ (selectlist x st))))
+
+(defthm member-set-difference-equal
+ (iff
+ (member e (set-difference-equal l1 l2))
+ (and
+ (member e l1)
+ (not (member e l2)))))
+
+(defthm intersection-equal-set-difference
+ (equal
+ (intersection-equal
+ (intersection-equal a b)
+ (set-difference-equal c b))
+ nil))
+
+;; We will prove that the firewall works by casesplitting on which
+;; partition is the current partition. For each of the cases we use
+;; the separation axiom to posit a state that is "equivalent" to the
+;; actual state with respect to an arbitrary memory segment of b. The
+;; following rule helps that proof along by using a free variable
+;; match of the equivalent state.
+
+(defthm black-from-equivalent-allblack
+ (implies
+ (and
+ (equal (select seg (next st)) (select seg (next st2)))
+ (blacklist (segslist (allparts)) st2))
+ (black seg (next st)))
+ :hints (("goal" :use (:instance black-function-of-segment
+ (st1 (next st))
+ (st2 (next st2))
+ (x seg)))))
+
+;; Now, each of the cases. The current partition is either b, f, or
+;; some other partition, and we prove a lemma about each case
+
+;(defthm firewall-step-kernel
+; (implies (and (subsetp segs (segs 'b))
+; (blacklist segs st)
+; (equal (current st) (kernel-name)))
+; (blacklist segs (next st)))
+; :hints (("Subgoal *1/3'" :use
+; (:instance separation (seg (car segs))
+; (st1 st)
+; (st2 (scrublist (set-difference-equal
+; (segslist (allparts))
+; segs)
+; st))))))
+
+(defthm firewall-step-firewall-helper
+ (implies (and (subsetp segs (segs 'b))
+ (blacklist segs st)
+ (equal (current st) 'f))
+ (blacklist segs (next st)))
+ :hints (("Subgoal *1/3'" :cases ((equal (car segs) 'outbox)))
+ ("Subgoal *1/3.2" :use
+ (:instance separation (seg (car segs))
+ (st1 st)
+ (st2 (scrublist (set-difference-equal
+ (segslist (allparts))
+ segs)
+ st))))))
+
+(defthm firewall-step-firewall
+ (implies (and (blacklist (segs 'b) st)
+ (equal (current st) 'f))
+ (blacklist (segs 'b) (next st)))
+ :hints (("goal" :use (:instance firewall-step-firewall-helper
+ (segs (segs 'b))))))
+
+
+(defthm firewall-step-black-helper
+ (implies (and (blacklist (segs 'b) st)
+ (equal (current st) 'b)
+ (subsetp segs (segs 'b)))
+ (blacklist segs (next st)))
+ :hints (("Subgoal *1/2'" :use
+ (:instance separation (seg (car segs))
+ (st1 st)
+ (st2 (scrublist (set-difference-equal
+ (segslist (allparts))
+ (segs 'b))
+ st))))))
+
+(defthm firewall-step-black
+ (implies (and (blacklist (segs 'b) st)
+ (equal (current st) 'b))
+ (blacklist (segs 'b) (next st)))
+ :hints (("goal" :use (:instance firewall-step-black-helper
+ (segs (segs 'b))))))
+
+(defthm intersection-equal-segs-b-segs-other-helper
+ (implies
+ (and
+ (not (equal other 'b))
+ (not (equal other 'f))
+; (not (equal other (kernel-name)))
+ (member x (segs 'b))
+ (member other (allparts))
+ (subsetp z (dia x)))
+ (equal (intersection-equal z (segs other)) nil))
+ :hints (("Subgoal *1/3''"
+ :use (:instance dia-setup (seg2 x) (seg1 (car z))
+ (p other)
+ ;; (p2 other) obsolete
+ )))
+ :rule-classes nil)
+
+(defthm intersection-equal-segs-b-segs-other
+ (implies
+ (and
+ (not (equal other 'b))
+ (not (equal other 'f))
+; (not (equal other (kernel-name)))
+ (member x (segs 'b))
+ (member other (allparts)))
+ (equal (intersection-equal (dia x) (segs other)) nil))
+ :hints (("goal" :use
+ (:instance intersection-equal-segs-b-segs-other-helper
+ (z (dia x))))))
+
+(defthm firewall-step-other-helper
+ (implies (and (blacklist (segs 'b) st)
+; (not (equal (current st) (kernel-name)))
+ (not (equal (current st) 'f))
+ (not (equal (current st) 'b))
+ (member (current st) (allparts))
+ (subsetp segs (segs 'b)))
+ (blacklist segs (next st)))
+ :hints (("Subgoal *1/2'" :use
+ (:instance separation (seg (car segs))
+ (st1 st)
+ (st2 (scrublist (set-difference-equal
+ (segslist (allparts))
+ (segs 'b))
+ st))))))
+(defthm firewall-step-other
+ (implies (and (blacklist (segs 'b) st)
+; (not (equal (current st) (kernel-name)))
+ (not (equal (current st) 'f))
+ (not (equal (current st) 'b))
+ (member (current st) (allparts)))
+ (blacklist (segs 'b) (next st)))
+ :hints (("goal" :use (:instance firewall-step-other-helper
+ (segs (segs 'b))))))
+
+
+;; We combine the sublemmas about a single step into a single lemma
+;; about a single step
+(defthm firewall-step
+ (implies
+ (blacklist (segs 'b) st)
+ (blacklist (segs 'b) (next st)))
+ :hints (("goal" :use ( ;firewall-step-kernel
+ firewall-step-black
+ firewall-step-firewall
+ firewall-step-other))))
+
+;;
+;; The firewall system works: Data in partition b is always black
+;;
+(defthm firewall-works
+ (implies
+ (blacklist (segs 'b) st)
+ (blacklist (segs 'b) (run st n))))
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/make-consistency-test.lisp b/books/workshops/2003/greve-wilding-vanfleet/support/make-consistency-test.lisp
new file mode 100644
index 0000000..0fbc2a5
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/make-consistency-test.lisp
@@ -0,0 +1,47 @@
+
+
+;; This code sets up a file that tests whether the axioms of the file
+;; firewallworks.lisp are consistent with the axioms introduced in the
+;; encapsulates of the files separation.lisp and firewallspec.lisp.
+
+;; It would be better if ACL2 provided this capability directly, but
+;; with some sneaky coding we arrange things so that ACL2 checks that
+;; the axioms are consistent.
+
+(defun read-forms (ifile)
+ (let ((form (read ifile nil nil)))
+ (and
+ form
+ (cons form (read-forms ifile)))))
+
+(defun read-all-forms (file)
+ (with-open-file
+ (ifile file :direction :input)
+ (read-forms ifile)))
+
+;; The forms we need to execute in the consistency test
+(defun test-forms ()
+ `(
+ (include-book "../../../../data-structures/set-theory")
+ (ld "separation.lisp")
+ (puff :x)
+ (ld "firewallspec.lisp")
+ (puff :x)
+
+ ;; load all the axioms from the file, changing the axioms to defthms
+ ,@(remove nil
+ (mapcar
+ #'(lambda (x)
+ (if (equal (car x) 'defaxiom)
+ `(defthm ,@(cdr x))
+ nil))
+ (read-all-forms "firewallworks.lisp")))
+ (ubt! 1)
+ (certify-book "consistency-test-passed")))
+
+(defun make-test (file)
+ (with-open-file
+ (ofile file :direction :output)
+ (mapcar #'(lambda (x) (format ofile "~%~S" x)) (test-forms))))
+
+
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/separation.acl2 b/books/workshops/2003/greve-wilding-vanfleet/support/separation.acl2
new file mode 100644
index 0000000..863bcdf
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/separation.acl2
@@ -0,0 +1,4 @@
+(value :q)
+(lp)
+(include-book "../../../../data-structures/set-theory")
+(certify-book "separation" ? t)
diff --git a/books/workshops/2003/greve-wilding-vanfleet/support/separation.lisp b/books/workshops/2003/greve-wilding-vanfleet/support/separation.lisp
new file mode 100644
index 0000000..bff2596
--- /dev/null
+++ b/books/workshops/2003/greve-wilding-vanfleet/support/separation.lisp
@@ -0,0 +1,118 @@
+(in-package "ACL2")
+
+;; Requires set-theory book
+;; (include-book "/accts/dagreve/local/src/acl2-2.6/gcl/books/data-structures/set-theory")
+
+(encapsulate
+
+;; DIA
+;; input: memory segment
+;; output: list of memory segments from which direct interaction
+;; is allowed
+ (((dia *) => *)
+
+;; CURRENT
+;; input: machine state
+;; output: name of current partition
+ ((current *) => *)
+
+;; ALLPARTS
+;; input: none
+;; output: list of partition names
+ ((allparts) => *)
+
+;; KERNEL-NAME
+;; input: none
+;; output: name of kernel partition
+;; ((kernel-name) => *)
+
+;; SELECT
+;; input: memory segment name, machine state
+;; output: memory segment values associated segment name
+ ((select * *) => *)
+
+;; NEXT
+;; input: machine state
+;; output: machine state after one step
+ ((next *) => *)
+
+;; SEGS
+;; input: partition name
+;; output: list of memory segment names associated with partition
+ ((segs *) => *)
+
+ )
+
+;; direct interation allowed: list of segments that can communicate
+;; directly with seg
+(local (defun dia (seg) (list seg)))
+
+; (local (defun kernel-name () 'k))
+
+;; current partition name of st
+(local (defun current (st) (declare (ignore st)) 'b))
+
+;; list of partition names in st
+(local (defun allparts () '(b f)))
+
+(defthm current-is-partition
+ (member (current st) (allparts)))
+
+;(defthm kernel-is-partition
+; (member (kernel-name) (allparts)))
+
+;; Select a segment from state
+(local (defun select (seg st) (declare (ignore seg st)) nil))
+
+;; Select a list of segments given a list of segment names
+(defun selectlist (segs st)
+ (if (consp segs)
+ (cons
+ (select (car segs) st)
+ (selectlist (cdr segs) st))
+ nil))
+
+(local (defun next (st) st))
+
+(defun run (st n)
+ (if (zp n)
+ st
+ (run (next st) (1- n))))
+
+;; The segments associated with a partition name
+(local (defun segs (partname) (declare (ignore partname)) nil))
+
+;; The segments associated with a list of partition names
+(defun segslist (partnamelist)
+ (if (consp partnamelist)
+ (append
+ (segs (car partnamelist))
+ (segslist (cdr partnamelist)))
+ nil))
+
+;; Correctness of underlying separation system
+(defthm separation
+ (let ((segs (intersection-equal (dia seg) (segs (current st1)))))
+ (implies
+ (and
+ (equal (selectlist segs st1) (selectlist segs st2))
+ (equal (current st1) (current st2))
+ (equal (select seg st1) (select seg st2)))
+ (equal
+ (select seg (next st1))
+ (select seg (next st2))))))
+
+;;; The "kernel" partition is the partition switch code. It is special
+;;; in several ways. Part of the specification of its correctness is
+;;; that it does not change the state of any of the other partitions.
+
+;(defthm kernel-touches-nothing
+; (implies
+; (and
+; (member seg (segs p))
+; (not (equal p (kernel-name))))
+; (equal
+; (intersection-equal (dia seg) (segs (kernel-name)))
+; nil)))
+
+)
diff --git a/books/workshops/2003/greve-wilding_defrecord/defrecord.pdf.gz b/books/workshops/2003/greve-wilding_defrecord/defrecord.pdf.gz
new file mode 100644
index 0000000..08cf99d
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_defrecord/defrecord.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/greve-wilding_defrecord/defrecord.ps.gz b/books/workshops/2003/greve-wilding_defrecord/defrecord.ps.gz
new file mode 100644
index 0000000..cc030a4
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_defrecord/defrecord.ps.gz
Binary files differ
diff --git a/books/workshops/2003/greve-wilding_defrecord/support/defrecord.lisp b/books/workshops/2003/greve-wilding_defrecord/support/defrecord.lisp
new file mode 100644
index 0000000..39d4d92
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_defrecord/support/defrecord.lisp
@@ -0,0 +1,245 @@
+#|
+
+Typed records in ACL2
+
+This file contains an enhancement to the ACL2 standard "records" book.
+We introduce the macro "defrecord" to define an accessor and updater
+function for a record structure with elements of a particular type.
+This facility extends somewhat the hypothesis-less theorems of the
+standard ACL2 "records" book. Besides providing a convenient way to
+introduce multiple record structures, this macro adds a theorem to the
+theorems provided by that book: namely, that the accessor function
+returns values of the right "type".
+
+For example,
+
+ (include-book ;; defeat dependency checker
+ "XXX/books/misc/records")
+
+ (defun sbp16 (x)
+ (declare (xargs :guard t))
+ (and
+ (integerp x)
+ (<= (- (expt 2 15)) x)
+ (< x (expt 2 15))))
+
+ (defun fix-sbp16 (x)
+ (declare (xargs :guard t))
+ (if (sbp16 x) x 0))
+
+ (defrecord sbp :rd getbv :wr putbv :fix fix-sbp16 :typep sbp16)
+
+The "raw" record structure introduced in the standard records book is
+used to define records defined using defrecord, and the functions for
+accessing and updating a record that are introduced by defrecord are
+proved to have many of the same properties as the records in the
+standard records book. In particular, assume that the record
+introduced by defrecord has operations (g a r) and (s a v r) that get
+and set elements of record r for address a and value v. We prove the
+following lemmas, each of which also holds of "raw" records:
+
+(defthm g-same-s
+ (equal (g a (s a v r))
+ v))
+
+(defthm g-diff-s
+ (implies (not (equal a b))
+ (equal (g a (s b v r))
+ (g a r))))
+
+(defthm s-same-g
+ (equal (s a (g a r) r)
+ r))
+
+(defthm s-same-s
+ (equal (s a y (s a x r))
+ (s a y r)))
+
+(defthm s-diff-s
+ (implies (not (equal a b))
+ (equal (s b y (s a x r))
+ (s a x (s b y r))))
+ :rule-classes ((:rewrite :loop-stopper ((b a s)))))
+
+In addition, the defrecord macro proves one additional lemma that is
+not provable about raw records:
+
+(defthm typep-g
+ (typep (g a r)))
+
+for a typep predicate provided by the user.
+
+What makes this implementation of records interesting is that it has
+the peculiar property that each of the lemmas has no "type"
+hypotheses. This makes reasoning about operations considerably
+easier, but the implementation of the record operations is obscure, to
+say the least. We are interested in providing an implementation to
+show that the theorems listed above are consistent.
+
+(Historical Note: Matt Kaufmann of AMD proposed a challenge problem to
+the ACL2 list in March, 2000 to define a "get" and "set" function
+without hypotheses, based on a request of Rob Sumner's. Kaufmann
+released his version, which uses a bizarre record implementation to
+avoid the type hypotheses. (We posted our independantly-derived
+solution to the challenge to the ACL2 list in Mar 2000, which uses a
+strikingly similar approach. Is there basically only one way to
+implement these functions?) An improved version that exploits the
+total order of ACL2 objects was developed by Kaufmann and Sumners and
+presented at the 2002 ACL2 workshop, and this book is incorporated
+into the standard ACL2 books. In 2002 we realized that we needed data
+element type information - for example, that a memory returns only
+bit-vectors - and wanted to continue to avoid unnecessary hypotheses.
+This led us to create this enhancement.)
+
+David Greve and Matt Wilding
+November 2002
+
+|#
+
+(in-package "ACL2")
+
+(include-book "../../../../misc/records")
+
+(defthm equal-s-record-equality
+ (implies
+ (and
+ (equal rec2 rec1)
+ (equal v (g a rec1)))
+ (and (iff (equal rec1 (s a v rec2)) t)
+ (iff (equal (s a v rec2) rec1) t))))
+
+(defun symbol-list-to-string (list)
+ (declare (type (satisfies symbol-listp) list))
+ (if (consp list)
+ (concatenate 'string (symbol-name (car list)) (symbol-list-to-string (cdr list)))
+ ""))
+
+(defmacro join-symbols (witness &rest rst)
+ `(intern-in-package-of-symbol (symbol-list-to-string (list ,@rst)) ,witness))
+
+(defmacro defrecord (name &key (rd 'nil) (wr 'nil) (fix 'ifix) (default '0) (typep 'integerp))
+
+ (let* ((base name)
+ (rd (if (null rd) (join-symbols name name '-rd) rd))
+ (wr (if (null wr) (join-symbols name name '-wr) wr))
+ (wf (join-symbols name 'wf- typep))
+ (zp (join-symbols name typep '-zp))
+ (wf-forward (join-symbols name wf '-forward))
+ )
+
+ `(encapsulate
+ ()
+
+ (defun ,zp (x)
+ (declare (type t x))
+ (equal (,fix x) ,default))
+
+ (defun ,wf (x)
+ (declare (type t x))
+ (and (consp x)
+ (,typep (car x))
+ (not (,zp (car x)))
+ (not (,wf (cdr x)))))
+
+ (in-theory (disable (,zp) (,wf)))
+
+ (defthm ,wf-forward
+ (implies (,wf x)
+ (and (consp x)
+ (,typep (car x))
+ (not (,zp (car x)))
+ (not (,wf (cdr x)))))
+ :rule-classes (:forward-chaining))
+
+ (defun ,wr (a v m)
+ (declare (type t a v m))
+ (let ((x (g a m)))
+ (if (,wf x)
+ (if (,zp v)
+ (s a (cdr x) m)
+ (s a (cons (,fix v) (cdr x)) m))
+ (if (,zp v) m
+ (s a (cons (,fix v) x) m)))))
+
+ (defun ,rd (a m)
+ (declare (type t a m))
+ (let ((x (g a m)))
+ (if (,wf x) (car x)
+ ,default)))
+
+
+ (defthm ,(join-symbols base rd '-same- wr '-hyps)
+ (implies (equal a b)
+ (equal (,rd a (,wr b v r))
+ (,fix v))))
+
+ (defthm ,(join-symbols base rd '-diff- wr '-hyps)
+ (implies (not (equal a b))
+ (equal (,rd a (,wr b v r))
+ (,rd a r))))
+
+ (defthm ,(join-symbols base wr '-same- rd '-hyps)
+ (implies (equal a b)
+ (equal (,wr a (,rd b r) r)
+ r)))
+
+ (defthm ,(join-symbols base wr '-diff- wr '-hyps)
+ (implies (not (equal a b))
+ (equal (,wr b y (,wr a x r))
+ (,wr a x (,wr b y r))))
+ :rule-classes ((:rewrite :loop-stopper ((b a ,wr)))))
+
+ (defthm ,(join-symbols base wr '-same- wr '-hyps)
+ (implies (equal a b)
+ (equal (,wr a y (,wr b x r))
+ (,wr a y r))))
+
+ (defthm ,(join-symbols base rd '-of- wr '-redux)
+ (equal (,rd a (,wr b v r))
+ (if (equal b a) (,fix v)
+ (,rd a r)))
+ :hints (("goal" :in-theory (disable ,fix ,rd ,wr))))
+
+ (defthm ,(join-symbols base wr '-same- rd)
+ (equal (,wr a (,rd a r) r)
+ r))
+
+ (defthm ,(join-symbols base wr '-same- wr)
+ (equal (,wr a y (,wr a x r))
+ (,wr a y r)))
+
+ (defthm ,(join-symbols base typep '- rd)
+ (and (,typep (,rd a r))
+ (equal (,fix (,rd a r))
+ (,rd a r))))
+
+ (defun ,(join-symbols base wr '==r-hyp) (v a r)
+ (declare (type t v a r))
+ (equal (,fix v) (,rd a r)))
+
+ (defthm ,(join-symbols base wr '==r)
+ (implies
+ (and
+ (,(join-symbols base wr '==r-hyp) v a r1)
+ (equal r2 r1))
+ (and (iff (equal r1 (,wr a v r2)) t)
+ (iff (equal (,wr a v r2) r1) t))))
+
+ (defun ,(join-symbols base wr '== wr '-hyp) (v1 v2)
+ (declare (type t v1 v2))
+ (equal (,fix v1) (,fix v2)))
+
+ (in-theory (disable (,(join-symbols base wr '== wr '-hyp))))
+
+ (defthm ,(join-symbols base wr '== wr)
+ (implies
+ (and
+ (equal a1 a2)
+ (,(join-symbols base wr '== wr '-hyp) v1 v2)
+ (equal r2 r1))
+ (iff (equal (,wr a1 v1 r1) (,wr a2 v2 r2)) t)))
+
+ (in-theory (disable ,(join-symbols base rd '-of- wr '-redux)
+ ,rd ,wr))
+
+ )))
diff --git a/books/workshops/2003/greve-wilding_mbe/mbe.pdf.gz b/books/workshops/2003/greve-wilding_mbe/mbe.pdf.gz
new file mode 100644
index 0000000..a96a335
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_mbe/mbe.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/greve-wilding_mbe/mbe.ps.gz b/books/workshops/2003/greve-wilding_mbe/mbe.ps.gz
new file mode 100644
index 0000000..68b8859
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_mbe/mbe.ps.gz
Binary files differ
diff --git a/books/workshops/2003/greve-wilding_mbe/support/README b/books/workshops/2003/greve-wilding_mbe/support/README
new file mode 100644
index 0000000..e6d128b
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_mbe/support/README
@@ -0,0 +1,23 @@
+These files contain an optimized version of a program that searches
+for a path in a graph. It is the subject of 2 ACL2 workshop papers,
+one in 2000 by Matt Wilding and one in 2003 by David Greve and Matt
+Wilding, that describe using ACL2 features to build fast and
+verifiable software.
+
+A makefile creates books from two files
+
+ fpst.lisp - definition of the optimized pathfinder and proof that
+ it is equivalent to previously distributed version
+
+ run-fpst.lisp - definitions that provide for benchmarking the
+ pathfinder
+
+Currently-unreleased ACL2 2.8 builds these books in about 2 minutes.
+
+This proof relies upon books developed by J Moore that are freely
+available and documented in the chapter "An Exercise in Graph Theory"
+in the book "Computer-Aided Reasoning: ACL2 Case Studies".
+
+David Greve
+Matt Wilding
+June 2003 \ No newline at end of file
diff --git a/books/workshops/2003/greve-wilding_mbe/support/fpst.lisp b/books/workshops/2003/greve-wilding_mbe/support/fpst.lisp
new file mode 100644
index 0000000..5fd4a8f
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_mbe/support/fpst.lisp
@@ -0,0 +1,905 @@
+(in-package "ACL2")
+
+#|
+
+A Verified Pathfinder
+---------------------
+
+These files contain an optimized version of a program that searches
+for a path in a graph. It is the subject of 2 ACL2 workshop papers,
+one in 2000 by Matt Wilding and one in 2003 by David Greve and Matt
+Wilding, that describe using ACL2 features to build fast and
+verifiable versions of these programs.
+
+The initial version of this file introduced a stobj representing the
+state that was proved equal to a (proved) pathfinding implementation
+of J Moore's, and is documented in the 2000 paper. Subsequently, the
+proof was updated to work with the publically-released version of
+Moore's proof distributed with the ACL2 book chapter in which Moore
+wrote about this example. An issue identified and discussed at length
+in Wilding's 2000 paper is the need to add complexity to some programs
+in order to prove termination. In ACL2, sometimes this complexity
+would not be necessary if there were some way to ensure that the
+guards to the function would be met. Wilding required an axiom in his
+2000 example to prove that the fastest possible implementation of the
+otherwise-proved program was correct. The axiom was justified with an
+informal argument, but its use highlighted a weakness in ACL2.
+
+In 2003, Matt Kaufmann asked us to try out an experimental feature of
+ACL2, MBE (which stands for "must be equal"). This feature allows the
+introduction of executable versions of functions that can be justified
+by appeal to their guards. This led us to reimplement the pathfinding
+program and associated proof yet again to demonstrate how this fast
+implementation can now be proved correct with no assumptions.
+
+This book certifies in experimental ACL2 2.8 in about 2 minutes. See
+the companion file "run-fpst.lisp" for functions that support the
+running the pathfinding program.
+
+Matt Wilding and David Greve
+February 2003
+
+
+Some original documentation for this program:
+
+xx Stobj-Based Linear Find Path
+xx
+xx Matt Wilding
+xx July 1999
+
+xx J Moore developed an example in 1998 of a linear path search. He
+xx wrote the example of in some detail, and it is a wonderful example
+xx of doing a small software proof using ACL2. Subsequently, inspired
+xx he writes in large part by our executable formal model work, J
+xx added stobjs to ACL2.
+xx
+xx This file contains a linear path search program written in ACL2
+xx that uses stobjs for data structures. My goal in doing this is to
+xx use stobjs in a context besides microprocessor models to explore
+xx how practical this mechanism is for writing efficient, analyzable
+xx code. DSH suggested doing something softwarish with stobj last
+xx January.
+xx
+xx We implement a pathfinding algorithm that employs stobjs. It runs
+xx fast and is proved correct. Given a graph with numbered nodes and
+xx edges, the program finds a path between two nodes if possible.
+xx
+xx For example, for a graph with nodes
+xx
+xx 0 (with edges to 1 and 2),
+xx 1 (with no edges),
+xx 2 (with edges to each of the nodes), and
+xx 3 (with an edge to 1)
+xx
+xx the program finds a path between nodes 0 and 3:
+xx
+xx ACL2 !>(assign g '((0 1 2) (1) (2 0 1 2 3) (3 1)))
+xx ((0 1 2) (1) (2 0 1 2 3) (3 1))
+xx ACL2 !>(linear-find-st 0 3 (@ g) st)
+xx ((0 2 3) <st>)
+xx
+xx J Moore proved a similar program correct in 1999. He documented
+xx his example in a chapter titled "An Exercise in Graph Theory" in
+xx the book "Using the ACL2 Theorem Prover: ACL2 Case Studies",
+xx published by Kluwer in 2000. It is an interesting example of a
+xx multiply-recursive program that has been proved correct using ACL2.
+
+xx Matt Wilding reimplemented Moore's program using stobjs to
+xx represent the state of the computation. This optimization avoided
+xx datastructure accesses that were not linear time operations. ACL2
+xx was used to verify that the optimized version calculates the same
+xx path as the previously-verified version in Moore's paper. This
+xx example is documented in "Using a Single-Threaded Object to Speed a
+xx Verified Graph Pathfinder" presented to the 2nd ACL2 Workshop in
+xx 2000.
+
+|#
+
+; This example assumes J Moore's linear-find-path proof.
+(include-book "../../../1999/graph/linear-find-path")
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+(set-verify-guards-eagerness 2)
+
+;; We introduce a version of J's lfns that does not do the irrelevant
+;; check. The irrelevancy of the subset check is something J points
+;; out in the comments of his example, and he proves the neccessary
+;; lemmas, but he doesn't bother to fix it. We go ahead and get it
+;; out of the way so it doesn't complicate our later proofs
+
+(defthm linear-find-next-step-simpler
+ (equal
+ (linear-find-next-step c stack b g mt)
+ (cond
+ ((endp c) (mv 'failure mt))
+ ((markedp (car c) mt)
+ (linear-find-next-step (cdr c) stack b g mt))
+ ((equal (car c) b)
+ (mv (rev (cons b stack))
+ mt))
+ (t (mv-let (temp new-mt)
+ (linear-find-next-step (neighbors (car c) g)
+ (cons (car c) stack)
+ b g
+ (mark (car c) mt))
+ (cond
+ ((eq temp 'failure)
+ (linear-find-next-step (cdr c) stack b g new-mt))
+ (t (mv temp mt)))))))
+ :rule-classes :definition)
+
+(in-theory (disable linear-find-next-step))
+
+;; We introduce a stobj that has many of the datastructures we need to
+;; write our version of this program. There are two operations that
+;; we particularly want to optimize: detecting whether a node has been
+;; marked, and finding the neighbors of a node. We implement the
+;; datastuctures that are involved in these operations, the graph and
+;; the mark list, using stobj arrays. We also add to the stobj a status
+;; bit to indicate failure and success so as to avoid using mv-let.
+
+;; Note that the stack is handled somewhat less efficiently because of
+;; its constant-time operations. We could speed things further by
+;; implementing the stack as something other than a list to avoid gc.
+
+;; maximum number of nodes in the graph
+(defmacro maxnode () '2500)
+
+;;
+(defstobj st
+ (g :type (array list (2500)) :initially nil) ; list of edges
+ (marks :type (array (integer 0 1) (2500)) :initially 0) ; visited?
+ (stack :type (satisfies true-listp)) ; path
+ (status :type (integer 0 1) :initially 0)) ; 0 = success, 1 = failure
+
+;; indicies into datastructure
+(defmacro gindex () 0)
+(defmacro marksindex () 1)
+(defmacro stackindex () 2)
+(defmacro statusindex () 3)
+
+;; Some miscellaneous rules that will be useful about st
+
+(defthm <=-cancel
+ (equal
+ (<= a (+ y b))
+ (<= (- a y) b))
+ :rule-classes nil)
+
+(defthm <-cancel
+ (implies
+ (syntaxp (quotep y))
+ (equal
+ (< (+ y b) a)
+ (< b (+ (- a y)))))
+ :hints (("goal" :use <=-cancel)))
+
+(defmacro bounded-natp (a max)
+ `(and (integerp ,a) (<= 0 ,a) (< ,a ,max)))
+
+(defthm integerp-nth-marksp
+ (implies
+ (and
+ (marksp l)
+ (integerp i)
+ (<= 0 i)
+ (< i (len l)))
+ (acl2-numberp (nth i l))))
+
+;; We introduce the notion of the number of unmarked nodes in the
+;; graph, which will be used as a measure function to prove
+;; termination of our algorithm.
+
+(defun number-unmarked1 (st i)
+ (declare (xargs :stobjs st
+ :guard (and (stp st) (bounded-natp i (1+ (maxnode))))
+ :measure (max 0 (nfix (- (maxnode) i)))))
+ (if (and (integerp i) (< i (maxnode)))
+ (if (= (marksi i st) 1)
+ (number-unmarked1 st (1+ i))
+ (1+ (number-unmarked1 st (1+ i))))
+ 0))
+
+(defun number-unmarked (st)
+ (declare (xargs :stobjs st
+ :guard (stp st)))
+ (number-unmarked1 st 0))
+
+;; Some facts about number-unmarked
+
+(defthm number-unmarked1-update-nth-other
+ (implies
+ (not (equal j (marksindex)))
+ (equal
+ (number-unmarked1 (update-nth j v st) i)
+ (number-unmarked1 st i))))
+
+(defthm number-unmarked1-above
+ (implies
+ (and
+ (< i k)
+ (bounded-natp i (maxnode)))
+ (equal
+ (number-unmarked1 (list nil (update-nth i 1 l)) k)
+ (number-unmarked1 (list nil l) k))))
+
+(defthm number-unmarked1-marked
+ (implies
+ (and
+ (<= k i)
+ (bounded-natp i (maxnode))
+ (bounded-natp k (maxnode)))
+ (equal
+ (number-unmarked1 (list nil (update-nth i 1 l)) k)
+ (if (equal (nth i l) 1)
+ (number-unmarked1 (list nil l) k)
+ (1- (number-unmarked1 (list nil l) k))))))
+
+(defthm number-unmarked1-hack
+ (equal
+ (number-unmarked1 st k)
+ (number-unmarked1 (list nil (nth (marksindex) st)) k))
+ :rule-classes nil)
+
+(defthm number-unmarked1-update-nth-1-update-nth
+ (implies
+ (and
+ (<= k i)
+ (bounded-natp i (maxnode))
+ (bounded-natp k (maxnode)))
+ (equal
+ (number-unmarked1 (update-nth (marksindex) (update-nth i 1 (nth (marksindex) st)) st) k)
+ (if (equal (nth i (nth (marksindex) st)) 1)
+ (number-unmarked1 st k)
+ (1- (number-unmarked1 st k)))))
+ :hints (("goal"
+ :use ((:instance number-unmarked1-hack
+ (st (update-nth (marksindex) (update-nth i 1 (nth (marksindex) st)) st)))
+ number-unmarked1-hack))))
+
+(defun measure-st (c st)
+ (declare (xargs :stobjs st
+ :guard (stp st)))
+ (cons
+ (1+ (number-unmarked st))
+ (len c)))
+
+(defun numberlistp (l max)
+ (declare (xargs :guard (integerp max)))
+ (if (consp l)
+ (and
+ (bounded-natp (car l) max)
+ (numberlistp (cdr l) max))
+ (equal l nil)))
+
+(defthm true-listp-numberlistp
+ (implies
+ (numberlistp l n)
+ (true-listp l)))
+
+;; A graph is an alist with nodes as keys and edge lists as values
+(defun graphp1-st (st i)
+ (declare (xargs :stobjs st
+ :measure (max 0 (nfix (- (maxnode) i)))))
+ (if (and (bounded-natp i (maxnode)) (stp st))
+ (and
+ (numberlistp (gi i st) (maxnode))
+ (graphp1-st st (1+ i)))
+ t))
+
+(defun graphp-st (st)
+ (declare (xargs :stobjs st))
+ (and
+ (stp st)
+ (graphp1-st st 0)))
+
+;; We want to use a reverse function. We might use "rev", but no
+;; guard is proved for it. Since we don't want to modify anything
+;; outside this proof, we add our own.
+
+(defun myrev (x)
+ (declare (xargs :guard (true-listp x)))
+ (if (endp x)
+ nil
+ (append (myrev (cdr x)) (list (car x)))))
+
+(defthm true-listp-myrev
+ (true-listp (myrev l)))
+
+(defthm true-listp-update-nth-rewrite
+ (implies
+ (true-listp l)
+ (true-listp (update-nth i v l))))
+
+(defun repeat (n v)
+ (if (and (integerp n) (< 0 n)) (cons v (repeat (1- n) v)) nil))
+
+(defthm len-repeat
+ (equal (len (repeat n v)) (nfix n)))
+
+(defthm nlistp-update-nth
+ (implies
+ (not (consp l))
+ (equal (update-nth i v l) (append (repeat i nil) (list v)))))
+
+(defmacro coerce-node (x)
+ `(let ((nx (nfix ,x))) (if (<= (maxnode) nx) 0 nx)))
+
+(in-theory (disable update-nth nth))
+
+(in-theory (disable number-unmarked1))
+
+#|
+;; Comment from the July, 1999 version of this proof:
+
+xx ;; Finally, the stobj-based algorithm.
+
+xx ;This is a good example of when we wish we could use the guards in
+xx ;the logic. The st argument is guarded with graphp-st, which
+xx ;potentially provides us with an important fact needed for the
+xx ;termination proof: when marking a previously-unmarked node, we are
+xx ;in fact in the mark array's range. However, guards are not usable
+xx ;in a proof about the logic, so we are left to our own devices.
+xx ;The most obvious thing to do is to guard the body of the function
+xx ;by adding (graphp-st st) to it, but this is obviously very
+xx ;inefficient. My solution is to coerce the pointer to be in range
+xx ;before its use: it'll slow down execution a bit, but during proof
+xx ;with the assumption of correct type it'll be quickly simplified
+xx ;away.
+
+xx ;This problem would be eliminated by the addition of defbody to
+xx ;ACL2, as J and Matt have talked about doing.
+
+xx ;; Just as J in his example, we first introduce a version that has
+xx ;; an irrelevant check in it that eases the measure proof. After
+xx ;; proving that the check is in fact irrelevant, we add the
+xx ;; "real" definition.
+
+xx ;; c is the list of neighbors being explored, b is the goal node
+
+|#
+
+;; Feb 2003 - We have updated this function to exploit MBE, an
+;; experimental feature that is expected to be part of ACL2 2.8. The
+;; executable version omits the guards needed to prove termination.
+;; When we prove the guards of this function, we will be obliged to
+;; prove that, assuming the function arguments meet the assumed
+;; guards, the two versions are identical.
+
+(defun linear-find-next-step-st-mbe (c b st)
+ (declare (xargs :stobjs st
+ :measure (measure-st c st)
+ :guard (and (graphp-st st)
+ (bounded-natp b (maxnode))
+ (numberlistp c (maxnode)))
+ :verify-guards nil))
+ (mbe
+ :logic
+ (if (endp c) st
+ (let ((cur (coerce-node (car c)))
+ (temp (number-unmarked st)))
+ (cond
+ ((equal (marksi cur st) 1)
+ (linear-find-next-step-st-mbe (cdr c) b st))
+ ((equal cur b)
+ (let ((st (update-status 0 st)))
+ (update-stack (myrev (cons (car c) (stack st))) st)))
+ (t (let ((st (update-marksi cur 1 st)))
+ (let ((st (update-stack (cons (car c) (stack st)) st)))
+ (let ((st (linear-find-next-step-st-mbe (gi cur st) b st)))
+ (if (or (<= temp (number-unmarked st)) ; always nil
+ (equal (status st) 0))
+ st
+ (let ((st (update-stack (cdr (stack st)) st)))
+ (linear-find-next-step-st-mbe (cdr c) b st))))))))))
+ :exec
+ (if (endp c) st
+ (cond
+ ((equal (marksi (car c) st) 1)
+ (linear-find-next-step-st-mbe (cdr c) b st))
+ ((equal (car c) b)
+ (let ((st (update-status 0 st)))
+ (update-stack (myrev (cons b (stack st))) st)))
+ (t (let ((st (update-marksi (car c) 1 st)))
+ (let ((st (update-stack (cons (car c) (stack st)) st)))
+ (let ((st (linear-find-next-step-st-mbe (gi (car c) st) b st)))
+ (if (equal (status st) 0)
+ st
+ (let ((st (update-stack (cdr (stack st)) st)))
+ (linear-find-next-step-st-mbe (cdr c) b st)))))))))))
+
+;; We prove a bunch of lemmas needed for the guard proof of lfns-st
+
+(defthm true-listp-linear-find-next-step-st-mbe
+ (implies
+ (true-listp st)
+ (true-listp (linear-find-next-step-st-mbe c b st))))
+
+(defthm number-unmarked-positive
+ (<= 0 (number-unmarked st))
+ :rule-classes :linear)
+
+(in-theory (disable number-unmarked))
+
+(defthm marksp-append
+ (implies
+ (true-listp x)
+ (equal
+ (marksp (append x y))
+ (and (marksp x) (marksp y)))))
+
+(defthm marksp-repeat
+ (equal
+ (marksp (repeat n x))
+ (or
+ (zp n)
+ (bounded-natp x 2))))
+
+(defthm marksp1-update-nth
+ (implies
+ (and
+ (integerp v) (<= 0 v) (<= v 1)
+ (<= i (len l))
+ (marksp l))
+ (marksp (update-nth i v l)))
+ :hints (("goal" :in-theory (enable update-nth))))
+
+(defthm nth-0-linear-find-next-step-st-mbe
+ (equal
+ (nth (gindex) (linear-find-next-step-st-mbe c b st))
+ (nth (gindex) st)))
+
+(defthm marksp1-linear-find-next-step-st-mbe
+ (implies
+ (and
+ (marksp (nth (marksindex) st))
+ (equal (len (nth (marksindex) st)) (maxnode)))
+ (and
+ (marksp (nth (marksindex) (linear-find-next-step-st-mbe c b st)))
+ (equal (len (nth (marksindex) (linear-find-next-step-st-mbe c b st)))
+ (maxnode)))))
+
+(in-theory (disable len true-listp graphp1-st))
+
+(defthm true-listp-cdr
+ (implies
+ (true-listp l)
+ (true-listp (cdr l))))
+
+(defthm true-listp-stack
+ (implies
+ (true-listp (nth (stackindex) st))
+ (true-listp (nth (stackindex) (linear-find-next-step-st-mbe c b st)))))
+
+(defthm integerp-status
+ (implies
+ (integerp (nth (statusindex) st))
+ (integerp (nth (statusindex) (linear-find-next-step-st-mbe c b st)))))
+
+(defthm status-linear1
+ (implies
+ (<= 0 (nth (statusindex) st))
+ (<= 0 (nth (statusindex) (linear-find-next-step-st-mbe c b st))))
+ :rule-classes (:linear :rewrite))
+
+(defthm status-linear2
+ (implies
+ (not (< 1 (nth (statusindex) st)))
+ (not (< 1 (nth (statusindex) (linear-find-next-step-st-mbe c b st)))))
+ :rule-classes (:linear :rewrite))
+
+(defthm len-linear-find-next-step-st-mbe
+ (implies
+ (equal (len st) 4)
+ (equal (len (linear-find-next-step-st-mbe c b st)) 4)))
+
+(defthm stp-linear-find-next-step-st-mbe
+ (implies
+ (stp st)
+ (stp (linear-find-next-step-st-mbe c b st))))
+
+(defthm stp-update-nth
+ (implies
+ (stp st)
+ (and
+ (equal (stp (update-nth (gindex) v st))
+ (and
+ (gp v)
+ (equal (len v) (maxnode))))
+ (equal (stp (update-nth (marksindex) v st))
+ (and
+ (marksp v)
+ (equal (len v) (maxnode))))
+ (equal (stp (update-nth (stackindex) v st))
+ (stackp v))
+ (equal (stp (update-nth (statusindex) v st))
+ (statusp v)))))
+
+(defthm neighbors-graphp-st
+ (implies
+ (and
+ (graphp1-st st i)
+ (<= i j)
+ (< j (maxnode))
+ (bounded-natp i (maxnode))
+ (bounded-natp j (maxnode))
+ (stp st))
+ (numberlistp (nth j (nth (gindex) st)) (maxnode)))
+ :hints (("goal" :in-theory (enable graphp1-st))))
+
+(defthm graphp1-st-update-nth-other
+ (implies
+ (and
+ (graphp1-st st i)
+ (stp st)
+ (not (equal j 0))
+ (bounded-natp j 5))
+ (graphp1-st (update-nth j marks st) i))
+ :hints (("goal" :in-theory (enable graphp1-st))))
+
+(defthm graphp-st-update-nth-other
+ (implies
+ (and
+ (graphp-st st)
+ (stp st)
+ (not (equal j 0))
+ (bounded-natp j 5))
+ (equal
+ (graphp-st (update-nth j marks st))
+ (stp (update-nth j marks st))))
+ :hints (("goal" :in-theory (enable graphp-st))))
+
+(defthm graphp1-st-linear-find-next-step-st-mbe
+ (implies
+ (and
+ (graphp1-st st i)
+ (stp st))
+ (graphp1-st (linear-find-next-step-st-mbe c b st) i)))
+
+(defthm graphp-st-linear-find-next-step-st-mbe
+ (implies
+ (graphp-st st)
+ (graphp-st (linear-find-next-step-st-mbe c b st))))
+
+(defthm consp-of-truelistp
+ (implies
+ (true-listp l)
+ (iff (consp l) l)))
+
+(defthm len-append
+ (equal (len (append x y)) (+ (len x) (len y)))
+ :hints (("goal" :in-theory (enable len))))
+
+(defthm len-myrev
+ (equal (len (myrev x)) (len x))
+ :hints (("goal" :in-theory (enable len))))
+
+(defthm len-stack
+ (<= (len (nth (stackindex) st))
+ (len (nth (stackindex) (linear-find-next-step-st-mbe c b st))))
+ :hints (("Subgoal *1/3.1" :expand (LINEAR-FIND-NEXT-STEP-ST-MBE C 0 ST))
+ ("goal" :in-theory (enable len))))
+
+(defthm len-linear
+ (<= 0 (len l))
+ :rule-classes :linear
+ :hints (("goal" :in-theory (enable len))))
+
+(defthm len-bound-hack
+ (equal
+ (< 0 (len l))
+ (not (equal (len l) 0))))
+
+(defthm equal-len-0
+ (equal
+ (equal (len l) 0)
+ (not (consp l)))
+ :hints (("goal" :in-theory (enable len))))
+
+(defthm stack-hack
+ (implies
+ (and
+ (nth (stackindex) st)
+ (true-listp (nth (stackindex) st)))
+ (nth (stackindex) (linear-find-next-step-st-mbe c b st)))
+ :hints (("goal" :use len-stack
+ :in-theory (set-difference-theories (enable len)
+ '(len-stack)))))
+(defthm linear-unmarked-not-increased
+ (>= (number-unmarked1 st 0)
+ (number-unmarked1 (linear-find-next-step-st-mbe c b st) 0))
+ :rule-classes :linear)
+
+;; The simpler version of the algorithm is equivalent to the one we
+;; just proved.
+
+(defthm linear-find-next-step-st-mbe-simpler
+ (implies
+ (and
+ (graphp-st st)
+ (bounded-natp b (maxnode))
+ (numberlistp c (maxnode)))
+ (equal
+ (linear-find-next-step-st-mbe c b st)
+ (if (endp c) st
+ (cond
+ ((equal (marksi (car c) st) 1)
+ (linear-find-next-step-st-mbe (cdr c) b st))
+ ((equal (car c) b)
+ (let ((st (update-status 0 st)))
+ (update-stack (myrev (cons b (stack st))) st)))
+ (t (let ((st (update-marksi (car c) 1 st)))
+ (let ((st (update-stack (cons (car c) (stack st)) st)))
+ (let ((st (linear-find-next-step-st-mbe (gi (car c) st) b st)))
+ (if (equal (status st) 0)
+ st
+ (let ((st (update-stack (cdr (stack st)) st)))
+ (linear-find-next-step-st-mbe (cdr c) b st)))))))))))
+ :hints (("goal" :in-theory (enable number-unmarked)))
+ :rule-classes nil)
+
+;; We verify the guards of our program, which includes an obligation
+;; to show that the unguarded executable version is identical to the
+;; logical version of the definition body.
+(verify-guards linear-find-next-step-st-mbe
+ :hints (("goal" :use linear-find-next-step-st-mbe-simpler)))
+
+
+;; Now we prove that our stobj representation and J's alist
+;; representation are equivalence. "equivalent" means...
+
+(defun graph-equivp1 (alist st i)
+ (declare (xargs :measure (max 0 (- (maxnode) (nfix i)))
+ :verify-guards nil
+ :stobjs st))
+ (if (< (nfix i) (maxnode))
+ (and
+ (equal (neighbors i alist) (gi i st))
+ (graph-equivp1 alist st (1+ (nfix i))))
+ t))
+
+(defun graph-equivp (alist st)
+ (declare (xargs :verify-guards nil
+ :stobjs st))
+ (graph-equivp1 alist st 0))
+
+(defun mark-equivp1 (list st i)
+ (declare (xargs :measure (max 0 (- (maxnode) (nfix i)))
+ :verify-guards nil
+ :stobjs st))
+ (if (< (nfix i) (maxnode))
+ (and
+ (iff (member i list) (equal (marksi i st) 1))
+ (mark-equivp1 list st (1+ (nfix i))))
+ t))
+
+(defun mark-equivp (list st)
+ (declare (xargs :verify-guards nil
+ :stobjs st))
+ (mark-equivp1 list st 0))
+
+(defun equiv (stack g mt st)
+ (declare (xargs :stobjs st
+ :verify-guards nil))
+ (and
+ (equal stack (stack st))
+ (graph-equivp g st)
+ (mark-equivp mt st)))
+
+(in-theory (disable graph-equivp mark-equivp))
+
+(defthm stack-of-failed-search
+ (implies
+ (not (equal (nth (statusindex) (linear-find-next-step-st-mbe c b st)) 0))
+ (equal (nth (stackindex) (linear-find-next-step-st-mbe c b st)) (stack st)))
+ :hints (("goal" :in-theory (enable number-unmarked))))
+
+(defthm graph-equivp1-update-nth-other
+ (implies
+ (not (zp i))
+ (equal (graph-equivp1 g (update-nth i v st) j)
+ (graph-equivp1 g st j))))
+
+(defthm graph-equivp-update-nth-other
+ (implies
+ (not (zp i))
+ (equal (graph-equivp g (update-nth i v st))
+ (graph-equivp g st)))
+ :hints (("goal" :in-theory (enable graph-equivp))))
+
+(defthm graph-equivp-linear-find-next-step-st-mbe
+ (equal (graph-equivp g (linear-find-next-step-st-mbe c b st))
+ (graph-equivp g st))
+ :hints (("goal" :in-theory (enable linear-find-next-step-st-mbe))))
+
+(defthm mark-equivp1-update-nth-other
+ (implies
+ (not (equal i (marksindex)))
+ (equal (mark-equivp1 g (update-nth i v st) j)
+ (mark-equivp1 g st j))))
+
+(defthm mark-equivp-update-nth-other
+ (implies
+ (not (equal i (marksindex)))
+ (equal (mark-equivp g (update-nth i v st))
+ (mark-equivp g st)))
+ :hints (("goal" :in-theory (enable mark-equivp))))
+
+(set-irrelevant-formals-ok :warn)
+
+;; We need to show ACL2 how to induct on the merged definitions
+;; This is pretty tricky due to the multiply recursive nature of
+;; the program.
+
+; Because a recursive call of lfns contains a value that is a function
+; of another recursive call, the inductive schema definition appears
+; in the proof obligations that get generated. We've arranged for the
+; schema definition to compute exactly what the stobj version does so
+; that the induction we use is the right one.
+
+(defun induct-equiv (c b st stack g mt)
+ (declare (xargs :stobjs st
+ :measure (measure-st c st)
+ :guard (and (graphp-st st)
+ (bounded-natp b (maxnode))
+ (numberlistp c (maxnode)))
+ :verify-guards nil
+ :hints (("goal" :in-theory (enable number-unmarked len)))))
+ (if (endp c) st
+ (let ((cur (coerce-node (car c)))
+ (temp (number-unmarked st))) ; note for "irrelevant" check
+ (cond
+ ((equal (marksi cur st) 1)
+ (induct-equiv (cdr c) b st stack g mt))
+ ((equal cur b)
+ (let ((st (update-status 0 st)))
+ (update-stack (myrev (cons (car c) (stack st))) st)))
+ (t (let ((st (update-marksi cur 1 st)))
+ (let ((st (update-stack (cons (car c) (stack st)) st)))
+ (let ((st (induct-equiv (gi cur st) b st (cons (car c) stack)
+ g (cons (car c) mt))))
+ (if (or (<= temp (number-unmarked st)) ; always nil
+ (equal (status st) 0))
+ st
+ (let ((st (update-stack (cdr (stack st)) st)))
+ (mv-let (temp2 new-mt)
+ (linear-find-next-step (neighbors (car c) g)
+ (cons (car c) stack)
+ b g
+ (mark (car c) mt))
+ (declare (ignore temp2))
+ (induct-equiv (cdr c) b st stack g new-mt))))))))))))
+
+(defthm induct-equiv-is-lfns-st
+ (equal
+ (induct-equiv c b st stack g mt)
+ (linear-find-next-step-st-mbe c b st))
+ :hints (("goal" :induct (induct-equiv c b st stack g mt)
+ :in-theory (set-difference-theories
+ (enable induct-equiv linear-find-next-step-st-mbe number-unmarked)
+ '(FIND-NEXT-STEP-AVOIDING-CONS
+ STEP1 REV binary-append step2)))))
+
+(defthm nth-mark-equivp1
+ (implies
+ (and
+ (mark-equivp1 mt st i)
+ (bounded-natp i (maxnode))
+ (bounded-natp j (maxnode))
+ (<= i j))
+ (iff
+ (equal (nth j (nth (marksindex) st)) 1)
+ (member j mt))))
+
+(defthm nth-mark-equivp
+ (implies
+ (and
+ (mark-equivp mt st)
+ (bounded-natp j (maxnode)))
+ (iff
+ (equal (nth j (nth (marksindex) st)) 1)
+ (member j mt)))
+ :hints (("goal" :in-theory (set-difference-theories (enable mark-equivp)
+ '(mark-equivp1)))))
+(defthm mark-equivp1-above1
+ (implies
+ (and
+ (< i j)
+ (integerp i)
+ (integerp j))
+ (equal
+ (mark-equivp1 (cons i mt) st j)
+ (mark-equivp1 mt st j))))
+
+(defthm mark-equivp1-above2
+ (implies
+ (and
+ (< i j)
+ (bounded-natp i (maxnode))
+ (integerp j))
+ (equal
+ (mark-equivp1 mt (update-nth (marksindex) (update-nth i 1 (nth (marksindex) st)) st) j)
+ (mark-equivp1 mt st j))))
+
+(defthm mark-equivp1-add
+ (implies
+ (and
+ (mark-equivp1 mt st j)
+ (<= j i)
+ (bounded-natp j (maxnode))
+ (integerp i))
+ (mark-equivp1 (cons i mt) (update-nth (marksindex) (update-nth i 1 (nth (marksindex) st)) st) j))
+ :hints (("goal" :expand
+ (:free (x)
+ (mark-equivp1 (cons x mt)
+ (update-nth (marksindex) (update-nth x 1 (nth (marksindex) st))
+ st)
+ x)))))
+
+(defthm mark-equivp-add
+ (implies
+ (and
+ (mark-equivp mt st)
+ (integerp i)
+ (<= 0 i))
+ (mark-equivp (cons i mt) (update-nth (marksindex) (update-nth i 1 (nth (marksindex) st)) st)))
+ :hints (("goal" :in-theory (set-difference-theories (enable mark-equivp)
+ '(mark-equivp1)))))
+(defthm nth-graph-equivp1
+ (implies
+ (and
+ (graph-equivp1 g st i)
+ (bounded-natp i (maxnode))
+ (bounded-natp j (maxnode))
+ (<= i j))
+ (equal
+ (neighbors j g)
+ (gi j st))))
+
+(defthm nth-graph-equivp
+ (implies
+ (and
+ (graph-equivp g st)
+ (bounded-natp j (maxnode)))
+ (equal
+ (neighbors j g)
+ (gi j st)))
+ :hints (("goal" :in-theory (enable graph-equivp))))
+
+(defthm graphp-st-means-stp
+ (implies
+ (graphp-st st)
+ (stp st))
+ :rule-classes :forward-chaining)
+
+(defthm true-listp-cons
+ (equal
+ (true-listp (cons a b))
+ (true-listp b))
+ :hints (("goal" :in-theory (enable true-listp))))
+
+(defthm myrev-is-rev
+ (equal (myrev x) (rev x)))
+
+;;; The stobj implementation of lfp works just like the original
+;;; list-based one.
+
+(defthm implementations-same
+ (implies
+ (and
+ (equiv stack g mt st)
+ (graphp-st st)
+ (not (equal (status st) 0))
+ (numberlistp c (maxnode))
+ (numberlistp stack (maxnode))
+ (bounded-natp b (maxnode)))
+ (let ((st (linear-find-next-step-st-mbe c b st)))
+ (mv-let (temp marks) (linear-find-next-step c stack b g mt)
+ (or
+ (and (not (equal (status st) 0)) (equal temp 'failure) (mark-equivp marks st))
+ (and (equal (status st) 0) (not (equal temp 'failure)) (equal temp (stack st)))))))
+ :hints (("goal" :in-theory (enable linear-find-next-step-st-mbe linear-find-next-step
+ number-unmarked)
+ :induct (induct-equiv c b st stack g mt)))
+ :rule-classes nil)
diff --git a/books/workshops/2003/greve-wilding_mbe/support/run-fpst.lisp b/books/workshops/2003/greve-wilding_mbe/support/run-fpst.lisp
new file mode 100644
index 0000000..a009c8b
--- /dev/null
+++ b/books/workshops/2003/greve-wilding_mbe/support/run-fpst.lisp
@@ -0,0 +1,425 @@
+(in-package "ACL2")
+
+#|
+
+We introduce functions for loading the datastructure of the
+stobj-based pathfinding program and prove that the loading and
+calculating of this optimized program works just like the original
+implementation.
+
+See also "fpst.lisp".
+
+Matt Wilding and David Greve
+Updated February, 2003
+
+|#
+
+;; Assumes the "find path - stobj" program is loaded
+(include-book "fpst")
+
+(set-verify-guards-eagerness 2)
+
+;; We want to prove the guards of the functions we need from J's
+;; proof. However, some of the functions are not guard-provable
+;; because the guards weren't in place. In this case, we add a
+;; function with the same body and the needed guards, and use that
+;; instead.
+
+(defun myall-nodes (g)
+ (declare (xargs :guard (alistp g)))
+ (cond ((endp g) nil)
+ (t (cons (car (car g))
+ (myall-nodes (cdr g))))))
+
+(defthm myall-nodes-is-all-nodes
+ (equal
+ (myall-nodes g)
+ (all-nodes g)))
+
+; mygraph1p is just like J's graph1p, except that the node and the
+; children are in-range naturals.
+(defun mygraph1p (g nodes)
+ (declare (xargs :guard (and (true-listp nodes) (alistp g))))
+ (cond ((endp g) t)
+ (t (and (consp (car g))
+ (true-listp (cdr (car g)))
+ (numberlistp (car g) (maxnode)) ; needed for stobj version
+ (subsetp (cdr (car g)) nodes)
+ (no-duplicatesp (cdr (car g)))
+ (mygraph1p (cdr g) nodes)))))
+
+(defthm mygraph1p-is-graph1p
+ (implies
+ (mygraph1p g nodes)
+ (graph1p g nodes)))
+
+(defun mygraphp (g)
+ (declare (xargs :guard (alistp g)))
+ (and (alistp g)
+ (eqlable-listp (myall-nodes g))
+ (no-duplicatesp (myall-nodes g))
+ (mygraph1p g (myall-nodes g))))
+
+(defthm mygraphp-is-graphp
+ (implies
+ (mygraphp g)
+ (graphp g)))
+
+(defun myneighbors (node g)
+ (declare (xargs :guard (alistp g)))
+ (cond ((endp g) nil)
+ ((equal node (car (car g)))
+ (cdr (car g)))
+ (t (myneighbors node (cdr g)))))
+
+(defthm myneighbors-is-neighbors
+ (equal
+ (myneighbors n g)
+ (neighbors n g)))
+
+(defthm consp-neighbors
+ (implies
+ (mygraph1p g l)
+ (iff
+ (consp (neighbors i g))
+ (neighbors i g))))
+
+(defthm gp-update-nth
+ (implies
+ (and
+ (gp g)
+ (listp v)
+ (bounded-natp i max))
+ (gp (update-nth i v g)))
+ :hints (("goal" :in-theory (enable update-nth))))
+
+
+;; Now, some functions that allow us to load the stobj with
+;; values in the datastructures used by J's implementation.
+
+(defun load-graph1 (g i st)
+ (declare (xargs :stobjs st
+ :guard (and (stp st) (alistp g)
+ (bounded-natp i (1+ (maxnode)))
+ (mygraphp g))
+ :measure (max 0 (nfix (- (maxnode) i)))))
+ (if (or (not (integerp i)) (not (< i (maxnode))))
+ st
+ (let
+ ((st (update-gi i (myneighbors i g) st)))
+ (load-graph1 g (1+ i) st))))
+
+(defun load-graph (g st)
+ (declare (xargs :stobjs st
+ :guard (and (stp st) (alistp g) (mygraphp g))))
+ (load-graph1 g 0 st))
+
+(defun init-marks1 (i st)
+ (declare (xargs :stobjs st
+ :guard (and (stp st) (bounded-natp i (1+ (maxnode))))
+ :measure (max 0 (nfix (- (maxnode) i)))))
+ (if (or (not (integerp i)) (not (< i (maxnode))))
+ st
+ (let
+ ((st (update-marksi i 0 st)))
+ (init-marks1 (1+ i) st))))
+
+;; Some rules about our loading functions
+(defthm stp-load-graph1
+ (implies
+ (and
+ (stp st)
+ (mygraphp g)
+ (integerp i)
+ (<= 0 i))
+ (stp (load-graph1 g i st))))
+
+(defthm stp-init-marks1
+ (implies
+ (and
+ (stp st)
+ (integerp i)
+ (<= 0 i))
+ (stp (init-marks1 i st))))
+
+(defthm nth-init-marks1-other
+ (implies
+ (not (equal i (marksindex)))
+ (equal (nth i (init-marks1 j st))
+ (nth i st))))
+
+(defun init-marks (st)
+ (declare (xargs :stobjs st :guard (stp st)))
+ (init-marks1 0 st))
+
+(defun load-st (g st)
+ (declare (xargs :stobjs st
+ :guard (and (stp st) (alistp g) (mygraphp g))))
+ (let ((st (load-graph g st)))
+ (let ((st (init-marks st)))
+ (let ((st (update-status 1 st)))
+ (let ((st (update-stack nil st)))
+ st)))))
+
+(defthm graph-equivp-only-on-g
+ (implies
+ (equal (nth (gindex) st1) (nth (gindex) st2))
+ (equal
+ (graph-equivp1 g st1 i)
+ (graph-equivp1 g st2 i)))
+ :rule-classes nil)
+
+(defthm graph-equivp1-init-marks
+ (equal
+ (graph-equivp1 g (init-marks1 i st) i)
+ (graph-equivp1 g st i))
+ :hints (("goal" :use (:instance graph-equivp-only-on-g
+ (st1 (init-marks1 i st)) (st2 st)))))
+(defthm graphp1-equal-graphs
+ (implies
+ (and
+ (equal (nth (gindex) st1) (nth (gindex) st2))
+ (stp st1)
+ (stp st2))
+ (iff
+ (graphp1-st st1 i)
+ (graphp1-st st2 i)))
+ :hints (("goal" :in-theory (enable graphp1-st)))
+ :rule-classes nil)
+
+(defthm graphp1-st-lesser
+ (implies
+ (and
+ (graphp1-st st i)
+ (bounded-natp i j))
+ (graphp1-st st j))
+ :hints (("goal" :in-theory (enable graphp1-st))))
+
+(defthm graphp1-st-init-marks
+ (implies
+ (and
+ (stp st)
+ (integerp i)
+ (<= 0 i))
+ (equal
+ (graphp1-st (init-marks1 i st) i)
+ (graphp1-st st i)))
+ :hints (("goal" :use (:instance graphp1-equal-graphs
+ (st1 (init-marks1 i st)) (st2 st))
+ :in-theory (disable stp))))
+
+(defthm nth-0-load-graph1-above
+ (implies
+ (and
+ (bounded-natp i j)
+ (integerp j))
+ (equal
+ (nth i (nth (gindex) (load-graph1 g j st)))
+ (nth i (nth (gindex) st)))))
+
+(defthm graph-equivp1-load-graph1
+ (implies
+ (bounded-natp i (maxnode))
+ (graph-equivp1 g (load-graph1 g i st) i))
+ :hints (("Subgoal *1/3'" :expand (:free (x) (LOAD-GRAPH1 G x ST)))
+ ("Subgoal *1/3''" :expand (:free (x n) (GRAPH-EQUIVP1 G x n)))))
+
+(defthm nth-1-init-marks-above
+ (implies
+ (and
+ (bounded-natp i j)
+ (integerp j))
+ (equal
+ (nth i (nth (marksindex) (init-marks1 j st)))
+ (nth i (nth (marksindex) st)))))
+
+(defthm mark-equivp1-init-marks1
+ (implies
+ (and
+ (integerp i)
+ (<= 0 i))
+ (mark-equivp1 nil (init-marks1 i st) i)))
+
+(defthm equiv-load-st
+ (equiv nil g nil (load-st g st))
+ :hints (("goal" :in-theory (set-difference-theories
+ (enable graph-equivp mark-equivp)
+ '(graph-equivp1 mark-equivp1 init-marks1)))))
+
+(defthm numberlistp-neighbors
+ (implies
+ (mygraph1p g n)
+ (numberlistp (neighbors i g) (maxnode))))
+
+(defthm graph1p-st-load-graph1
+ (implies
+ (and
+ (mygraphp g)
+ (integerp i)
+ (<= 0 i))
+ (graphp1-st (load-graph1 g i st) i))
+ :hints (("goal" :in-theory (enable load-graph1 graphp1-st))))
+
+(defun linear-find-st (a b g st)
+ (declare (xargs :stobjs st
+ :guard (and (stp st)
+ (bounded-natp a (maxnode))
+ (bounded-natp b (maxnode))
+ (alistp g)
+ (mygraphp g))))
+ (let ((st (load-st g st)))
+ (let ((st (linear-find-next-step-st-mbe (list a) b st)))
+ (if (not (equal (status st) 0))
+ (mv 'failure st)
+ (mv (stack st) st)))))
+
+(defthm nth-init-marks1
+ (implies
+ (and
+ (integerp j)
+ (integerp i)
+ (<= 0 i)
+ (<= j i)
+ (< i (maxnode)))
+ (equal (nth i (nth (marksindex) (init-marks1 j st)))
+ 0))
+ :hints (("goal" :expand ((INIT-MARKS1 I ST)))))
+
+(defthm linear-find-next-step-st-mbe-base
+ (implies
+ (and
+ (equal (nth i (nth (marksindex) st)) 0)
+ (bounded-natp i (maxnode))
+ (equal (stack st) nil))
+ (equal (nth (stackindex) (linear-find-next-step-st-mbe (list i) i st)) (list i)))
+ :hints (("goal" :expand (linear-find-next-step-st-mbe (list i) i st))))
+
+(defthm nth-load-graph1
+ (implies
+ (and
+ (integerp i)
+ (<= 0 i)
+ (not (equal i (gindex))))
+ (equal (nth i (load-graph1 g j st))
+ (nth i st))))
+
+;; ****************
+;; Main lemma
+;; ****************
+;; Our implementation returns the same value as the original
+;; list-based one when we load the stobj using the functions
+;; of this file.
+(defthm linear-find-st-linear-find-path
+ (implies
+ (and
+ (bounded-natp a (maxnode))
+ (bounded-natp b (maxnode))
+ (mygraphp g)
+ (stp st))
+ (equal
+ (car (linear-find-st a b g st))
+ (linear-find-path a b g)))
+ :hints (("goal" :use ((:instance implementations-same (stack nil) (mt nil) (c (list a))
+ (st (load-st g st)))
+ equiv-load-st)
+ :in-theory (disable linear-find-path-is-find-path equiv-load-st stp))))
+
+#|
+ACL2 !>(assign g '((0 1 2) (1) (2 0 1 2 3) (3 1)))
+ ((0 1 2) (1) (2 0 1 2 3) (3 1))
+ACL2 !>(mygraphp (@ g))
+T
+ACL2 !>(stp st)
+T
+ACL2 !>(linear-find-st 0 3 (@ g) st)
+((0 2 3) <st>)
+ACL2 !>(linear-find-path 0 3 (@ g))
+(0 2 3)
+
+|#
+
+;; Some functions for building graphs
+
+;; Generate a graph with nodes numbered curr though last and edges
+;; from each node to the list all
+(defun completeg-helper (curr last all)
+ (declare (xargs :verify-guards t))
+ (declare (xargs :measure (nfix (- (1+ (nfix last)) (nfix curr)))))
+ (if (<= (nfix curr) (nfix last))
+ (cons
+ (cons curr all)
+ (completeg-helper (1+ (nfix curr)) last all))
+ nil))
+
+;; Generate a list of naturals from curr to last
+(defun listofnats (curr last)
+ (declare (xargs :verify-guards t
+ :measure (nfix (- (1+ (nfix last)) (nfix curr)))))
+ (if (<= (nfix curr) (nfix last))
+ (cons
+ curr
+ (listofnats (1+ (nfix curr)) last))
+ nil))
+
+;; Generate a complete graph with nodes 0 to size-1
+(defun completeg (size)
+ (declare (xargs :verify-guards t))
+ (completeg-helper 0 (1- (nfix size)) (listofnats 0 (1- (nfix size)))))
+
+;; Generate a "bad" graph with n nodes. Nodes 0..n-1 are a complete
+;; graph, and node n is disconnected
+(defun badg (size)
+ (declare (xargs :verify-guards t))
+ (cons
+ (list size)
+ (completeg size)))
+
+#|
+
+The pathfinder can be run from the ACL2 read-eval-print loop.
+
+First, load this book
+
+ ACL2 !>(include-book
+ "run-fpst")
+ Loading /accts/dagreve/local/src/acl2-2.8a/books/arithmetic/equalities.o
+ start address -T 1827ecc Finished loading /accts/dagreve/local/src/acl2-2.8a/books/arithmetic/equalities.o
+ Loading /accts/dagreve/local/src/acl2-2.8a/books/arithmetic/rational-listp.o
+
+ ...
+
+ Summary
+ Form: ( INCLUDE-BOOK ; manual editing by Matt K. to avoid Makefile-deps dependency
+ "run-fpst" ...)
+ Rules: NIL
+ Warnings: None
+ Time: 1.49 seconds (prove: 0.00, print: 0.00, other: 1.49)
+ "/accts/dagreve/ACL/challenges/graph/run-fpst.lisp"
+
+Next, load the datastructure with a graph. In this example, we load a
+graph with 1,000 nodes and 1,000,000 edges, which takes about a minute.
+
+ ACL2 !>(load-st (badg 1000) st)
+ <st>
+
+We try to find a non-existent path so that the program traverses all
+the edges. This requires less than a second.
+
+ ACL2 !>(linear-find-next-step-st-mbe (list 0) 1000 st)
+ <st>
+ ACL2 !>(status st)
+ 1
+
+We reset the marks array and search for an existing path. Note that
+it's not guaranteed to be the shortest one, only a valid one.
+
+ ACL2 !>(init-marks st)
+ <st>
+ ACL2 !>(linear-find-next-step-st-mbe (list 0) 6 st)
+ <st>
+ ACL2 !>(status st)
+ 0
+ ACL2 !>(stack st)
+ (0 1 2 3 4 5 6)
+
+|#
diff --git a/books/workshops/2003/hbl/dynamic-hbl.pdf.gz b/books/workshops/2003/hbl/dynamic-hbl.pdf.gz
new file mode 100644
index 0000000..28382cb
--- /dev/null
+++ b/books/workshops/2003/hbl/dynamic-hbl.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/hbl/dynamic-hbl.ps.gz b/books/workshops/2003/hbl/dynamic-hbl.ps.gz
new file mode 100644
index 0000000..20b30ae
--- /dev/null
+++ b/books/workshops/2003/hbl/dynamic-hbl.ps.gz
Binary files differ
diff --git a/books/workshops/2003/hbl/hanbing-slides.pdf.gz b/books/workshops/2003/hbl/hanbing-slides.pdf.gz
new file mode 100644
index 0000000..285df95
--- /dev/null
+++ b/books/workshops/2003/hbl/hanbing-slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/hbl/hanbing-slides.ps.gz b/books/workshops/2003/hbl/hanbing-slides.ps.gz
new file mode 100644
index 0000000..74a8cef
--- /dev/null
+++ b/books/workshops/2003/hbl/hanbing-slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/hbl/support/sol1.lisp b/books/workshops/2003/hbl/support/sol1.lisp
new file mode 100644
index 0000000..4841a1f
--- /dev/null
+++ b/books/workshops/2003/hbl/support/sol1.lisp
@@ -0,0 +1,1813 @@
+; A Solution to the Rockwell challenge
+; Hanbing Liu (version for submission to ACL2 workshop)
+; March 26th, 2003
+
+
+; Abstract
+; Rockwell challenge is about reasoning effectively about updates to dynamic
+; data structures in a linear address space.
+;
+; Dynamic Datastructures in ACL2: A Challenge
+;
+; David Greve and Matt Wilding
+; Nov. 2002
+; http://hokiepokie.org/docs/festival02.txt
+; a local copy is in http://melton.csres.utexas.edu
+
+; The key is to
+; (1) recover the notion of objects being independent entities and
+; (2) reduce update-on-the fly operations to simpler operations that apply a
+; corresponding sequence of updates.
+
+; START OF THE SCRIPT
+;
+; This file contains the proofs of the concrete problem. 3 properties as
+; described below
+
+; We assume that two books have been loaded, part of the ACL2
+; distribution:
+
+
+; 1. Problem Set Up
+; *****************************
+; (acl2::set-match-free-error nil) ;
+(in-package "ACL2")
+(include-book "misc/records" :dir :system)
+(include-book "arithmetic/top-with-meta" :dir :system)
+
+(defun seq-int (start len)
+ (if (zp len)
+ nil
+ (cons start
+ (seq-int (1+ start) (1- len)))))
+
+(defun unique (list)
+ (if (consp list)
+ (and (not (member (car list) (cdr list)))
+ (unique (cdr list)))
+ t))
+
+;; We introduce two data structures.
+;; "A" nodes have 4 words.
+;; Words 0 and 3 are scalars and words 1 and 2 are A node pointers.
+
+;; Collect addresses in the first n nodes of an a structure
+(defun a-collect (ptr n ram)
+ (declare (xargs :measure (nfix n)))
+
+ ; +---+
+ ; 0: | |
+ ; +---+
+ ; 1: | o-+--> a-node
+ ; +---+
+ ; 2: | o-+--> a-node
+ ; +---+
+ ; 3: | |
+ ; +---+
+
+ (if (zp n)
+ nil
+ (if (zp ptr)
+ nil
+ (append
+ (seq-int ptr 4)
+ (a-collect (g (+ 1 ptr) ram) (1- n) ram)
+ (a-collect (g (+ 2 ptr) ram) (1- n) ram)
+ ))))
+
+;; "B" nodes have 3 words. Word 2 is an integer, words 0 and 1 are
+;; B-node pointers. "0" is a null pointer
+
+;; Collect addresses from the first n nodes of a b structure
+(defun b-collect (ptr n ram)
+ (declare (xargs :measure (nfix n)))
+
+ ; +---+
+ ; 0: | o-+--> b-node
+ ; +---+
+ ; 1: | o-+--> b-node
+ ; +---+
+ ; 2: | |
+ ; +---+
+
+ (if (zp n)
+ nil
+ (if (zp ptr)
+ nil
+ (append
+ (seq-int ptr 3)
+ (b-collect (g ptr ram) (1- n) ram)
+ (b-collect (g (+ 1 ptr) ram) (1- n) ram)
+ ))))
+
+;; Crawl through at most n nodes in an "a" structure along the second
+;; pointer. Modify word 0 of each node by adding word 2 to it.
+(defun a-mark-objects (addr n ram)
+ (declare (xargs :measure (nfix n)))
+ (if (zp n) ram
+ (if (zp addr) ram
+ (let ((ram (s addr (+ (g addr ram) (g (+ 2 addr) ram)) ram)))
+ (a-mark-objects (g (+ addr 2) ram) (1- n) ram)))))
+
+;; Crawl through at most n nodes in an "b" structure along the pointer
+;; in the first field
+
+(defun b-mark-objects (addr n ram)
+ (declare (xargs :measure (nfix n)))
+ (if (zp n) ram
+ (if (zp addr) ram
+ (let ((ram (s (+ 2 addr) 0 ram)))
+ (b-mark-objects (g addr ram) (1- n) ram)))))
+
+
+(defun compose-bab (ptr1 n1 ptr2 n2 ptr3 n3 ram)
+ (let ((ram (b-mark-objects ptr1 n1 ram)))
+ (let ((ram (a-mark-objects ptr2 n2 ram)))
+ (let ((ram (b-mark-objects ptr3 n3 ram)))
+ ram))))
+
+
+
+; 2. Proof of property I
+; *****************************
+;
+; 2.1 Problem Analysis
+; *****************************
+; Difficulty:
+; Data structures in linear addressed space.
+; Abtraction at high level language hides many important assumption.
+; (1) Independent entity.
+; (2) Well-formness
+
+(defun make-ram-config (addr n ram)
+ (list addr n ram))
+
+(defun addr (rm-config)
+ (car rm-config))
+(defun n (rm-config)
+ (cadr rm-config))
+(defun ram (rm-config)
+ (caddr rm-config))
+
+;; Comment: Introduce RAM-configuration to rephrase the problem in
+;; RAM-configuration. The structural equivalence on RCs is used to capture
+;; the "shape" of the object at addr being the same.
+
+(defun rc-s (x v rc)
+ (let ((addr (addr rc))
+ (n (n rc))
+ (ram (ram rc)))
+ (make-ram-config addr n (s x v ram))))
+
+
+; Strategy:
+; To prove (g addr (s addrx v mem)) = (g addr mem)
+; The only way we know is to prove
+; addr!=addrx
+;
+; Update on the fly is hard. Thus let's reduce it to
+; apply a sequnce of updates.
+;
+; If we can prove addr not member of updated cells, then we prove the final
+; result
+
+(defun collect-A-updates-dynamic (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (let* ((rc1 (rc-s addr (+ (g addr ram) (g (+ 2 addr) ram)) rc))
+ (ram (ram rc1))
+ (addr (addr rc1))
+ (n (n rc1)))
+ (append
+ (list addr)
+ (collect-A-updates-dynamic (make-ram-config (g (+ 2 addr) ram) (1- n)
+ ram))))))))
+
+(defun apply-A-update (addr ram)
+ (s addr (+ (g addr ram) (g (+ 2 addr) ram)) ram))
+
+
+(defun apply-A-updates (seq ram)
+ (if (endp seq) ram
+ (apply-A-updates (cdr seq) (apply-A-update (car seq) ram))))
+
+
+(defthm a-mark-objects-alt-definition
+ (equal (a-mark-objects addr n ram)
+ (apply-a-updates (collect-a-updates-dynamic
+ (make-ram-config addr n ram))
+ ram))
+ :rule-classes :definition)
+
+; The above theorem ''a-mark-objects-alt-definition''
+; Reduce the a-mark-objects to apply dynamic
+
+
+
+; And we know:
+(defun a-updates-w (l)
+ (if (endp l) nil
+ (cons (car l) (a-updates-w (cdr l)))))
+
+(defthm apply-a-updates-equal
+ (implies (not (member x (a-updates-w updates)))
+ (equal (g x (apply-a-updates updates ram))
+ (g x ram))))
+
+
+; Thus to prove the final goal
+;
+; (defthm rd-read-over-a-mark-objects
+; (implies
+; (let ((list (a-collect ptr n ram)))
+; (and (not (member addr list))
+; (unique list)))
+; (equal (g addr (a-mark-objects ptr n ram))
+; (g addr ram)))
+;
+; We need to show the following: *P1*
+; (implies (not (member addr (a-collect-1 rc)))
+; (not (member addr
+; (a-updates-w
+; (collect-a-udpate-dynamic rc)))))
+;
+; where a-collect-1 is
+
+(defun a-collect-1 (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append
+ (seq-int addr 4)
+ (a-collect-1 (make-ram-config (g (+ 1 addr) ram) (1- n) ram))
+ (a-collect-1 (make-ram-config (g (+ 2 addr) ram) (1- n) ram)))))))
+
+
+(defthm a-collect-1-alt-definition
+ (equal (a-collect addr n ram)
+ (a-collect-1 (make-ram-config addr n ram)))
+ :rule-classes :definition)
+
+; However *P1* is not true.
+; We can only a similar *P1* style lemma for
+
+(defun collect-a-updates-static (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append
+ (list addr)
+ (collect-A-updates-static
+ (make-ram-config (g (+ 2 addr) ram) (1- n)
+ ram)))))))
+
+
+
+
+; Now the Major Task is to show
+; (collect-a-updates-dynamic rc) == (collect-A-updates-static rc)
+; under the condition of (uniqueness (a-collect-1 rc))
+
+; We have the observation that "uniqueness" is not the fundamental reason.
+; We need to characterize the "shape" of object does not change, in order to
+; prove
+; (collect-a-updates-dynamic rc) == (collect-A-updates-static rc)
+
+; Define structural Equivalent.
+;
+; Basically, if two objects are structural equivalent, they occupied the same
+; range of memory and their components are structural equivalent to each other.
+;
+(defun struct-equiv-A-ram-config1 (addr1 n1 ram1 addr2 n2 ram2)
+ (declare (xargs :measure (nfix n1)))
+ (and (equal addr1 addr2)
+ (equal n1 n2)
+ (cond ((zp n1) t)
+ ((zp addr1) t)
+ (t (and
+ (struct-equiv-A-ram-config1
+ (g (+ addr1 1) ram1)
+ (- n1 1)
+ ram1
+ (g (+ addr2 1) ram2)
+ (- n2 1)
+ ram2)
+ (struct-equiv-A-ram-config1
+ (g (+ addr1 2) ram1)
+ (- n1 1)
+ ram1
+ (g (+ addr2 2) ram2)
+ (- n2 1)
+ ram2))))))
+
+(defun struct-equiv-A-ram-config (rc1 rc2)
+ (struct-equiv-A-ram-config1 (addr rc1) (n rc1) (ram rc1)
+ (addr rc2) (n rc2) (ram rc2)))
+
+
+(defthm struct-equiv-A-ram-config1-reflexive
+ (struct-equiv-A-ram-config1 x1 x2 x3 x1 x2 x3))
+
+(defthm struct-equiv-A-ram-config1-symentric
+ (iff (struct-equiv-A-ram-config1 x12 x22 x32 x11 x21 x31)
+ (struct-equiv-A-ram-config1 x11 x21 x31 x12 x22 x32)))
+
+(defthm struct-equiv-A-ram-config1-transitive
+ (implies (and (struct-equiv-A-ram-config1 x11 x21 x31 x12 x22 x32)
+ (struct-equiv-A-ram-config1 x12 x22 x32 x13 x23 x33))
+ (struct-equiv-A-ram-config1 x11 x21 x31 x13 x23 x33)))
+
+(defequiv struct-equiv-A-ram-config)
+
+; For "shape" not change, we need to introduce the concept of link cell and
+; data cells. and show structural equivalent state, these two set do not
+; change.
+
+(defun A-collect-link-cells-static (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append (list (+ addr 1)
+ (+ addr 2))
+ (A-collect-link-cells-static
+ (make-ram-config (g (+ 1 addr) ram)
+ (1- n)
+ ram))
+ (A-collect-link-cells-static
+ (make-ram-config (g (+ 2 addr) ram)
+ (1- n)
+ ram)))))))
+
+(defthm rc-config-accessor
+ (and (equal (addr (make-ram-config addr n ram)) addr)
+ (equal (n (make-ram-config addr n ram)) n)
+ (equal (ram (make-ram-config addr n ram)) ram)))
+
+(in-theory (disable make-ram-config ram n addr))
+
+(defcong struct-equiv-A-ram-config equal (n rc) 1)
+(defcong struct-equiv-A-ram-config equal (addr rc) 1)
+
+(defun cong-induct (rc rc-equiv)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) (list rc rc-equiv)
+ (if (zp addr) (list rc rc-equiv)
+ (list (cong-induct (make-ram-config (g (+ 1 addr) ram)
+ (1- n)
+ ram)
+ (make-ram-config (g (+ 1 (addr rc-equiv)) (ram
+ rc-equiv))
+ (1- (n rc-equiv))
+ (ram rc-equiv)))
+ (cong-induct (make-ram-config (g (+ 2 addr) ram)
+ (1- n)
+ ram)
+ (make-ram-config (g (+ 2 (addr rc-equiv)) (ram
+ rc-equiv))
+ (1- (n rc-equiv))
+ (ram rc-equiv))))))))
+
+
+(defthm member-append-1
+ (implies (not (member x a))
+ (iff (member x (append a b))
+ (member x b))))
+
+(defthm member-append-2
+ (implies (not (member x b))
+ (iff (member x (append a b))
+ (member x a))))
+
+(defthm member-append-3
+ (implies (member x b)
+ (member x (append a b))))
+
+(defthm member-append-4
+ (implies (member x a)
+ (member x (append a b))))
+
+
+
+(defcong struct-equiv-A-ram-config equal (A-collect-link-cells-static rc) 1
+ :hints (("Goal" :induct (cong-induct rc rc-equiv))))
+
+; Now we can state the condition under which the "shape" does not change after
+; an update.
+
+(defthm set-non-link-cells-collect-equal
+ (implies (not (member x (a-collect-link-cells-static rc)))
+ (struct-equiv-A-ram-config (rc-s x v rc) rc))
+ :hints (("Goal" :induct (a-collect-link-cells-static rc))))
+
+
+(defun A-collect-data-cells-static (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append (list addr
+ (+ addr 3))
+ (A-collect-data-cells-static
+ (make-ram-config (g (+ 1 addr) ram)
+ (1- n)
+ ram))
+ (A-collect-data-cells-static
+ (make-ram-config (g (+ 2 addr) ram)
+ (1- n)
+ ram)))))))
+
+
+(defcong struct-equiv-A-ram-config equal (A-collect-data-cells-static rc) 1
+ :hints (("Goal" :induct (cong-induct rc rc-equiv))))
+
+
+; We can prove
+; under the condition that link cells and data cells do not overlap
+; collect-dynamic == collect-static
+;
+
+(defthm addr-member-a-collect-data-cells-static
+ (let ((n (n rc))
+ (addr (addr rc)))
+ (implies (and (not (zp n))
+ (not (zp addr)))
+ (member addr (a-collect-data-cells-static rc)))))
+
+
+(defthm accessor-rc-s
+ (and (equal (addr (rc-s x v rc)) (addr rc))
+ (equal (n (rc-s x v rc)) (n rc))))
+
+
+
+(defun overlap (a b)
+ (if (endp a) nil
+ (or (member (car a) b)
+ (overlap (cdr a) b))))
+
+
+(defthm addr-not-a-member-a-collect-link-cells-static
+ (let ((n (n rc))
+ (addr (addr rc)))
+ (implies (and (not (zp n))
+ (not (zp addr))
+ (not (overlap (a-collect-data-cells-static rc)
+ (a-collect-link-cells-static rc))))
+ (not (member addr (a-collect-link-cells-static rc))))))
+
+
+(defthm struct-equiv-A-ram-config1-implies-struct-equiv-A-ram-config1
+ (and (implies (and (struct-equiv-A-ram-config1 addr1 n1 ram1 addr2 n2 ram2)
+ (not (zp n1))
+ (not (zp addr1)))
+ (struct-equiv-A-ram-config
+ (make-ram-config (g (+ 2 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 2 addr2) ram2) (1- n2) ram2)))
+ (implies (and (struct-equiv-A-ram-config1 addr1 n1 ram1 addr2 n2 ram2)
+ (not (zp addr1))
+ (not (zp n1)))
+ (struct-equiv-A-ram-config
+ (make-ram-config (g (+ 1 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 1 addr2) ram2) (1- n2) ram2)))))
+
+;; Comment: this is saying if structural equivalent, then branches are
+;; structural equivalent.
+
+(defthm struct-equiv-A-ram-config-implies-struct-equiv-A-ram-config-1
+ (let ((addr1 (addr rc1))
+ (n1 (n rc1))
+ (ram1 (ram rc1))
+ (addr2 (addr rc2))
+ (n2 (n rc2))
+ (ram2 (ram rc2)))
+ (and (implies (and (struct-equiv-A-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-A-ram-config
+ (make-ram-config (g (+ 2 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 2 addr2) ram2) (1- n2) ram2)))
+ (implies (and (struct-equiv-A-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-A-ram-config
+ (make-ram-config (g (+ 1 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 1 addr2) ram2) (1- n2) ram2))))))
+
+(defthm struct-equiv-A-ram-config-implies-struct-equiv-A-ram-config-1-instance
+ (let* ((rc1 (rc-s (addr rc) (+ (g (addr rc) (ram rc))
+ (g (+ 2 (addr rc)) (ram rc))) rc))
+ (rc2 rc)
+ (addr1 (addr rc1))
+ (n1 (n rc1))
+ (ram1 (ram rc1))
+ (addr2 (addr rc2))
+ (n2 (n rc2))
+ (ram2 (ram rc2)))
+ (and (implies (and (struct-equiv-A-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-A-ram-config
+ (make-ram-config (g (+ 2 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 2 addr2) ram2) (1- n2) ram2)))
+ (implies (and (struct-equiv-A-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-A-ram-config
+ (make-ram-config (g (+ 1 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 1 addr2) ram2) (1- n2) ram2))))))
+
+;; Comments: this is bad. that I need to explicitly instantiate the lemma
+
+(defthm struct-equiv-A-ram-config-implies-struct-equiv-A-ram-config-1-instance-2
+ (implies (and (not (overlap (a-collect-data-cells-static rc)
+ (a-collect-link-cells-static rc)))
+ (not (zp (addr rc)))
+ (not (zp (n rc))))
+ (struct-equiv-A-ram-config
+ (MAKE-RAM-CONFIG (G (+ 2 (ADDR RC))
+ (RAM (RC-S (ADDR RC)
+ (+ (G (ADDR RC) (RAM RC))
+ (G (+ 2 (ADDR RC)) (RAM RC)))
+ RC)))
+ (+ -1 (N RC))
+ (RAM (RC-S (ADDR RC)
+ (+ (G (ADDR RC) (RAM RC))
+ (G (+ 2 (ADDR RC)) (RAM RC)))
+ RC)))
+ (MAKE-RAM-CONFIG (G (+ 2 (ADDR RC))
+ (RAM RC))
+ (+ -1 (N RC))
+ (RAM RC))))
+ :hints (("Goal" :in-theory (disable struct-equiv-A-ram-config rc-s)
+ :use
+ struct-equiv-A-ram-config-implies-struct-equiv-A-ram-config-1-instance)))
+
+
+(defthm overlap-append-1
+ (implies (overlap a b)
+ (overlap (append c a) b)))
+
+(defthm overlap-append-2
+ (implies (overlap a b)
+ (overlap a (append d b))))
+
+
+(defthm overlap-append-3-cons
+ (implies (overlap a b)
+ (overlap a (cons x b))))
+
+
+
+(defthm not-overlap-not-overlap-branch
+ (implies (and (not (overlap (a-collect-data-cells-static rc)
+ (a-collect-link-cells-static rc)))
+ (not (zp (n rc)))
+ (not (zp (addr rc))))
+ (not (overlap (a-collect-data-cells-static
+ (make-ram-config (G (+ 2 (ADDR RC)) (RAM RC))
+ (+ -1 (N RC))
+ (RAM RC)))
+ (a-collect-link-cells-static
+ (make-ram-config (G (+ 2 (ADDR RC)) (RAM RC))
+ (+ -1 (N RC))
+ (RAM RC))))))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defcong struct-equiv-A-ram-config equal (collect-A-updates-static rc) 1
+ :hints (("Goal" :induct (cong-induct rc rc-equiv))))
+
+
+(defthm not-overlap-implies-collect-a-update-dynamic-equal-static
+ (implies (not (overlap (a-collect-data-cells-static rc)
+ (a-collect-link-cells-static rc)))
+ (equal (collect-a-updates-dynamic rc)
+ (collect-a-updates-static rc)))
+ :hints (("Goal" :induct (collect-a-updates-dynamic rc)
+ :do-not '(generalize)
+ :in-theory (disable rc-s struct-equiv-A-ram-config))))
+
+; After we proved the above
+; (equal (collect-a-updates-dynamic rc)
+; (collect-a-updates-static rc))
+;
+; We need to show (unique (a-collect-1 rc) implies not overlap link + data
+
+
+
+; But let us prove the following fact before we move on to show UNIQUE implies NOT OVERLAP
+; That is a *P1* style property for collect-a-updates-static
+(defthm inrange-seen
+ (implies (and (not (zp l))
+ (integerp x)
+ (integerp y)
+ (integerp l)
+ (< y (+ x l))
+ (<= x y))
+ (member y (seq-int x l)))
+ :hints (("Goal" :do-not '(generalize))))
+
+(defthm mem-collect-a-updates-static-mem-a-collect-1
+ (implies (member x (a-updates-w (collect-a-updates-static rc)))
+ (member x (a-collect-1 rc)))
+ :rule-classes ((:rewrite :corollary
+ (implies (not (member x (a-collect-1 rc)))
+ (not (member x (a-updates-w (collect-a-updates-static rc))))))))
+
+; and this fact
+
+(defthm not-overlap-g-a-mark
+ (let ((rc (make-ram-config addr n ram)))
+ (implies (and (not (overlap (a-collect-data-cells-static rc)
+ (a-collect-link-cells-static rc)))
+ (not (member x (a-updates-w (collect-a-updates-static rc)))))
+ (equal (g x (a-mark-objects addr n ram))
+ (g x ram)))))
+
+
+; TO SHOW UNIQUE implies not overlap
+(defthm seq-int-1-equal
+ (equal (seq-int x 1)
+ (list x))
+ :hints (("Goal" :expand (seq-int x 1))))
+
+
+#| ;; just to show as not closely related result.
+(defthm mem-a-collect-mem-link-or-data
+ (implies (and (member x (a-collect-1 rc))
+ (not (member x (a-collect-data-cells-static rc))))
+ (member x (a-collect-link-cells-static rc))))
+; either be link or data, possibly being both
+|#
+
+(defthm subset-append-1
+ (implies (and (subsetp a b)
+ (subsetp c b))
+ (subsetp (append a c) b)))
+
+(defthm subset-append-2
+ (implies (subsetp a b)
+ (subsetp a (append c b))))
+
+(defthm subset-append-3
+ (implies (and (subsetp a b)
+ (subsetp c d))
+ (subsetp (append a c)
+ (append b d))))
+
+(defthm subsetp-link-all
+ (subsetp (a-collect-link-cells-static rc)
+ (a-collect-1 rc)))
+
+
+(defthm subsetp-data-all
+ (subsetp (a-collect-data-cells-static rc)
+ (a-collect-1 rc)))
+
+
+(defthm member-subsetp
+ (implies (and (member x a)
+ (subsetp a b))
+ (member x b)))
+
+(defthm shared-member-not-unique
+ (implies (and (member x a)
+ (member x b))
+ (not (unique (append a b)))))
+
+(defthm mem-link-mem-all
+ (implies (member x (a-collect-link-cells-static rc))
+ (member x (a-collect-1 rc)))
+ :rule-classes :forward-chaining)
+
+(defthm mem-data-mem-all
+ (implies (member x (a-collect-data-cells-static rc))
+ (member x (a-collect-1 rc)))
+ :rule-classes :forward-chaining)
+
+
+
+(defthm member-link-data-not-unique-lemma
+ (implies (and (member x (a-collect-data-cells-static rc1))
+ (member x (a-collect-link-cells-static rc2)))
+ (not (unique (append (a-collect-1 rc1)
+ (a-collect-1 rc2))))))
+
+
+(defthm not-unique-append
+ (implies (not (unique a))
+ (not (unique (append a b)))))
+
+(defthm not-unique-append-2
+ (implies (not (unique b))
+ (not (unique (append a b)))))
+
+(defthm member-link-data-not-unique
+ (implies (and (member x (a-collect-data-cells-static rc))
+ (member x (a-collect-link-cells-static rc)))
+ (not (unique (a-collect-1 rc)))))
+
+
+(defun overlap-witness (a b)
+ (if (endp a)
+ nil
+ (if (member (car a) b)
+ (car a)
+ (overlap-witness (cdr a) b))))
+
+(defthm overlap-witness-mem-a
+ (implies (overlap a b)
+ (member (overlap-witness a b) a))
+ :rule-classes :forward-chaining)
+
+(defthm overlap-witness-mem-b
+ (implies (overlap a b)
+ (member (overlap-witness a b) b))
+ :rule-classes :forward-chaining)
+
+
+(defthm unique-implies-no-overlap
+ (implies (overlap (a-collect-data-cells-static rc)
+ (a-collect-link-cells-static rc))
+ (not (unique (a-collect-1 rc))))
+ :hints (("Goal" :do-not '(generalize)))
+ :rule-classes ((:rewrite :corollary
+ (implies (unique (a-collect-1 rc))
+ (not (overlap (a-collect-data-cells-static rc)
+ (a-collect-link-cells-static rc)))))))
+;; Finally w proved
+;; (implies (overlap (a-collect-data-cells-static rc)
+;; (a-collect-link-cells-static rc))
+;; (not (unique (a-collect-1 rc))))
+
+(defthm a-collect-unique-implies-not-changed
+ (implies (and (unique (a-collect addr n ram))
+ (not (member x (a-collect addr n ram))))
+ (equal (g x (a-mark-objects addr n ram))
+ (g x ram))))
+
+
+;----------------------------------------------------
+; Finally we have the first proof for A
+
+; Very similar for B data structure. Comment skipped
+
+(defun collect-B-updates-dynamic (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (let* ((rc1 (rc-s (+ 2 addr) 0 rc))
+ (ram (ram rc1))
+ (addr (addr rc1))
+ (n (n rc1)))
+ (append
+ (list addr)
+ (collect-B-updates-dynamic (make-ram-config (g addr ram) (1- n)
+ ram))))))))
+
+(defun apply-B-update (addr ram)
+ (s (+ 2 addr) 0 ram))
+
+(defun apply-B-updates (seq ram)
+ (if (endp seq) ram
+ (apply-B-updates (cdr seq) (apply-B-update (car seq) ram))))
+
+
+(defthm B-mark-object-alt-definition
+ (equal (B-mark-objects addr n ram)
+ (apply-B-updates (collect-B-updates-dynamic
+ (make-ram-config addr n ram)) ram))
+ :rule-classes :definition)
+
+
+(defun collect-B-updates-static (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append
+ (list addr)
+ (collect-B-updates-static (make-ram-config (g addr ram) (1- n)
+ ram)))))))
+
+
+
+(defun struct-equiv-B-ram-config1 (addr1 n1 ram1 addr2 n2 ram2)
+ (declare (xargs :measure (nfix n1)))
+ (and (equal addr1 addr2)
+ (equal n1 n2)
+ (cond ((zp n1) t)
+ ((zp addr1) t)
+ (t (and
+ (struct-equiv-B-ram-config1
+ (g addr1 ram1)
+ (- n1 1)
+ ram1
+ (g addr2 ram2)
+ (- n2 1)
+ ram2)
+ (struct-equiv-B-ram-config1
+ (g (+ addr1 1) ram1)
+ (- n1 1)
+ ram1
+ (g (+ addr2 1) ram2)
+ (- n2 1)
+ ram2))))))
+
+(defun struct-equiv-B-ram-config (rc1 rc2)
+ (struct-equiv-B-ram-config1 (addr rc1) (n rc1) (ram rc1)
+ (addr rc2) (n rc2) (ram rc2)))
+
+
+(defthm struct-equiv-B-ram-config1-reflexive
+ (struct-equiv-B-ram-config1 x1 x2 x3 x1 x2 x3))
+
+(defthm struct-equiv-B-ram-config1-symentric
+ (iff (struct-equiv-B-ram-config1 x12 x22 x32 x11 x21 x31)
+ (struct-equiv-B-ram-config1 x11 x21 x31 x12 x22 x32)))
+
+(defthm struct-equiv-B-ram-config1-transitive
+ (implies (and (struct-equiv-B-ram-config1 x11 x21 x31 x12 x22 x32)
+ (struct-equiv-B-ram-config1 x12 x22 x32 x13 x23 x33))
+ (struct-equiv-B-ram-config1 x11 x21 x31 x13 x23 x33)))
+
+(defequiv struct-equiv-B-ram-config)
+
+
+(defun B-collect-link-cells-static (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append (list addr
+ (+ addr 1))
+ (B-collect-link-cells-static
+ (make-ram-config (g addr ram)
+ (1- n)
+ ram))
+ (B-collect-link-cells-static
+ (make-ram-config (g (+ 1 addr) ram)
+ (1- n)
+ ram)))))))
+
+
+
+
+(defcong struct-equiv-B-ram-config equal (n rc) 1)
+(defcong struct-equiv-B-ram-config equal (addr rc) 1)
+
+
+(defun cong-induct-B (rc rc-equiv)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) (list rc rc-equiv)
+ (if (zp addr) (list rc rc-equiv)
+ (list (cong-induct-B (make-ram-config (g addr ram)
+ (1- n)
+ ram)
+ (make-ram-config (g (addr rc-equiv)
+ (ram rc-equiv))
+ (1- (n rc-equiv))
+ (ram rc-equiv)))
+ (cong-induct-B (make-ram-config (g (+ 1 addr) ram)
+ (1- n)
+ ram)
+ (make-ram-config (g (+ 1 (addr rc-equiv)) (ram
+ rc-equiv))
+ (1- (n rc-equiv))
+ (ram rc-equiv))))))))
+
+(defcong struct-equiv-B-ram-config equal (B-collect-link-cells-static rc) 1
+ :hints (("Goal" :induct (cong-induct-B rc rc-equiv))))
+
+
+
+(defthm B-set-non-link-cells-collect-equal
+ (implies (not (member x (B-collect-link-cells-static rc)))
+ (struct-equiv-B-ram-config (rc-s x v rc) rc))
+ :hints (("Goal" :induct (B-collect-link-cells-static rc))))
+
+
+
+
+
+(defun B-collect-data-cells-static (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append (list (+ addr 2))
+ (B-collect-data-cells-static
+ (make-ram-config (g addr ram)
+ (1- n)
+ ram))
+ (B-collect-data-cells-static
+ (make-ram-config (g (+ 1 addr) ram)
+ (1- n)
+ ram)))))))
+
+
+
+(defcong struct-equiv-B-ram-config equal (B-collect-data-cells-static rc) 1
+ :hints (("Goal" :induct (cong-induct-B rc rc-equiv))))
+
+;-----------------------------
+
+
+
+
+(defthm addr-member-B-collect-data-cells-static
+ (let ((n (n rc))
+ (addr (addr rc)))
+ (implies (and (not (zp n))
+ (not (zp addr)))
+ (member (+ 2 addr) (B-collect-data-cells-static rc)))))
+
+(defthm addr-not-B-member-a-collect-link-cells-static
+ (let ((n (n rc))
+ (addr (addr rc)))
+ (implies (and (not (zp n))
+ (not (zp addr))
+ (not (overlap (b-collect-data-cells-static rc)
+ (b-collect-link-cells-static rc))))
+ (not (member (+ 2 addr) (B-collect-link-cells-static rc))))))
+
+(defthm unique-B-collect-1-struct-equiv-B-ram-config
+ (implies (and (not (overlap (b-collect-data-cells-static rc)
+ (b-collect-link-cells-static rc)))
+ (not (zp (n rc)))
+ (not (zp (addr rc))))
+ (struct-equiv-B-ram-config (rc-s (+ 2 (addr rc)) any rc) rc))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+
+
+(defthm struct-equiv-B-ram-config1-implies-struct-equiv-B-ram-config1
+ (and (implies (and (struct-equiv-B-ram-config1 addr1 n1 ram1 addr2 n2 ram2)
+ (not (zp n1))
+ (not (zp addr1)))
+ (struct-equiv-B-ram-config
+ (make-ram-config (g addr1 ram1) (1- n1) ram1)
+ (make-ram-config (g addr2 ram2) (1- n2) ram2)))
+ (implies (and (struct-equiv-B-ram-config1 addr1 n1 ram1 addr2 n2 ram2)
+ (not (zp addr1))
+ (not (zp n1)))
+ (struct-equiv-B-ram-config
+ (make-ram-config (g (+ 1 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 1 addr2) ram2) (1- n2) ram2)))))
+
+
+(defthm struct-equiv-B-ram-config-implies-struct-equiv-B-ram-config-1
+ (let ((addr1 (addr rc1))
+ (n1 (n rc1))
+ (ram1 (ram rc1))
+ (addr2 (addr rc2))
+ (n2 (n rc2))
+ (ram2 (ram rc2)))
+ (and (implies (and (struct-equiv-B-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-B-ram-config
+ (make-ram-config (g addr1 ram1) (1- n1) ram1)
+ (make-ram-config (g addr2 ram2) (1- n2) ram2)))
+ (implies (and (struct-equiv-B-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-B-ram-config
+ (make-ram-config (g (+ 1 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 1 addr2) ram2) (1- n2) ram2))))))
+
+
+(defthm struct-equiv-B-ram-config-implies-struct-equiv-B-ram-config-1-instance
+ (let* ((rc1 (rc-s (+ 2 (addr rc)) 0 rc))
+ (rc2 rc)
+ (addr1 (addr rc1))
+ (n1 (n rc1))
+ (ram1 (ram rc1))
+ (addr2 (addr rc2))
+ (n2 (n rc2))
+ (ram2 (ram rc2)))
+ (and (implies (and (struct-equiv-B-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-B-ram-config
+ (make-ram-config (g addr1 ram1) (1- n1) ram1)
+ (make-ram-config (g addr2 ram2) (1- n2) ram2)))
+ (implies (and (struct-equiv-B-ram-config rc1 rc2)
+ (not (zp (addr rc1)))
+ (not (zp (n rc1))))
+ (struct-equiv-B-ram-config
+ (make-ram-config (g (+ 1 addr1) ram1) (1- n1) ram1)
+ (make-ram-config (g (+ 1 addr2) ram2) (1- n2) ram2))))))
+
+
+(defthm struct-equiv-B-ram-config-implies-struct-equiv-B-ram-config-1-instance-2
+ (implies (and (not (overlap (b-collect-data-cells-static rc)
+ (b-collect-link-cells-static rc)))
+ (not (zp (addr rc)))
+ (not (zp (n rc))))
+ (struct-equiv-B-ram-config
+ (MAKE-RAM-CONFIG (G (ADDR RC)
+ (RAM (RC-S (+ 2 (addr RC)) 0 RC)))
+ (+ -1 (N RC))
+ (RAM (RC-S (+ 2 (ADDR RC)) 0 RC)))
+ (MAKE-RAM-CONFIG (G (ADDR RC)
+ (RAM RC))
+ (+ -1 (N RC))
+ (RAM RC))))
+ :hints (("Goal" :in-theory (disable struct-equiv-B-ram-config rc-s)
+ :use
+ struct-equiv-B-ram-config-implies-struct-equiv-B-ram-config-1-instance)))
+
+;----------------------------------------------------
+
+(defthm overlap-cons
+ (iff (overlap c (cons x d))
+ (or (member x c)
+ (overlap c d))))
+
+(defthm overlap-app-app
+ (implies (overlap a b)
+ (overlap (append a c) (append b d))))
+
+
+(defthm not-overlap-not-overlap-branch-B
+ (implies (and (not (overlap (b-collect-data-cells-static rc)
+ (b-collect-link-cells-static rc)))
+ (not (zp (n rc)))
+ (not (zp (addr rc))))
+ (not (overlap (b-collect-data-cells-static
+ (make-ram-config (G (ADDR RC) (RAM RC))
+ (+ -1 (N RC))
+ (RAM RC)))
+ (b-collect-link-cells-static
+ (make-ram-config (G (ADDR RC) (RAM RC))
+ (+ -1 (N RC))
+ (RAM RC))))))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defcong struct-equiv-B-ram-config equal (collect-B-updates-static rc) 1
+ :hints (("Goal" :induct (cong-induct-B rc rc-equiv))))
+
+
+
+(defthm not-overlap-implies-collect-B-update-dynamic-equal-static
+ (implies (not (overlap (B-collect-data-cells-static rc)
+ (B-collect-link-cells-static rc)))
+ (equal (collect-B-updates-dynamic rc)
+ (collect-B-updates-static rc)))
+ :hints (("Goal" :induct (collect-B-updates-dynamic rc)
+ :do-not '(generalize)
+ :in-theory (disable rc-s struct-equiv-B-ram-config))))
+
+
+(defun b-updates-w (updates)
+ (if (endp updates)
+ nil
+ (cons (+ 2 (car updates))
+ (b-updates-w (cdr updates)))))
+
+(defthm apply-B-updates-equal
+ (implies (not (member x (b-updates-w updates)))
+ (equal (g x (apply-B-updates updates ram))
+ (g x ram))))
+
+
+(defthm not-overlap-g-B-mark
+ (let ((rc (make-ram-config addr n ram)))
+ (implies (and (not (overlap (B-collect-data-cells-static rc)
+ (B-collect-link-cells-static rc)))
+ (not (member x (b-updates-w (collect-B-updates-static rc)))))
+ (equal (g x (B-mark-objects addr n ram))
+ (g x ram)))))
+
+
+;---------------------------------------------------
+(defun B-collect-1 (rc)
+ (declare (xargs :measure (nfix (n rc))))
+ (let ((n (n rc))
+ (addr (addr rc))
+ (ram (ram rc)))
+ (if (zp n) nil
+ (if (zp addr) nil
+ (append
+ (seq-int addr 3)
+ (B-collect-1 (make-ram-config (g addr ram) (1- n) ram))
+ (B-collect-1 (make-ram-config (g (+ 1 addr) ram) (1- n) ram)))))))
+
+
+(defthm B-collect-1-alt-definition
+ (equal (B-collect addr n ram)
+ (B-collect-1 (make-ram-config addr n ram)))
+ :rule-classes :definition)
+
+;----------------------------------------------------
+
+(defthm mem-collect-B-updates-static-mem-B-collect-1
+ (implies (member x (b-updates-w (collect-B-updates-static rc)))
+ (member x (B-collect-1 rc)))
+ :rule-classes ((:rewrite :corollary
+ (implies (not (member x (b-collect-1 rc)))
+ (not (member x (b-updates-w (collect-b-updates-static rc))))))))
+
+;---------------------------------------------------
+
+(defthm subsetp-link-all-b
+ (subsetp (b-collect-link-cells-static rc)
+ (b-collect-1 rc)))
+
+
+(defthm subsetp-data-all-b
+ (subsetp (b-collect-data-cells-static rc)
+ (b-collect-1 rc)))
+
+
+
+(defthm mem-link-mem-all-b
+ (implies (member x (b-collect-link-cells-static rc))
+ (member x (b-collect-1 rc)))
+ :rule-classes :forward-chaining)
+
+(defthm mem-data-mem-all-b
+ (implies (member x (b-collect-data-cells-static rc))
+ (member x (b-collect-1 rc)))
+ :rule-classes :forward-chaining)
+
+
+
+(defthm member-link-data-not-unique-lemma-b
+ (implies (and (member x (b-collect-data-cells-static rc1))
+ (member x (b-collect-link-cells-static rc2)))
+ (not (unique (append (b-collect-1 rc1)
+ (b-collect-1 rc2))))))
+
+
+(defthm member-link-data-not-unique-b
+ (implies (and (member x (b-collect-data-cells-static rc))
+ (member x (b-collect-link-cells-static rc)))
+ (not (unique (b-collect-1 rc)))))
+
+
+(defthm unique-implies-no-overlap-b
+ (implies (overlap (b-collect-data-cells-static rc)
+ (b-collect-link-cells-static rc))
+ (not (unique (b-collect-1 rc))))
+ :hints (("Goal" :do-not '(generalize)))
+ :rule-classes ((:rewrite :corollary
+ (implies (unique (b-collect-1 rc))
+ (not (overlap (b-collect-data-cells-static rc)
+ (b-collect-link-cells-static rc)))))))
+
+
+(defthm b-collect-unique-implies-not-changed
+ (implies (and (unique (b-collect addr n ram))
+ (not (member x (b-collect addr n ram))))
+ (equal (g x (b-mark-objects addr n ram))
+ (g x ram))))
+
+
+; 3. Proof of property II
+; *****************************
+;
+; 3.1 Proof Analysis
+; The key point is to prove that update one objects maintain the structural
+; equivalent with respect to another object.
+;
+; Successively reduce composition of X-mark to a composition of apply-X-updates
+
+; 3.2 Proof Scipts
+
+; Similarly introduce
+(defun collect-bab-updates-dynamic (addr1 n1 addr2 n2 addr3 n3 ram)
+ (let* ((rc1 (make-ram-config addr1 n1 ram))
+ (rc2 (make-ram-config addr2 n2 (apply-B-updates
+ (collect-B-updates-dynamic rc1)
+ (ram rc1))))
+ (rc3 (make-ram-config addr3 n3 (apply-A-updates
+ (collect-A-updates-dynamic rc2)
+ (ram rc2)))))
+ (list (collect-B-updates-dynamic rc1)
+ (collect-A-updates-dynamic rc2)
+ (collect-B-updates-dynamic rc3))))
+
+
+
+(defun apply-bab-updates (l ram)
+ (apply-B-updates (caddr l)
+ (apply-a-updates (cadr l)
+ (apply-B-updates (car l) ram))))
+
+(defthm equal-compose-bab-apply-bab
+ (equal (compose-bab addr1 n1 addr2 n2 addr3 n3 ram)
+ (apply-bab-updates (collect-bab-updates-dynamic
+ addr1 n1 addr2 n2 addr3 n3 ram) ram)))
+
+; Now we need to prove
+;
+; (defthm unique-equal-collect-dynamic-to-static
+; (implies (unique (append (b-collect-1 (make-ram-config addr1 n1 ram))
+; (a-collect-1 (make-ram-config addr2 n2 ram))
+; (b-collect-1 (make-ram-config addr3 n3 ram))))
+; (equal (collect-bab-updates-dynamic addr1 n1 addr2 n2 addr3 n3 ram)
+; (collect-bab-updates-static addr1 n1 addr2 n2 addr3 n3 ram)))
+;
+
+; The idea is to successively reduce collect-X-updates-dynamic to
+; collect-X-updates-static
+; We need to show perservation of structural equivalence with respect to one
+; object after updates to other objects
+;
+
+
+(defthm make-ram-config-is-struct-equiv-a-ram-config
+ (STRUCT-EQUIV-A-RAM-CONFIG (MAKE-RAM-CONFIG (ADDR RC)
+ (N RC)
+ (RAM RC))
+ RC))
+
+(defthm make-ram-config-is-struct-equiv-b-ram-config
+ (STRUCT-EQUIV-B-RAM-CONFIG (MAKE-RAM-CONFIG (ADDR RC)
+ (N RC)
+ (RAM RC))
+ RC))
+
+
+(defthm struct-equiv-a-ram-config-apply-B-update
+ (implies (not (member (+ 2 x) (a-collect-link-cells-static rc)))
+ (struct-equiv-a-ram-config
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-B-update x (ram rc)))
+ rc)))
+
+(defun no-overlap-induct-A (l rc)
+ (if (endp l)
+ (list l rc)
+ (no-overlap-induct-A (cdr l)
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-B-update (car l) (ram rc))))))
+
+
+
+(defthm no-overlap-implies-A-struct-equiv-lemma
+ (implies (not (overlap (b-updates-w l)
+ (a-collect-link-cells-static rc)))
+ (struct-equiv-A-ram-config
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-B-updates l (ram rc)))
+ rc))
+ :hints (("Goal" :do-not '(generalize)
+ :in-theory (disable apply-B-update struct-equiv-A-ram-config)
+ :induct (no-overlap-induct-A l rc))))
+
+; above is about structure equivalent with respect to A after unrelated B updates
+; Similarly for B after A, B after B, (and A after A)
+
+
+(defthm struct-equiv-B-ram-config-apply-A-update
+ (implies (not (member x (B-collect-link-cells-static rc)))
+ (struct-equiv-B-ram-config
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-A-update x (ram rc)))
+ rc)))
+
+(defun no-overlap-induct-B (l rc)
+ (if (endp l)
+ (list l rc)
+ (no-overlap-induct-B (cdr l)
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-A-update (car l) (ram rc))))))
+
+
+(defthm no-overlap-implies-B-struct-equiv-lemma
+ (implies (not (overlap (a-updates-w l)
+ (B-collect-link-cells-static rc)))
+ (struct-equiv-B-ram-config
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-A-updates l (ram rc)))
+ rc))
+ :hints (("Goal" :do-not '(generalize)
+ :in-theory (disable apply-A-update struct-equiv-B-ram-config)
+ :induct (no-overlap-induct-B l rc))))
+
+;----------
+; A after A
+(defthm struct-equiv-a-ram-config-apply-A-update
+ (implies (not (member x (a-collect-link-cells-static rc)))
+ (struct-equiv-a-ram-config
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-A-update x (ram rc)))
+ rc)))
+
+
+(defthm no-overlap-implies-A-struct-equiv-2-lemma
+ (implies (not (overlap (a-updates-w l)
+ (a-collect-link-cells-static rc)))
+ (struct-equiv-A-ram-config
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-A-updates l (ram rc)))
+ rc))
+ :hints (("Goal" :do-not '(generalize)
+ :in-theory (disable apply-A-update struct-equiv-A-ram-config)
+ :induct (no-overlap-induct-B l rc))))
+
+
+(defthm no-overlap-implies-A-struct-equiv-2
+ (implies (not (overlap (a-updates-w l)
+ (a-collect-link-cells-static (make-ram-config addr n ram))))
+ (struct-equiv-A-ram-config
+ (make-ram-config addr
+ n
+ (apply-A-updates l ram))
+ (make-ram-config addr n ram)))
+ :hints (("Goal" :do-not-induct t
+ :use ((:instance no-overlap-implies-A-struct-equiv-2-lemma
+ (rc (make-ram-config addr n ram))))
+ :in-theory (disable struct-equiv-A-ram-config))))
+
+
+;---
+; B after B
+
+(defthm struct-equiv-B-ram-config-apply-B-update
+ (implies (not (member (+ 2 x) (B-collect-link-cells-static rc)))
+ (struct-equiv-B-ram-config
+ (make-ram-config (addr rc)
+ (n rc)
+ (apply-B-update x (ram rc)))
+ rc)))
+
+
+(defthm no-overlap-implies-B-struct-equiv-2-lemma
+ (implies (not (overlap (b-updates-w l)
+ (B-collect-link-cells-static rc)))
+ (struct-equiv-B-ram-config
+ (make-ram-config (addr rc) ;; (addr rc) doesn't match
+ (n rc)
+ (apply-B-updates l (ram rc)))
+ rc))
+ :hints (("Goal" :do-not '(generalize)
+ :in-theory (disable apply-B-update struct-equiv-B-ram-config)
+ :induct (no-overlap-induct-A l rc))))
+
+
+; Colloray from the result of property 1
+(defthm collect-dynamic-equal-static-A-1
+ (implies (unique (a-collect-1 rc1))
+ (equal (collect-A-updates-dynamic rc1)
+ (collect-A-updates-static rc1))))
+
+
+(in-theory (disable struct-equiv-A-ram-config apply-A-update))
+
+(defthm collect-dynamic-equal-static-A-2
+ (implies (and (unique (a-collect-1 rc1))
+ (struct-equiv-A-ram-config rc2 rc1))
+ (equal (collect-A-updates-dynamic rc2)
+ (collect-A-updates-static rc1)))
+ :hints (("Goal" :use ((:instance collect-dynamic-equal-static-A-1
+ (rc1 rc2)))
+ :do-not-induct t)))
+
+
+(defthm collect-dynamic-equal-static-B-1
+ (implies (unique (b-collect-1 rc))
+ (equal (collect-B-updates-dynamic rc)
+ (collect-B-updates-static rc))))
+
+(in-theory (disable struct-equiv-B-ram-config apply-B-update))
+
+
+(defthm collect-dynamic-equal-static-B-2
+ (implies (and (unique (b-collect-1 rc1))
+ (struct-equiv-B-ram-config rc2 rc1))
+ (equal (collect-B-updates-dynamic rc2)
+ (collect-B-updates-static rc1)))
+ :hints (("Goal" :use ((:instance collect-dynamic-equal-static-B-1
+ (rc rc2)))
+ :do-not-induct t)))
+
+;----
+(defthm unique-append-f-1
+ (implies (unique (append a b))
+ (unique a))
+ :rule-classes :forward-chaining)
+
+(defthm unique-append-f-2
+ (implies (unique (append a b))
+ (unique b))
+ :rule-classes :forward-chaining)
+
+(defthm subset-b-updates-w-all
+ (subsetp (b-updates-w (collect-B-updates-static rc))
+ (b-collect-1 rc)))
+
+
+(defthm overlap-subset
+ (implies (and (overlap a c)
+ (subsetp a b)
+ (subsetp c d))
+ (overlap b d)))
+
+
+(defthm unique-implies-no-overlap-B-data-A-link
+ (implies (unique (append (b-collect-1 rc2)
+ (a-collect-1 rc1)))
+ (not (overlap (b-updates-w (collect-B-updates-static rc2))
+ (a-collect-link-cells-static rc1))))
+ :hints (("Goal" :in-theory (disable
+ overlap-subset
+ a-collect-1 b-collect-1)
+ :do-not-induct t
+ :use ((:instance overlap-subset
+ (a (b-updates-w
+ (collect-B-updates-static rc2)))
+ (b (b-collect-1 rc2))
+ (c (a-collect-link-cells-static rc1))
+ (d (a-collect-1 rc1))))))
+ :rule-classes :forward-chaining)
+
+
+
+(defthm collect-dynamic-equal-static-A-2-instance
+ (implies (unique (append (b-collect-1 (make-ram-config addr1 n1 ram))
+ (a-collect-1 (make-ram-config addr2 n2 ram))))
+ (equal (collect-A-updates-dynamic
+ (make-ram-config addr2 n2
+ (apply-b-updates (collect-B-updates-static
+ (make-ram-config addr1 n1 ram))
+ ram)))
+ (collect-A-updates-static
+ (make-ram-config addr2 n2 ram))))
+ :hints (("Goal" :use ((:instance no-overlap-implies-A-struct-equiv-lemma
+ (l (collect-B-updates-static
+ (make-ram-config addr1 n1 ram)))
+ (rc (make-ram-config addr2 n2 ram)))))))
+
+;
+; This above is an important step towards,
+; (equal (collect-bab-updates-dynamic addr1 n1 addr2 n2 addr3 n3 ram)
+; (collect-bab-updates-static addr1 n1 addr2 n2 addr3 n3 ram)))
+;
+
+; next we need to prove
+; (equal (collect-B-updates-dynamic
+; (make-ram-config addr3 n3
+; (apply-A-updates
+; (collect-A-updates-static
+; (make-ram-config addr2 n2 ram))
+; (apply-b-updates
+; (collect-B-updates-static
+; (make-ram-config addr1 n1 ram)) ram))))
+; (collect-B-updates-static
+; (make-ram-config addr3 n3 ram))))
+; We prove this by establishing reducing inner most of apply-X-updates to
+; structural-equivalence to original state
+
+(defthm unique-implies-no-overlap-B-data-B-link
+ (implies (unique (append (B-collect-1 rc1)
+ (B-collect-1 rc2)))
+ (not (overlap (b-updates-w (collect-B-updates-static rc1))
+ (B-collect-link-cells-static rc2))))
+ :hints (("Goal" :in-theory (disable
+ overlap-subset
+ a-collect-1 b-collect-1)
+ :do-not-induct t
+ :use ((:instance overlap-subset
+ (A (b-updates-w
+ (collect-B-updates-static rc1)))
+ (c (B-collect-link-cells-static rc2))
+ (b (B-collect-1 rc1))
+ (d (B-collect-1 rc2))))))
+ :rule-classes :forward-chaining)
+
+
+
+(defthm collect-dynamic-equal-static-B-3-instance-lemma-1
+ (implies (unique (append (b-collect-1 (make-ram-config addr1 n1 ram))
+ (b-collect-1 (make-ram-config addr3 n3 ram))))
+ (struct-equiv-B-ram-config
+ (make-ram-config addr3 n3
+ (apply-b-updates (collect-B-updates-static
+ (make-ram-config addr1 n1 ram))
+ ram))
+ (make-ram-config addr3 n3 ram)))
+ :hints (("Goal" :use ((:instance no-overlap-implies-B-struct-equiv-2-lemma
+ (l (collect-B-updates-static
+ (make-ram-config addr1 n1 ram)))
+ (rc (make-ram-config addr3 n3 ram))))))
+ :rule-classes :forward-chaining)
+
+
+
+
+(defthm subset-a-updates-w-all
+ (subsetp (a-updates-w (collect-a-updates-static rc))
+ (a-collect-1 rc)))
+
+
+(defthm unique-implies-no-overlap-A-data-B-link
+ (implies (unique (append (a-collect-1 rc1)
+ (b-collect-1 rc2)))
+ (not (overlap (a-updates-w (collect-A-updates-static rc1))
+ (B-collect-link-cells-static rc2))))
+ :hints (("Goal" :in-theory (disable
+ overlap-subset
+ a-collect-1 b-collect-1)
+ :do-not-induct t
+ :use ((:instance overlap-subset
+ (A (a-updates-w
+ (collect-A-updates-static rc1)))
+ (b (a-collect-1 rc1))
+ (c (b-collect-link-cells-static rc2))
+ (d (b-collect-1 rc2))))))
+ :rule-classes :forward-chaining)
+
+
+(defthm collect-dynamic-equal-static-B-3-instance-lemma-2
+ (implies (unique (append (a-collect-1 (make-ram-config addr2 n2 ram))
+ (b-collect-1 (make-ram-config addr3 n3 ram))))
+ (struct-equiv-B-ram-config
+ (make-ram-config addr3 n3
+ (apply-a-updates (collect-A-updates-static
+ (make-ram-config addr2 n2 ram))
+ ram))
+ (make-ram-config addr3 n3 ram)))
+ :hints (("Goal" :use ((:instance no-overlap-implies-B-struct-equiv-lemma
+ (l (collect-A-updates-static
+ (make-ram-config addr2 n2 ram)))
+ (rc (make-ram-config addr3 n3 ram))))))
+ :rule-classes :forward-chaining)
+
+
+(defthm collect-dynamic-equal-static-B-3-instance-lemma-3
+ (implies (unique (append (b-collect-1 (make-ram-config addr1 n1 ram))
+ (a-collect-1 (make-ram-config addr2 n2 ram))))
+ (struct-equiv-A-ram-config
+ (make-ram-config addr2 n2
+ (apply-b-updates (collect-B-updates-static
+ (make-ram-config addr1 n1 ram))
+ ram))
+ (make-ram-config addr2 n2 ram)))
+ :hints (("Goal" :use ((:instance no-overlap-implies-A-struct-equiv-lemma
+ (l (collect-B-updates-static
+ (make-ram-config addr1 n1 ram)))
+ (rc (make-ram-config addr2 n2 ram))))))
+ :rule-classes :forward-chaining)
+
+
+
+(defthm unique-append
+ (implies (unique (append a b c))
+ (unique (append a c)))
+ :hints (("Goal" :do-not '(generalize)))
+ :rule-classes :forward-chaining)
+
+(defthm subsetp-append-x
+ (subsetp x (append x l)))
+
+(defthm unique-append-f-3
+ (implies (unique (append a b c))
+ (unique (append a b)))
+ :rule-classes :forward-chaining)
+
+(defcong struct-equiv-B-ram-config equal (b-collect-1 rc) 1
+ :hints (("Goal" :induct (cong-induct-B rc rc-equiv)
+ :in-theory (enable struct-equiv-B-ram-config))))
+
+
+(defcong struct-equiv-A-ram-config equal (a-collect-1 rc) 1
+ :hints (("Goal" :induct (cong-induct rc rc-equiv)
+ :in-theory (enable struct-equiv-A-ram-config))))
+
+(defthm collect-dynamic-equal-static-B-3-instance-lemma
+ (implies (unique (append (b-collect-1 (make-ram-config addr1 n1 ram))
+ (a-collect-1 (make-ram-config addr2 n2 ram))
+ (b-collect-1 (make-ram-config addr3 n3 ram))))
+ (struct-equiv-B-ram-config
+ (make-ram-config addr3 n3
+ (apply-A-updates
+ (collect-A-updates-static
+ (make-ram-config addr2 n2 ram))
+ (apply-b-updates (collect-B-updates-static
+ (make-ram-config addr1
+ n1
+ ram)) ram)))
+ (make-ram-config addr3 n3 ram)))
+ :hints (("Goal" :in-theory (disable
+ collect-dynamic-equal-static-B-3-instance-lemma-2)
+ :use ((:instance collect-dynamic-equal-static-B-3-instance-lemma-2
+ (ram (apply-b-updates (collect-B-updates-static
+ (make-ram-config addr1 n1
+ ram)) ram)))))))
+
+
+;----------------------
+(defthm collect-dynamic-equal-static-B-3-instance
+ (implies (unique (append (b-collect-1 (make-ram-config addr1 n1 ram))
+ (a-collect-1 (make-ram-config addr2 n2 ram))
+ (b-collect-1 (make-ram-config addr3 n3 ram))))
+ (equal (collect-B-updates-dynamic
+ (make-ram-config addr3 n3
+ (apply-A-updates
+ (collect-A-updates-static
+ (make-ram-config addr2 n2 ram))
+ (apply-b-updates
+ (collect-B-updates-static
+ (make-ram-config addr1 n1 ram)) ram))))
+ (collect-B-updates-static
+ (make-ram-config addr3 n3 ram))))
+ :hints (("Goal" :use ((:instance collect-dynamic-equal-static-B-2
+ (rc2
+ (make-ram-config addr3 n3
+ (apply-A-updates
+ (collect-A-updates-static
+ (make-ram-config addr2 n2 ram))
+ (apply-b-updates
+ (collect-B-updates-static
+ (make-ram-config addr1 n1 ram)) ram))))
+ (rc1 (make-ram-config addr3 n3 ram))))))
+ :rule-classes :forward-chaining)
+
+;------
+(defun collect-bab-updates-static (addr1 n1 addr2 n2 addr3 n3 ram)
+ (let* ((rc1 (make-ram-config addr1 n1 ram))
+ (rc2 (make-ram-config addr2 n2 ram))
+ (rc3 (make-ram-config addr3 n3 ram)))
+ (list (collect-B-updates-static rc1)
+ (collect-A-updates-static rc2)
+ (collect-B-updates-static rc3))))
+
+
+
+(defthm unique-equal-collect-dynamic-to-static
+ (implies (unique (append (b-collect-1 (make-ram-config addr1 n1 ram))
+ (a-collect-1 (make-ram-config addr2 n2 ram))
+ (b-collect-1 (make-ram-config addr3 n3 ram))))
+ (equal (collect-bab-updates-dynamic addr1 n1 addr2 n2 addr3 n3 ram)
+ (collect-bab-updates-static addr1 n1 addr2 n2 addr3 n3 ram)))
+ :hints (("Goal" :in-theory (disable
+ apply-B-updates
+ apply-B-update
+ apply-A-updates
+ apply-A-update
+ struct-equiv-A-ram-config
+ struct-equiv-B-ram-config))))
+
+
+(defthm not-mem-append-f-1
+ (implies (not (member x (append a b)))
+ (not (member x a)))
+ :rule-classes :forward-chaining)
+
+(defthm not-mem-append-f-2
+ (implies (not (member x (append a b)))
+ (not (member x b)))
+ :rule-classes :forward-chaining)
+
+
+(defthm read-over-bab
+ (implies
+ (let ((list (append (b-collect ptr1 n1 ram)
+ (a-collect ptr2 n2 ram)
+ (b-collect ptr3 n3 ram)
+ )))
+ (and
+ (not (member addr list))
+ (unique list)))
+ (equal
+ (g addr (compose-bab ptr1 n1 ptr2 n2 ptr3 n3 ram))
+ (g addr ram))))
+
+
+; 4. Proof of property III
+; *****************************
+;
+(in-theory (enable apply-A-update apply-B-update))
+(defun a-data-cell-w-r (l)
+ (if (endp l) nil
+ (append (list (car l) (+ 2 (car l)))
+ (a-data-cell-w-r (cdr l)))))
+
+(defun b-data-cell-w-r (l)
+ (if (endp l) nil
+ (append (list (car l) (+ 2 (car l)))
+ (b-data-cell-w-r (cdr l)))))
+
+;; Introduce the concept of cells that will be used.
+
+
+(defthm g-after-apply-Bs
+ (implies (not (member x (b-data-cell-w-r l2)))
+ (equal (g x (apply-B-updates l2 ram))
+ (g x ram)))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defthm s-after-apply-Bs
+ (implies (not (member x (b-data-cell-w-r l2)))
+ (equal (s x any (apply-B-updates l2 ram))
+ (apply-B-updates l2 (s x any ram))))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defthm apply-A-after-apply-Bs
+ (implies (and (not (member a1 (b-data-cell-w-r l2)))
+ (not (member (+ 2 a1) (b-data-cell-w-r l2))))
+ (equal (apply-A-update a1 (apply-B-updates l2 ram))
+ (apply-B-updates l2 (apply-A-update a1 ram))))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defthm apply-update-ram
+ (implies (not (overlap (a-data-cell-w-r l1) (b-data-cell-w-r l2)))
+ (equal (apply-B-updates l2 (apply-A-updates l1 ram))
+ (apply-A-updates l1 (apply-B-updates l2 ram))))
+ :hints (("Goal" :in-theory (disable apply-A-update)
+ :do-not '(generalize))))
+
+
+(defthm subsetp-a-data-cell-w-r
+ (subsetp (a-data-cell-w-r (collect-a-updates-static rc1))
+ (a-collect-1 rc1)))
+
+(defthm subsetp-b-data-cell-w-r
+ (subsetp (b-data-cell-w-r (collect-b-updates-static rc1))
+ (b-collect-1 rc1)))
+
+
+(defthm unqiue-app-implies-w-r-w-r-no-overlap
+ (implies (unique (append (a-collect-1 rc1)
+ (b-collect-1 rc2)))
+ (not (overlap (a-data-cell-w-r (collect-A-updates-static rc1))
+ (b-data-cell-w-r (collect-B-updates-static rc2)))))
+ :hints (("Goal" :in-theory (disable overlap-subset)
+ :use ((:instance overlap-subset
+ (a (a-data-cell-w-r
+ (collect-A-updates-static rc1)))
+ (b (a-collect-1 rc1))
+ (c (b-data-cell-w-r
+ (collect-B-updates-static rc2)))
+ (d (b-collect-1 rc2)))))))
+
+
+(defthm |Subgoal *1/3'4'|
+ (IMPLIES (not (member x (append l2 l1)))
+ (equal (UNIQUE (APPEND l1 (CONS x l2)))
+ (unique (append l1 l2))))
+ :hints (("Goal" :do-not '(generalize))))
+
+(defthm unique-append-rev
+ (implies (unique (append a b))
+ (unique (append b a))))
+
+
+(defthm a-mark-over-b-mark
+ (implies
+ (let ((list (append (a-collect ptr1 n1 ram)
+ (b-collect ptr2 n2 ram))))
+ (unique list))
+ (equal
+ (a-mark-objects ptr1 n1 (b-mark-objects ptr2 n2 ram))
+ (b-mark-objects ptr2 n2 (a-mark-objects ptr1 n1 ram)))))
+
+; 5. Generalization
+; *****************************
+; In sol2.lisp
diff --git a/books/workshops/2003/hbl/support/sol2.lisp b/books/workshops/2003/hbl/support/sol2.lisp
new file mode 100644
index 0000000..0fd14aa
--- /dev/null
+++ b/books/workshops/2003/hbl/support/sol2.lisp
@@ -0,0 +1,3010 @@
+;(acl2::set-match-free-error nil)
+(in-package "ACL2")
+(include-book "misc/records" :dir :system)
+(include-book "arithmetic/top-with-meta" :dir :system)
+(include-book "ordinals/e0-ordinal" :dir :system)
+(set-well-founded-relation e0-ord-<)
+;-------------------
+;; use record book instead of using list
+
+(defmacro make-rc (ptrs ram map)
+ `(s 'ptrs ,ptrs (s 'ram ,ram (s 'map ,map nil))))
+
+
+;; not this ptrs is expected to a list of 3 turples
+;; (typ addr n)
+
+(defmacro ptrs (rc) `(g 'ptrs ,rc))
+(defmacro ram (rc) `(g 'ram ,rc))
+(defmacro getmap (rc) `(g 'map ,rc))
+
+(defmacro set-ptrs (ptrs rc) `(s 'ptrs ,ptrs ,rc))
+(defmacro set-ram (ram rc) `(s 'ram ,ram ,rc))
+(defmacro set-map (map rc) `(s 'map ,map ,rc))
+
+(defun set-equal (a b)
+ (and (subsetp a b)
+ (subsetp b a)))
+
+(defthm subsetp-append
+ (subsetp a (append b a)))
+
+(defthm append-nil-x-x
+ (equal (append nil a) a))
+
+(defthm subsetp-reflexive
+ (subsetp a a)
+ :hints (("Goal"
+ :use ((:instance subsetp-append (b nil))))))
+
+(defthm subsetp-transitive
+ (implies (and (subsetp a b)
+ (subsetp b c))
+ (subsetp a c)))
+
+(defequiv set-equal)
+
+(defun seq-int (start len)
+ (if (zp len)
+ nil
+ (cons (+ 0 start)
+ (seq-int (1+ start) (1- len)))))
+
+(defun struct-equiv-1-aux-m (typ-or-typs n mode)
+ (cond ((equal mode 'ATOM)
+ (cons (+ 1 (nfix n)) 0))
+ ((equal mode 'LIST)
+ (cons (+ 1 (nfix n)) (len typ-or-typs)))
+ (t 0)))
+
+(defun struct-equiv-1-aux (typ-or-typs ptr-or-ptrs n ram1 ram2 map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) t
+ (if (zp ptr) t
+ (if (not (assoc-equal typ map)) t
+ (if (not (equal (g ptr ram1)
+ (g ptr ram2))) nil
+ (let ((addr (g ptr ram1)))
+ (struct-equiv-1-aux desc
+ (seq-int addr size)
+ (- n 1)
+ ram1 ram2 map 'LIST))))))))
+ ((equal mode 'LIST)
+ (if (endp typs) t
+ (if (not (assoc-equal (car typs) map))
+ (struct-equiv-1-aux
+ (cdr typs) (cdr ptrs) n ram1 ram2 map 'LIST)
+ (and (struct-equiv-1-aux (car typs) (car ptrs) n ram1 ram2 map 'ATOM)
+ (struct-equiv-1-aux (cdr typs) (cdr ptrs) n ram1 ram2 map 'LIST)))))
+ (t t))))
+
+(defun struct-equiv-1 (typ addr n ram1 ram2 map)
+ (struct-equiv-1-aux typ addr n ram1 ram2 map 'ATOM))
+
+(defun struct-equiv-1-list (typs addrs n ram1 ram2 map)
+ (struct-equiv-1-aux typs addrs n ram1 ram2 map 'LIST))
+
+;--------
+(defun typ (ptrs) (car ptrs))
+(defun addr (ptrs) (cadr ptrs))
+(defun n (ptrs) (caddr ptrs))
+
+(defun typ-list (ptrs)
+ (if (endp ptrs) nil
+ (cons (typ (car ptrs)) (typ-list (cdr ptrs)))))
+
+(defun addr-list (ptrs)
+ (if (endp ptrs) nil
+ (cons (addr (car ptrs)) (addr-list (cdr ptrs)))))
+
+(defun n-list (ptrs)
+ (if (endp ptrs) nil
+ (cons (n (car ptrs)) (n-list (cdr ptrs)))))
+
+(defun all-struct-equiv-1 (typs addrs ns ram1 ram2 map)
+ (if (endp typs) t
+ (and (struct-equiv-1 (car typs) (car addrs) (car ns) ram1 ram2 map)
+ (all-struct-equiv-1 (cdr typs) (cdr addrs) (cdr ns) ram1 ram2 map))))
+
+(defun struct-equiv (rc1 rc2)
+ (and (set-equal (ptrs rc1) (ptrs rc2))
+ (equal (getmap rc1) (getmap rc2))
+ (all-struct-equiv-1 (typ-list (ptrs rc1))
+ (addr-list (ptrs rc1))
+ (n-list (ptrs rc1))
+ (ram rc1) (ram rc2) (getmap rc1))))
+
+;------------- prove this a equivalence relation ----
+
+(defthm struct-equiv-1-aux-reflexive
+ (struct-equiv-1-aux typ-of-typs ptr-or-ptrs n ram ram map mode))
+
+(defthm struct-equiv-1-aux-symentric
+ (implies (struct-equiv-1-aux typ-of-typs ptr-or-ptrs n ram1 ram2 map mode)
+ (struct-equiv-1-aux typ-of-typs ptr-or-ptrs n ram2 ram1 map mode)))
+
+(defthm struct-equiv-1-aux-implies-g-ptr-equal
+ (implies (and (struct-equiv-1-aux typ ptr n ram1 ram2 map mode)
+ (not (zp n))
+ (not (zp ptr))
+ (equal mode 'ATOM)
+ (assoc-equal typ map))
+ (equal (g ptr ram1) (g ptr ram2)))
+ :rule-classes :forward-chaining)
+
+(defthm struct-equiv-1-aux-transitive
+ (implies (and (struct-equiv-1-aux typ-of-typs ptr-or-ptrs n
+ ram1 ram2 map mode)
+ (struct-equiv-1-aux typ-of-typs ptr-or-ptrs n
+ ram2 ram3 map mode))
+ (struct-equiv-1-aux typ-of-typs ptr-or-ptrs n
+ ram1 ram3 map mode)))
+
+(defthm all-struct-equiv-1-reflexive
+ (all-struct-equiv-1 typs addrs ns ram ram map))
+
+(defthm all-struct-equiv-1-symentric
+ (implies (all-struct-equiv-1 typs addrs ns ram1 ram2 map)
+ (all-struct-equiv-1 typs addrs ns ram2 ram1 map)))
+
+(defthm all-struct-equiv-1-transitive
+ (implies (and (all-struct-equiv-1 typs addrs ns ram1 ram2 map)
+ (all-struct-equiv-1 typs addrs ns ram2 ram3 map))
+ (all-struct-equiv-1 typs addrs ns ram1 ram3 map)))
+
+
+;------------
+
+(in-theory (disable struct-equiv-1))
+
+(defthm all-struct-equiv-1-mem
+ (implies (and (member ptr ptrs)
+ (not (struct-equiv-1 (typ ptr) (addr ptr) (n ptr) ram1 ram2 map)))
+ (not (all-struct-equiv-1 (typ-list ptrs) (addr-list ptrs) (n-list ptrs)
+ ram1 ram2 map))))
+
+
+
+(defthm all-struct-equiv-1-subsetp
+ (implies (and (subsetp ptrs2 ptrs1)
+ (all-struct-equiv-1 (typ-list ptrs1)
+ (addr-list ptrs1)
+ (n-list ptrs1)
+ ram1 ram2 map))
+ (all-struct-equiv-1 (typ-list ptrs2)
+ (addr-list ptrs2)
+ (n-list ptrs2)
+ ram1 ram2 map)))
+
+
+
+(defthm struct-equiv-transitive
+ (implies (and (struct-equiv rc1 rc2)
+ (struct-equiv rc2 rc3))
+ (struct-equiv rc1 rc3)))
+
+;; (in-theory (disable set-equal))
+
+(defequiv struct-equiv)
+
+
+;--------------
+
+(defun collect-link-cells-1-aux
+ (typ-or-typs ptr-or-ptrs n ram map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) nil
+ (if (zp ptr) nil
+ (if (not (assoc-equal typ map))
+ nil
+ (let ((addr (g ptr ram)))
+ (cons ptr (collect-link-cells-1-aux desc
+ (seq-int addr size)
+ (- n 1)
+ ram map 'LIST))))))))
+
+ ((equal mode 'LIST)
+ (if (endp typs) nil
+ (if (not (assoc-equal (car typs) map)) ;; skip non pointer
+ (collect-link-cells-1-aux (cdr typs) (cdr ptrs) n ram map 'LIST)
+ (append (collect-link-cells-1-aux (car typs)
+ (car ptrs)
+ n
+ ram map 'ATOM)
+ (collect-link-cells-1-aux (cdr typs)
+ (cdr ptrs)
+ n
+ ram map 'LIST)))))
+ (t nil))))
+
+
+;---------------
+(defun collect-link-cells-1 (typ addr n ram map)
+ (collect-link-cells-1-aux typ addr n ram map 'ATOM))
+
+(defun collect-link-cells-1-list (typs addrs n ram map)
+ (collect-link-cells-1-aux typs addrs n ram map 'LIST))
+
+
+(defun all-collect-link-cells-1 (typs addrs ns ram map)
+ (if (endp typs)
+ nil
+ (append (collect-link-cells-1 (car typs) (car addrs) (car ns) ram map)
+ (all-collect-link-cells-1 (cdr typs) (cdr addrs) (cdr ns) ram map))))
+
+;---------------
+
+(defun collect-link-cells (rc)
+ (all-collect-link-cells-1 (typ-list (ptrs rc))
+ (addr-list (ptrs rc))
+ (n-list (ptrs rc))
+ (ram rc) (getmap rc)))
+
+
+;; next task (defcong struct-equiv
+
+(defthm member-append-1
+ (implies (member x b)
+ (member x (append a b))))
+
+(defthm member-append-2
+ (implies (member x a)
+ (member x (append a b))))
+
+(defthm subsetp-append-x-1
+ (implies (subsetp a b)
+ (subsetp (append a c)
+ (append b c))))
+
+(defthm subsetp-append-x-2
+ (implies (subsetp a b)
+ (subsetp (append c a)
+ (append c b))))
+
+
+
+(defcong set-equal set-equal (append a b) 1)
+(defcong set-equal set-equal (append a b) 2)
+
+(defthm subsetp-append-b
+ (subsetp a (append a b)))
+
+(defthm subsetp-collect-link-cells-1-subsetp
+ (implies (member ptr ptrs)
+ (subsetp (collect-link-cells-1 (typ ptr)
+ (addr ptr)
+ (n ptr)
+ ram map)
+ (all-collect-link-cells-1 (typ-list ptrs)
+ (addr-list ptrs)
+ (n-list ptrs)
+ ram map)))
+ :hints (("Goal" :in-theory (disable collect-link-cells-1)
+ :do-not '(generalize))))
+
+(in-theory (disable typ addr n))
+
+(defthm subsetp-merged-still-subsetp
+ (implies (and (subsetp a b)
+ (subsetp c b))
+ (subsetp (append a c) b)))
+
+
+(defthm subsetp-all-collect-link-cells-1-subsetp
+ (implies (subsetp ptrs1 ptrs2)
+ (subsetp (all-collect-link-cells-1 (typ-list ptrs1)
+ (addr-list ptrs1)
+ (n-list ptrs1)
+ ram map)
+ (all-collect-link-cells-1 (typ-list ptrs2)
+ (addr-list ptrs2)
+ (n-list ptrs2)
+ ram map)))
+ :hints (("Goal" :in-theory (disable collect-link-cells-1))))
+
+
+
+(defthm set-equal-collect-link-cells-1-set-equal
+ (implies (and (set-equal ptrs1 ptrs2)
+ ;; Added for mod to ACL2 v2-8 that does better matching for
+ ;; calls of equivalence relations against the current context:
+ (syntaxp (not (term-order ptrs1 ptrs2))))
+ (set-equal (all-collect-link-cells-1 (typ-list ptrs1)
+ (addr-list ptrs1)
+ (n-list ptrs1)
+ ram map)
+ (all-collect-link-cells-1 (typ-list ptrs2)
+ (addr-list ptrs2)
+ (n-list ptrs2)
+ ram map))))
+
+
+(defthm struct-equiv-1-aux-implies-collect-link-cells-aux-equal
+ (implies (struct-equiv-1-aux typ-or-typs ptr-or-ptrs n ram1 ram2 map mode)
+ (equal (collect-link-cells-1-aux typ-or-typs ptr-or-ptrs n
+ ram1 map mode)
+ (collect-link-cells-1-aux typ-or-typs ptr-or-ptrs n
+ ram2 map mode))))
+
+
+(defthm struct-equiv-1-equal-collect-link-cells-1-equal
+ (implies (all-struct-equiv-1 typs addrs ns ram1 ram2 map)
+ (equal (all-collect-link-cells-1 typs
+ addrs
+ ns
+ ram1 map)
+ (all-collect-link-cells-1 typs
+ addrs
+ ns
+ ram2 map)))
+ :hints (("Goal" :in-theory (enable struct-equiv-1))))
+
+
+;--------------
+(in-theory (disable set-equal))
+
+
+(defcong struct-equiv set-equal (collect-link-cells rc) 1)
+
+;-- need to prove update to the non link cell keep the struct-equiv
+
+(defthm not-member-append-f-1
+ (implies (not (member x (append a b)))
+ (not (member x a)))
+ :rule-classes :forward-chaining)
+
+(defthm not-member-append-f-2
+ (implies (not (member x (append a b)))
+ (not (member x b)))
+ :rule-classes :forward-chaining)
+
+
+(defun struct-equiv-1-induct (addrx typ-or-typs ptr-or-ptrs n ram map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) t
+ (if (zp ptr) t
+ (if (not (assoc-equal typ map)) t
+ (if (equal addrx ptr) t
+ (let ((addr (g ptr ram)))
+ (struct-equiv-1-induct addrx desc (seq-int addr size)
+ (- n 1) ram map 'LIST))))))))
+ ((equal mode 'LIST)
+ (if (endp typs) t
+ (if (not (assoc-equal (car typs) map))
+ (struct-equiv-1-induct addrx (cdr typs) (cdr ptrs) n ram map 'LIST)
+ (list (struct-equiv-1-induct addrx (car typs) (car ptrs) n ram map 'ATOM)
+ (struct-equiv-1-induct addrx (cdr typs) (cdr ptrs) n ram map 'LIST)))))
+ (t (list addrx typ-or-typs ptr-or-ptrs n ram map mode)))))
+
+
+(defthm struct-equiv-1-aux-atom-implies-member
+ (implies (AND
+ (NOT (ZP N))
+ (NOT (ZP ADDR))
+ (ASSOC-EQUAL TYP MAP))
+ (MEMBER ADDR
+ (COLLECT-LINK-CELLS-1-AUX TYP ADDR N RAM MAP
+ 'ATOM)))
+ :hints (("Goal" :expand (COLLECT-LINK-CELLS-1-AUX TYP ADDR N RAM MAP 'ATOM))))
+
+(defthm struct-equiv-1-aux-s-add-v-struct-equiv-1-aux
+ (implies (not (member addr (collect-link-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)))
+ (struct-equiv-1-aux typ-or-typs ptr-or-ptrs n
+ (s addr any ram) ram map mode))
+ :hints (("Goal" :induct (struct-equiv-1-induct addr typ-or-typs ptr-or-ptrs n ram
+ map mode)
+ :do-not '(generalize))))
+
+;-----------------------
+
+(defthm all-struct-equiv-1-s-add-v-all-struct-equiv-1
+ (implies (not (member addr (all-collect-link-cells-1
+ typs ptrs ns ram map)))
+ (all-struct-equiv-1 typs ptrs ns
+ (s addr any ram) ram map))
+ :hints (("Goal" :in-theory (enable struct-equiv-1))))
+
+
+(defthm struct-equiv-preserved-if-update-non-link-cell
+ (implies (not (member addr (collect-link-cells rc)))
+ (struct-equiv (set-ram (s addr v (ram rc)) rc)
+ rc)))
+
+;-----------------------
+
+;;
+;; done with the proof that (s addr v ram) preserve struct-equiv
+;; so far, we have
+;;
+;; (defcong struct-equiv set-equal (collect-link-cells rc) 1)
+;;
+;; and
+;;
+;; struct-equiv-preserved-if-update-non-link-cell
+;;
+
+
+;
+;--- define the generic mark algorithm, that only change data cells
+;
+
+;;
+;; we need to be able to tell that data cell value only depend on data cells
+;;
+
+
+(defun collect-data-cells-1-aux (typ-or-typs ptr-or-ptrs n ram map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) nil
+ (if (zp ptr) nil
+ (if (not (assoc-equal typ map))
+ nil
+ ;; maybe I should modify it so that it matches with
+ ;; collect-updates. i.e. collect data cells here in one
+ ;; batch. Still want a try with the other proof.
+ (let ((addr (g ptr ram)))
+ (collect-data-cells-1-aux desc
+ (seq-int addr size)
+ (- n 1)
+ ram map 'LIST)))))))
+ ((equal mode 'LIST)
+ (if (endp typs) nil
+ (if (not (assoc-equal (car typs) map))
+ ;; this is a data cell, recorded it.
+ (cons (car ptrs)
+ (collect-data-cells-1-aux (cdr typs) (cdr ptrs)
+ n ram map 'LIST))
+ (append (collect-data-cells-1-aux (car typs)
+ (car ptrs)
+ n
+ ram map 'ATOM)
+ (collect-data-cells-1-aux (cdr typs)
+ (cdr ptrs)
+ n
+ ram map 'LIST)))))
+ (t nil))))
+
+
+;-----------
+
+(defun collect-data-cells-1 (typ addr n ram map)
+ (collect-data-cells-1-aux typ addr n ram map 'ATOM))
+
+(defun collect-data-cells-1-list (typs addrs n ram map)
+ (collect-link-cells-1-aux typs addrs n ram map 'LIST))
+
+
+(defun all-collect-data-cells-1 (typs addrs ns ram map)
+ (if (endp typs)
+ nil
+ (append (collect-data-cells-1 (car typs) (car addrs) (car ns) ram map)
+ (all-collect-data-cells-1 (cdr typs) (cdr addrs) (cdr ns) ram map))))
+
+;------------
+
+(defun collect-data-cells (rc)
+ (all-collect-data-cells-1 (typ-list (ptrs rc))
+ (addr-list (ptrs rc))
+ (n-list (ptrs rc))
+ (ram rc) (getmap rc)))
+
+;; prove (defcong .... )
+
+(defthm subsetp-collect-data-cells-1-subsetp
+ (implies (member ptr ptrs)
+ (subsetp (collect-data-cells-1 (typ ptr)
+ (addr ptr)
+ (n ptr)
+ ram map)
+ (all-collect-data-cells-1 (typ-list ptrs)
+ (addr-list ptrs)
+ (n-list ptrs)
+ ram map)))
+ :hints (("Goal" :in-theory (disable collect-data-cells-1)
+ :do-not '(generalize))))
+
+
+(defthm subsetp-all-collect-data-cells-1-subsetp
+ (implies (subsetp ptrs1 ptrs2)
+ (subsetp (all-collect-data-cells-1 (typ-list ptrs1)
+ (addr-list ptrs1)
+ (n-list ptrs1)
+ ram map)
+ (all-collect-data-cells-1 (typ-list ptrs2)
+ (addr-list ptrs2)
+ (n-list ptrs2)
+ ram map)))
+ :hints (("Goal" :in-theory (disable collect-data-cells-1))))
+
+
+(defthm set-equal-collect-data-cells-1-set-equal
+ (implies (and (set-equal ptrs1 ptrs2)
+ ;; Added for mod to ACL2 v2-8 that does better matching for
+ ;; calls of equivalence relations against the current context:
+ (syntaxp (not (term-order ptrs1 ptrs2))))
+ (set-equal (all-collect-data-cells-1 (typ-list ptrs1)
+ (addr-list ptrs1)
+ (n-list ptrs1)
+ ram map)
+ (all-collect-data-cells-1 (typ-list ptrs2)
+ (addr-list ptrs2)
+ (n-list ptrs2)
+ ram map)))
+ :hints (("Goal" :in-theory (enable set-equal))))
+
+
+(defthm struct-equiv-1-aux-implies-collect-data-cells-aux-equal
+ (implies (struct-equiv-1-aux typ-or-typs ptr-or-ptrs n ram1 ram2 map mode)
+ (equal (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs n
+ ram1 map mode)
+ (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs n
+ ram2 map mode))))
+
+
+(defthm struct-equiv-1-equal-collect-data-cells-1-equal
+ (implies (all-struct-equiv-1 typs addrs ns ram1 ram2 map)
+ (equal (all-collect-data-cells-1 typs
+ addrs
+ ns
+ ram1 map)
+ (all-collect-data-cells-1 typs
+ addrs
+ ns
+ ram2 map)))
+ :hints (("Goal" :in-theory (enable struct-equiv-1))))
+
+(defcong struct-equiv set-equal (collect-data-cells rc) 1)
+
+;----------------
+;;
+;; the problem here is how to characterize all possible updates?
+;;
+;; A constraint function is good. However to argue it can model all possible
+;; computation need some efforts.
+;;
+;; Because in this mark function, we update in the pre-order, once we reach
+;; some node, we update, then we continue, etc.
+;;
+;; It is hard to argue that we could implement all kinds of update order,
+;; because it is possible that the data value depends on the order we do them.
+;;
+;; In J's model, the value of new data fills only depends on the old data
+;; within the same node.
+;;
+;; In my model, I want to extend that to all possible data fields reachable.
+;;
+;; Then I have to face this problem.
+;;
+
+
+
+;; say only change up
+
+(encapsulate
+ ((new-field-value (typ ptr i n ram map) t))
+ (local (defun new-field-value (typ ptr i n ram map)
+ (declare (ignore typ ptr i n ram map))
+ 0))
+ (defthm new-field-value-s-commutes
+ (implies (not (member addr (append (collect-data-cells-1 typ ptr n ram map)
+ (collect-link-cells-1 typ ptr n ram map))))
+ (equal (new-field-value typ ptr i n (s addr val ram) map)
+ (new-field-value typ ptr i n ram map)))))
+
+;;
+;; This is to say, any write outside the reachable data+link fields,
+;; doesn't matter to the new-field-value
+;;
+
+(defun single-update1 (typ ptr i n ram map)
+ (declare (xargs :measure (nfix (- (len (cdr (assoc-equal typ map)))
+ (nfix i)))))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor))
+ (addr (g ptr ram)))
+ (if (zp ptr) ram
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (single-update1 typ ptr (+ i 1) n ram map)
+ ;; else not a struct type, update the value
+ (let ((ram (s (+ addr i) (new-field-value typ ptr i n ram map) ram)))
+ ;; let the new value depends on the changes to the previous slos
+ (single-update1 typ ptr (+ i 1) n ram map)))
+ ram))))
+
+;; (defstub single-update2 (types addr size ram map) ram) ;; update in inorder
+;; (defstub single-update3 (type ptr size ram map) ram) ;; update in postorder
+
+;;
+;; chose not to deal with those now.
+;;
+;;
+;; assume our constainted new-value is so powerful that it can emulates all
+;; possible changes with in-order and post-order updates, arbitary updates.
+;;
+;; not so sure. this is possible,
+;;
+;; I could find a particular way of updating memory that cause the program
+;; enter into a loop, however oracle in the single-updates have to garantee to
+;; provide us an initial ram to result in the same loop....
+;; it is possible, because oracle can detect if the initial ram config is ...
+;;
+;;
+
+(defun mark-1-aux (typ-or-typs ptr-or-ptrs n ram map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) ram
+ (if (zp ptr) ram
+ (if (not (assoc-equal typ map)) ;; not bound
+ ram
+ (let* ((addr (g ptr ram))
+ (new-ram (single-update1 typ ptr 0 n ram map)))
+ (mark-1-aux desc
+ (seq-int addr size)
+ (- n 1)
+ new-ram map 'LIST)))))))
+ ((equal mode 'LIST)
+ (if (endp typs)
+ ram
+ (if (not (assoc-equal (car typs) map))
+ (mark-1-aux (cdr typs) (cdr ptrs) n ram map 'LIST)
+ (let ((new-ram (mark-1-aux (car typs)
+ (car ptrs)
+ n
+ ram map 'ATOM)))
+ (mark-1-aux (cdr typs)
+ (cdr ptrs)
+ n
+ new-ram map 'LIST)))))
+ (t ram))))
+
+
+;--- mark-1
+(defun mark-1 (typ addr n ram map)
+ (mark-1-aux typ addr n ram map 'ATOM))
+
+(defun mark-1-list (typs addrs n ram map)
+ (mark-1-aux typs addrs n ram map 'LIST))
+
+;-------------
+
+(defun all-mark-1 (typs addrs ns ram map)
+ (if (endp typs)
+ ram
+ (all-mark-1 (cdr typs) (cdr addrs) (cdr ns)
+ (mark-1 (car typs) (car addrs) (car ns) ram map)
+ map)))
+
+;-------------
+
+(defun mark (rc)
+ (all-mark-1 (typ-list (ptrs rc))
+ (addr-list (ptrs rc))
+ (n-list (ptrs rc))
+ (ram rc)
+ (getmap rc)))
+
+;------------
+;;
+;; update is of this format (type ptr i n),
+;; new-value depends on these
+;;
+
+;; relevence analysis problem.
+
+(defun m-collect-updates (typ map i ram)
+ (declare (ignore ram))
+ (nfix (- (len (cdr (assoc-equal typ map)))
+ (nfix i))))
+
+
+(defun make-update (typ ptr i n)
+ (list typ ptr i n))
+
+(defun gtyp (update) (car update))
+(defun gptr (update) (cadr update))
+(defun gi (update) (caddr update))
+(defun gn (update) (caddr (cdr update)))
+
+(defthm make-update-accessor
+ (and (equal (gtyp (make-update typ ptr i n)) typ)
+ (equal (gptr (make-update typ ptr i n)) ptr)
+ (equal (gi (make-update typ ptr i n)) i)
+ (equal (gn (make-update typ ptr i n)) n)))
+
+(in-theory (disable make-update gtyp gptr gi gn))
+
+
+(defun collect-updates-from-single-update1 (typ ptr i n ram map)
+ (declare (xargs :measure (m-collect-updates typ map i ram)))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor))
+ (addr (g ptr ram)))
+ (if (zp ptr) nil
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (collect-updates-from-single-update1 typ ptr (+ i 1) n ram map)
+ ;; else not a struct type, update the value
+ (let ((new-ram (s (+ addr i) (new-field-value typ ptr i n ram map) ram)))
+ ;; let the new value depends on the changes to the previous slos
+ (cons (make-update typ ptr i n)
+ (collect-updates-from-single-update1 typ ptr (+ i 1) n
+ new-ram map))))
+ nil))))
+
+
+(defun collect-updates-zdynamic-1-aux (typ-or-typs ptr-or-ptrs n ram map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) nil
+ (if (zp ptr) nil
+ (if (not (assoc-equal typ map)) ;; not bound
+ nil
+ (let* ((addr (g ptr ram))
+ (new-ram (single-update1 typ ptr 0 n ram map)))
+ (append (collect-updates-from-single-update1
+ typ ptr 0 n ram map)
+ (collect-updates-zdynamic-1-aux
+ desc
+ (seq-int addr size)
+ (- n 1)
+ new-ram map 'LIST))))))))
+ ((equal mode 'LIST)
+ (if (endp typs)
+ nil
+ (if (not (assoc-equal (car typs) map))
+ (collect-updates-zdynamic-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST)
+ (let ((new-ram (mark-1-aux (car typs)
+ (car ptrs)
+ n
+ ram map 'ATOM)))
+ (append (collect-updates-zdynamic-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM)
+ (collect-updates-zdynamic-1-aux (cdr typs)
+ (cdr ptrs)
+ n
+ new-ram map 'LIST))))))
+ (t nil))))
+
+
+;---------- prove apply-dynamic update equal to mark on the fly
+;
+; update is a (typ ptr i n)
+;
+;
+
+(defun apply-update (update ram map)
+ (let ((typ (gtyp update))
+ (ptr (gptr update))
+ (i (gi update))
+ (n (gn update)))
+ (let ((addr (g ptr ram)))
+ (s (+ addr i) (new-field-value typ ptr i n ram map) ram))))
+
+
+(defun apply-updates (updates ram map)
+ (if (endp updates) ram
+ (apply-updates (cdr updates) (apply-update (car updates) ram map) map)))
+
+
+(defthm apply-updates-collect-updates-from-single-update1-is-single-update1
+ (equal (single-update1 typ ptr i n ram map)
+ (apply-updates (collect-updates-from-single-update1
+ typ ptr i n ram map)
+ ram map)))
+
+
+(defthm apply-updates-append
+ (equal (apply-updates (append updates1 updates2) ram map)
+ (apply-updates updates2
+ (apply-updates updates1 ram map) map)))
+
+(in-theory (disable apply-update))
+
+(defthm apply-updates-collect-dynamic-is-mark
+ (equal (mark-1-aux typ-or-typs ptr-or-ptrs n ram map mode)
+ (apply-updates (collect-updates-zdynamic-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)
+ ram map))
+ :hints (("Goal" :do-not '(generalize))))
+
+;
+;--------------------
+;
+
+(defun collect-updates-dynamic-1 (typ ptr n ram map)
+ (collect-updates-zdynamic-1-aux typ ptr n ram map 'ATOM))
+
+(defun collect-updates-dynamic-1-list (typs ptrs n ram map)
+ (collect-updates-zdynamic-1-aux typs ptrs n ram map 'LIST))
+
+
+;--------------------
+
+(defun all-collect-updates-dynamic-1 (typs ptrs ns ram map)
+ (if (endp typs)
+ nil
+ (append (collect-updates-dynamic-1 (car typs) (car ptrs) (car ns)
+ ram map)
+ (all-collect-updates-dynamic-1
+ (cdr typs) (cdr ptrs) (cdr ns)
+ (mark-1 (car typs) (car ptrs) (car ns) ram map)
+ map))))
+
+;--------------
+
+(defun collect-updates-dynamic (rc)
+ (all-collect-updates-dynamic-1 (typ-list (ptrs rc))
+ (addr-list (ptrs rc))
+ (n-list (ptrs rc))
+ (ram rc)
+ (getmap rc)))
+
+;--------------
+
+(defthm all-mark-1-is-apply-update-1
+ (equal (all-mark-1 typs addrs ns ram map)
+ (apply-updates (all-collect-updates-dynamic-1 typs addrs ns ram map)
+ ram map)))
+
+
+(defthm apply-equal-mark
+ (equal (mark rc)
+ (apply-updates (collect-updates-dynamic rc)
+ (ram rc) (getmap rc))))
+
+;--------------
+;;
+;; next is to prove struct-equiv,
+;; is if data cell doesn't overlap with link cell,
+;; then collect-dyanmic is collect-static
+;;
+
+
+(defun overlap (a b)
+ (if (endp a) nil
+ (or (member (car a) b)
+ (overlap (cdr a) b))))
+
+(defun update-2-w (update ram)
+ (let ((ptr (gptr update))
+ (i (gi update)))
+ (+ i (g ptr ram))))
+
+(defun updates-2-ws (updates ram map)
+ (if (endp updates)
+ nil
+ (cons (update-2-w (car updates) ram)
+ (updates-2-ws (cdr updates) (apply-update (car updates) ram map)
+ map))))
+
+(defthm member-append
+ (implies (member x a)
+ (member x (append a b))))
+
+(defthm inrange-seen
+ (implies (and (not (zp l))
+ (integerp x)
+ (integerp y)
+ (integerp l)
+ (< y (+ x l))
+ (<= x y))
+ (member y (seq-int x l)))
+ :hints (("Goal" :do-not '(generalize))))
+
+(defthm consp-car-append
+ (implies (consp l)
+ (equal (car (append l x))
+ (car l))))
+
+
+(defthm consp-implies-consp
+ (implies (and (consp (append a b))
+ (not (consp b)))
+ (consp a))
+ :rule-classes :forward-chaining)
+
+
+;----------------------------------
+;
+; very awkward, because our collect-data-cell doesn't match our collect-updates.
+;
+; collect-data-cell, record the data cell, in collect-data-cell-1-list
+; while collect-updates-dymanic collect data-cell in collect-data-cell-1
+;
+
+(defthm first-update-must-be-a-data-field
+ (implies (consp (collect-updates-from-single-update1 TYP PTR I N RAM MAP))
+ (not (assoc-equal (nth (gi (car (collect-updates-from-single-update1 TYP PTR i N RAM MAP)))
+ (cdr (assoc-equal typ map)))
+ map)))
+ :hints (("Goal" :do-not '(generalize))))
+
+;
+; proved that first update must be a data cell, we can't claim more,
+; because the second update would be a data cell in a modified ram.
+; we can't show that data cell is a data cell in the original ram.
+;
+; unless we have already shown that there is no overlap between data cell and
+; link cell.
+;
+
+;--------------
+
+(defun pos (x l)
+ (if (endp l) 0
+ (if (equal (car l) x) 0
+ (+ 1 (pos x (cdr l))))))
+
+
+(defun not-assoc-equal-induct (typx typs ptrs)
+ (if (endp typs)
+ (list typx typs)
+ (if (equal (car typs) typx)
+ (list typx typs ptrs)
+ (not-assoc-equal-induct typx (cdr typs) (cdr ptrs)))))
+
+(defthm not-assoc-equal-must-be-in-collect-data-cell-list
+ (implies (and (member typx typs)
+ (not (assoc-equal typx map)))
+ (member (nth (pos typx typs) ptrs)
+ (collect-data-cells-1-aux typs
+ ptrs
+ n
+ ram map 'LIST)))
+ :hints (("Goal" :induct (not-assoc-equal-induct typx typs ptrs))))
+
+
+;;
+;; we need to prove (nth (gi ....)) is such a typx
+;; we probably don't have to prove the general case with i in the theorem.
+;;
+
+;--- First: prove member (gi ..)
+
+(defthm update-typ-i-is-in-range-1
+ (implies (consp (collect-updates-from-single-update1
+ TYP PTR I N RAM MAP))
+ (<= (nfix i) (gi (car (collect-updates-from-single-update1 typ ptr i n ram
+ map)))))
+ :hints (("Goal" :do-not '(generalize)))
+ :rule-classes :linear)
+
+(defthm update-typ-i-is-in-range-2
+ (implies (consp (collect-updates-from-single-update1
+ TYP PTR I N RAM MAP))
+ (< (gi (car (collect-updates-from-single-update1 typ ptr i n ram
+ map)))
+ (len (cdr (assoc-equal typ map)))))
+ :hints (("Goal" :do-not '(generalize)))
+ :rule-classes :linear)
+
+
+(defthm nth-member
+ (implies (and (<= 0 i)
+ (< i (len l)))
+ (member (nth i l) l)))
+
+(defun mycdrn (i l)
+ (if (zp i)
+ l
+ (mycdrn (- i 1) (cdr l))))
+
+
+(defthm member-nth-cdrn-2
+ (implies (and (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= i j)
+ (< j (len l)))
+ (member (nth j l)
+ (mycdrn i l))))
+
+
+(defthm integerp-gi-g-ptr-car-collect-update-from-single-update1
+ (implies (consp (collect-updates-from-single-update1 typ ptr i n ram map))
+ (integerp (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map)))))
+ :rule-classes :forward-chaining)
+
+(defthm first-update-typ-is-member-of-sig
+ (implies (consp (collect-updates-from-single-update1 typ ptr i n ram map))
+ (member (nth (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map)))
+ (cdr (assoc-equal typ map)))
+ (mycdrn i (cdr (assoc-equal typ map)))))
+ :hints (("Goal" :do-not '(generalize)))
+ :rule-classes :forward-chaining)
+
+
+;------------------
+;
+; Because we already have (member (nth (pos typx) ...) in data cells
+;
+; next we need to prove (nth (pos (nth (gi ...)) is (nth (gi ...))
+;
+;------------------
+
+(defthm pos-mycdrn
+ (implies (and (integerp i)
+ (<= 0 i)
+ (< i (len l)))
+ (equal (pos (nth i l)
+ (mycdrn i l)) 0)))
+
+
+(defthm assoc-equal-not-equal-nth-gi
+ (implies (and (consp (collect-updates-from-single-update1 typ ptr i n ram map))
+ (assoc-equal typx map))
+ (not (equal (nth (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map)))
+ (cdr (assoc-equal typ map)))
+ typx))))
+
+
+(defthm pos-mycdrn-2
+ (implies (and (integerp i)
+ (<= 0 i)
+ (< i (len l))
+ (not (equal x (nth i l))))
+ (equal (+ 1 (pos x (mycdrn i (cdr l))))
+ (pos x
+ (mycdrn i l)))))
+
+
+
+
+(defthm pos-is-gi
+ (implies (and (consp (collect-updates-from-single-update1 typ ptr i n ram map))
+ (integerp i)
+ (<= 0 i))
+ (equal (+ i (pos (nth (gi (car
+ (collect-updates-from-single-update1
+ typ ptr i n ram map)))
+ (cdr (assoc-equal typ map)))
+ (mycdrn i (cdr (assoc-equal typ map)))))
+ (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map))))))
+
+
+(defthm nth-pos-mycdrn
+ (implies (and (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j))
+ (equal (nth i (mycdrn j l))
+ (nth (+ j i) l))))
+
+
+
+(defthm nth-pos-is-nth-gi
+ (implies (and (consp (collect-updates-from-single-update1 typ ptr i n ram map))
+ (integerp i)
+ (<= 0 i))
+ (equal (nth (pos (nth (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map)))
+ (cdr (assoc-equal typ map)))
+ (mycdrn i (cdr (assoc-equal typ map))))
+ (mycdrn i ptrs))
+ (nth (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map)))
+ ptrs))))
+
+
+
+
+
+
+(defthm member-x-collect-data-cells-1-aux
+ (implies (member x (collect-data-cells-1-aux (mycdrn i typs)
+ (mycdrn i ptrs)
+ n
+ ram map 'LIST))
+ (member x (collect-data-cells-1-aux typs ptrs n ram map
+ 'LIST))))
+
+
+
+(defthm first-update-is-in-data-cells-colllect-lemma
+ (implies (and (consp (collect-updates-from-single-update1 TYP PTR I N RAM MAP))
+ (<= 0 i)
+ (integerp i))
+ (member
+ (nth (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map))) ptrs)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ ptrs
+ (- n 1)
+ ram map 'LIST)))
+ :hints (("Goal" :in-theory (disable not-assoc-equal-must-be-in-collect-data-cell-list)
+ :use ((:instance
+ not-assoc-equal-must-be-in-collect-data-cell-list
+ (typx (nth (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map)))
+ (cdr (assoc-equal typ map))))
+ (typs (mycdrn i (cdr (assoc-equal typ map))))
+ (ptrs (mycdrn i ptrs))
+ (n (- n 1))))
+ :do-not-induct t)))
+
+
+(defun nth-i-seq-int-induct (i addr l)
+ (if (zp i)
+ (list i addr l)
+ (if (zp l)
+ (list i addr l)
+ (nth-i-seq-int-induct (- i 1)
+ (+ addr 1)
+ (- l 1)))))
+
+
+(defthm seq-int-1-equal
+ (equal (seq-int x 1)
+ (list (+ 0 x)))
+ :hints (("Goal" :expand (seq-int x 1))))
+
+
+(defthm nth-i-seq-int
+ (implies (and (<= 0 i)
+ (< i l)
+ (integerp l)
+ (integerp i))
+ (equal (nth i (seq-int addr l))
+ (+ addr i)))
+ :hints (("Goal" :do-not '(generalize)
+ :induct (nth-i-seq-int-induct i addr l))))
+
+(defthm gptr-is-g-ptr-car-collect-update-from-single-update1
+ (implies (consp (collect-updates-from-single-update1 typ ptr i n ram map))
+ (equal (gptr (car (collect-updates-from-single-update1
+ typ ptr i n ram map)))
+ ptr)))
+
+
+(defthm first-update-is-in-data-cells-colllect
+ (implies (and (consp (collect-updates-from-single-update1 TYP PTR I N RAM MAP))
+ (integerp i)
+ (<= 0 i))
+ (member
+ (update-2-w
+ (car (collect-updates-from-single-update1 typ ptr i n ram map)) ram)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ
+ map))))
+ (- n 1)
+ ram map 'LIST)))
+ :hints (("Goal" :in-theory (disable first-update-is-in-data-cells-colllect-lemma)
+ :use ((:instance
+ first-update-is-in-data-cells-colllect-lemma
+ (ptrs (seq-int (g ptr ram)
+ (len (cdr (assoc-equal typ map))))))
+ (:instance nth-i-seq-int
+ (i (gi (car (collect-updates-from-single-update1
+ typ ptr i n ram map))))
+ (l (len (cdr (assoc-equal typ map))))))
+ :do-not-induct t)))
+
+
+
+(in-theory (disable collect-updates-from-single-update1 update-2-w))
+
+
+(defthm first-update-is-in-data-cells
+ (implies (consp (collect-updates-zdynamic-1-aux typs ptrs n ram map mode))
+ (member
+ (update-2-w
+ (car (collect-updates-zdynamic-1-aux typs ptrs n ram map mode)) ram)
+ (collect-data-cells-1-aux typs ptrs n ram map mode)))
+ :hints (("Goal" :do-not '(generalize))
+ ("Subgoal *1/12.1" :cases
+ ((consp
+ (collect-updates-zdynamic-1-aux
+ (CAR TYPS) PTRS1 N RAM MAP 'ATOM))))
+ ("Subgoal *1/10.1" :cases
+ ((consp
+ (collect-updates-zdynamic-1-aux
+ (CAR TYPS) PTRS1 N RAM MAP 'ATOM))))
+ ("Subgoal *1/5"
+ :expand (COLLECT-UPDATES-ZDYNAMIC-1-AUX TYPS PTRS N RAM MAP 'ATOM)
+ :cases ((consp (COLLECT-UPDATES-FROM-SINGLE-UPDATE1 TYPS PTRS 0 N RAM MAP))))
+ ("Subgoal *1/4"
+ :expand (COLLECT-UPDATES-ZDYNAMIC-1-AUX TYPS PTRS N RAM MAP 'ATOM)
+ :cases ((consp (COLLECT-UPDATES-FROM-SINGLE-UPDATE1 TYPS PTRS 0 N RAM MAP))))))
+
+
+(defthm member-implies-not-member
+ (implies (and (not (overlap a b))
+ (member x a))
+ (not (member x b))))
+
+(defthm not-overlap-data-link-implies-first-step-does-not-update-link-cell
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n ram map mode)
+ (collect-link-cells-1-aux typs ptrs n ram map mode)))
+ (consp (collect-updates-zdynamic-1-aux typs ptrs n ram map mode)))
+ (not (member
+ (update-2-w (car (collect-updates-zdynamic-1-aux typs ptrs n
+ ram map mode)) ram)
+ (collect-link-cells-1-aux typs ptrs n ram map mode)))))
+
+
+;------------ proved that if data, link doesn't overlap,
+;------------ apply updates perserve the consistent state.
+
+(defthm first-update-1-in-collect-data-cell-1
+ (implies (consp (collect-updates-dynamic-1 typ ptr n ram map))
+ (member (update-2-w
+ (car (collect-updates-dynamic-1 typ ptr n ram map)) ram)
+ (collect-data-cells-1 typ ptr n ram map))))
+
+
+(defthm not-consp-collect-updates-dynamic-1-mark-1-is-no-op
+ (implies (not (consp (collect-updates-dynamic-1 typ ptr n ram map)))
+ (equal (mark-1 typ ptr n ram map)
+ ram)))
+
+(defthm all-collect-updates-dynamic-1-opener
+ (implies (consp typs)
+ (equal (all-collect-updates-dynamic-1 typs ptrs ns ram map)
+ (append (collect-updates-dynamic-1
+ (car typs) (car ptrs) (car ns) ram map)
+ (all-collect-updates-dynamic-1 (cdr typs) (cdr ptrs)
+ (cdr ns)
+ (mark-1 (car typs)
+ (car ptrs)
+ (car ns)
+ ram map)
+ map))))
+ :hints (("Goal" :in-theory (disable collect-updates-dynamic-1 mark-1))))
+
+(in-theory (disable all-collect-updates-dynamic-1-opener))
+
+(defthm first-update-1-in-all-collect-data-cell-1
+ (implies (consp (all-collect-updates-dynamic-1 typs ptrs ns ram map))
+ (member (update-2-w
+ (car (all-collect-updates-dynamic-1 typs ptrs ns ram map)) ram)
+ (all-collect-data-cells-1 typs ptrs ns ram map)))
+ :hints (("Goal" :in-theory (cons 'all-collect-updates-dynamic-1-opener
+ (disable collect-updates-dynamic-1
+ update-2-w mark-1
+ collect-data-cells-1))
+ :do-not '(generalize))
+ ("Subgoal *1/3" :cases ((consp (collect-updates-dynamic-1
+ (car typs) (car ptrs) (car ns) ram
+ map))))
+ ("Subgoal *1/2" :cases ((consp (collect-updates-dynamic-1
+ (car typs) (car ptrs) (car ns) ram
+ map))))))
+
+
+(defthm first-update-in-collect-data-cell
+ (implies (consp (collect-updates-dynamic rc))
+ (member (update-2-w
+ (car (collect-updates-dynamic rc)) (ram rc))
+ (collect-data-cells rc))))
+
+;----------------
+
+(defthm first-update-not-in-collect-link-cell
+ (implies (and (consp (collect-updates-dynamic rc))
+ (not (overlap (collect-data-cells rc)
+ (collect-link-cells rc))))
+ (not (member (update-2-w
+ (car (collect-updates-dynamic rc)) (ram rc))
+ (collect-link-cells rc)))))
+
+
+;------------------
+
+(defthm struct-equiv-preserved-if-update-non-link-cell
+ (implies (not (member addr (collect-link-cells rc)))
+ (struct-equiv (set-ram (s addr v (ram rc)) rc)
+ rc)))
+
+(defthm struct-equiv-preserved-if-apply-update-non-link-cell
+ (implies (not (member (update-2-w update (ram rc))
+ (collect-link-cells rc)))
+ (struct-equiv (set-ram (apply-update update (ram rc) (getmap rc))
+ rc)
+ rc))
+ :hints (("Goal" :in-theory (list* 'apply-update
+ 'update-2-w
+ (disable struct-equiv
+ collect-link-cells)))))
+
+
+
+;;
+;; this can't be proved, easily.
+;;
+
+;
+;(defthm struct-equiv-apply-updates
+; (implies (not (overlap (collect-data-cells rc)
+; (collect-link-cells rc)))
+; (struct-equiv
+; (apply-updates (collect-updates-dynamic rc)
+; (ram rc) (getmap rc))
+; rc))
+; :hints (("Goal" :in-theory (disable collect-updates-dynamic
+; collect-link-cells
+; collect-data-cells
+; struct-equiv))))
+;
+
+
+;;
+;; because, we can't prove a (defcong equal collect-update-dynamic ...)
+;; unless we know no-overlap
+;;
+
+;; we set out to prove
+;
+; (defthm not-overlap-and-collect-dynamic-is-collect-static
+; (implies (not (overlap (collect-data-cells rc)
+; (collect-link-cells rc)))
+; (equal (collect-update-dynamic rc)
+; (collect-update-static rc))))
+;
+
+(defun collect-updates-from-single-update1-static (typ ptr i n ram map)
+ (declare (xargs :measure (m-collect-updates typ map i ram)))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor)))
+ (if (zp ptr) nil
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (collect-updates-from-single-update1-static typ ptr (+ i 1) n ram map)
+ ;; else not a struct type, update the value
+ ;; let the new value depends on the changes to the previous slos
+ (cons (make-update typ ptr i n)
+ (collect-updates-from-single-update1-static
+ typ ptr (+ i 1) n ram map)))
+ nil))))
+
+(defun collect-updates-static-1-aux (typ-or-typs ptr-or-ptrs n ram map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) nil
+ (if (zp ptr) nil
+ (if (not (assoc-equal typ map)) ;; not bound
+ nil
+ (let* ((addr (g ptr ram)))
+ (append (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map)
+ (collect-updates-static-1-aux
+ desc
+ (seq-int addr size)
+ (- n 1)
+ ram map 'LIST))))))))
+ ((equal mode 'LIST)
+ (if (endp typs)
+ nil
+ (if (not (assoc-equal (car typs) map))
+ (collect-updates-static-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST)
+ (append (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM)
+ (collect-updates-static-1-aux (cdr typs)
+ (cdr ptrs)
+ n
+ ram map 'LIST)))))
+ (t nil))))
+
+
+;--------------------
+(defthm collect-updates-from-single-update1-static-is-independent-of-ram
+ (equal (collect-updates-from-single-update1-static
+ typ ptr i n AnyRam map)
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map))
+ :hints (("Goal" :do-not '(generalize)))
+ :rule-classes nil)
+
+
+
+(defthm struct-equiv-1-aux-implies-collect-static-updates-1-aux-equal
+ (implies (struct-equiv-1-aux typ-or-typs ptr-or-ptrs n ram1 ram2 map mode)
+ (equal (collect-updates-static-1-aux typ-or-typs ptr-or-ptrs n
+ ram1 map mode)
+ (collect-updates-static-1-aux typ-or-typs ptr-or-ptrs n
+ ram2 map mode)))
+ :hints (("Subgoal *1/6"
+ :use ((:instance
+ collect-updates-from-single-update1-static-is-independent-of-ram
+ (i 0) (typ typ-or-typs) (ptr ptr-or-ptrs) (anyRam ram1) (ram ram2))))))
+
+;; i need a strong theorem that establish equal after an update to the non-link
+;; cell
+
+
+(defthm not-change-link-collect-updates-from-single-update1-static-not-changed
+ (equal (collect-updates-from-single-update1-static
+ typ ptr i n (s addr v ram) map)
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map)))
+
+
+(defthm not-change-link-cell-collect-update-static-1-aux-not-changed
+ (implies (not (member addr (collect-link-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)))
+ (equal (collect-updates-static-1-aux typ-or-typs ptr-or-ptrs
+ n (s addr v ram) map mode)
+ (collect-updates-static-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)))
+ :hints (("Goal" :in-theory (disable
+ collect-updates-from-single-update1-static))))
+
+;--------------------
+;; ready to prove the most important theorem
+;; collect-dynamic is collect-static
+;; when data cell and link cell doesn't overlap
+
+
+(defun not-change-induct (typ ptr i n AnyRam ram map)
+ (declare (xargs :measure (m-collect-updates typ map i ram)))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor))
+ (addr (g ptr AnyRam)))
+ (if (zp ptr) (list typ ptr i n anyRam ram map)
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (not-change-induct typ ptr (+ i 1) n AnyRam ram map)
+ ;; else not a struct type, update the value
+ (let ((new-ram (s (+ addr i) (new-field-value typ ptr i n AnyRam map) AnyRam)))
+ ;; let the new value depends on the changes to the previous slos
+ (not-change-induct typ ptr (+ i 1) n new-ram ram map)))
+ (list typ ptr i n anyRam ram map)))))
+
+
+
+(defthm not-change-link-collect-updates-from-single-update1-is-statick-not-changed
+ (equal (collect-updates-from-single-update1
+ typ ptr i n AnyRam map)
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map))
+ :hints (("Goal" :do-not '(generalize)
+ :induct (not-change-induct typ ptr i n AnyRam ram map))
+ ("Subgoal *1/3" :expand (collect-updates-from-single-update1
+ typ ptr i n AnyRam map))
+ ("Subgoal *1/2" :expand (collect-updates-from-single-update1
+ typ ptr i n AnyRam map))
+ ("Subgoal *1/1" :expand (collect-updates-from-single-update1
+ typ ptr i n AnyRam map))))
+
+(in-theory (disable collect-updates-from-single-update1
+ collect-updates-from-single-update1-static))
+
+
+(defthm not-overlap-append
+ (implies (not (overlap (append a b)
+ (append c d)))
+ (not (overlap a c))))
+
+
+(defthm not-overlap-append-2
+ (implies (not (overlap (append a b)
+ (append c d)))
+ (not (overlap b d))))
+
+
+;------------------
+
+;; We proved the following
+;(thm
+; (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n ram map mode)
+; (collect-link-cells-1-aux typs ptrs n ram map mode)))
+; (consp (collect-updates-zdynamic-1-aux typs ptrs n ram map mode)))
+; (not (member
+; (update-2-w (car (collect-updates-zdynamic-1-aux typs ptrs n
+; ram map mode)) ram)
+; (collect-link-cells-1-aux typs ptrs n ram map mode)))))
+
+;--- prove more general theorem using the above
+
+;; 1/4.1
+
+(defthm overlap-lemma
+ (implies (overlap a b)
+ (overlap a (cons x b))))
+
+;-------------------
+
+;; why the following skip-proofs are true.
+;
+; because we can show
+;
+; (apply-updates (collect-updates-static-1-aux ...) gives struct-equiv state
+; by showing applying first update, give you a struct-equiv state
+; and the collect-updates-static-1-aux from that state is not changed.
+; thus apply the second update
+;
+;
+; current approach is to prove if no overlap then, collect-updates-static-1-aux
+; is a subset of data links.
+;
+
+(defun subset-induct (typ-or-typs ptr-or-ptrs n ram map mode)
+ (declare (xargs :measure (struct-equiv-1-aux-m typ-or-typs n mode)))
+ (let ((typ typ-or-typs)
+ (ptr ptr-or-ptrs)
+ (typs typ-or-typs)
+ (ptrs ptr-or-ptrs))
+ (cond ((equal mode 'ATOM)
+ (let* ((desc (cdr (assoc-equal typ map)))
+ (size (len desc)))
+ (if (zp n) nil
+ (if (zp ptr) nil
+ (if (not (assoc-equal typ map)) ;; not bound
+ nil
+ (let* ((addr (g ptr ram)))
+ (subset-induct
+ desc (seq-int addr size)
+ (- n 1)
+ (apply-updates
+ (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ map 'LIST)))))))
+
+ ((equal mode 'LIST)
+ (if (endp typs)
+ nil
+ (if (not (assoc-equal (car typs) map))
+ (subset-induct (cdr typs) (cdr ptrs) n ram map 'LIST)
+ (list (subset-induct (car typs) (car ptrs) n ram map 'ATOM)
+ (subset-induct (cdr typs) (cdr ptrs)
+ n (apply-updates
+ (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM)
+ ram map)
+ map 'LIST)))))
+ (t (list typs ptrs n ram map mode)))))
+
+
+(defthm subsetp-cons
+ (implies (subsetp x l)
+ (subsetp x (cons y l))))
+
+
+;--------------------------
+
+(defthm struct-equiv-1-aux-preserved-if-apply-update-non-link-cell
+ (implies (not (member (update-2-w update ram)
+ (collect-link-cells-1-aux typs ptrs n ram map mode)))
+ (struct-equiv-1-aux
+ typs ptrs n (apply-update update ram map) ram map
+ mode))
+ :hints (("Goal" :in-theory (enable apply-update update-2-w))))
+
+
+(defthm subsetp-update-2-ws
+ (implies (and (subsetp (updates-2-ws updates ram map) l)
+ (consp updates))
+ (member (update-2-w (car updates) ram) l))
+ :rule-classes :forward-chaining)
+
+(defthm member-overlap-2
+ (implies (and (not (overlap a b))
+ (member x a))
+ (not (member x b)))
+ :rule-classes :forward-chaining)
+
+
+(defthm subsetp-not-member-link-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)
+ (collect-link-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)))
+ (consp updates)
+ (subsetp (updates-2-ws updates ram map)
+ (collect-data-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)))
+ (not (member (update-2-w (car updates) ram)
+ (collect-link-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode))))
+ :hints (("Goal" :in-theory (disable collect-data-cells-1-aux
+ collect-link-cells-1-aux
+ subsetp overlap))))
+
+
+(defthm apply-updates-nil-is-not-changed
+ (implies (not (consp updates))
+ (equal (apply-updates updates ram map) ram)))
+
+
+(defthm struct-equiv-1-aux-preserved-if-apply-update-non-link-cell-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)
+ (collect-link-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)))
+ (consp updates)
+ (subsetp (updates-2-ws updates ram map)
+ (collect-data-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)))
+ (struct-equiv-1-aux
+ typ-or-typs ptr-or-ptrs n (apply-update (car updates) ram map) ram map
+ mode))
+ :hints (("Goal" :cases ((not (consp updates))))))
+
+
+(defthm collect-link-cells-1-aux-apply-updates-collect-links-updates-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n
+ ram map mode)
+ (collect-link-cells-1-aux typs ptrs n
+ ram map mode)))
+ (consp updates)
+ (subsetp (updates-2-ws updates ram map)
+ (collect-data-cells-1-aux
+ typs ptrs n ram map mode)))
+ (equal (collect-link-cells-1-aux typs ptrs n
+ (apply-update (car updates) ram
+ map)
+ map
+ mode)
+ (collect-link-cells-1-aux typs ptrs n
+ ram map mode)))
+ :hints (("Goal" :use ((:instance
+ struct-equiv-1-aux-implies-collect-link-cells-aux-equal
+ (ram1 (apply-update (car updates) ram map))
+ (ram2 ram)
+ (typ-or-typs typs) (ptr-or-ptrs ptrs))))))
+
+
+
+
+
+(defthm collect-link-cells-1-aux-apply-updates-collect-data-updates-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n
+ ram map mode)
+ (collect-link-cells-1-aux typs ptrs n
+ ram map mode)))
+ (consp updates)
+ (subsetp (updates-2-ws updates ram map)
+ (collect-data-cells-1-aux
+ typs ptrs n ram map mode)))
+ (equal (collect-data-cells-1-aux typs ptrs n
+ (apply-update (car updates) ram
+ map)
+ map
+ mode)
+ (collect-data-cells-1-aux typs ptrs n
+ ram map mode)))
+ :hints (("Goal" :use ((:instance
+ struct-equiv-1-aux-implies-collect-data-cells-aux-equal
+ (ram1 (apply-update (car updates) ram map))
+ (ram2 ram)
+ (typ-or-typs typs) (ptr-or-ptrs ptrs))))))
+
+
+
+(defthm apply-updates-struct-equiv-1-aux
+ (implies (and (not (overlap (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs n ram map mode)
+ (collect-link-cells-1-aux typ-or-typs ptr-or-ptrs n ram map mode)))
+ (consp updates)
+ (subsetp (updates-2-ws updates ram map)
+ (collect-data-cells-1-aux
+ typ-or-typs ptr-or-ptrs n ram map mode)))
+ (struct-equiv-1-aux
+ typ-or-typs ptr-or-ptrs n
+ (apply-updates updates ram map)
+ ram map
+ mode))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+; shared
+
+;-------------------------
+
+(defthm subsetp-collect-data-cells-1-collect-data-cells-1
+ (implies (consp typs)
+ (subsetp (collect-data-cells-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM)
+ (collect-data-cells-1-aux
+ typs ptrs n ram map 'LIST))))
+
+
+(defthm apply-updates-struct-equiv-1-aux-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux
+ typs ptrs n ram map 'LIST)
+ (collect-link-cells-1-aux
+ typs ptrs n ram map 'LIST)))
+ (consp updates)
+ (subsetp (updates-2-ws updates ram map)
+ (collect-data-cells-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM)))
+ (struct-equiv-1-aux
+ typs ptrs n
+ (apply-updates updates ram map)
+ ram map
+ 'LIST)))
+
+(defthm apply-updates-struct-equiv-1-aux-instance-1-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n ram map 'LIST)
+ (collect-link-cells-1-aux typs ptrs n ram map
+ 'LIST)))
+ (not (endp typs))
+ (assoc-equal (car typs) map)
+ (subsetp (updates-2-ws updates ram map)
+ (collect-data-cells-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM)))
+ (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates updates
+ ram map)
+ ram map 'LIST))
+ :hints (("Goal" :in-theory (disable apply-updates-struct-equiv-1-aux-instance)
+ :use apply-updates-struct-equiv-1-aux-instance)))
+
+
+
+(defthm struct-equiv-1-aux-implies-collect-data-equal-instance
+ (implies (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST)
+ (equal (collect-data-cells-1-aux
+ (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map) map 'LIST)
+ (collect-data-cells-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST))))
+
+
+(defthm struct-equiv-1-aux-implies-collect-link-equal-instance
+ (implies (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST)
+ (equal (collect-link-cells-1-aux
+ (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map) map 'LIST)
+ (collect-link-cells-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST))))
+
+
+(defthm struct-equiv-1-aux-implies-collect-static-equal-instance
+ (implies (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST)
+ (equal (collect-updates-static-1-aux
+ (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map) map 'LIST)
+ (collect-updates-static-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST))))
+
+
+;; solved 1-7-2-1
+
+(defthm updates-2-ws-append
+ (equal (updates-2-ws (append updates1 updates2)
+ ram map)
+ (append (updates-2-ws updates1 ram map)
+ (updates-2-ws updates2
+ (apply-updates updates1 ram map) map))))
+
+
+;; solved 1-7-1-1
+
+
+
+
+;; because our induction in collect-data-cells and collect-updates doesn't
+;; match well. This proof is complicated.
+
+(defun collect-data-cells-from-single-node (typ ptr i ram map)
+ (declare (xargs :measure (m-collect-updates typ map i ram)))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor))
+ (addr (g ptr ram)))
+ (if (zp ptr) nil
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (collect-data-cells-from-single-node typ ptr (+ i 1) ram map)
+ ;; else not a struct type, update the value
+ (cons (+ i addr)
+ (collect-data-cells-from-single-node
+ typ ptr (+ i 1) ram map)))
+ nil))))
+
+
+
+;; prove a more general one than
+;; subsetp-collect-data-cells-from-single-node-collect-data-cells
+
+(defthm nth-i-equal-car-mycdrn-i
+ (implies (and (< i (len l))
+ (<= 0 i))
+ (equal (nth i l)
+ (car (mycdrn i l)))))
+
+
+(defthm member-collect-data-cells-1-aux
+ (implies (and (not (assoc-equal (car (mycdrn i typs)) map))
+ (< i (len typs))
+ (<= 0 i))
+ (member (+ i addr)
+ (collect-data-cells-1-aux
+ (mycdrn i typs)
+ (seq-int (+ i addr)
+ (len (mycdrn i typs)))
+ n
+ ram map 'LIST))))
+
+
+(defthm subsetp-collect-data-1-aux-mycdrn
+ (implies (and (consp typs)
+ (integerp i)
+ (<= 0 i))
+ (subsetp (collect-data-cells-1-aux
+ (cdr typs)
+ (seq-int (+ 1 addr)
+ (len (cdr typs)))
+ n
+ ram map 'LIST)
+ (collect-data-cells-1-aux
+ typs
+ (seq-int addr
+ (len typs))
+ n
+ ram map 'LIST)))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defthm mycdrn-i-cdr
+ (equal (mycdrn i (cddr typs))
+ (cdr (mycdrn i (cdr typs)))))
+
+
+(defthm subsetp-collect-data-1-aux-mycdrn-2
+ (implies (and (consp typs)
+ (integerp i)
+ (<= 0 i)
+ (assoc-equal (car typs) map))
+ (subsetp (collect-data-cells-1-aux
+ (cdr typs)
+ (seq-int (+ 1 addr)
+ (len (cdr typs)))
+ n
+ ram map 'LIST)
+ (collect-data-cells-1-aux
+ typs
+ (cons any
+ (seq-int (+ 1 addr)
+ (len (cdr typs))))
+ n
+ ram map 'LIST)))
+ :hints (("Goal" :do-not '(generalize))))
+
+(defthm subsetp-collect-data-cells-from-single-node-collect-data-cells-lemma
+ (implies (and (integerp i)
+ (<= 0 i))
+ (subsetp (collect-data-cells-from-single-node
+ typ ptr i ram map)
+ (collect-data-cells-1-aux
+ (mycdrn i (cdr (assoc-equal typ map)))
+ (seq-int (+ i (g ptr ram)) (len (mycdrn i (cdr (assoc-equal typ map)))))
+ (- n 1)
+ ram map 'LIST)))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defthm seq-int-fix
+ (equal (seq-int (fix addr) len)
+ (seq-int addr len)))
+
+(defthm subsetp-collect-data-cells-from-single-node-collect-data-cells
+ (subsetp (collect-data-cells-from-single-node
+ typ ptr 0 ram map)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))
+ :hints (("Goal"
+ :in-theory (disable subsetp-collect-data-cells-from-single-node-collect-data-cells-lemma)
+ :use ((:instance
+ subsetp-collect-data-cells-from-single-node-collect-data-cells-lemma
+ (i 0))))))
+
+;-----------
+(defun induct-collect-updates (typ ptr i n ram map)
+ (declare (xargs :measure (m-collect-updates typ map i ram)))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor))
+ (addr (g ptr ram)))
+ (if (zp ptr) nil
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (induct-collect-updates typ ptr (+ i 1) n ram map)
+ ;; else not a struct type, update the value
+ (let ((new-ram (s (+ addr i) (new-field-value typ ptr i n ram map) ram)))
+ ;; let the new value depends on the changes to the previous slos
+ (induct-collect-updates typ ptr (+ i 1) n
+ new-ram map)))
+ nil))))
+
+#|
+;; a general statement. easy to prove but not so good.
+(defthm collect-data-cells-from-single-node-not-affected-by-lemma
+ (implies (equal (g ptr ram2) (g ptr ram1))
+ (equal (collect-data-cells-from-single-node
+ typ ptr i ram2 map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram1 map))))
+;; free variables. not good. so write a more specific one.
+|#
+
+
+(defthm collect-data-cells-from-single-node-not-affected-by-lemma-2
+ (implies (not (equal addr ptr))
+ (equal (collect-data-cells-from-single-node
+ typ ptr i (s addr anyValue ram) map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram map))))
+
+
+(defthm member-not-member-implies-not-equal-f
+ (implies (and (not (member x l))
+ (member y l))
+ (not (equal x y)))
+ :rule-classes :forward-chaining)
+
+
+
+;; not a very good one.
+(defthm collect-data-cells-from-single-node-not-affected-by
+ (implies (and (not (member ptr (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ (member addr (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ (equal (collect-data-cells-from-single-node
+ typ ptr i (s addr anyValue ram) map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram map))))
+
+(defthm collect-updates-from-single-update1-static-opener
+ (implies (zp ptr)
+ (equal (collect-updates-from-single-update1-static
+ typ ptr i n ram map) nil))
+ :hints (("Goal" :expand
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map))))
+
+(defthm collect-updates-from-single-update1-static-opener-2
+ (implies (and (<= (LEN (CDR (ASSOC-EQUAL TYP MAP))) I)
+ (integerp i))
+ (equal (collect-updates-from-single-update1-static
+ typ ptr i n ram map) nil))
+ :hints (("Goal" :expand
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map))))
+#|
+(defthm collect-updates-from-single-update1-static-opener-3
+ (implies (zp n)
+ (equal (collect-updates-from-single-update1-static
+ typ ptr i n ram map) nil))
+ :hints (("Goal" :expand
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map))))
+|#
+
+
+(defthm equal-collect-data-cells-from-single-node-equal-updates-2-ws
+ (implies (and (not (member ptr (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ (integerp i)
+ (<= 0 i))
+ (equal (updates-2-ws (collect-updates-from-single-update1-static
+ typ ptr i n ram map) ram map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ :hints (("Goal" :induct (induct-collect-updates typ ptr i n ram map)
+ :in-theory (enable update-2-w make-update apply-update gptr gi gn gtyp)
+ :do-not '(generalize fertilize)
+ :expand (collect-updates-from-single-update1-static
+ typ ptr i n ram map))))
+
+
+(defthm not-member-forward-chaining
+ (implies (and (subsetp a b)
+ (not (member x b)))
+ (not (member x a)))
+ :rule-classes :forward-chaining)
+
+
+(defthm subsetp-collect-updates-from-single-update-1-static
+ (implies (not (member ptr (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ
+ map))))
+ (- n 1) ram map 'LIST)))
+ (subsetp (updates-2-ws (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST)))
+ :hints (("Goal" :in-theory (disable subsetp-collect-data-cells-from-single-node-collect-data-cells)
+ :use subsetp-collect-data-cells-from-single-node-collect-data-cells)))
+
+
+
+(defthm not-overlap-not-member-x
+ (implies (not (overlap a (cons x b)))
+ (not (member x a)))
+ :rule-classes :forward-chaining)
+
+
+(defthm not-overlap-implies-not-member
+ (implies (not (overlap (collect-data-cells-1-aux typ ptr n ram map 'ATOM)
+ (collect-link-cells-1-aux typ ptr n ram map 'ATOM)))
+ (not (member ptr (collect-data-cells-1-aux
+ typ ptr n ram map 'ATOM))))
+ :hints (("Goal" :expand (collect-link-cells-1-aux typ ptr n ram map 'ATOM)))
+ :rule-classes :forward-chaining)
+
+
+;; I should modify the definition of collect-updates-from-single-update1-static
+;; to return nil when n is zero
+
+(defthm subsetp-collect-updates-from-single-update-collect-data-1-aux
+ (implies (and (not (overlap (collect-data-cells-1-aux typ ptr n ram map 'ATOM)
+ (collect-link-cells-1-aux typ ptr n ram map
+ 'ATOM)))
+ (not (zp n)))
+ (subsetp (updates-2-ws (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ (collect-data-cells-1-aux typ ptr n ram map 'ATOM)))
+ :hints (("Goal" :expand (collect-data-cells-1-aux typ ptr n ram map 'ATOM))))
+
+
+(defthm apply-updates-struct-equiv-1-aux-instance-2
+ (implies (not (overlap (collect-data-cells-1-aux
+ typ ptr n ram map 'ATOM)
+ (collect-link-cells-1-aux
+ typ ptr n ram map 'ATOM)))
+ (struct-equiv-1-aux
+ typ ptr n
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram map
+ 'ATOM))
+ :hints (("Goal" :cases ((not (zp n))))
+ ("Subgoal 1" :cases ((consp (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map))))))
+
+
+
+(defthm apply-updates-struct-equiv-1-aux-instance-2-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux typ ptr n ram map 'ATOM)
+ (collect-link-cells-1-aux typ ptr n ram map 'ATOM)))
+ (assoc-equal typ map)
+ (not (zp n))
+ (not (zp ptr)))
+ (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST))
+ :hints (("Goal" :in-theory (disable apply-updates-struct-equiv-1-aux-instance-2)
+ :use apply-updates-struct-equiv-1-aux-instance-2)))
+
+;----------------------- concrete instantiations
+
+(defthm struct-equiv-1-aux-implies-collect-data-equal-instance-2
+ (implies (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST)
+ (equal (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ map 'LIST)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))))
+
+
+(defthm struct-equiv-1-aux-implies-collect-link-equal-instance-2
+ (implies (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST)
+ (equal (collect-link-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ map 'LIST)
+ (collect-link-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))))
+
+
+
+(defthm struct-equiv-1-aux-implies-collect-update-static-equal-instance-2
+ (implies (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST)
+ (equal (collect-updates-static-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ map 'LIST)
+ (collect-updates-static-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))))
+
+
+
+
+;-------------------------
+
+;; because our induction in collect-data-cells and collect-updates doesn't
+;; match well. This proof is complicated.
+
+(defun collect-data-cells-from-single-node (typ ptr i ram map)
+ (declare (xargs :measure (m-collect-updates typ map i ram)))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor))
+ (addr (g ptr ram)))
+ (if (zp ptr) nil
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (collect-data-cells-from-single-node typ ptr (+ i 1) ram map)
+ ;; else not a struct type, update the value
+ (cons (+ i addr)
+ (collect-data-cells-from-single-node
+ typ ptr (+ i 1) ram map)))
+ nil))))
+
+
+
+;; prove a more general one than
+;; subsetp-collect-data-cells-from-single-node-collect-data-cells
+
+(defthm nth-i-equal-car-mycdrn-i
+ (implies (and (< i (len l))
+ (<= 0 i))
+ (equal (nth i l)
+ (car (mycdrn i l)))))
+
+
+(defthm member-collect-data-cells-1-aux
+ (implies (and (not (assoc-equal (car (mycdrn i typs)) map))
+ (< i (len typs))
+ (<= 0 i))
+ (member (+ i addr)
+ (collect-data-cells-1-aux
+ (mycdrn i typs)
+ (seq-int (+ i addr)
+ (len (mycdrn i typs)))
+ n
+ ram map 'LIST))))
+
+
+(defthm subsetp-collect-data-1-aux-mycdrn
+ (implies (and (consp typs)
+ (integerp i)
+ (<= 0 i))
+ (subsetp (collect-data-cells-1-aux
+ (cdr typs)
+ (seq-int (+ 1 addr)
+ (len (cdr typs)))
+ n
+ ram map 'LIST)
+ (collect-data-cells-1-aux
+ typs
+ (seq-int addr
+ (len typs))
+ n
+ ram map 'LIST)))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defthm mycdrn-i-cdr
+ (equal (mycdrn i (cddr typs))
+ (cdr (mycdrn i (cdr typs)))))
+
+
+(defthm subsetp-collect-data-1-aux-mycdrn-2
+ (implies (and (consp typs)
+ (integerp i)
+ (<= 0 i)
+ (assoc-equal (car typs) map))
+ (subsetp (collect-data-cells-1-aux
+ (cdr typs)
+ (seq-int (+ 1 addr)
+ (len (cdr typs)))
+ n
+ ram map 'LIST)
+ (collect-data-cells-1-aux
+ typs
+ (cons any
+ (seq-int (+ 1 addr)
+ (len (cdr typs))))
+ n
+ ram map 'LIST)))
+ :hints (("Goal" :do-not '(generalize))))
+
+(defthm subsetp-collect-data-cells-from-single-node-collect-data-cells-lemma
+ (implies (and (integerp i)
+ (<= 0 i))
+ (subsetp (collect-data-cells-from-single-node
+ typ ptr i ram map)
+ (collect-data-cells-1-aux
+ (mycdrn i (cdr (assoc-equal typ map)))
+ (seq-int (+ i (g ptr ram)) (len (mycdrn i (cdr (assoc-equal typ map)))))
+ (- n 1)
+ ram map 'LIST)))
+ :hints (("Goal" :do-not '(generalize))))
+
+
+(defthm seq-int-fix
+ (equal (seq-int (fix addr) len)
+ (seq-int addr len)))
+
+(defthm subsetp-collect-data-cells-from-single-node-collect-data-cells
+ (subsetp (collect-data-cells-from-single-node
+ typ ptr 0 ram map)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))
+ :hints (("Goal"
+ :in-theory (disable subsetp-collect-data-cells-from-single-node-collect-data-cells-lemma)
+ :use ((:instance
+ subsetp-collect-data-cells-from-single-node-collect-data-cells-lemma
+ (i 0))))))
+
+;-----------
+(defun induct-collect-updates (typ ptr i n ram map)
+ (declare (xargs :measure (m-collect-updates typ map i ram)))
+ (let* ((descriptor (cdr (assoc-equal typ map)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor))
+ (addr (g ptr ram)))
+ (if (zp ptr) nil
+ (if (< i (len descriptor))
+ (if (assoc-equal slot-typ map)
+ ;; a struct type, meaning a ptr in the (car addrs)
+ ;; don't touch link cells
+ (induct-collect-updates typ ptr (+ i 1) n ram map)
+ ;; else not a struct type, update the value
+ (let ((new-ram (s (+ addr i) (new-field-value typ ptr i n ram map) ram)))
+ ;; let the new value depends on the changes to the previous slos
+ (induct-collect-updates typ ptr (+ i 1) n
+ new-ram map)))
+ nil))))
+
+#|
+;; a general statement. easy to prove but not so good.
+(defthm collect-data-cells-from-single-node-not-affected-by-lemma
+ (implies (equal (g ptr ram2) (g ptr ram1))
+ (equal (collect-data-cells-from-single-node
+ typ ptr i ram2 map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram1 map))))
+;; free variables. not good. so write a more specific one.
+|#
+
+
+(defthm collect-data-cells-from-single-node-not-affected-by-lemma-2
+ (implies (not (equal addr ptr))
+ (equal (collect-data-cells-from-single-node
+ typ ptr i (s addr anyValue ram) map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram map))))
+
+
+(defthm member-not-member-implies-not-equal-f
+ (implies (and (not (member x l))
+ (member y l))
+ (not (equal x y)))
+ :rule-classes :forward-chaining)
+
+
+
+;; not a very good one.
+(defthm collect-data-cells-from-single-node-not-affected-by
+ (implies (and (not (member ptr (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ (member addr (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ (equal (collect-data-cells-from-single-node
+ typ ptr i (s addr anyValue ram) map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram map))))
+
+(defthm collect-updates-from-single-update1-static-opener
+ (implies (zp ptr)
+ (equal (collect-updates-from-single-update1-static
+ typ ptr i n ram map) nil))
+ :hints (("Goal" :expand
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map))))
+
+(defthm collect-updates-from-single-update1-static-opener-2
+ (implies (and (<= (LEN (CDR (ASSOC-EQUAL TYP MAP))) I)
+ (integerp i))
+ (equal (collect-updates-from-single-update1-static
+ typ ptr i n ram map) nil))
+ :hints (("Goal" :expand
+ (collect-updates-from-single-update1-static
+ typ ptr i n ram map))))
+
+
+
+(defthm equal-collect-data-cells-from-single-node-equal-updates-2-ws
+ (implies (and (not (member ptr (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ (integerp i)
+ (<= 0 i))
+ (equal (updates-2-ws (collect-updates-from-single-update1-static
+ typ ptr i n ram map) ram map)
+ (collect-data-cells-from-single-node
+ typ ptr i ram map)))
+ :hints (("Goal" :induct (induct-collect-updates typ ptr i n ram map)
+ :in-theory (enable update-2-w make-update apply-update gptr gi gn gtyp)
+ :do-not '(generalize fertilize)
+ :expand (collect-updates-from-single-update1-static
+ typ ptr i n ram map))))
+
+
+(defthm not-member-forward-chaining
+ (implies (and (subsetp a b)
+ (not (member x b)))
+ (not (member x a)))
+ :rule-classes :forward-chaining)
+
+
+(defthm subsetp-collect-updates-from-single-update-1-static
+ (implies (not (member ptr (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ
+ map))))
+ (- n 1) ram map 'LIST)))
+ (subsetp (updates-2-ws (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST)))
+ :hints (("Goal" :in-theory (disable subsetp-collect-data-cells-from-single-node-collect-data-cells)
+ :use subsetp-collect-data-cells-from-single-node-collect-data-cells)))
+
+
+
+(defthm not-overlap-not-member-x
+ (implies (not (overlap a (cons x b)))
+ (not (member x a)))
+ :rule-classes :forward-chaining)
+
+
+
+(defthm subsetp-collect-updates-static-1-aux-data-cells
+ (implies (not (overlap (collect-data-cells-1-aux typ-or-typs
+ ptr-or-ptrs n ram map mode)
+ (collect-link-cells-1-aux typ-or-typs
+ ptr-or-ptrs n ram map mode)))
+ (subsetp (updates-2-ws (collect-updates-static-1-aux typ-or-typs
+ ptr-or-ptrs
+ n ram map mode) ram map)
+ (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)))
+ :hints (("Goal" :induct (subset-induct
+ typ-or-typs ptr-or-ptrs n ram map mode)
+ :do-not '(generalize))))
+
+;; this is important result
+
+
+
+;--- this above the important result we want to show ---
+(defun prefix (a b)
+ (if (endp a) t
+ (if (endp b) nil
+ (and (equal (car a) (car b))
+ (prefix (cdr a) (cdr b))))))
+
+(defthm prefix-subsetp
+ (implies (prefix updates2 updates1)
+ (subsetp (updates-2-ws updates2 ram map)
+ (updates-2-ws updates1 ram map))))
+
+(defthm prefix-append
+ (prefix a (append a b)))
+
+(defthm subsetp-collect-updates-static-1-aux
+ (implies (and (not (endp typs))
+ (assoc-equal (car typs) map))
+ (subsetp (updates-2-ws (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM) ram map)
+ (updates-2-ws (collect-updates-static-1-aux
+ typs ptrs n ram map 'LIST) ram map))))
+
+
+(defthm apply-updates-struct-equiv-1-aux-instance-1
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n ram map 'LIST)
+ (collect-link-cells-1-aux typs ptrs n ram map
+ 'LIST)))
+ (not (endp typs))
+ (assoc-equal (car typs) map))
+ (struct-equiv-1-aux typs ptrs n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST))
+ :hints (("Goal" :do-not '(generalize)
+ :cases ((consp (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map 'ATOM))))
+ ("Subgoal 1" :use ((:instance subsetp-transitive
+ (a (updates-2-ws
+ (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map))
+ (b (updates-2-ws
+ (collect-updates-static-1-aux
+ typs ptrs n ram map 'LIST) ram
+ map))
+ (c (collect-data-cells-1-aux
+ typs ptrs n ram map 'LIST)))))))
+
+
+;-----------------
+;
+; need to instantiate it again to get the version I wanted.
+;
+#|
+(defthm apply-updates-struct-equiv-1-aux-instance-1-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n ram map 'LIST)
+ (collect-link-cells-1-aux typs ptrs n ram map
+ 'LIST)))
+ (not (endp typs))
+ (assoc-equal (car typs) map))
+ (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST))
+ :hints (("Goal" :in-theory (disable apply-updates-struct-equiv-1-aux-instance-1)
+ :use apply-updates-struct-equiv-1-aux-instance-1)))
+
+;; now I have what I want.
+
+;; instantiate some of struct-equiv-1-aux-implies-collect-XXX-equal
+
+(defthm struct-equiv-1-aux-implies-collect-data-equal-instance
+ (implies (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST)
+ (equal (collect-data-cells-1-aux
+ (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map) map 'LIST)
+ (collect-data-cells-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST))))
+
+(defthm struct-equiv-1-aux-implies-collect-link-equal-instance
+ (implies (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST)
+ (equal (collect-link-cells-1-aux
+ (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map) map 'LIST)
+ (collect-link-cells-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST))))
+|#
+
+(defthm struct-equiv-1-aux-implies-collect-update-static-1-aux-equal-instance
+ (implies (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST)
+ (equal (collect-updates-static-1-aux
+ (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map) map 'LIST)
+ (collect-updates-static-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST))))
+
+
+
+(defthm mark-1-aux-equal-is-if-dynamic-equal-static
+ (implies (equal (collect-updates-zdynamic-1-aux typ ptr n ram map 'ATOM)
+ (collect-updates-static-1-aux typ ptr n ram map 'ATOM))
+ (equal (mark-1-aux typ ptr n ram map 'ATOM)
+ (apply-updates (collect-updates-static-1-aux
+ typ ptr n ram map 'ATOM) ram map))))
+
+;-------------------------------
+
+
+
+
+(defthm lemma-1-7-2-1
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n ram map 'list)
+ (collect-link-cells-1-aux typs ptrs n ram map 'list)))
+ (equal (collect-updates-zdynamic-1-aux (car typs)
+ (car ptrs) n ram map
+ 'ATOM)
+ (collect-updates-static-1-aux (car typs)
+ (car ptrs) n ram map
+ 'ATOM))
+ (not (endp typs))
+ (assoc-equal (car typs) map))
+ (not (overlap (collect-data-cells-1-aux
+ (cdr typs) (cdr ptrs) n
+ (mark-1-aux (car typs) (car ptrs) n ram map 'ATOM)
+ map 'LIST)
+ (collect-link-cells-1-aux
+ (cdr typs) (cdr ptrs) n
+ (mark-1-aux (car typs) (car ptrs) n ram map 'ATOM)
+ map 'LIST))))
+ :hints (("Goal" :in-theory (disable apply-updates-collect-dynamic-is-mark))))
+
+
+
+
+;; (in-theory (disable mark-1-aux-equal-is-if-dynamic-equal-static))
+
+#|
+(defthm struct-equiv-1-aux-implies-collect-update-static-1-aux-equal-instance
+ (implies (struct-equiv-1-aux (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM)
+ ram map)
+ ram map 'LIST)
+ (equal (collect-updates-static-1-aux
+ (cdr typs) (cdr ptrs) n
+ (apply-updates (collect-updates-static-1-aux
+ (car typs) (car ptrs) n ram map
+ 'ATOM) ram map) map 'LIST)
+ (collect-updates-static-1-aux
+ (cdr typs) (cdr ptrs) n ram map 'LIST))))
+|#
+
+(defthm lemma-1-7-1-1
+ (implies (and (not (overlap (collect-data-cells-1-aux typs ptrs n ram map 'list)
+ (collect-link-cells-1-aux typs ptrs n ram map
+ 'list)))
+ (not (endp typs))
+ (assoc-equal (car typs) map)
+ (equal (collect-updates-zdynamic-1-aux (car typs)
+ (car ptrs) n ram map
+ 'ATOM)
+ (collect-updates-static-1-aux (car typs)
+ (car ptrs) n ram map
+ 'ATOM))
+ (equal (collect-updates-zdynamic-1-aux (cdr typs)
+ (cdr ptrs) n
+ (mark-1-aux (car typs)
+ (car ptrs)
+ n
+ ram map
+ 'ATOM)
+ map 'LIST)
+ (collect-updates-static-1-aux (cdr typs)
+ (cdr ptrs) n
+ (mark-1-aux (car typs)
+ (car ptrs)
+ n
+ ram map
+ 'ATOM)
+ map 'LIST)))
+ (equal (collect-updates-zdynamic-1-aux (cdr typs)
+ (cdr ptrs) n
+ (mark-1-aux (car typs)
+ (car ptrs)
+ n
+ ram map
+ 'ATOM)
+ map 'LIST)
+ (collect-updates-static-1-aux (cdr typs)
+ (cdr ptrs) n
+ ram
+ map 'LIST)))
+ :hints (("Goal" :in-theory (disable
+ apply-updates-collect-dynamic-is-mark))))
+
+
+
+;--------------- prove the two lemmas that deal with recursion
+;--------------- mode = LIST.
+
+;--------------- mode = ATOM
+#|
+(skip-proofs
+ (defthm subsetp-collect-updates-from-single-update-collect-data-1-aux
+ (implies (not (overlap (collect-data-cells-1-aux typ ptr n ram map 'ATOM)
+ (collect-link-cells-1-aux typ ptr n ram map 'ATOM)))
+ (subsetp (updates-2-ws (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ (collect-data-cells-1-aux typ ptr n ram map 'ATOM)))))
+|#
+
+
+(defthm subsetp-collect-updates-from-single-update-collect-updates-static-1-aux
+ (implies (and (assoc-equal typ map)
+ (not (zp n))
+ (not (zp ptr)))
+ (subsetp (updates-2-ws (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ (updates-2-ws (collect-updates-static-1-aux
+ typ ptr n ram map 'ATOM) ram map)))
+ :hints (("Goal" :expand (collect-updates-static-1-aux typ ptr n ram map
+ 'ATOM))))
+
+;---------------
+#|
+(defthm apply-updates-struct-equiv-1-aux-instance-2
+ (implies (and (not (overlap (collect-data-cells-1-aux typ ptr n ram map 'ATOM)
+ (collect-link-cells-1-aux typ ptr n ram map 'ATOM)))
+ (assoc-equal typ map)
+ (not (zp ptr)))
+ (struct-equiv-1-aux typ ptr n
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map)
+ ram map)
+ ram map 'ATOM))
+ :hints (("Goal"
+ :cases ((consp (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map))))
+ ("Subgoal 1"
+ :use ((:instance subsetp-transitive
+ (a (updates-2-ws
+ (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map))
+ (b (updates-2-ws
+ (collect-updates-static-1-aux
+ typ ptr n ram map 'ATOM) ram ram))
+ (c (collect-data-cells-1-aux
+ typ ptr n ram map 'ATOM)))))))
+
+|#
+#|
+; instantiate the about again
+
+
+(defthm apply-updates-struct-equiv-1-aux-instance-2-instance
+ (implies (and (not (overlap (collect-data-cells-1-aux typ ptr n ram map 'ATOM)
+ (collect-link-cells-1-aux typ ptr n ram map 'ATOM)))
+ (assoc-equal typ map)
+ (not (zp n))
+ (not (zp ptr)))
+ (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST))
+ :hints (("Goal" :in-theory (disable apply-updates-struct-equiv-1-aux-instance-2)
+ :use apply-updates-struct-equiv-1-aux-instance-2)))
+
+;----------------------- concrete instantiations
+
+(defthm struct-equiv-1-aux-implies-collect-data-equal-instance-2
+ (implies (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST)
+ (equal (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ map 'LIST)
+ (collect-data-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))))
+
+
+(defthm struct-equiv-1-aux-implies-collect-link-equal-instance-2
+ (implies (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST)
+ (equal (collect-link-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ map 'LIST)
+ (collect-link-cells-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))))
+
+
+(defthm struct-equiv-1-aux-implies-collect-update-static-equal-instance-2
+ (implies (struct-equiv-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ ram
+ map 'LIST)
+ (equal (collect-updates-static-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ (apply-updates (collect-updates-from-single-update1-static
+ typ ptr 0 n ram map) ram map)
+ map 'LIST)
+ (collect-updates-static-1-aux
+ (cdr (assoc-equal typ map))
+ (seq-int (g ptr ram) (len (cdr (assoc-equal typ map))))
+ (- n 1)
+ ram map 'LIST))))
+
+|#
+;---------------------------------------
+
+
+(defthm collect-updates-zdynamic-1-aux-is-collect-updates-static-1-aux
+ (implies (not (overlap (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)
+ (collect-link-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)))
+ (equal (collect-updates-zdynamic-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)
+ (collect-updates-static-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)))
+ :hints (("Goal" :induct (collect-updates-zdynamic-1-aux typ-or-typs
+ ptr-or-ptrs
+ n ram map mode)
+ :in-theory (disable
+ APPLY-UPDATES-COLLECT-DYNAMIC-IS-MARK)
+ :do-not '(generalize))))
+
+
+
+;------------------ done at last !!! -------
+;
+; we now have this result and a theorem that
+; (updates-2-ws (collect-updates-static-1-aux ..) is a subset of
+; (collect-static-data ..)
+;
+
+
+(defthm g-over-apply-update-lemma
+ (implies (not (equal addr (update-2-w update ram)))
+ (equal (g addr (apply-update update ram map))
+ (g addr ram)))
+ :hints (("Goal" :in-theory (enable apply-update
+ update-2-w
+ gtyp gptr gi gn))))
+
+(defthm g-over-apply-updates-lemma
+ (implies (not (member addr (updates-2-ws updates ram map)))
+ (equal (g addr (apply-updates updates ram map))
+ (g addr ram))))
+
+
+(defthm g-over-mark-1-aux-lemma
+ (implies (and (not (overlap (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)
+ (collect-link-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)))
+ (not (member addr
+ (updates-2-ws (collect-updates-static-1-aux
+ typ-or-typs ptr-or-ptrs
+ n ram map mode) ram map))))
+ (equal (g addr (mark-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode))
+ (g addr ram))))
+
+
+
+(defthm g-over-mark-1-aux
+ (implies (and (not (overlap (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)
+ (collect-link-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode)))
+ (not (member addr
+ (collect-data-cells-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode))))
+ (equal (g addr (mark-1-aux typ-or-typs ptr-or-ptrs
+ n ram map mode))
+ (g addr ram)))
+ :hints (("Goal" :in-theory (disable subsetp-collect-updates-static-1-aux-data-cells)
+ :use subsetp-collect-updates-static-1-aux-data-cells)))
+
+
+;------------ done! -------------
+(defun collect-updates-static-1 (typ ptr n ram map)
+ (collect-updates-static-1-aux typ ptr n ram map 'ATOM))
+
+
+(defun collect-updates-static-1-list (typs ptrs n ram map)
+ (collect-updates-static-1-aux typs ptrs n ram map 'LIST))
+
+
+(defun all-collect-updates-static-1 (typs ptrs ns ram map)
+ (if (endp typs)
+ nil
+ (append (collect-updates-static-1 (car typs) (car ptrs) (car ns) ram map)
+ (all-collect-updates-static-1
+ (cdr typs) (cdr ptrs) (cdr ns) ram map))))
+
+
+(defun collect-updates-static (rc)
+ (all-collect-updates-static-1 (typ-list (ptrs rc))
+ (addr-list (ptrs rc))
+ (n-list (ptrs rc))
+ (ram rc)
+ (getmap rc)))
+
+
+
+
+;----------------------------------
+
+; (defthm g-over-mark
+; (implies (and (not (overlap (collect-data-cells rc)
+; (collect-link-cells rc)))
+; (not (member addr (updates-2-ws (collect-updates-static rc)))))
+; (equal (g addr (mark rc))
+; (g addr (ram rc)))))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/books/workshops/2003/hendrix/hendrix-slides.pdf.gz b/books/workshops/2003/hendrix/hendrix-slides.pdf.gz
new file mode 100644
index 0000000..8aba330
--- /dev/null
+++ b/books/workshops/2003/hendrix/hendrix-slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/hendrix/hendrix-slides.ps.gz b/books/workshops/2003/hendrix/hendrix-slides.ps.gz
new file mode 100644
index 0000000..ffdee59
--- /dev/null
+++ b/books/workshops/2003/hendrix/hendrix-slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/hendrix/hendrix.pdf.gz b/books/workshops/2003/hendrix/hendrix.pdf.gz
new file mode 100644
index 0000000..be4a139
--- /dev/null
+++ b/books/workshops/2003/hendrix/hendrix.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/hendrix/hendrix.ps.gz b/books/workshops/2003/hendrix/hendrix.ps.gz
new file mode 100644
index 0000000..79c72e9
--- /dev/null
+++ b/books/workshops/2003/hendrix/hendrix.ps.gz
Binary files differ
diff --git a/books/workshops/2003/hendrix/support/madd.lisp b/books/workshops/2003/hendrix/support/madd.lisp
new file mode 100644
index 0000000..eb09c85
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/madd.lisp
@@ -0,0 +1,156 @@
+;;;;; Matrix addition.
+;;;;; Defines m+ and basic properties. This includes associativity,
+;;;;; commutativity, a definition by column operations, and properties
+;;;;; involving mentry and mzero.
+(in-package "ACL2")
+
+(include-book "mdefthms")
+
+(defmacro m+-guard (m n)
+ `(and (matrixp ,m)
+ (matrixp ,n)
+ (equal (row-count ,m) (row-count ,n))
+ (equal (col-count ,m) (col-count ,n))))
+
+(defun m+ (m n)
+ (declare (xargs :guard (m+-guard m n)
+ :verify-guards nil))
+ (if (m-emptyp m)
+ (m-empty)
+ (row-cons (v+ (row-car m) (row-car n))
+ (m+ (row-cdr m) (row-cdr n)))))
+
+(defthm m-emptyp-m+
+ (equal (m-emptyp (m+ m n))
+ (m-emptyp m)))
+
+(defthm row-count-m+
+ (equal (row-count (m+ m n))
+ (row-count m)))
+
+(defthm col-count-m+
+ (implies (matrixp m)
+ (equal (col-count (m+ m n))
+ (col-count m)))
+ :hints (("Goal" :induct (m+ m n))))
+
+(defthm matrixp-m+
+ (implies (matrixp m)
+ (matrixp (m+ m n))))
+
+(verify-guards m+)
+
+
+(defthm col-count-m+
+ (implies (matrixp m)
+ (equal (col-count (m+ m n))
+ (col-count m))))
+
+(defthm row-count-m+
+ (equal (row-count (m+ m n))
+ (row-count m)))
+
+(local
+ (defthm col-car-m+
+ (implies (and (matrixp m) (matrixp n))
+ (equal (col-car (m+ m n))
+ (v+ (col-car m) (col-car n))))
+ :hints (("Goal" :induct (m+ m n))
+ ("Subgoal *1/2.2" :expand ((v+ (row-car m) (row-car n)))))))
+
+(defun m+-by-col-recursion (m n)
+ (declare (xargs :guard (m+-guard m n)
+ :guard-hints
+ (("Subgoal 2"
+ :cases ((m-emptyp (col-cdr m))))
+ ("Subgoal 2.2'4'"
+ :cases ((m-emptyp (col-cdr n))))
+ ("Subgoal 1" :cases ((m-emptyp (col-cdr m)))))))
+ (if (or (m-emptyp m) (m-emptyp n))
+ nil
+ (m+-by-col-recursion (col-cdr m) (col-cdr n))))
+
+(defthm m+-by-col-def
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (m+ m n)
+ (if (m-emptyp m)
+ (m-empty)
+ (col-cons (v+ (col-car m) (col-car n))
+ (m+ (col-cdr m) (col-cdr n))))))
+ :hints (("Goal" :in-theory (enable row-cons-def)
+ :induct (m+ m n)))
+ :rule-classes :definition)
+
+(defthm m+-assoc
+ (implies (and (m+-guard m n)
+ (matrixp p))
+ (equal (m+ (m+ m n) p)
+ (m+ m (m+ n p))))
+ :hints (("Goal" :induct (and (m+ m n)
+ (m+ n p)))))
+(defthm m+-assoc2
+ (implies (and (m+-guard m n)
+ (matrixp p))
+ (equal (m+ m (m+ n p))
+ (m+ n (m+ m p))))
+ :hints (("Goal" :induct (and (m+ m n)
+ (m+ n p)))))
+
+(defthm m+-comm
+ (implies (m+-guard m n)
+ (equal (m+ m n)
+ (m+ n m)))
+ :hints (("Goal" :induct (m+ m n))))
+
+;;;; Properties about adding zero to a matrix.
+;;;; These currently use (mzero (row-count m) (col-count m)) in
+;;;; their definition. This may not match as much as we would like,
+;;;; so it may be smart to change this to (mzero r c) and add
+;;;; appropriate conditions.
+(include-book "mzero")
+
+(defthm m+zero
+ (implies (matrixp m)
+ (equal (m+ m (mzero (row-count m) (col-count m))) m))
+ :hints (("Goal" :induct (m+ m m))
+; :With directed added 3/13/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2'''" :expand ((:with mzero (mzero 1 (col-count m)))))))
+
+(defthm zero+m
+ (implies (matrixp m)
+ (equal (m+ (mzero (row-count m) (col-count m)) m) m))
+ :hints (("Goal" :induct (m+ m m))
+; :With directed added 3/13/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2'''" :expand ((:with mzero (mzero 1 (col-count m)))))))
+
+;;;; Properties related to mentry
+(include-book "mentry")
+
+(defthm row-m+
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (row i (m+ m n))
+ (if (< (nfix i) (row-count m))
+ (v+ (row i m) (row i n))
+ nil)))
+ :hints (("Goal" :induct (and (and (row i m)
+ (m+ m n))))))
+
+(defthm col-m+
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (col i (m+ m n))
+ (if (< (nfix i) (col-count m))
+ (v+ (col i m) (col i n))
+ nil)))
+ :hints (("Goal" :induct (m+ m n))))
+
+(defthm entry-m+
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (mentry r c (m+ m n))
+ (if (and (< (nfix r) (row-count m))
+ (< (nfix c) (col-count m)))
+ (+ (mentry r c m) (mentry r c n))
+ nil))))
diff --git a/books/workshops/2003/hendrix/support/matrices.lisp b/books/workshops/2003/hendrix/support/matrices.lisp
new file mode 100644
index 0000000..773ae24
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/matrices.lisp
@@ -0,0 +1,15 @@
+;;;;; Top level book that includes all matrix operations.
+
+(in-package "ACL2")
+
+(include-book "vector")
+(include-book "mdefuns")
+(include-book "mdefthms")
+(include-book "mentry")
+(include-book "mzero")
+(include-book "madd")
+(include-book "mscal")
+(include-book "msub")
+(include-book "mid")
+(include-book "mmult")
+(include-book "mtrans")
diff --git a/books/workshops/2003/hendrix/support/mdefthms.lisp b/books/workshops/2003/hendrix/support/mdefthms.lisp
new file mode 100644
index 0000000..6d35a78
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mdefthms.lisp
@@ -0,0 +1,651 @@
+;;;;; Basic theorems for low level matrix operations. The other books are designed to
+;;;;; be provable using the theorems defined here without relying on the implementation
+;;;;; details.
+
+(in-package "ACL2")
+
+(include-book "mdefuns")
+
+;;; If the length of an variable is zero, it is an atom.
+(defthm len-atom
+ (implies (equal (len x) 0)
+ (atom x))
+ :rule-classes :forward-chaining)
+
+;;; We know that the length of a cons is at least one.
+(defthm len-consp
+ (implies (consp l)
+ (< 0 (len l)))
+ :rule-classes :type-prescription)
+
+;;;; Low level theorems used in proving public theorems.
+;;;; Not currently documented.
+(local
+ (defthm mvectorp-col-car-local
+ (implies (and (vector-list-of-lenp m i)
+ (< 0 i))
+ (mvectorp (col-car m)))
+ :rule-classes ((:rewrite :match-free :once))))
+
+(local
+ (defthm vector-list-col-cdr
+ (implies (vector-list-of-lenp m (+ 1 i))
+ (vector-list-of-lenp (col-cdr m) i))))
+
+(local
+ (defthm vector-list-col-cons-nil
+ (implies (mvectorp l)
+ (vector-list-of-lenp (col-cons-impl l nil) 1))))
+
+(local
+ (defthm vector-list-col-cons
+ (implies (and (vector-list-of-lenp m i)
+ (mvectorp l)
+ (equal (len l) (len m)))
+ (vector-list-of-lenp (col-cons-impl l m) (1+ i)))))
+
+(local
+ (defthm len-car-col-cdr
+ (implies (and (vector-list-of-lenp m i)
+ (< 0 i)
+ (consp m))
+ (equal (len (car (col-cdr m)))
+ (1- i)))
+ :rule-classes ((:rewrite :match-free :once))))
+
+(local
+ (defthm len-car-col-cons
+ (implies (consp l)
+ (equal (len (car (col-cons-impl l m)))
+ (1+ (len (car m)))))))
+
+(local
+ (defthm consp-col-car-local
+ (implies (and (vector-list-of-lenp m i)
+ (< 0 i))
+ (equal (consp (col-car m))
+ (consp m)))
+ :rule-classes ((:rewrite :match-free :once))))
+
+(local
+ (defthm consp-col-cdr
+ (implies (and (vector-list-of-lenp m i)
+ (< 1 i)
+ (consp m))
+ (consp (col-cdr m)))
+ :rule-classes ((:rewrite :match-free :once))))
+
+(local
+ (defthm consp-col-cons-impl
+ (implies (consp l)
+ (consp (col-cons-impl l m)))
+ :rule-classes ((:rewrite :match-free :once))))
+
+(local
+ (defthm col-cons-impl-atom
+ (implies (vector-list-of-lenp m 1)
+ (equal (col-cons-impl (col-car m) nil)
+ m))))
+
+(local
+ (defthm col-cons-impl-elim
+ (implies (and (vector-list-of-lenp m i)
+ (< 0 i))
+ (equal (col-cons-impl (col-car m) (col-cdr m))
+ m))
+ :rule-classes ((:rewrite :match-free :once))))
+
+;;;;;Type rules
+
+;;;; Type rules for row car, cdr, cons
+
+(defthm m-empty-nil
+ (implies (and (m-emptyp m)
+ (matrixp m))
+ (equal m nil))
+ :rule-classes :forward-chaining)
+
+(defthm car-vector-type
+ (implies (and (mvectorp l)
+ (consp l))
+ (acl2-numberp (car l)))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm mvectorp-row-car
+ (implies (matrixp m)
+ (mvectorp (row-car m)))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm consp-row-car
+ (implies (and (case-split (not (m-emptyp m)))
+ (matrixp m))
+ (consp (row-car m)))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm matrixp-row-cdr
+ (implies (matrixp m)
+ (matrixp (row-cdr m))))
+
+(defthm matrixp-row-cons
+ (implies (and (matrixp m)
+ (mvectorp l)
+ (consp l)
+ (or (m-emptyp m)
+ (equal (col-count m) (len l))))
+ (matrixp (row-cons l m))))
+
+;;;; Col car, cdr, cons type rules
+(defthm mvectorp-col-car
+ (implies (matrixp m)
+ (mvectorp (col-car m)))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm consp-col-car
+ (implies (and (not (m-emptyp m))
+ (matrixp m))
+ (consp (col-car m)))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm matrixp-col-cdr
+ (implies (matrixp m)
+ (matrixp (col-cdr m))))
+
+(defthm matrixp-col-cons
+ (implies (col-cons-guard l m)
+ (matrixp (col-cons l m))))
+
+
+(defthm empty-row-cdr-col-cdr
+ (implies (matrixp m)
+ (equal (m-emptyp (row-cdr (col-cdr m)))
+ (or (m-emptyp (row-cdr m))
+ (m-emptyp (col-cdr m))))))
+
+(local
+ (defthm vector-list-1-not-consp-col-cdr
+ (implies (vector-list-of-lenp m 1)
+ (not (consp (col-cdr m))))))
+
+(defthm empty-col-cdr-row-cdr
+ (implies (matrixp m)
+ (equal (m-emptyp (col-cdr (row-cdr m)))
+ (or (m-emptyp (col-cdr m))
+ (m-emptyp (row-cdr m))))))
+
+;;;; Theorems necessary to admit common recursion scheme for matrix operations.
+
+(defthm acl2-count-col-cdr
+ (implies (not (m-emptyp m))
+ (< (acl2-count (col-cdr m))
+ (acl2-count m))))
+
+(defthm acl2-count-row-cdr
+ (implies (not (m-emptyp m))
+ (< (acl2-count (row-cdr m))
+ (acl2-count m))))
+
+;;;; The row-cons or col-cons is never an m-empty
+(defthm not-empty-row-cons
+ (not (m-emptyp (row-cons r m))))
+
+(defthm not-empty-col-cons
+ (not (m-emptyp (col-cons c m))))
+
+;;;;; Logical definitions are provided for the basic functions since they
+;;;;; are disabled by this package. Row-cdr, row-cons, col-cdr, and col-cons
+;;;;; are not actually enabled as they are not normally needed, however they
+;;;;; can be used in special circumstances. I also added induction rules that
+;;;;; can be used in induction heuristics.
+
+;;;; Logical definitions for row-car, row-cdr, and row-cons.
+
+(defun row-car-recursion (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (m-emptyp m)
+ nil
+ (row-car-recursion (col-cdr m))))
+
+(defthm row-car-def
+ (implies (matrixp m)
+ (equal (row-car m)
+ (if (m-emptyp m)
+ nil
+ (cons (car (col-car m)) (row-car (col-cdr m))))))
+ :rule-classes ((:definition
+ :clique (col-car row-car col-cdr)
+ :controller-alist ((col-car t)
+ (row-car t)
+ (col-cdr t)))
+ (:induction :pattern (row-car m)
+ :scheme (row-car-recursion m))))
+
+(defun row-cdr-recursion (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (or (m-emptyp (row-cdr m))
+ (m-emptyp (col-cdr m)))
+ nil
+ (row-cdr-recursion (col-cdr m))))
+
+(defthmd row-cdr-def
+ (implies (matrixp m)
+ (equal (row-cdr m)
+ (if (endp (cdr (col-car m)))
+ nil
+ (col-cons (cdr (col-car m))
+ (row-cdr (col-cdr m))))))
+ :rule-classes ((:definition
+ :clique (col-car row-cdr col-cdr col-cons)
+ :controller-alist ((col-car t)
+ (row-cdr t)
+ (col-cdr t)
+ (col-cons t t)))
+ (:induction :pattern (row-cdr m)
+ :scheme (row-cdr-recursion m))))
+
+(defun row-cons-recursion (l m)
+ (declare (xargs :guard (row-cons-guard l m)))
+ (cond ((endp (cdr l)) nil)
+ ((m-emptyp m) (row-cons-recursion (cdr l) m))
+ (t (row-cons-recursion (cdr l) (col-cdr m)))))
+
+(defthmd row-cons-def
+ (implies (row-cons-guard l m)
+ (equal (row-cons l m)
+ (col-cons (cons (car l) (col-car m))
+ (if (endp (cdr l))
+ nil
+ (row-cons (cdr l) (col-cdr m))))))
+ :rule-classes ((:definition
+ :clique (col-car col-cdr row-cons col-cons)
+ :controller-alist ((col-car t)
+ (col-cdr t)
+ (row-cons t t)
+ (col-cons t t)))
+ (:induction :pattern (row-cons l m)
+ :scheme (row-cons-recursion l m))))
+
+;;;; Logical definitions for col-car, col-cdr, col-cons
+
+(defun col-car-recursion (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (m-emptyp m)
+ nil
+ (col-car-recursion (row-cdr m))))
+
+(defthm col-car-def
+ (implies (matrixp m)
+ (equal (col-car m)
+ (if (m-emptyp m)
+ nil
+ (cons (car (row-car m)) (col-car (row-cdr m))))))
+ :rule-classes ((:definition
+ :clique (col-car row-car row-cdr)
+ :controller-alist ((col-car t)
+ (row-car t)
+ (row-cdr t)))
+ (:induction :pattern (col-car m)
+ :scheme (col-car-recursion m))))
+
+(defun col-cdr-recursion (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (or (m-emptyp (col-cdr m))
+ (m-emptyp (row-cdr m)))
+ nil
+ (col-cdr-recursion (row-cdr m))))
+
+(defthmd col-cdr-def
+ (implies (matrixp m)
+ (equal (col-cdr m)
+ (if (endp (cdr (row-car m)))
+ nil
+ (row-cons (cdr (row-car m))
+ (col-cdr (row-cdr m))))))
+ :rule-classes ((:definition
+ :clique (row-car row-cdr col-cdr row-cons)
+ :controller-alist ((row-car t)
+ (row-cdr t)
+ (col-cdr t)
+ (row-cons t t)))
+ (:induction :pattern (col-cdr m)
+ :scheme (col-cdr-recursion m))))
+
+(defun col-cons-recursion (l m)
+ (declare (xargs :guard (col-cons-guard l m)))
+ (cond ((endp (cdr l)) nil)
+ ((m-emptyp m) (col-cons (cdr l) m))
+ (t (col-cons-recursion (cdr l) (row-cdr m)))))
+
+(defthmd col-cons-def
+ (implies (col-cons-guard l m)
+ (equal (col-cons l m)
+ (row-cons (cons (car l) (row-car m))
+ (if (endp (cdr l))
+ nil
+ (col-cons (cdr l) (row-cdr m))))))
+ :rule-classes ((:definition
+ :clique (row-car row-cdr row-cons col-cons)
+ :controller-alist ((row-car t)
+ (row-cdr t)
+ (row-cons t t)
+ (col-cons t t)))
+ (:induction :pattern (col-cons l m)
+ :scheme (col-cons-recursion l m))))
+
+
+;;;;; Row and column simplification rules
+
+;;;; Simple row operation reductions
+
+(defthm row-car-row-cons
+ (equal (row-car (row-cons l m)) l))
+
+(defthm row-cdr-empty
+ (implies (and (equal (row-count m) 1)
+ (matrixp m))
+ (equal (row-cdr m) nil)))
+
+(defthm row-cdr-row-cons
+ (equal (row-cdr (row-cons l m)) m))
+
+(defthm row-cons-elim-nil
+ (implies (and (m-emptyp (row-cdr m))
+ (matrixp m)
+ (not (m-emptyp m)))
+ (equal (row-cons (row-car m) nil)
+ m)))
+
+(defthm row-cons-elim
+ (implies (not (m-emptyp m))
+ (equal (row-cons (row-car m) (row-cdr m))
+ m))
+ :rule-classes :rewrite)
+
+;;;; Simple column operation reductions
+
+(local
+ (defthm col-car-col-cons-impl
+ (implies (mvectorp l)
+ (equal (col-car (col-cons-impl l m))
+ l))))
+
+(defthm col-car-col-cons
+ (implies (col-cons-guard l m)
+ (equal (col-car (col-cons l m)) l)))
+
+(local
+ (defthm col-cdr-col-cons-impl-nil
+ (equal (col-cdr (col-cons-impl l nil)) nil)))
+
+(local
+ (defthm col-cdr-col-cons-impl
+ (implies (and (mvectorp l)
+ (>= (len l) (len m))
+ (and (vector-list-of-lenp m i)
+ (< 0 i)))
+ (equal (col-cdr (col-cons-impl l m)) m))
+ :rule-classes ((:rewrite :match-free :once))))
+
+(defthm col-cdr-empty
+ (implies (equal (col-count m) 1)
+ (equal (col-cdr m) nil)))
+
+(defthm col-cdr-col-cons
+ (implies (col-cons-guard l m)
+ (equal (col-cdr (col-cons l m)) m)))
+
+(defthm col-cons-elim-nil
+ (implies (and (m-emptyp (col-cdr m))
+ (matrixp m)
+ (not (m-emptyp m)))
+ (equal (col-cons (col-car m) nil)
+ m)))
+
+(defthm col-cons-elim
+ (implies (and (matrixp m)
+ (not (m-emptyp m)))
+ (equal (col-cons (col-car m) (col-cdr m))
+ m)))
+
+;;;; Joint row col reductions.
+
+;;;; The first four are not enabled, because they should be handled
+;;;; by the logical definitions of row-car and col-car.
+(defthmd row-car-col-cdr
+ (implies (matrixp m)
+ (equal (row-car (col-cdr m))
+ (cdr (row-car m)))))
+
+(defthmd col-car-row-cdr
+ (implies (matrixp m)
+ (equal (col-car (row-cdr m))
+ (cdr (col-car m)))))
+
+(defthmd row-car-col-cons
+ (implies (consp l)
+ (equal (row-car (col-cons l m))
+ (cons (car l) (row-car m)))))
+
+(defthmd col-car-row-cons
+ (implies (consp l)
+ (equal (col-car (row-cons l m))
+ (cons (car l) (col-car m)))))
+
+;;;; The car of row-car equals the car of col-car. It may be a good
+;;;; idea to convert this to a single term, but for now a forward-chaining
+;;;; rule is used.
+(defthm car-row-car-car-col-car
+ (equal (car (row-car m))
+ (car (col-car m)))
+ :rule-classes ((:forward-chaining
+ :trigger-terms ((car (row-car m)) (car (col-car m))))))
+
+(local
+ (defthm not-col-cdr-local
+ (implies (vector-list-of-lenp m 1)
+ (not (col-cdr m)))))
+
+;;;; col-cdr row-cdr can be rotated, but it is not clear when this is
+;;;; a good idea, so forward-chaining is used in lieu of rewriting.
+(defthm col-cdr-row-cdr
+ (implies (matrixp m)
+ (equal (col-cdr (row-cdr m))
+ (row-cdr (col-cdr m))))
+ :rule-classes ((:forward-chaining
+ :trigger-terms ((col-cdr (row-cdr m))
+ (row-cdr (col-cdr m))))))
+
+(defthm col-cdr-row-cons
+ (implies (row-cons-guard l m)
+ (equal (col-cdr (row-cons l m))
+ (if (equal (len l) 1)
+ nil
+ (row-cons (cdr l) (col-cdr m))))))
+
+;;;; As a general rule, row operations are kept on the outside, so this is
+;;;; not normally enabled.
+(defthmd row-cdr-col-cons
+ (implies (col-cons-guard l m)
+ (equal (row-cdr (col-cons l m))
+ (if (equal (len l) 1)
+ nil
+ (col-cons (cdr l) (row-cdr m))))))
+
+;;;; Theorems relating row-cons and col-cons together.
+
+(defthm col-cons-row-cons-unit
+ (implies (and (equal (len l) 1)
+ (mvectorp l))
+ (equal (col-cons l nil)
+ (row-cons l nil))))
+
+(defthm col-cons-row-cons
+ (implies (and (matrixp m)
+ (consp k)
+ (or (case-split (m-emptyp m))
+ (equal (col-count m) (len k)))
+ (equal (1+ (row-count m)) (len l)))
+ (equal (col-cons l (row-cons k m))
+ (if (m-emptyp m)
+ (row-cons (cons (car l) k) nil)
+ (row-cons (cons (car l) k) (col-cons (cdr l) m))))))
+
+(defthm row-cons-col-cons-empty
+ (implies (and (mvectorp k)
+ (consp k)
+ (mvectorp l)
+ (equal (len l) 1))
+ (equal (row-cons l (col-cons k nil))
+ (col-cons (cons (car l) k) nil))))
+
+;;;; Row ops are kept on outside, so not normally enabled
+(defthmd row-cons-col-cons
+ (implies (and (matrixp m)
+ (not (m-emptyp m))
+ (mvectorp k)
+ (equal (len k) (row-count m))
+ (mvectorp l)
+ (equal (len l) (1+ (col-count m))))
+ (equal (row-cons l (col-cons k m))
+ (col-cons (cons (car l) k) (row-cons (cdr l) m)))))
+
+;;;; Theorems for row-count
+
+(defthm row-count-type
+ (and (integerp (row-count m))
+ (<= 0 (row-count m)))
+ :rule-classes :type-prescription)
+
+(defthm row-count-type-not-empty
+ (implies (not (m-emptyp m))
+ (< 0 (row-count m)))
+ :rule-classes :type-prescription)
+
+(defun row-count-recursion (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (m-emptyp m)
+ 0
+ (row-count-recursion (row-cdr m))))
+
+;;; Row count's logical definition
+(defthm row-count-def
+ (equal (row-count m)
+ (if (m-emptyp m)
+ 0
+ (1+ (row-count (row-cdr m)))))
+ :rule-classes :definition)
+
+(defthm row-count-implies-empty
+ (equal (equal (row-count m) 0)
+ (m-emptyp m)))
+
+(defthm row-count-implies-not-empty
+ (equal (< 0 (row-count m))
+ (not (m-emptyp m))))
+
+(local
+ (defthm len-col-cdr
+ (implies (and (vector-list-of-lenp m i)
+ (< 1 i))
+ (equal (len (col-cdr m))
+ (len m)))
+ :rule-classes ((:rewrite :match-free :once))))
+
+(defthm row-count-col-cdr
+ (implies (and (case-split (not (m-emptyp (col-cdr m))))
+ (matrixp m))
+ (equal (row-count (col-cdr m))
+ (row-count m))))
+
+(local
+ (defthm len-col-cons
+ (equal (len (col-cons-impl l m))
+ (len l))))
+
+(defthm row-count-col-cons
+ (implies (consp l)
+ (equal (row-count (col-cons l m))
+ (len l))))
+
+(defthm row-count-row-cdr-col-cdr
+ (implies (and (matrixp m)
+ (not (m-emptyp (col-cdr m))))
+ (equal (row-count (row-cdr (col-cdr m)))
+ (row-count (row-cdr m)))))
+
+(defthm len-col-car
+ (implies (matrixp m)
+ (equal (len (col-car m))
+ (row-count m))))
+
+(defthmd <=-len-col-car
+ (<= (len (col-car m))
+ (row-count m)))
+
+(defthmd <=-row-count-col-cdr
+ (<= (row-count (col-cdr m))
+ (row-count m)))
+
+;;;; Theorems for column count.
+
+(defthm col-count-type
+ (and (integerp (col-count m))
+ (<= 0 (col-count m)))
+ :rule-classes :type-prescription)
+
+(defthm col-count-type-not-empty
+ (implies (and (not (m-emptyp m))
+ (matrixp m))
+ (< 0 (col-count m)))
+ :rule-classes :type-prescription)
+
+(defun col-count-recursion (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (m-emptyp m)
+ 0
+ (col-count-recursion (col-cdr m))))
+
+;;; Column count's logical definition.
+(defthm col-count-def
+ (implies (matrixp m)
+ (equal (col-count m)
+ (if (m-emptyp m)
+ 0
+ (1+ (col-count (col-cdr m))))))
+ :rule-classes :definition)
+
+(defthm col-count-implies-empty
+ (implies (matrixp m)
+ (equal (equal (col-count m) 0)
+ (m-emptyp m))))
+
+(defthm col-count-implies-not-empty
+ (implies (matrixp m)
+ (equal (< 0 (col-count m))
+ (not (m-emptyp m)))))
+
+(defthm col-count-row-cdr
+ (implies (and (case-split (not (m-emptyp (row-cdr m))))
+ (matrixp m))
+ (equal (col-count (row-cdr m))
+ (col-count m))))
+
+(defthm col-count-row-cons
+ (equal (col-count (row-cons l m))
+ (len l)))
+
+(defthm col-count-col-cdr-row-cdr
+ (implies (and (matrixp m)
+ (not (m-emptyp (row-cdr m))))
+ (equal (col-count (col-cdr (row-cdr m)))
+ (col-count (col-cdr m)))))
+
+(defthm len-row-car
+ (equal (len (row-car m))
+ (col-count m)))
+
+;;; Disable low level functions.
+(in-theory (disable matrixp m-emptyp
+ vector-list-of-lenp
+ row-car row-cdr row-cons
+ col-car col-cdr col-cons
+ row-count col-count))
diff --git a/books/workshops/2003/hendrix/support/mdefuns.lisp b/books/workshops/2003/hendrix/support/mdefuns.lisp
new file mode 100644
index 0000000..2c77947
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mdefuns.lisp
@@ -0,0 +1,127 @@
+;;;;; Implement low level operations for matrices. No theorems other than those
+;;;;; necessary for guard verification are proven. See mdefthms.lisp for theorems.
+(in-package "ACL2")
+
+(include-book "vector")
+
+;;; Returns true if l is a true-list where each element is a vector
+;;; of length n.
+(defun vector-list-of-lenp (l n)
+ (declare (xargs :verify-guards t))
+ (if (consp l)
+ (and (mvectorp (car l))
+ (equal (len (car l)) n)
+ (vector-list-of-lenp (cdr l) n))
+ (eq l nil)))
+
+;;;; A Matrix is represented as a true-list of true-lists of numbers
+;;;; where each list has the same length. In contrast to traditional
+;;;; mathematics, it is possible for a list to contain 0 rows and
+;;;; columns in which case it is the empty matrix. The empty matrix
+;;;; is the only matrix with zero rows or columns, all other matrices
+;;;; must contain at least one row and column.
+
+;;; Returns true if m is a matrix.
+(defun matrixp (m)
+ (declare (xargs :verify-guards t))
+ (or (eq m nil)
+ (and (consp m)
+ (consp (car m))
+ (vector-list-of-lenp m (len (car m))))))
+
+;;; Returns the m-empty.
+(defun m-empty ()
+ (declare (xargs :verify-guards t))
+ nil)
+
+;;; Returns true if m is an atom (this more general definition of
+;;; an empty matrix is needed so that termination checking is
+;;; easier).
+(defun m-emptyp (m)
+ (declare (xargs :guard (matrixp m)))
+ (endp m))
+
+;;; Return the number of rows in the matrix m.
+(defun row-count (m)
+ (declare (xargs :guard (matrixp m)))
+ (len m))
+
+;;; Return the number of columns in the matrix m.
+(defun col-count (m)
+ (declare (xargs :guard (matrixp m)))
+ (len (car m)))
+
+;;; Returns the top row of the matrix.
+(defun row-car (m)
+ (declare (xargs :guard (matrixp m)))
+ (car m))
+
+;;; Returns a matrix with the top row removed.
+(defun row-cdr (m)
+ (declare (xargs :guard (matrixp m)))
+ (cdr m))
+
+;;; Guard for "consing" a row (vector) to a matrix.
+(defmacro row-cons-guard (l m)
+ `(and (matrixp ,m)
+ (mvectorp ,l)
+ (consp ,l)
+ (or (m-emptyp ,m)
+ (equal (col-count ,m) (len ,l)))))
+
+;;; Adds a new row r to the matrix m. The existing rows are moved down
+;;; one row. If m is the m-empty, then r is expected to be of
+;;; length greater than zero. Otherwise, r is expected to be the same
+;;; length as the number of columns in the matrix.
+(defun row-cons (r m)
+ (declare (xargs :guard (row-cons-guard r m)))
+ (cons r m))
+
+;;; Returns the leftmost column of the matrix.
+(defun col-car (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (or (endp m) (endp (car m)))
+ nil
+ (cons (caar m) (col-car (cdr m)))))
+
+;;; Returns a matrix with the leftmost column removed.
+(defun col-cdr (m)
+ (declare (xargs :guard (matrixp m)))
+ (if (or (endp m) (endp (cdar m)))
+ nil
+ (cons (cdar m) (col-cdr (cdr m)))))
+
+;;; Implementation function for col-cons (below).
+(defun col-cons-impl (l m)
+ (declare (xargs :guard (and (true-listp l)
+ (true-listp m))))
+ (if (consp l)
+ (cons (cons (car l) (car m)) (col-cons-impl (cdr l) (cdr m)))
+ nil))
+
+(defmacro col-cons-guard (l m)
+ `(and (matrixp ,m)
+ (mvectorp ,l)
+ (consp ,l)
+ (or (m-emptyp ,m)
+ (equal (row-count ,m) (len ,l)))))
+
+(local
+ (defthm vector-list-is-true-list
+ (implies (vector-list-of-lenp m i)
+ (true-listp m))
+ :rule-classes :forward-chaining))
+
+;;; Adds a new column c to the matrix m. The existing rows are moved
+;;; down one row. If m is the m-empty, then c is expected to be of
+;;; length greater than zero. Otherwise, c is expected to be the same
+;;; length as the number of rows in the matrix.
+
+;;; The implementation using col-cons-impl so that it is guaranteed to
+;;; always return something considered not to be the empty matrix even
+;;; if the guards are violated.
+(defun col-cons (l m)
+ (declare (xargs :guard (col-cons-guard l m)))
+ (if (consp l)
+ (col-cons-impl l m)
+ (cons nil nil)))
diff --git a/books/workshops/2003/hendrix/support/mentry.lisp b/books/workshops/2003/hendrix/support/mentry.lisp
new file mode 100644
index 0000000..4f4729e
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mentry.lisp
@@ -0,0 +1,118 @@
+;;;;; Provides indexed access to rows, columns and entries in a matrix.
+(in-package "ACL2")
+
+;;; If (nfix i) is greater then the length of a list, then the nth equals nil.
+(defthm nth-over
+ (implies (<= (len l) (nfix i))
+ (equal (nth i l) nil)))
+
+(include-book "mdefthms")
+
+(defmacro row-guard (i m)
+ `(and (matrixp ,m)
+ (integerp ,i)
+ (<= 0 ,i)
+ (< ,i (row-count ,m))))
+
+;;; Returns row at index i in matrix m.
+(defun row (i m)
+ (declare (xargs :guard (row-guard i m)))
+ (cond ((m-emptyp m) nil)
+ ((zp i) (row-car m))
+ (t (row (1- i) (row-cdr m)))))
+
+;;; Provide an alterate definition of row that uses col-cdr instead of row-cdr.
+(defthm row-by-col-def
+ (implies (matrixp m)
+ (equal (row i m)
+ (if (or (m-emptyp m)
+ (>= (nfix i) (row-count m)))
+ nil
+ (cons (nth i (col-car m))
+ (row i (col-cdr m))))))
+ :hints (("Goal" :induct (row i m)))
+ :rule-classes :definition)
+
+(defthm mvectorp-row
+ (implies (matrixp m)
+ (mvectorp (row i m)))
+ :rule-classes (:rewrite :type-prescription))
+
+(defthm len-row
+ (implies (matrixp m)
+ (equal (len (row i m))
+ (if (< (nfix i) (row-count m))
+ (col-count m)
+ 0)))
+ :hints (("Goal" :induct (row i m))))
+
+(defthm consp-row
+ (implies (matrixp m)
+ (equal (consp (row i m))
+ (< (nfix i) (row-count m))))
+ :hints (("Subgoal *1/6"
+ :cases ((< (1- i) (row-count (row-cdr m)))))))
+
+(defmacro col-guard (i m)
+ `(and (matrixp ,m)
+ (integerp ,i)
+ (<= 0 ,i)
+ (< ,i (col-count ,m))))
+
+(defun col (i m)
+ (declare (xargs :guard (col-guard i m)))
+ (cond ((m-emptyp m) nil)
+ ((zp i) (col-car m))
+ (t (col (1- i) (col-cdr m)))))
+
+(defthm col-by-row-def
+ (implies (matrixp m)
+ (equal (col i m)
+ (if (or (m-emptyp m)
+ (>= (nfix i) (col-count m)))
+ nil
+ (cons (nth i (row-car m))
+ (col i (row-cdr m))))))
+ :hints (("Goal" :induct (col i m)))
+ :rule-classes :definition)
+
+(defthm mvectorp-col
+ (implies (matrixp m)
+ (mvectorp (col i m)))
+ :rule-classes (:rewrite :type-prescription))
+
+(defthm len-col
+ (implies (matrixp m)
+ (equal (len (col i m))
+ (if (< (nfix i) (col-count m))
+ (row-count m)
+ 0))))
+
+(defthm consp-col
+ (implies (matrixp m)
+ (equal (consp (col i m))
+ (< (nfix i) (col-count m))))
+ :hints (("Subgoal *1/6"
+ :cases ((< (1- i) (col-count (col-cdr m)))))))
+
+(defmacro mentry-guard (r c m)
+ `(and (matrixp ,m)
+ (integerp ,r)
+ (<= 0 ,r)
+ (< ,r (row-count ,m))
+ (integerp ,c)
+ (<= 0 ,c)
+ (< ,c (col-count ,m))))
+
+;;; Return the entry at the specified row and column
+(defun mentry (r c m)
+ (declare (xargs :guard (mentry-guard r c m)))
+ (nth c (row r m)))
+
+;;; Provide an alterate equivalent definition of mentry.
+(defthmd mentry-by-col
+ (implies (matrixp m)
+ (equal (mentry r c m)
+ (nth r (col c m))))
+ :rule-classes :definition)
+
diff --git a/books/workshops/2003/hendrix/support/mid.lisp b/books/workshops/2003/hendrix/support/mid.lisp
new file mode 100644
index 0000000..2fe7c26
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mid.lisp
@@ -0,0 +1,53 @@
+;;;;; Identity matrix
+;;;;; TODO: Tie this into mentry operations.
+(in-package "ACL2")
+
+(include-book "mdefthms")
+
+(defmacro mid-guard (n)
+ `(and (integerp ,n)
+ (<= 0 ,n)))
+
+(defun mid (n)
+ (declare (xargs :guard (mid-guard n)
+ :verify-guards nil))
+ (cond ((zp n) nil)
+ ((zp (1- n)) '((1)))
+ (t (let ((zero-row (vzero (1- n))))
+ (row-cons (cons 1 zero-row)
+ (col-cons zero-row
+ (mid (1- n))))))))
+
+(local
+ (defthm id-bootstrap
+ (and (matrixp (mid n))
+ (equal (row-count (mid n))
+ (nfix n))
+ (equal (col-count (mid n))
+ (nfix n)))))
+
+(defthm matrix-id
+ (matrixp (mid n)))
+
+(defthm m-empty-id
+ (equal (m-emptyp (mid n))
+ (zp n)))
+
+(defthm row-count-id
+ (equal (row-count (mid n))
+ (nfix n)))
+
+(defthm col-count-id
+ (equal (col-count (mid n))
+ (nfix n)))
+
+(verify-guards mid)
+
+(defthm id-by-col-def
+ (equal (mid n)
+ (cond ((zp n) nil)
+ ((zp (1- n)) (col-cons '(1) nil))
+ (t (col-cons (cons 1 (vzero (1- n)))
+ (row-cons (vzero (1- n))
+ (mid (1- n)))))))
+ :rule-classes :definition)
diff --git a/books/workshops/2003/hendrix/support/mmult.lisp b/books/workshops/2003/hendrix/support/mmult.lisp
new file mode 100644
index 0000000..f13c875
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mmult.lisp
@@ -0,0 +1,446 @@
+;;;;; Matrix multiplication and vector matrix multiplication.
+;;;;; This includes col* (normally called multiplication of a matrix
+;;;;; by a vector in math), row* (multiplication of a vector by each row
+;;;;; in a matrix), and and matrix multiplication.
+;;;;; Basic properties are proven as well as relations to the mzero, madd,
+;;;;; mid, and mentry books. This includes the group properties.
+
+(in-package "ACL2")
+
+(include-book "mdefthms")
+
+;;;; Definition of col* and basic properties
+(defmacro col*-guard (r m)
+ `(and (matrixp ,m)
+ (mvectorp ,r)
+ (or (m-emptyp ,m)
+ (equal (len ,r) (row-count ,m)))))
+
+;;; Returns list containing dot product of each column in m and r.
+(defun col* (r m)
+ (declare (xargs :guard (col*-guard r m)))
+ (if (m-emptyp m)
+ nil
+ (cons (dot* r (col-car m))
+ (col* r (col-cdr m)))))
+
+(defthm mvectorp-col*
+ (mvectorp (col* r m))
+ :rule-classes (:rewrite :type-prescription))
+
+(defthm consp-col*
+ (implies (not (m-emptyp m))
+ (consp (col* r m)))
+ :rule-classes :type-prescription)
+
+(defthm len-col*
+ (implies (matrixp m)
+ (equal (len (col* r m))
+ (col-count m))))
+
+(defthm col*-by-row-def
+ (implies (matrixp m)
+ (equal (col* l m)
+ (if (m-emptyp m)
+ nil
+ (v+ (sv* (car l) (row-car m))
+ (col* (cdr l) (row-cdr m))))))
+ :hints (("Goal" :induct (col* l m)))
+ :rule-classes :definition)
+
+;;;; Definition of row* and basic properties
+
+(defmacro row*-guard (c m)
+ `(and (matrixp ,m)
+ (mvectorp ,c)
+ (or (m-emptyp ,m)
+ (equal (len ,c) (col-count ,m)))))
+
+;;; Returns list containing dot product of each row in m and c.
+(defun row* (c m)
+ (declare (xargs :guard (row*-guard c m)))
+ (if (m-emptyp m)
+ nil
+ (cons (dot* c (row-car m))
+ (row* c (row-cdr m)))))
+
+(defthm mvectorp-row*
+ (mvectorp (row* c m))
+ :rule-classes (:rewrite :type-prescription))
+
+(defthm consp-row*
+ (implies (not (m-emptyp m))
+ (consp (row* c m)))
+ :rule-classes :type-prescription)
+
+(defthm len-row*
+ (implies (matrixp m)
+ (equal (len (row* c m))
+ (row-count m))))
+
+(defthm row*-by-col-def
+ (implies (matrixp m)
+ (equal (row* l m)
+ (if (m-emptyp m)
+ nil
+ (v+ (sv* (car l) (col-car m))
+ (row* (cdr l) (col-cdr m))))))
+ :hints (("Goal" :induct (row* l m)))
+ :rule-classes :definition)
+
+;;; The dot product of col* and row* are related.
+(defthm dot*-col*
+ (implies (and (matrixp m)
+ (or (m-emptyp m)
+ (and (equal (len k) (col-count m))
+ (equal (len l) (row-count m)))))
+ (equal (dot* k (col* l m))
+ (dot* l (row* k m))))
+ :hints (("Goal" :induct (row-cons k m)
+
+; Added by Matt Kaufmann, 2/25/06, to accommodate fix for runic designators
+; to match their spec, where disabling the name of a defthm disables all rules
+; generated for that defthm (in this case, row-cons-def).
+
+ :in-theory (enable (:induction row-cons-def))))
+ :rule-classes ((:forward-chaining
+ :trigger-terms ((dot* k (col* l m))
+ (dot* l (row* k m))))))
+
+;;;; Definition of m* and basic properties
+(defmacro m*-guard (m n)
+ `(and (matrixp ,m)
+ (matrixp ,n)
+ (equal (col-count ,m) (row-count ,n))))
+
+(defun m* (m n)
+ (declare (xargs :guard (m*-guard m n)
+ :verify-guards nil))
+ (if (or (m-emptyp m) (m-emptyp n))
+ (m-empty)
+ (row-cons (col* (row-car m) n)
+ (if (m-emptyp (row-cdr m))
+ (m-empty)
+ (m* (row-cdr m) n)))))
+
+(local
+ (defthm m*-bootstrap
+ (implies (and (matrixp m)
+ (matrixp n))
+ (and (matrixp (m* m n))
+ (equal (col-count (m* m n))
+ (if (m-emptyp m) 0 (col-count n)))))
+ :hints (("Goal" :induct (m* m n)))))
+
+(verify-guards m*)
+
+(defthm matrixp-m*
+ (implies (and (matrixp m)
+ (matrixp n))
+ (matrixp (m* m n))))
+
+(defthm col-count-m*
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (col-count (m* m n))
+ (if (m-emptyp m)
+ 0
+ (col-count n)))))
+
+(defthm row-count-m*
+ (equal (row-count (m* m n))
+ (if (m-emptyp n) 0 (row-count m))))
+
+(defthm m-empty-m*
+ (equal (m-emptyp (m* m n))
+ (or (m-emptyp m)
+ (m-emptyp n))))
+
+(defthm m*-by-col-def
+ (implies (and (matrixp m)
+ (matrixp n)
+ (or (m-emptyp m)
+ (m-emptyp n)
+ (equal (col-count m) (row-count n))))
+ (equal (m* m n)
+ (if (or (m-emptyp m) (m-emptyp n))
+ (m-empty)
+ (col-cons (row* (col-car n) m)
+ (m* m (col-cdr n))))))
+ :hints (("Goal" :induct (m* m n)))
+ :rule-classes :definition)
+
+(defthm col*-m*
+ (implies (and (matrixp m)
+ (matrixp n)
+ (equal (len l) (row-count m))
+ (equal (col-count m) (row-count n)))
+ (equal (col* l (m* m n))
+ (col* (col* l m) n)))
+ :hints (("Goal" :induct (col* l n))
+ ("Subgoal *1/2"
+ :cases ((m-emptyp m)))
+ ("Subgoal *1/2.2"
+ :use (:instance dot*-col* (k (col-car n))))))
+
+(defthm row*-m*
+ (implies (and (matrixp m)
+ (matrixp n)
+ (mvectorp l)
+ (equal (len l) (col-count n))
+ (equal (col-count m) (row-count n)))
+ (equal (row* l (m* m n))
+ (row* (row* l n) m)))
+ :hints (("Goal" :induct (row* l m))
+ ("Subgoal *1/2"
+ :use (:instance dot*-col*
+ (k l)
+ (l (row-car m))
+ (m n)))))
+
+(defthm m*-assoc
+ (implies (and (matrixp m)
+ (matrixp n)
+ (matrixp p)
+ (equal (col-count m) (row-count n))
+ (equal (col-count n) (row-count p)))
+ (equal (m* (m* m n) p)
+ (m* m (m* n p))))
+ :hints (("Goal" :induct (m* m n))))
+
+(include-book "mzero")
+
+(defthm col*-zero-left
+ (implies (matrixp m)
+ (equal (col* (vzero r) m)
+ (vzero (col-count m)))))
+
+(defthm col*-zero-right
+ (equal (col* l (mzero r c))
+ (if (zp r) nil (vzero c)))
+ :hints (("Goal" :induct (vzero c))))
+
+(defthm row*-zero-left
+ (implies (matrixp m)
+ (equal (row* (vzero c) m)
+ (vzero (row-count m))))
+ :hints (("Goal" :induct (row* l m))))
+
+(defthm row*-zero-right
+ (equal (row* l (mzero r c))
+ (if (zp c) nil (vzero r)))
+ :hints (("Goal" :induct (vzero r))))
+
+(defthm m*-zero-left
+ (implies (and (matrixp m)
+ (equal (row-count m) c))
+ (equal (m* (mzero r c) m)
+ (mzero r (col-count m)))))
+
+(defthm m*-zero-right
+ (implies (and (matrixp m)
+ (if (zp c)
+ (m-emptyp m)
+ (equal (col-count m) r)))
+ (equal (m* m (mzero r c))
+ (mzero (row-count m) c))))
+
+(include-book "madd")
+
+(defthm dist-col*-v+
+ (implies (and (matrixp m)
+ (or (m-emptyp m)
+ (equal (len j) (row-count m))))
+ (equal (col* (v+ j k) m)
+ (v+ (col* j m) (col* k m)))))
+
+(defthm dist-col*-m+
+ (implies (and (matrixp m)
+ (matrixp n)
+ (equal (row-count m) (row-count n))
+ (equal (col-count m) (col-count n))
+ (or (m-emptyp m)
+ (equal (len l) (row-count m))))
+ (equal (col* l (m+ m n))
+ (v+ (col* l m) (col* l n))))
+ :hints (("Goal" :induct (m+-by-col-recursion m n))))
+
+(defthm dist-row*-v+
+ (implies (and (matrixp m)
+ (or (m-emptyp m)
+ (equal (len j) (col-count m))))
+ (equal (row* (v+ j k) m)
+ (v+ (row* j m) (row* k m))))
+ :hints (("Goal" :induct (row* k m))))
+
+(defthm dist-row*-m+
+ (implies (and (matrixp m)
+ (matrixp n)
+ (equal (row-count m) (row-count n))
+ (equal (col-count m) (col-count n))
+ (or (m-emptyp m)
+ (equal (len l) (col-count m))))
+ (equal (row* l (m+ m n))
+ (v+ (row* l m) (row* l n))))
+ :hints (("Goal" :induct (m+ m n))))
+
+(defthm dist-m*+
+ (implies (and (matrixp m)
+ (matrixp n)
+ (matrixp p)
+ (equal (col-count m) (row-count n))
+ (equal (row-count n) (row-count p))
+ (equal (col-count n) (col-count p)))
+ (equal (m* m (m+ n p))
+ (m+ (m* m n) (m* m p))))
+ :hints (("Goal" :induct (m* m n))))
+
+(defthm dist-m+*
+ (implies (and (matrixp m)
+ (matrixp n)
+ (matrixp p)
+ (equal (row-count m) (row-count n))
+ (equal (col-count m) (col-count n))
+ (equal (col-count n) (row-count p)))
+ (equal (m* (m+ m n) p)
+ (m+ (m* m p) (m* n p))))
+ :hints (("Goal" :induct (m+ m n))))
+
+(include-book "mscal")
+(defthm dist-col*-sv*
+ (implies (and (matrixp m)
+ (or (m-emptyp m)
+ (equal (len l) (row-count m))))
+ (equal (col* (sv* a l) m)
+ (sv* a (col* l m)))))
+
+(defthm dist-col*-sm*
+ (implies (and (matrixp m)
+ (or (m-emptyp m)
+ (equal (len l) (row-count m))))
+ (equal (col* l (sm* a m))
+ (sv* a (col* l m))))
+ :hints (("Subgoal *1/3.2"
+ :use (:instance sm*-by-col-def (s a)))))
+
+(defthm dist-row*-sv*
+ (implies (and (matrixp m)
+ (or (m-emptyp m)
+ (equal (len l) (col-count m))))
+ (equal (row* (sv* a l) m)
+ (sv* a (row* l m))))
+ :hints (("Goal" :induct (row* l m))))
+
+(defthm dist-row*-sm*
+ (implies (and (matrixp m)
+ (or (m-emptyp m)
+ (equal (len l) (col-count m))))
+ (equal (row* l (sm* a m))
+ (sv* a (row* l m))))
+ :hints (("Goal" :induct (row* l m))))
+
+(defthm dist-m*-sm*-left
+ (implies (and (matrixp m)
+ (matrixp n)
+ (equal (col-count m) (row-count n)))
+ (equal (m* (sm* a m) n)
+ (sm* a (m* m n))))
+ :hints (("Goal" :induct (m* m n))))
+
+(defthm dist-m*-sm*-right
+ (implies (and (matrixp m)
+ (matrixp n)
+ (equal (col-count m) (row-count n)))
+ (equal (m* m (sm* a n))
+ (sm* a (m* m n))))
+ :hints (("Goal" :induct (m* m n))))
+
+(include-book "mid")
+
+(defthm col*-1-left
+ (implies (matrixp m)
+ (equal (col* (cons 1 (vzero r)) m)
+ (row-car m)))
+ :hints (("Goal" :induct (row-car m))
+ ("Subgoal *1/2.5.2" :expand ((dot* (col-car m) (cons 1 (vzero r)))))))
+
+(defthm col*-id
+ (implies (and (mvectorp l)
+ (equal (len l) n))
+ (equal (col* l (mid n)) l)))
+
+(defthm row*-1-left
+ (implies (matrixp m)
+ (equal (row* (cons 1 (vzero c)) m)
+ (col-car m)))
+ :hints (("Goal" :induct (col-car m))))
+
+(defthm row*-id
+ (implies (and (mvectorp l)
+ (equal (len l) n))
+ (equal (row* l (mid n)) l)))
+
+(defthm m*-id-left
+ (implies (and (matrixp m)
+ (equal (row-count m) n))
+ (equal (m* (mid n) m) m))
+ :hints (("Goal" :induct (col* l m))))
+
+(defthm m*-id-right
+ (implies (and (matrixp m)
+ (equal (col-count m) n))
+ (equal (m* m (mid n)) m))
+ :hints (("Goal" :induct (row* l m))))
+
+(include-book "mentry")
+
+(defthm nth-col*
+ (implies (matrixp m)
+ (equal (nth i (col* v m))
+ (if (< (nfix i) (col-count m))
+ (dot* v (col (nfix i) m))
+ nil)))
+ :hints (("Goal" :induct (col i m))
+; :With directive added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2'''" :expand (:with col* (col* v m)))))
+
+(defthm col-m*
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (col i (m* m n))
+ (if (< (nfix i) (col-count n))
+ (row* (col i n) m)
+ nil)))
+ :hints (("Goal" :induct (m* m n))
+; :With directive added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2" :expand (:with col* (col* (row-car m) n)))))
+
+(defthm nth-row*
+ (implies (matrixp m)
+ (equal (nth i (row* v m))
+ (if (< (nfix i) (row-count m))
+ (dot* v (row i m))
+ nil)))
+ :hints (("Goal" :induct (row i m))
+; :With directive added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2" :expand (:with row* (row* v m)))))
+
+(defthm row-m*
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (row i (m* m n))
+ (if (< (nfix i) (row-count m))
+ (col* (row i m) n)
+ nil)))
+ :hints (("Goal" :induct (row i m))
+; :With directive added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2.1'" :expand (:with m* (m* m n)))))
+
+(defthm entry-m*
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (mentry r c (m* m n))
+ (if (and (< (nfix r) (row-count m))
+ (< (nfix c) (col-count n)))
+ (dot* (row r m) (col c n))
+ nil))))
diff --git a/books/workshops/2003/hendrix/support/mscal.lisp b/books/workshops/2003/hendrix/support/mscal.lisp
new file mode 100644
index 0000000..7242631
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mscal.lisp
@@ -0,0 +1,139 @@
+;;;;; Matrix multiplication by a scalar.
+;;;;; This includes basic properties, collecting multiple multiplications,
+;;;;; and relations to mzero, madd, and mentry book contents.
+(in-package "ACL2")
+
+(include-book "mdefthms")
+
+(defun sm* (s m)
+ (declare (xargs :guard (and (acl2-numberp s)
+ (matrixp m))
+ :verify-guards nil))
+ (if (m-emptyp m)
+ (m-empty)
+ (row-cons (sv* s (row-car m))
+ (sm* s (row-cdr m)))))
+
+(local
+ (defthm sm*-bootstrap
+ (implies (matrixp m)
+ (and (matrixp (sm* s m))
+ (equal (col-count (sm* s m))
+ (col-count m))))
+ :hints (("Goal" :induct (sm* s m)))))
+
+(defthm m-empty-sm*
+ (equal (m-emptyp (sm* s m))
+ (m-emptyp m)))
+
+(verify-guards sm*)
+
+(defthm matrix-sm*
+ (implies (matrixp m)
+ (matrixp (sm* s m))))
+
+(defthm col-count-sm*
+ (implies (matrixp m)
+ (equal (col-count (sm* s m))
+ (col-count m))))
+
+(defthm row-count-sm*
+ (equal (row-count (sm* s m))
+ (row-count m)))
+
+(defthm sm*-1
+ (implies (matrixp m)
+ (equal (sm* 1 m) m)))
+
+(defthm sm*-sm*
+ (implies (matrixp m)
+ (equal (sm* a (sm* b m))
+ (sm* (* a b) m))))
+
+(local
+ (defthm col-car-sm*
+ (implies (matrixp m)
+ (equal (col-car (sm* s m))
+ (sv* s (col-car m))))
+ :hints (("Goal" :in-theory (enable col-car-row-cons))
+ ("Subgoal *1/3" :expand ((sv* s (row-car m)))))))
+
+(defthm sm*-by-col-def
+ (implies (matrixp m)
+ (equal (sm* s m)
+ (if (m-emptyp m)
+ (m-empty)
+ (col-cons (sv* s (col-car m))
+ (sm* s (col-cdr m))))))
+ :hints (("Subgoal *1/1.3'"
+ :use (:instance row-cons-def
+ (l (list (* s (car (col-car m)))))
+ (m (sm* s (row-cdr m))))))
+ :rule-classes :definition)
+
+;;;; Properties about scalar multiplication and zero.
+(include-book "mzero")
+
+(defthm sm*-0-left
+ (implies (matrixp m)
+ (equal (sm* 0 m)
+ (mzero (row-count m) (col-count m))))
+ :hints (("Goal" :induct (sm* 0 m))))
+
+(defthm sm*-0-right
+ (equal (sm* s (mzero r c))
+ (mzero r c))
+ :hints (("Goal" :induct (vzero r))))
+
+;;;; Properties about scalar multiplication and addition.
+(include-book "madd")
+
+(defthm sm*-collect
+ (implies (matrixp m)
+ (equal (m+ m m)
+ (sm* 2 m))))
+
+(defthm sm*-collect-left
+ (implies (matrixp m)
+ (equal (m+ (sm* a m) m)
+ (sm* (1+ a) m))))
+
+(defthm sm*-collect-right
+ (implies (matrixp m)
+ (equal (m+ m (sm* a m))
+ (sm* (1+ a) m))))
+
+(defthm sm*-collect-both
+ (implies (matrixp m)
+ (equal (m+ (sm* a m) (sm* b m))
+ (sm* (+ a b) m))))
+
+(defthm sm*-dist
+ (implies (m+-guard m n)
+ (equal (sm* a (m+ m n))
+ (m+ (sm* a m) (sm* a n))))
+ :hints (("Goal" :induct (m+ m n))))
+
+;;;; Properties about scalar multiplication and entries.
+(include-book "mentry")
+
+(defthm row-sm*
+ (implies (matrixp m)
+ (equal (row i (sm* a m))
+ (sv* a (row (nfix i) m))))
+ :hints (("Goal" :induct (row i m))
+; :With directive added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ ("Subgoal *1/2'''" :expand ((:with sm* (sm* a m))))))
+
+(defthm col-sm*
+ (implies (matrixp m)
+ (equal (col i (sm* a m))
+ (sv* a (col i m)))))
+
+(defthm entry-sm*
+ (implies (matrixp m)
+ (equal (mentry r c (sm* a m))
+ (if (and (< (nfix r) (row-count m))
+ (< (nfix c) (col-count m)))
+ (* a (mentry r c m))
+ nil))))
diff --git a/books/workshops/2003/hendrix/support/msub.lisp b/books/workshops/2003/hendrix/support/msub.lisp
new file mode 100644
index 0000000..63bad02
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/msub.lisp
@@ -0,0 +1,15 @@
+;;;;; Matrix negation and subtration.
+;;;;;
+;;;;; Both operations are implemented as a single macro,
+;;;;; so this book is really short.
+
+(in-package "ACL2")
+
+(include-book "mdefthms")
+(include-book "madd")
+(include-book "mscal")
+
+(defmacro m- (m &optional (n 'nil binary-casep))
+ (if binary-casep
+ `(m+ ,m (sm* -1 ,n))
+ `(sm* -1 ,m)))
diff --git a/books/workshops/2003/hendrix/support/mtrans.lisp b/books/workshops/2003/hendrix/support/mtrans.lisp
new file mode 100644
index 0000000..3bea448
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mtrans.lisp
@@ -0,0 +1,124 @@
+;;;;; Matrix transpose
+;;;;; Contains definition of matrix transpose and basis properties.
+;;;;; Includes relations with mzero, madd, mid, mmult, and mentry.
+(in-package "ACL2")
+
+(include-book "mdefthms")
+
+(defun mtrans (m)
+ (declare (xargs :guard (matrixp m)
+ :verify-guards nil))
+ (if (m-emptyp m)
+ (m-empty)
+ (col-cons (row-car m) (mtrans (row-cdr m)))))
+
+(defthm m-emptyp-mtrans
+ (equal (m-emptyp (mtrans m))
+ (m-emptyp m)))
+
+(defthm row-count-mtrans
+ (implies (matrixp m)
+ (equal (row-count (mtrans m))
+ (col-count m))))
+
+(defthm matrixp-mtrans
+ (implies (matrixp m)
+ (matrixp (mtrans m))))
+
+(local
+ (defun col-cdr-recurse (m)
+ (if (m-emptyp m)
+ 0
+ (col-cdr-recurse (col-cdr m)))))
+
+(defthm col-count-mtrans
+ (implies (matrixp m)
+ (equal (col-count (mtrans m))
+ (row-count m)))
+ :hints (("Subgoal *1/3"
+ :use (:instance col-count-def
+ (m (col-cons (row-car m)
+ (mtrans (row-cdr m))))))))
+
+(verify-guards mtrans)
+
+(defthm mtrans-by-col-def
+ (implies (matrixp m)
+ (equal (mtrans m)
+ (if (m-emptyp m)
+ (m-empty)
+ (row-cons (col-car m)
+ (mtrans (col-cdr m))))))
+ :hints (("Goal" :induct (mtrans m)))
+ :rule-classes :definition)
+
+(defthm mtrans-mtrans
+ (implies (matrixp m)
+ (equal (mtrans (mtrans m))
+ m)))
+
+(include-book "mzero")
+
+(defthm mtrans-zero
+ (equal (mtrans (mzero r c))
+ (mzero c r)))
+
+(include-book "madd")
+
+(defthm distr+mtrans
+ (implies (and (matrixp m)
+ (matrixp n))
+ (equal (mtrans (m+ m n))
+ (m+ (mtrans m) (mtrans n))))
+ :hints (("Goal" :induct (m+ m n))))
+
+(include-book "mid")
+
+(defthm mtrans-id
+ (equal (mtrans (mid n))
+ (mid n)))
+
+(include-book "mscal")
+
+(defthm sm*-trans
+ (implies (matrixp m)
+ (equal (mtrans (sm* s m))
+ (sm* s (mtrans m)))))
+
+(include-book "mmult")
+
+(defthm col*-mtrans
+ (implies (row*-guard l m)
+ (equal (col* l (mtrans m))
+ (row* l m))))
+
+(defthm row*-mtrans
+ (implies (col*-guard l m)
+ (equal (row* l (mtrans m))
+ (col* l m))))
+
+(defthm mtrans-m*
+ (implies (m*-guard m n)
+ (equal (mtrans (m* m n))
+ (m* (mtrans n) (mtrans m))))
+ :hints (("Goal" :induct (m* m n))))
+
+(include-book "mentry")
+
+(defthm row-trans
+ (implies (matrixp m)
+ (equal (row i (mtrans m))
+ (col i m))))
+
+(defthm col-trans
+ (implies (matrixp m)
+ (equal (col i (mtrans m))
+ (row i m)))
+; :With directive added 3/14/06 by Matt Kaufmann for after v2-9-4.
+ :hints (("Goal" :expand (:with mtrans (mtrans m)))))
+
+(defthm entry-trans
+ (implies (matrixp m)
+ (equal (mentry r c (mtrans m))
+ (mentry c r m)))
+ :hints (("Subgoal *1/2.4'" :use (:instance row-by-col-def (i c)))))
diff --git a/books/workshops/2003/hendrix/support/mzero.lisp b/books/workshops/2003/hendrix/support/mzero.lisp
new file mode 100644
index 0000000..8387efc
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/mzero.lisp
@@ -0,0 +1,56 @@
+;;;;; Contains method for generating a zero matrix (matrix where all entries are 0).
+;;;;; Also contains theorems for row-count, col-count and a logical definition in terms
+;;;;; of col-cons.
+(in-package "ACL2")
+
+(include-book "mdefthms")
+
+(defmacro mzero-guard (r c)
+ `(and (integerp ,r)
+ (integerp ,c)
+ (<= 0 ,r)
+ (<= 0 ,c)))
+
+;;; Creates a zero matrix with r rows and c columns if r and c are positive integers.
+;;; Otherwise creates the m-empty.
+(defun mzero (r c)
+ (declare (xargs :guard (mzero-guard r c)
+ :verify-guards nil))
+ (if (or (zp r) (zp c))
+ nil
+ (row-cons (vzero c)
+ (mzero (1- r) c))))
+
+(local
+ (defthm zero-bootstrap
+ (and (matrixp (mzero r c))
+ (equal (col-count (mzero r c))
+ (if (or (zp c) (zp r)) 0 c)))))
+
+(verify-guards mzero)
+
+(defthm matrixp-zero
+ (matrixp (mzero r c)))
+
+(defthm m-empty-zero
+ (equal (m-emptyp (mzero r c))
+ (or (zp r) (zp c))))
+
+(defthm col-count-zero
+ (equal (col-count (mzero r c))
+ (if (or (zp c) (zp r)) 0 c)))
+
+(defthm row-count-zero
+ (equal (row-count (mzero r c))
+ (if (or (zp c) (zp r)) 0 r)))
+
+(defthm zero-by-col-def
+ (equal (mzero r c)
+ (if (or (zp r) (zp c))
+ nil
+ (col-cons (vzero r)
+ (if (= c 1)
+ nil
+ (mzero r (1- c))))))
+ :hints (("Goal" :induct (mzero r c)))
+ :rule-classes :definition)
diff --git a/books/workshops/2003/hendrix/support/vector.lisp b/books/workshops/2003/hendrix/support/vector.lisp
new file mode 100644
index 0000000..42f272d
--- /dev/null
+++ b/books/workshops/2003/hendrix/support/vector.lisp
@@ -0,0 +1,255 @@
+;;;;; Some functions for mathematical vectors.
+;;;;;
+;;;;; Includes functions for creating zero vector, vector addition, negation,
+;;;;; subtraction, multiplication by scalar, and dot product and basic
+;;;;; theorems about those functions.
+
+(in-package "ACL2")
+
+(include-book "../../../../arithmetic/top-with-meta")
+
+;;; Returns true if v is a true-list of numbers.
+(defun mvectorp (v)
+ (declare (xargs :verify-guards t))
+ (if (consp v)
+ (and (acl2-numberp (car v))
+ (mvectorp (cdr v)))
+ (eq v nil)))
+
+(defthm vector-is-true-list
+ (implies (mvectorp l)
+ (true-listp l))
+ :rule-classes :compound-recognizer)
+
+;;;; Zero vector and basic theorems.
+
+;;; Returns a list of length len of zeros - a zero vector.
+(defun vzero (len)
+ (declare (xargs :guard (and (integerp len) (<= 0 len))))
+ (if (zp len)
+ nil
+ (cons 0 (vzero (1- len)))))
+
+;;; Theorem proving the zero vector is a vector.
+(defthm mvectorp-vzero
+ (mvectorp (vzero n))
+ :rule-classes (:rewrite :type-prescription))
+
+(defthm consp-vzero
+ (equal (consp (vzero n))
+ (not (zp n))))
+
+;;; Length of zero vector equals its argument.
+(defthm len-vzero
+ (equal (len (vzero n))
+ (nfix n)))
+
+;;;; Vector addition and basic properties.
+
+;;; v+ (vector addition) should take two lists of equal length.
+(defmacro v+-guard (k l)
+ `(and (mvectorp ,k)
+ (mvectorp ,l)
+ (equal (len ,k) (len ,l))))
+
+;;; Returns the sum of two vectors - Recursively iterates down each argument.
+(defun v+ (k l)
+ (declare (xargs :guard (v+-guard k l)))
+ (if (endp k)
+ nil
+ (cons (+ (car k) (car l))
+ (v+ (cdr k) (cdr l)))))
+
+(defthm mvectorp-v+
+ (mvectorp (v+ k l)))
+
+(defthm consp-v+
+ (equal (consp (v+ k l))
+ (consp k)))
+
+(defthm len-v+
+ (equal (len (v+ k l))
+ (len k)))
+
+;;;; Vector addition is associative and commutative.
+(defthm v+-assoc
+ (implies (<= (len j) (len k))
+ (equal (v+ (v+ j k) l)
+ (v+ j (v+ k l)))))
+
+(defthm v+-assoc2
+ (implies (equal (len j) (len k))
+ (equal (v+ j (v+ k l))
+ (v+ k (v+ j l)))))
+
+(defthm v+-comm
+ (implies (equal (len k) (len l))
+ (equal (v+ k l)
+ (v+ l k))))
+
+;;;; Adding the zero vector to a vector does not affect the vector if
+;;;; the lengths are the same.
+
+(defthm v+-nil
+ (implies (mvectorp v)
+ (equal (v+ v nil) v)))
+
+(defthm v+-zero-left
+ (implies (and (mvectorp v)
+ (equal (len v) n))
+ (equal (v+ (vzero n) v) v)))
+
+(defthm v+zero-right
+ (implies (and (mvectorp v)
+ (equal (len v) n))
+ (equal (v+ v (vzero n)) v))
+ :hints (("Goal" :induct (nth n v))))
+
+(defthm nth-v+
+ (equal (nth i (v+ u v))
+ (if (< (nfix i) (len u))
+ (+ (nth i u) (nth i v))
+ nil))
+ :hints (("Goal" :induct (and (nth i u)
+ (v+ u v)))))
+
+;;;; Multiplication of a vector by a scalar.
+
+(defun sv* (s v)
+ (declare (xargs :guard (and (acl2-numberp s) (mvectorp v))))
+ (if (endp v)
+ nil
+ (cons (* s (car v))
+ (sv* s (cdr v)))))
+
+(defthm vector-sv*
+ (mvectorp (sv* s v)))
+
+(defthm len-sv*
+ (equal (len (sv* s v))
+ (len v)))
+
+(defthm consp-sv*
+ (equal (consp (sv* s v))
+ (consp v)))
+
+;;;; Multiplying by zero results in a zero vector.
+(defthm sv*-0-left
+ (equal (sv* 0 v)
+ (vzero (len v))))
+
+(defthm sv*-0-right
+ (equal (sv* s (vzero n))
+ (vzero n)))
+
+;;; Multiplying by 1 does not change a vector.
+(defthm sv*-1
+ (implies (mvectorp v)
+ (equal (sv* 1 v) v)))
+
+;;; Collect 2 scalar multiplications into a single multiplication.
+(defthm sv*-sv*
+ (equal (sv* a (sv* b l))
+ (sv* (* a b) l)))
+
+;;;; Collect vector addition where one vector is a scalar multiple of
+;;;; the other into a single scalar multiplication.
+(defthm sv*-collect
+ (equal (v+ v v)
+ (sv* 2 v)))
+
+(defthm sv*-collect-left
+ (equal (v+ (sv* a v) v)
+ (sv* (1+ a) v)))
+
+(defthm sv*-collect-right
+ (equal (v+ v (sv* a v))
+ (sv* (1+ a) v)))
+
+(defthm sv*-collect-both
+ (equal (v+ (sv* a v) (sv* b v))
+ (sv* (+ a b) v)))
+
+(local
+ (defthm sv*-dist-nil
+ (equal (sv* a (v+ u nil))
+ (sv* a u))))
+
+(defthm sv*-dist
+ (equal (sv* a (v+ u v))
+ (v+ (sv* a u) (sv* a v))))
+
+(defthm nth-sv*
+ (equal (nth i (sv* a v))
+ (if (< (nfix i) (len v))
+ (* a (nth i v))
+ nil)))
+
+;;; Define v- to negate with a single argument and subtract with binary
+;;; arguments.
+(defmacro v- (l &optional (k 'nil binary-casep))
+ (if binary-casep
+ `(v+ ,l (sv* -1 ,k))
+ `(sv* -1 ,l)))
+
+;;;; Dot product function and basic theorems.
+(defun dot* (u v)
+ (declare (xargs :guard (and (mvectorp u)
+ (mvectorp v)
+ (equal (len u) (len v)))))
+ (if (endp u)
+ 0
+ (+ (* (car u) (car v))
+ (dot* (cdr u) (cdr v)))))
+
+(defthm numberp-dot*
+ (acl2-numberp (dot* l k))
+ :rule-classes :type-prescription)
+
+(defthm dot*-nil-left
+ (equal (dot* l nil) 0))
+
+(defthm dot*-nil-right
+ (equal (dot* nil l) 0))
+
+(defthm dot*-comm
+ (equal (dot* l k)
+ (dot* k l)))
+
+;;; This is used for generating the induction. It seems like an easier
+;;; way to do this should exist, but I do not yet understand the
+;;; induction heuristics.
+(local
+ (defun zero-dot*-recursion (n l)
+ (if (zp n)
+ l
+ (zero-dot*-recursion (1- n) (cdr l)))))
+
+(defthm dot*-zero-left
+ (equal (dot* (vzero n) l) 0)
+ :hints (("Goal" :induct (zero-dot*-recursion n l))))
+
+(defthm dot*-zero-right
+ (equal (dot* l (vzero n)) 0)
+ :hints (("Goal" :induct (nth n l))))
+
+;;; Distribute the dot product of vector addition.
+(defthm dist-dot*-v+-left
+ (implies (equal (len j) (len k))
+ (equal (dot* (v+ k l) j)
+ (+ (dot* k j) (dot* l j)))))
+
+(defthm dist-dot*-v+-right
+ (implies (equal (len j) (len k))
+ (equal (dot* j (v+ k l))
+ (+ (dot* j k) (dot* j l)))))
+
+;;; Distribute the dot production of scalar vector multiplication.
+(defthm dot*-sv*-left
+ (equal (dot* (sv* a l) k)
+ (* a (dot* l k))))
+
+(defthm dot*-sv*-right
+ (equal (dot* l (sv* a k))
+ (* a (dot* l k))))
+
diff --git a/books/workshops/2003/kaufmann/LICENSE b/books/workshops/2003/kaufmann/LICENSE
new file mode 100644
index 0000000..df9647c
--- /dev/null
+++ b/books/workshops/2003/kaufmann/LICENSE
@@ -0,0 +1,2 @@
+Copyright (C) 2002, Matt Kaufmann
+License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
diff --git a/books/workshops/2003/kaufmann/deps.lisp b/books/workshops/2003/kaufmann/deps.lisp
new file mode 100644
index 0000000..2d26787
--- /dev/null
+++ b/books/workshops/2003/kaufmann/deps.lisp
@@ -0,0 +1,16 @@
+;; Silly file to trick cert.pl into including the right books.
+
+(in-package "ACL2")
+
+#||
+(include-book "misc/file-io" :dir :system)
+(include-book "misc/rtl-untranslate" :dir :system)
+(include-book "misc/symbol-btree" :dir :system)
+(include-book "ordinals/e0-ordinal" :dir :system)
+(include-book "rtl/rel4/lib/rtl" :dir :system)
+(include-book "rtl/rel4/lib/rtlarr" :dir :system)
+(include-book "rtl/rel4/lib/simplify-model-helpers" :dir :system)
+(include-book "rtl/rel4/lib/top" :dir :system))
+(include-book "rtl/rel4/lib/util" :dir :system)
+(include-book "rtl/rel4/support/bvecp-helpers" :dir :system)
+||#
diff --git a/books/workshops/2003/kaufmann/paper.pdf.gz b/books/workshops/2003/kaufmann/paper.pdf.gz
new file mode 100644
index 0000000..2385559
--- /dev/null
+++ b/books/workshops/2003/kaufmann/paper.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/kaufmann/paper.ps.gz b/books/workshops/2003/kaufmann/paper.ps.gz
new file mode 100644
index 0000000..356c292
--- /dev/null
+++ b/books/workshops/2003/kaufmann/paper.ps.gz
Binary files differ
diff --git a/books/workshops/2003/kaufmann/slides.pdf.gz b/books/workshops/2003/kaufmann/slides.pdf.gz
new file mode 100644
index 0000000..6a71fb6
--- /dev/null
+++ b/books/workshops/2003/kaufmann/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/kaufmann/slides.ps.gz b/books/workshops/2003/kaufmann/slides.ps.gz
new file mode 100644
index 0000000..9d088dc
--- /dev/null
+++ b/books/workshops/2003/kaufmann/slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/kaufmann/slides4.pdf.gz b/books/workshops/2003/kaufmann/slides4.pdf.gz
new file mode 100644
index 0000000..78b2ff8
--- /dev/null
+++ b/books/workshops/2003/kaufmann/slides4.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/kaufmann/slides4.ps.gz b/books/workshops/2003/kaufmann/slides4.ps.gz
new file mode 100644
index 0000000..82fb954
--- /dev/null
+++ b/books/workshops/2003/kaufmann/slides4.ps.gz
Binary files differ
diff --git a/books/workshops/2003/kaufmann/support/Makefile b/books/workshops/2003/kaufmann/support/Makefile
new file mode 100644
index 0000000..3079301
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/Makefile
@@ -0,0 +1,2 @@
+DIRS = input rtl/tool rtl
+include ../../../../Makefile-subdirs
diff --git a/books/workshops/2003/kaufmann/support/README b/books/workshops/2003/kaufmann/support/README
new file mode 100644
index 0000000..3f54316
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/README
@@ -0,0 +1,9 @@
+These supporting materials allow you to run the tool described in the paper "A
+Tool for Simplifying Files of ACL2 Definitions", on the small example described
+in that paper. This directory should be placed under
+books/workshops/2003/kaufmann/. It is organized into these subdirectories.
+
+input/ contains all input files
+output/ contains copies of files generated from input/ by running make
+ when standing in input/
+rtl/ rtl example from final section of the paper [see README]
diff --git a/books/workshops/2003/kaufmann/support/input/.gitignore b/books/workshops/2003/kaufmann/support/input/.gitignore
new file mode 100644
index 0000000..de31371
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/.gitignore
@@ -0,0 +1,4 @@
+check.txt
+defs-eq.lisp
+defs-out.lisp
+lemmas-out.lisp \ No newline at end of file
diff --git a/books/workshops/2003/kaufmann/support/input/Makefile b/books/workshops/2003/kaufmann/support/input/Makefile
new file mode 100644
index 0000000..a83c8df
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/Makefile
@@ -0,0 +1,55 @@
+include ../../../../../Makefile-generic
+
+# Avoid provisional certification since we are not using Makefile-deps
+# (because there are generated .lisp files):
+override ACL2_PCERT =
+
+BOOKS = defs-in inputs lemmas-in defs-out defs-eq lemmas-out
+
+all: check.txt
+
+# Compare generated .lisp files against expected files, in ../output/ directory.
+check.txt: defs-eq.cert defs-out.cert lemmas-in.cert defs-in.cert inputs.cert lemmas-out.cert
+ @diff defs-out.lisp ../output/defs-out.lisp || (echo "diff of input/defs-out.lisp with output/defs-out.lisp failed" ; exit 1)
+ @diff defs-eq.lisp ../output/defs-eq.lisp || (echo "diff of input/defs-eq.lisp with output/defs-eq.lisp failed" ; exit 1)
+ @diff lemmas-out.lisp ../output/lemmas-out.lisp || (echo "diff of input/lemmas-out.lisp with output/lemmas-out.lisp failed" ; exit 1)
+ touch check.txt
+
+# Dependencies:
+
+# Created manually:
+
+defs-eq.lisp lemmas-out.lisp: defs-out.lisp
+
+defs-out.lisp: defs-in.cert lemmas-in.lisp ../../../../../misc/simplify-defuns.cert
+ $(ACL2) < defs-out.cmds > defs-out.lisp.out
+
+clean: clean-more
+
+clean-more:
+ rm -f defs-out.lisp defs-eq.lisp lemmas-out.lisp check.txt
+
+# Created with make dependencies after a successful run:
+
+defs-in.cert: defs-in.lisp
+defs-in.cert: defs-in.acl2
+defs-in.cert: inputs.cert
+
+inputs.cert: inputs.lisp
+
+lemmas-in.cert: lemmas-in.lisp
+lemmas-in.cert: defs-in.cert
+
+defs-out.cert: defs-out.lisp
+defs-out.cert: defs-out.acl2
+defs-out.cert: inputs.cert
+
+defs-eq.cert: defs-eq.lisp
+defs-eq.cert: defs-eq.acl2
+defs-eq.cert: defs-in.cert
+defs-eq.cert: defs-out.cert
+
+lemmas-out.cert: lemmas-out.lisp
+lemmas-out.cert: defs-out.cert
+lemmas-out.cert: lemmas-in.cert
+lemmas-out.cert: defs-eq.cert
diff --git a/books/workshops/2003/kaufmann/support/input/cert_pl_exclude b/books/workshops/2003/kaufmann/support/input/cert_pl_exclude
new file mode 100644
index 0000000..833501d
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/cert_pl_exclude
@@ -0,0 +1,2 @@
+This directory has a custom Makefile, so it is excluded from
+certification based on cert.pl.
diff --git a/books/workshops/2003/kaufmann/support/input/defs-eq.acl2 b/books/workshops/2003/kaufmann/support/input/defs-eq.acl2
new file mode 100644
index 0000000..31c8367
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/defs-eq.acl2
@@ -0,0 +1,9 @@
+(value :q)
+
+(LP)
+
+(include-book "defs-in")
+
+(include-book "defs-out")
+
+(certify-book "defs-eq" ? t)
diff --git a/books/workshops/2003/kaufmann/support/input/defs-in.acl2 b/books/workshops/2003/kaufmann/support/input/defs-in.acl2
new file mode 100644
index 0000000..663dd9a
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/defs-in.acl2
@@ -0,0 +1,7 @@
+(value :q)
+
+(LP)
+
+(include-book "inputs")
+
+(certify-book "defs-in" ? t)
diff --git a/books/workshops/2003/kaufmann/support/input/defs-in.lisp b/books/workshops/2003/kaufmann/support/input/defs-in.lisp
new file mode 100644
index 0000000..51e908e
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/defs-in.lisp
@@ -0,0 +1,41 @@
+(in-package "ACL2")
+
+(defun %g1 (x y)
+ (cond
+ ((zp x) x)
+ ((< 0 (f1 x)) y)
+ (t 23)))
+
+(in-theory (disable %g1))
+
+(defun %g2 (x y)
+ (if (atom x)
+ (%g1 x y)
+ (%g2 (cdr x) y)))
+
+(in-theory (disable %g2))
+
+(mutual-recursion
+ (defun %reg1 (n)
+ (declare (xargs :measure (make-ord 1 (1+ (nfix n)) 0)))
+ (if (zp n)
+ 0
+ (logxor (%wire1 (1- n))
+ (input1 (1- n)))))
+ (defun %reg2 (n)
+ (declare (xargs :measure (make-ord 1 (1+ (nfix n)) 1)))
+ (if (zp n)
+ (%reg1 n)
+ (logand (%wire1 (1- n))
+ (%wire2 (1- n)))))
+ (defun %wire1 (n)
+ (declare (xargs :measure (make-ord 1 (1+ (nfix n)) 2)))
+ (logior (%reg1 n) (input2 n)))
+ (defun %wire2 (n)
+ (declare (xargs :measure (make-ord 1 (1+ (nfix n)) 3)))
+ (lognot (%wire1 n))))
+
+(in-theory (disable %g1 %g2 %reg1 %reg2 %wire1 %wire2
+ logand logior logxor
+ ; Not disabled: f1 lognot
+ ))
diff --git a/books/workshops/2003/kaufmann/support/input/defs-out.acl2 b/books/workshops/2003/kaufmann/support/input/defs-out.acl2
new file mode 100644
index 0000000..5eb7586
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/defs-out.acl2
@@ -0,0 +1,7 @@
+(value :q)
+
+(LP)
+
+(include-book "inputs")
+
+(certify-book "defs-out" ? t)
diff --git a/books/workshops/2003/kaufmann/support/input/defs-out.cmds b/books/workshops/2003/kaufmann/support/input/defs-out.cmds
new file mode 100644
index 0000000..c4a7506
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/defs-out.cmds
@@ -0,0 +1,22 @@
+(value :q)
+
+(LP)
+
+(include-book "defs-in")
+(include-book "../../../../../misc/simplify-defuns")
+(transform-defuns "defs-in.lisp"
+ :out-defs "defs-out.lisp"
+ ;; can also specify
+ ;; :defs-extra <list of initial events for :out-defs>
+ :equalities "defs-eq.lisp"
+ ;; can also specify
+ ;; :eq-extra <list of initial events for :equalities>
+ :thm-file-pairs '(("lemmas-in.lisp" "lemmas-out.lisp"
+ ;; Initial events for lemmas-out.lisp:
+ (include-book "defs-out")
+ (local (include-book "lemmas-in"))
+ (local (include-book "defs-eq"))
+ (local (in-theory (theory
+ '%-removal-theory))))))
+(value :q)
+(good-bye)
diff --git a/books/workshops/2003/kaufmann/support/input/inputs.lisp b/books/workshops/2003/kaufmann/support/input/inputs.lisp
new file mode 100644
index 0000000..bdcdf73
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/inputs.lisp
@@ -0,0 +1,7 @@
+(in-package "ACL2")
+
+(defun f1 (x)
+ (+ x x))
+
+(defstub input1 (n) t)
+(defstub input2 (n) t)
diff --git a/books/workshops/2003/kaufmann/support/input/lemmas-in.lisp b/books/workshops/2003/kaufmann/support/input/lemmas-in.lisp
new file mode 100644
index 0000000..47d1ed2
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/input/lemmas-in.lisp
@@ -0,0 +1,8 @@
+(in-package "ACL2")
+
+(include-book "defs-in")
+
+(defthm %lemma-1
+ (implies (true-listp x)
+ (equal (%g2 x y) nil))
+ :hints (("Goal" :in-theory (enable %g1 %g2))))
diff --git a/books/workshops/2003/kaufmann/support/output/cert_pl_exclude b/books/workshops/2003/kaufmann/support/output/cert_pl_exclude
new file mode 100644
index 0000000..1d46140
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/output/cert_pl_exclude
@@ -0,0 +1,8 @@
+cert_pl_exclude
+
+The presence of this file tells cert.pl not to try to build any of the books in
+this directory.
+
+This directory contains books not to be certified. Rather, they are
+here for comparison with files that are generated; see the `diff'
+calls in ../input/Makefile.
diff --git a/books/workshops/2003/kaufmann/support/output/defs-eq.lisp b/books/workshops/2003/kaufmann/support/output/defs-eq.lisp
new file mode 100644
index 0000000..6db5c93
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/output/defs-eq.lisp
@@ -0,0 +1,188 @@
+(IN-PACKAGE "ACL2")
+
+(LOCAL (DEFUN %%SUB1-INDUCTION (N)
+ (IF (ZP N)
+ N (%%SUB1-INDUCTION (1- N)))))
+
+(LOCAL (DEFUN %%AND-TREE-FN (ARGS LEN)
+ (DECLARE (XARGS :MODE :PROGRAM))
+ (IF (< LEN 20)
+ (CONS 'AND ARGS)
+ (LET* ((LEN2 (FLOOR LEN 2)))
+ (LIST 'AND
+ (%%AND-TREE-FN (TAKE LEN2 ARGS) LEN2)
+ (%%AND-TREE-FN (NTHCDR LEN2 ARGS)
+ (- LEN LEN2)))))))
+
+(LOCAL (DEFMACRO %%AND-TREE (&REST ARGS)
+ (%%AND-TREE-FN ARGS (LENGTH ARGS))))
+
+(LOCAL (DEFTHEORY THEORY-0 (THEORY 'MINIMAL-THEORY)))
+
+(LOCAL (DEFTHM G1-BODY-IS-%G1-BODY_S
+ (EQUAL (IF (ZP X) X Y)
+ (COND ((ZP X) X)
+ ((< 0 (F1 X)) Y)
+ (T 23)))
+ :HINTS (("Goal" :DO-NOT '(PREPROCESS)))
+ :RULE-CLASSES NIL))
+
+(DEFTHM G1-IS-%G1 (EQUAL (G1 X Y) (%G1 X Y))
+ :HINTS (("Goal" :EXPAND ((:FREE (X Y) (%G1 X Y))
+ (:FREE (X Y) (G1 X Y)))
+ :IN-THEORY (THEORY 'THEORY-0)
+ :DO-NOT '(PREPROCESS)
+ :USE G1-BODY-IS-%G1-BODY_S)))
+
+(LOCAL (DEFTHEORY THEORY-1
+ (UNION-THEORIES '(G1-IS-%G1)
+ (THEORY 'THEORY-0))))
+
+(LOCAL (DEFUN %%G2 (X Y)
+ (IF (CONSP X)
+ (%%G2 (CDR X) Y)
+ (%G1 X Y))))
+
+(LOCAL (DEFTHM %%G2-IS-G2 (EQUAL (%%G2 X Y) (G2 X Y))
+ :HINTS (("Goal" :IN-THEORY (UNION-THEORIES '((:INDUCTION %%G2))
+ (THEORY 'THEORY-1))
+ :DO-NOT '(PREPROCESS)
+ :EXPAND ((%%G2 X Y) (G2 X Y))
+ :INDUCT T))))
+
+(DEFTHM G2-IS-%G2 (EQUAL (G2 X Y) (%G2 X Y))
+ :HINTS (("Goal" :BY (:FUNCTIONAL-INSTANCE %%G2-IS-G2 (%%G2 %G2))
+ :DO-NOT '(PREPROCESS)
+ :EXPAND ((%G2 X Y)))))
+
+(LOCAL (DEFTHEORY THEORY-2
+ (UNION-THEORIES '(G2-IS-%G2)
+ (THEORY 'THEORY-1))))
+
+(LOCAL (DEFUN %%P2 (N)
+ (DECLARE (XARGS :NORMALIZE NIL))
+ (%%AND-TREE (EQUAL (WIRE2 N) (%WIRE2 N))
+ (EQUAL (WIRE1 N) (%WIRE1 N))
+ (EQUAL (REG2 N) (%REG2 N))
+ (EQUAL (REG1 N) (%REG1 N)))))
+
+(LOCAL
+ (DEFTHM
+ %%P2-PROPERTY
+ (IMPLIES (%%P2 N)
+ (%%AND-TREE (EQUAL (WIRE2 N) (%WIRE2 N))
+ (EQUAL (WIRE1 N) (%WIRE1 N))
+ (EQUAL (REG2 N) (%REG2 N))
+ (EQUAL (REG1 N) (%REG1 N))))
+ :HINTS (("Goal" :IN-THEORY (UNION-THEORIES '(%%P2)
+ (THEORY 'MINIMAL-THEORY))))))
+
+(LOCAL
+ (DEFTHEORY %%P2-IMPLIES-F-IS-%F-THEORY
+ (UNION-THEORIES (SET-DIFFERENCE-THEORIES (CURRENT-THEORY :HERE)
+ (CURRENT-THEORY '%%P2))
+ (THEORY 'MINIMAL-THEORY))))
+
+(LOCAL
+ (ENCAPSULATE NIL
+ (LOCAL (IN-THEORY (DISABLE %%P2-PROPERTY)))
+ (LOCAL (DEFTHM REG1-IS-%REG1-BASE
+ (IMPLIES (ZP N)
+ (EQUAL (REG1 N) (%REG1 N)))
+ :HINTS (("Goal" :EXPAND ((REG1 N) (%REG1 N))))))
+ (LOCAL (DEFTHM REG2-IS-%REG2-BASE
+ (IMPLIES (ZP N)
+ (EQUAL (REG2 N) (%REG2 N)))
+ :HINTS (("Goal" :EXPAND ((REG2 N) (%REG2 N))))))
+ (LOCAL (DEFTHM WIRE1-IS-%WIRE1-BASE
+ (IMPLIES (ZP N)
+ (EQUAL (WIRE1 N) (%WIRE1 N)))
+ :HINTS (("Goal" :EXPAND ((WIRE1 N) (%WIRE1 N))))))
+ (LOCAL (DEFTHM WIRE2-IS-%WIRE2-BASE
+ (IMPLIES (ZP N)
+ (EQUAL (WIRE2 N) (%WIRE2 N)))
+ :HINTS (("Goal" :EXPAND ((WIRE2 N) (%WIRE2 N))))))
+ (DEFTHM %%P2-BASE (IMPLIES (ZP N) (%%P2 N))
+ :INSTRUCTIONS (:PROMOTE :X-DUMB (:S :NORMALIZE NIL)))))
+
+(LOCAL
+ (ENCAPSULATE
+ NIL
+ (LOCAL (IN-THEORY (DISABLE %%P2 %%P2-BASE)))
+ (LOCAL (DEFLABEL %%INDUCTION-START))
+ (LOCAL (DEFTHM REG1-IS-%REG1-INDUCTION_STEP
+ (IMPLIES (AND (NOT (ZP N)) (%%P2 (1- N)))
+ (EQUAL (REG1 N) (%REG1 N)))
+ :INSTRUCTIONS (:PROMOTE (:DV 1)
+ :X-DUMB
+ :NX :X-DUMB
+ :TOP (:S :NORMALIZE NIL
+ :BACKCHAIN-LIMIT 1000
+ :EXPAND :LAMBDAS
+ :REPEAT 4))))
+ (LOCAL (DEFTHM REG2-IS-%REG2-INDUCTION_STEP
+ (IMPLIES (AND (NOT (ZP N)) (%%P2 (1- N)))
+ (EQUAL (REG2 N) (%REG2 N)))
+ :INSTRUCTIONS (:PROMOTE (:DV 1)
+ :X-DUMB
+ :NX :X-DUMB
+ :TOP (:S :NORMALIZE NIL
+ :BACKCHAIN-LIMIT 1000
+ :EXPAND :LAMBDAS
+ :REPEAT 4))))
+ (LOCAL (DEFTHM WIRE1-IS-%WIRE1-INDUCTION_STEP
+ (IMPLIES (AND (NOT (ZP N)) (%%P2 (1- N)))
+ (EQUAL (WIRE1 N) (%WIRE1 N)))
+ :INSTRUCTIONS (:PROMOTE (:DV 1)
+ :X-DUMB
+ :NX :X-DUMB
+ :TOP (:S :NORMALIZE NIL
+ :BACKCHAIN-LIMIT 1000
+ :EXPAND :LAMBDAS
+ :REPEAT 4))))
+ (LOCAL (DEFTHM WIRE2-IS-%WIRE2-INDUCTION_STEP
+ (IMPLIES (AND (NOT (ZP N)) (%%P2 (1- N)))
+ (EQUAL (WIRE2 N) (%WIRE2 N)))
+ :INSTRUCTIONS (:PROMOTE (:DV 1)
+ :X-DUMB
+ :NX :X-DUMB
+ :TOP (:S :NORMALIZE NIL
+ :BACKCHAIN-LIMIT 1000
+ :EXPAND :LAMBDAS
+ :REPEAT 4))))
+ (DEFTHM %%P2-INDUCTION_STEP
+ (IMPLIES (AND (NOT (ZP N)) (%%P2 (1- N)))
+ (%%P2 N))
+ :INSTRUCTIONS (:PROMOTE :X-DUMB (:S :NORMALIZE NIL)))))
+
+(LOCAL
+ (DEFTHM
+ %%P2-HOLDS (%%P2 N)
+ :HINTS
+ (("Goal" :INDUCT (%%SUB1-INDUCTION N)
+ :DO-NOT '(PREPROCESS)
+ :IN-THEORY (UNION-THEORIES '(%%P2-BASE %%P2-INDUCTION_STEP
+ (:INDUCTION %%SUB1-INDUCTION))
+ (THEORY 'MINIMAL-THEORY))))))
+
+(ENCAPSULATE
+ NIL
+ (LOCAL (IN-THEORY (UNION-THEORIES '(%%P2-HOLDS)
+ (THEORY '%%P2-IMPLIES-F-IS-%F-THEORY))))
+ (DEFTHM REG1-IS-%REG1 (EQUAL (REG1 N) (%REG1 N))
+ :HINTS (("Goal" :DO-NOT '(PREPROCESS))))
+ (DEFTHM REG2-IS-%REG2 (EQUAL (REG2 N) (%REG2 N))
+ :HINTS (("Goal" :DO-NOT '(PREPROCESS))))
+ (DEFTHM WIRE1-IS-%WIRE1
+ (EQUAL (WIRE1 N) (%WIRE1 N))
+ :HINTS (("Goal" :DO-NOT '(PREPROCESS))))
+ (DEFTHM WIRE2-IS-%WIRE2
+ (EQUAL (WIRE2 N) (%WIRE2 N))
+ :HINTS (("Goal" :DO-NOT '(PREPROCESS)))))
+
+(DEFTHEORY %-REMOVAL-THEORY
+ (UNION-THEORIES '(G1-IS-%G1 G2-IS-%G2
+ WIRE2-IS-%WIRE2 WIRE1-IS-%WIRE1
+ REG2-IS-%REG2 REG1-IS-%REG1)
+ (THEORY 'MINIMAL-THEORY)))
+
diff --git a/books/workshops/2003/kaufmann/support/output/defs-out.lisp b/books/workshops/2003/kaufmann/support/output/defs-out.lisp
new file mode 100644
index 0000000..acde187
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/output/defs-out.lisp
@@ -0,0 +1,33 @@
+(IN-PACKAGE "ACL2")
+
+(SET-IGNORE-OK T)
+
+(SET-IRRELEVANT-FORMALS-OK T)
+
+(SET-BOGUS-MUTUAL-RECURSION-OK T)
+
+(DEFUND G1 (X Y) (IF (ZP X) X Y))
+
+(DEFUND G2 (X Y)
+ (IF (CONSP X) (G2 (CDR X) Y) (G1 X Y)))
+
+(MUTUAL-RECURSION
+ (DEFUND REG1 (N)
+ (DECLARE (XARGS :MEASURE (MAKE-ORD 1 (1+ (NFIX N)) 0)))
+ (IF (ZP N)
+ 0
+ (LOGXOR (WIRE1 (+ -1 N))
+ (INPUT1 (+ -1 N)))))
+ (DEFUND REG2 (N)
+ (DECLARE (XARGS :MEASURE (MAKE-ORD 1 (1+ (NFIX N)) 1)))
+ (IF (ZP N)
+ (REG1 N)
+ (LOGAND (WIRE1 (+ -1 N))
+ (WIRE2 (+ -1 N)))))
+ (DEFUND WIRE1 (N)
+ (DECLARE (XARGS :MEASURE (MAKE-ORD 1 (1+ (NFIX N)) 2)))
+ (LOGIOR (REG1 N) (INPUT2 N)))
+ (DEFUND WIRE2 (N)
+ (DECLARE (XARGS :MEASURE (MAKE-ORD 1 (1+ (NFIX N)) 3)))
+ (+ -1 (- (WIRE1 N)))))
+
diff --git a/books/workshops/2003/kaufmann/support/output/lemmas-out.lisp b/books/workshops/2003/kaufmann/support/output/lemmas-out.lisp
new file mode 100644
index 0000000..09a4ef5
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/output/lemmas-out.lisp
@@ -0,0 +1,15 @@
+(IN-PACKAGE "ACL2")
+
+(INCLUDE-BOOK "defs-out")
+
+(LOCAL (INCLUDE-BOOK "lemmas-in"))
+
+(LOCAL (INCLUDE-BOOK "defs-eq"))
+
+(LOCAL (IN-THEORY (THEORY '%-REMOVAL-THEORY)))
+
+(DEFTHM LEMMA-1
+ (IMPLIES (TRUE-LISTP X)
+ (EQUAL (G2 X Y) NIL))
+ :HINTS (("Goal" :USE %LEMMA-1)))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/.gitignore b/books/workshops/2003/kaufmann/support/rtl/.gitignore
new file mode 100644
index 0000000..9b51ab5
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/.gitignore
@@ -0,0 +1,4 @@
+bvecp.lisp
+model-defs.lisp
+model-eq.lisp
+model.lisp \ No newline at end of file
diff --git a/books/workshops/2003/kaufmann/support/rtl/Makefile b/books/workshops/2003/kaufmann/support/rtl/Makefile
new file mode 100644
index 0000000..dc46154
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/Makefile
@@ -0,0 +1,123 @@
+TOP_MODULE = FOO
+TOP_FILE = foo.v
+
+run:
+ @echo "Using ACL2=$(ACL2)"
+ $(MAKE) diffs.out
+
+diffs.out: bvecp.cert
+ rm -f diffs.out
+ diff model.lisp results/model.lisp > diffs.out
+ diff bvecp.lisp results/bvecp.lisp >> diffs.out
+ diff model-eq.lisp results/model-eq.lisp >> diffs.out
+ @if [ ! -z "`head -1 diffs.out`" ] ; then \
+ echo "**ERROR**: Found unexpected results." ;\
+ exit 1 ;\
+ fi
+
+BOOKS_DIR = ../../../../..
+LIB_DIR = $(BOOKS_DIR)/rtl/rel4/lib
+
+include $(BOOKS_DIR)/Makefile-generic
+
+# Avoid provisional certification since we are not using Makefile-deps
+# (because there are generated .lisp files):
+override ACL2_PCERT =
+
+INHIBIT = (assign inhibit-output-lst (list (quote prove) (quote proof-tree) (quote warning) (quote observation) (quote event)))
+
+model-eq.lisp bvecp.lisp: model-defs.lisp
+
+# The following target writes out not only file model-defs.lisp, but
+# also files model-eq.lisp and bvecp.lisp.
+model-defs.lisp: tool/simplify-defuns.cert tool/wrapper.cert bvecp-raw.cert
+ echo "Running transform-defuns."
+ echo '(acl2::value :q)' > workxxx
+ echo '(acl2::lp)' >> workxxx
+ echo '(include-book "tool/simplify-defuns")' >> workxxx
+ echo '(include-book "tool/wrapper")' >> workxxx
+ echo '(simplify-model)' >> workxxx
+ echo '(acl2::value :q)' >> workxxx
+ echo '(acl2::exit-lisp)' >> workxxx
+ $(ACL2) < workxxx > model.lisp.out
+ rm -f workxxx
+
+model.lisp: model-defs.lisp model-macro-aliases.lsp
+ cat model-defs.lisp model-macro-aliases.lsp > model.lisp
+
+clean-extra:
+ -rm -f model.lisp model-defs.lisp model-eq.lisp model.lisp bvecp.lisp
+
+clean: clean-extra
+
+bvecp-raw.cert: bvecp-raw.lisp
+bvecp-raw.cert: model-raw.cert
+bvecp-raw.cert: ../../../../../rtl/rel4/lib/top.cert
+bvecp-raw.cert: ../../../../../rtl/rel4/support/bvecp-helpers.cert
+bvecp-raw.cert: cert.acl2
+bvecp-raw.cert: pkgs.lsp
+
+bvecp.cert: bvecp.lisp
+bvecp.cert: model.cert
+bvecp.cert: model-eq.cert
+bvecp.cert: bvecp-raw.cert
+bvecp.cert: ../../../../../rtl/rel4/support/bvecp-helpers.cert
+bvecp.cert: cert.acl2
+bvecp.cert: pkgs.lsp
+
+common.cert: common.lisp
+common.cert: ../../../../../rtl/rel4/lib/rtl.cert
+common.cert: ../../../../../rtl/rel4/lib/rtlarr.cert
+common.cert: ../../../../../rtl/rel4/lib/util.cert
+common.cert: ../../../../../misc/symbol-btree.cert
+common.cert: ../../../../../misc/rtl-untranslate.cert
+common.cert: cert.acl2
+common.cert: pkgs.lsp
+
+model-defs.cert: model-defs.lisp
+model-defs.cert: ../../../../../ordinals/e0-ordinal.cert
+model-defs.cert: common.cert
+model-defs.cert: model-macros.cert
+model-defs.cert: cert.acl2
+model-defs.cert: pkgs.lsp
+
+model-eq.cert: model-eq.lisp
+model-eq.cert: bvecp-raw.cert
+model-eq.cert: ../../../../../rtl/rel4/lib/top.cert
+model-eq.cert: ../../../../../rtl/rel4/lib/simplify-model-helpers.cert
+model-eq.cert: model-raw.cert
+model-eq.cert: model.cert
+model-eq.cert: cert.acl2
+model-eq.cert: pkgs.lsp
+
+model-macros.cert: model-macros.lisp
+model-macros.cert: cert.acl2
+model-macros.cert: pkgs.lsp
+
+model-raw.cert: model-raw.lisp
+model-raw.cert: ../../../../../ordinals/e0-ordinal.cert
+model-raw.cert: common.cert
+model-raw.cert: cert.acl2
+model-raw.cert: pkgs.lsp
+
+model.cert: model.lisp
+model.cert: ../../../../../ordinals/e0-ordinal.cert
+model.cert: common.cert
+model.cert: model-macros.cert
+model.cert: cert.acl2
+model.cert: pkgs.lsp
+
+package-defs.cert: package-defs.lisp
+package-defs.cert: package-defs.acl2
+
+# Added manually, since cert.acl2 contains (ld "pkgs.lsp"), which contains
+# (include-book "package-defs"):
+
+bvecp-raw.cert: package-defs.cert
+bvecp.cert: package-defs.cert
+common.cert: package-defs.cert
+model-defs.cert: package-defs.cert
+model-eq.cert: package-defs.cert
+model-macros.cert: package-defs.cert
+model-raw.cert: package-defs.cert
+model.cert: package-defs.cert
diff --git a/books/workshops/2003/kaufmann/support/rtl/README b/books/workshops/2003/kaufmann/support/rtl/README
new file mode 100644
index 0000000..e4f69df
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/README
@@ -0,0 +1,8 @@
+Type "make" to generate and certify files in the current directory that should
+agree with the files in the results/ subdirectory, essentially:
+
+model.lisp simplified version of input file model-raw.lisp
+model-eq.lisp proofs of equivalence of model-raw and model functions
+bvecp.lisp proofs of bvecp lemmas about model functions, originally proved
+ for model-raw functions
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/bvecp-raw.lisp b/books/workshops/2003/kaufmann/support/rtl/bvecp-raw.lisp
new file mode 100644
index 0000000..cfc8b6f
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/bvecp-raw.lisp
@@ -0,0 +1,33 @@
+(in-package "ACL2")
+
+(set-inhibit-warnings "SUBSUME" "THEORY" "DISABLE" "NON-REC")
+
+(include-book "model-raw")
+
+(local (include-book "rtl/rel4/lib/top" :dir :system))
+
+(local
+ (include-book "rtl/rel4/support/bvecp-helpers" :dir :system))
+
+(local
+ (in-theory
+ (set-difference-theories
+ (current-theory :here)
+ (union-theories
+ '(bvecp)
+ (union-theories (theory 'ACL2::RTL-OPERATORS-AFTER-MACRO-EXPANSION)
+ (theory 'ACL2::MODEL-RAW-DEFS))))))
+
+(local (defthm bvecp-if
+ (equal (bvecp (if x y z) n)
+ (if x (bvecp y n) (bvecp z n)))))
+
+(local (in-theory (enable log=)))
+
+(defbvecp FOO$RAW::out1 (n)
+ 1 :hints (("Goal" :expand ((FOO$RAW::out1 n)))))
+
+(defbvecp FOO$RAW::out2 (n)
+ 4 :hints
+ (("Goal" :expand ((FOO$RAW::out2 n))
+ :induct (sub1-induction n))))
diff --git a/books/workshops/2003/kaufmann/support/rtl/cert.acl2 b/books/workshops/2003/kaufmann/support/rtl/cert.acl2
new file mode 100644
index 0000000..ddcacb5
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/cert.acl2
@@ -0,0 +1,3 @@
+(acl2::value :q)
+(acl2::lp)
+(ld "pkgs.lsp")
diff --git a/books/workshops/2003/kaufmann/support/rtl/common.lisp b/books/workshops/2003/kaufmann/support/rtl/common.lisp
new file mode 100644
index 0000000..9598a90
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/common.lisp
@@ -0,0 +1,134 @@
+(in-package "ACL2")
+
+(set-inhibit-warnings "THEORY" "DISABLE" "NON-REC")
+
+(include-book "rtl/rel4/lib/rtl" :dir :system)
+
+(include-book "rtl/rel4/lib/rtlarr" :dir :system)
+
+(include-book "rtl/rel4/lib/util" :dir :system)
+
+(include-book "misc/symbol-btree" :dir :system)
+
+(include-book "misc/rtl-untranslate" :dir :system)
+
+(deftheory rtl-operators-after-macro-expansion
+ *rtl-operators-after-macro-expansion*)
+
+(local
+ (in-theory
+ (set-difference-theories (current-theory :here)
+ (theory 'rtl-operators-after-macro-expansion))))
+
+(defmacro ww (n) (list 'ww$ n '$path))
+
+(defmacro sel (n) (list 'sel$ n '$path))
+
+(defmacro in3 (n) (list 'in3$ n '$path))
+
+(defmacro in2 (n) (list 'in2$ n '$path))
+
+(defmacro in1 (n) (list 'in1$ n '$path))
+
+(defmacro in0 (n) (list 'in0$ n '$path))
+
+(ENCAPSULATE
+ (
+ (ww$ (n $path) t)
+
+ (sel$ (n $path) t)
+
+ (in3$ (n $path) t)
+
+ (in2$ (n $path) t)
+
+ (in1$ (n $path) t)
+
+ (in0$ (n $path) t)
+
+ )
+
+ (local (defun ww$ (n $path)
+ (declare (ignore n $path))
+ 0))
+
+ (local (defun sel$ (n $path)
+ (declare (ignore n $path))
+ 0))
+
+ (local (defun in3$ (n $path)
+ (declare (ignore n $path))
+ 0))
+
+ (local (defun in2$ (n $path)
+ (declare (ignore n $path))
+ 0))
+
+ (local (defun in1$ (n $path)
+ (declare (ignore n $path))
+ 0))
+
+ (local (defun in0$ (n $path)
+ (declare (ignore n $path))
+ 0))
+
+ (defbvecp ww (n) 3)
+
+ (defbvecp sel (n) 2)
+
+ (defbvecp in3 (n) 1)
+
+ (defbvecp in2 (n) 1)
+
+ (defbvecp in1 (n) 1)
+
+ (defbvecp in0 (n) 1)
+
+)
+
+(add-macro-alias ww ww$)
+
+(add-macro-alias sel sel$)
+
+(add-macro-alias in3 in3$)
+
+(add-macro-alias in2 in2$)
+
+(add-macro-alias in1 in1$)
+
+(add-macro-alias in0 in0$)
+
+(deflabel start-of-loop-defs)
+
+(set-ignore-ok t)
+
+(set-irrelevant-formals-ok t)
+
+(deflabel end-of-loop-defs)
+
+(deflabel start-of-clock-defs)
+
+(defun clk (n)
+ (declare (ignore n))
+ 1)
+
+(deflabel end-of-clock-defs)
+
+(deftheory loop-defs
+ (set-difference-theories (current-theory 'end-of-loop-defs)
+ (current-theory 'start-of-loop-defs)))
+
+(deftheory
+ clock-defs
+ (set-difference-theories
+ (union-theories (function-theory 'end-of-clock-defs)
+ (executable-counterpart-theory 'end-of-clock-defs))
+ (union-theories (function-theory 'start-of-clock-defs)
+ (executable-counterpart-theory 'start-of-clock-defs))))
+
+(table rtl-tbl 'sigs-btree
+ (symbol-alist-to-btree
+ (dollar-alist '(ww sel in3 in2 in1 in0
+ out1 FOO$RAW::OUT1 out2 FOO$RAW::OUT2)
+ nil)))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/model-macro-aliases.lsp b/books/workshops/2003/kaufmann/support/rtl/model-macro-aliases.lsp
new file mode 100644
index 0000000..40b6fa2
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/model-macro-aliases.lsp
@@ -0,0 +1,18 @@
+(add-macro-alias out1 out1$)
+
+(add-macro-alias out2 out2$)
+
+(deflabel model-end-of-defs)
+
+(deftheory tmp-names 'nil)
+
+(deftheory
+ model-defs
+ (union-theories (set-difference-theories (current-theory 'model-end-of-defs)
+ (current-theory 'model-start-of-defs))
+ (union-theories (theory 'loop-defs)
+ (theory 'clock-defs))))
+
+(in-theory (set-difference-theories (current-theory :here)
+ (theory 'model-defs)))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/model-macros.lisp b/books/workshops/2003/kaufmann/support/rtl/model-macros.lisp
new file mode 100644
index 0000000..8e19a6e
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/model-macros.lisp
@@ -0,0 +1,8 @@
+(in-package "ACL2")
+
+(defmacro out1 (n)
+ (list 'out1$ n '$path))
+
+(defmacro out2 (n)
+ (list 'out2$ n '$path))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/model-raw.lisp b/books/workshops/2003/kaufmann/support/rtl/model-raw.lisp
new file mode 100644
index 0000000..8fb0a9a
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/model-raw.lisp
@@ -0,0 +1,76 @@
+(in-package "ACL2")
+
+(include-book "ordinals/e0-ordinal" :dir :system)
+(set-well-founded-relation e0-ord-<)
+
+(set-inhibit-warnings "THEORY" "DISABLE" "NON-REC")
+
+(include-book "common")
+
+(local
+ (in-theory
+ (set-difference-theories (current-theory :here)
+ (theory 'rtl-operators-after-macro-expansion))))
+
+(defmacro FOO$RAW::out1 (n)
+ (list 'FOO$RAW::out1$ n '$path))
+
+(defmacro FOO$RAW::out2 (n)
+ (list 'FOO$RAW::out2$ n '$path))
+
+(set-irrelevant-formals-ok t)
+
+(set-ignore-ok t)
+
+(deflabel model-raw-start-of-defs)
+
+(set-bogus-mutual-recursion-ok t)
+
+(MUTUAL-RECURSION
+
+(defun FOO$RAW::out2$ (n $path)
+ (declare (xargs :normalize
+ nil :measure (cons (1+ (nfix n)) 0)))
+ (if (zp n)
+ (reset 'ACL2::OUT2 4)
+ (mod+ (cat (n! 0 1)
+ 1 (bits (ww (1- n)) 2 0)
+ 3)
+ (n! 1 4)
+ 4)))
+
+(defun FOO$RAW::out1$ (n $path)
+ (declare (xargs :normalize
+ nil :measure (cons (1+ (nfix n)) 1)))
+ (bind case-select (bits (sel n) 1 0)
+ (if1 (log= (n! 0 2) case-select)
+ (bitn (in0 n) 0)
+ (if1 (log= (n! 1 2) case-select)
+ (bitn (in1 n) 0)
+ (if1 (log= (n! 2 2) case-select)
+ (bitn (in2 n) 0)
+ (if1 (log= (n! 3 2) case-select)
+ (bitn (in3 n) 0)
+ (n! 0 1)))))))
+
+)
+
+(add-macro-alias FOO$RAW::out1 FOO$RAW::out1$)
+
+(add-macro-alias FOO$RAW::out2 FOO$RAW::out2$)
+
+(deflabel model-raw-end-of-defs)
+
+(deftheory raw-tmp-names 'nil)
+
+(deftheory
+ model-raw-defs
+ (union-theories
+ (set-difference-theories (current-theory 'model-raw-end-of-defs)
+ (current-theory 'model-raw-start-of-defs))
+ (union-theories (theory 'loop-defs)
+ (theory 'clock-defs))))
+
+(in-theory (set-difference-theories (current-theory :here)
+ (theory 'model-raw-defs)))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/package-defs.acl2 b/books/workshops/2003/kaufmann/support/rtl/package-defs.acl2
new file mode 100644
index 0000000..e5ce1fd
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/package-defs.acl2
@@ -0,0 +1,3 @@
+(acl2::value :q)
+(acl2::lp)
+(certify-book "package-defs" ? t)
diff --git a/books/workshops/2003/kaufmann/support/rtl/package-defs.lisp b/books/workshops/2003/kaufmann/support/rtl/package-defs.lisp
new file mode 100644
index 0000000..98f4828
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/package-defs.lisp
@@ -0,0 +1,33 @@
+(in-package "ACL2")
+
+;;Miscellaneous symbols that are not in *acl2-exports*:
+
+(defmacro other-acl2-symbols ()
+ ''(local-defun local-defthm local-in-theory
+ $path ; path argument of signal functions
+ ))
+
+(defmacro rtl-symbols ()
+ ''(log= log<> log< log<= log> log>= lnot logand1 logior1 logxor1 shft lshft
+ rshft cat mulcat bitn bits setbits setbitn mod+ mod* mod- bind
+ case-select if1 cond1 reset reset2 land lior lxor lcat n! arr0 natp1
+ as ag mk-bvarr mk-bvec ag2 as2
+ unknown unknown2))
+
+;;Functions that are defined in the FP library:
+
+(defmacro fp-symbols ()
+ ''(natp fl cg fl-half bvecp bv-arrp sumbits sigm kap tau lamt lamg lamz lam1 lam2 lam3 lam4 lam0 lamb
+ expo sgn sig
+ exactp fp+ bias esgnf eexpof esigf erepp eencodingp eencode edecode ndecode rebias-expo isgnf iexpof isigf
+ nrepp drepp irepp nencodingp dencodingp iencodingp nencode dencode iencode ddecode idecode trunc away re
+ near near-witness near+ sticky oddr kp inf minf ieee-mode-p rnd flip rnd-const drnd))
+
+;;ACL2 symbols that are imported by all packages:
+
+(defmacro shared-symbols ()
+ '(union-eq *acl2-exports*
+ (union-eq *common-lisp-symbols-from-main-lisp-package*
+ (union-eq (other-acl2-symbols)
+ (union-eq (fp-symbols)
+ (rtl-symbols))))))
diff --git a/books/workshops/2003/kaufmann/support/rtl/pkgs.lsp b/books/workshops/2003/kaufmann/support/rtl/pkgs.lsp
new file mode 100644
index 0000000..0868f4b
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/pkgs.lsp
@@ -0,0 +1,23 @@
+(in-package "ACL2")
+
+(defconst *old2new-pkg-alist*
+ '(("FOO$RAW" . "ACL2")))
+
+(include-book "package-defs")
+
+(defconst *defrom-imports* 'nil)
+
+(defconst *loop-vars* 'nil)
+
+(defconst *loop-fns* 'nil)
+
+(defconst *all-imports*
+ (append *loop-vars* *defrom-imports*
+ *loop-fns* (shared-symbols)))
+
+(defconst *foo-inputs*
+ '(in0 in1 in2 in3 sel ww clk))
+
+(defpkg "FOO$RAW"
+ (append *foo-inputs* *all-imports*))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/results/bvecp.lisp b/books/workshops/2003/kaufmann/support/rtl/results/bvecp.lisp
new file mode 100644
index 0000000..1cfc0c9
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/results/bvecp.lisp
@@ -0,0 +1,19 @@
+(in-package "ACL2")
+
+(include-book "model")
+
+(local (include-book "model-eq"))
+
+(local (include-book "bvecp-raw"))
+
+(local (include-book "rtl/rel4/support/bvecp-helpers"
+ :dir :system))
+
+(defbvecp out1 (n)
+ 1
+ :hints (("Goal" :use foo$raw::bvecp$out1)))
+
+(defbvecp out2 (n)
+ 4
+ :hints (("Goal" :use foo$raw::bvecp$out2)))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/results/cert_pl_exclude b/books/workshops/2003/kaufmann/support/rtl/results/cert_pl_exclude
new file mode 100644
index 0000000..dd7b6c6
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/results/cert_pl_exclude
@@ -0,0 +1,8 @@
+cert_pl_exclude
+
+The presence of this file tells cert.pl not to try to build any of the books in
+this directory.
+
+This directory contains books not to be certified. Rather, they are
+here for comparison with files that are generated; see the `diff'
+calls in ../Makefile.
diff --git a/books/workshops/2003/kaufmann/support/rtl/results/model-eq.lisp b/books/workshops/2003/kaufmann/support/rtl/results/model-eq.lisp
new file mode 100644
index 0000000..ac1b32f
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/results/model-eq.lisp
@@ -0,0 +1,161 @@
+(in-package "ACL2")
+
+(local (defun %%sub1-induction (n)
+ (if (zp n)
+ n (%%sub1-induction (1- n)))))
+
+(local (defun %%and-tree-fn (args len)
+ (declare (xargs :mode :program))
+ (if (< len 20)
+ (cons 'and args)
+ (let* ((len2 (floor len 2)))
+ (list 'and
+ (%%and-tree-fn (take len2 args) len2)
+ (%%and-tree-fn (nthcdr len2 args)
+ (- len len2)))))))
+
+(local (defmacro %%and-tree (&rest args)
+ (%%and-tree-fn args (length args))))
+
+(local (include-book "bvecp-raw"))
+
+(local (include-book "rtl/rel4/lib/top"
+ :dir :system))
+
+(local (include-book "rtl/rel4/lib/simplify-model-helpers"
+ :dir :system))
+
+(include-book "model-raw")
+
+(include-book "model")
+
+(local (table user-defined-functions-table
+ nil nil :clear))
+
+(local (disable-forcing))
+
+(local (deftheory theory-0 (theory 'minimal-theory)))
+
+(local (defmacro %%p0-equalities nil
+ '(%%and-tree (equal (out1$ n $path)
+ (foo$raw::out1$ n $path))
+ (equal (out2$ n $path)
+ (foo$raw::out2$ n $path)))))
+
+(local (defun %%p0-aux (n $path)
+ (declare (xargs :normalize nil))
+ (%%p0-equalities)))
+
+(local (defun-sk %%p0 (n)
+ (forall ($path) (%%p0-aux n $path))))
+
+(local (defthm %%p0-implies-%%p0-aux
+ (implies (%%p0 n) (%%p0-aux n $path))))
+
+(local (encapsulate
+ nil
+ (local (defthm %%p0-property-lemma
+ (implies (%%p0-aux n $path)
+ (%%p0-equalities))
+ :rule-classes nil
+ :instructions ((:dv 1)
+ (:expand nil)
+ :top
+ (:generalize ((%%p0-equalities) eqs))
+ :s)))
+ (defthm %%p0-property
+ (implies (%%p0 n) (%%p0-equalities))
+ :instructions ((:use %%p0-property-lemma)
+ (:generalize ((%%p0-equalities) eqs))
+ :prove))))
+
+(local
+ (deftheory %%p0-implies-f-is-%f-theory
+ (union-theories (set-difference-theories (current-theory :here)
+ (current-theory '%%p0))
+ (theory 'minimal-theory))))
+
+(local
+ (encapsulate
+ nil
+ (local (in-theory (disable %%p0-property)))
+ (local (defthm out2$-is-out2$-base
+ (implies (zp n)
+ (equal (out2$ n $path)
+ (foo$raw::out2$ n $path)))
+ :hints (("Goal" :expand ((out2$ n $path)
+ (foo$raw::out2$ n $path))))))
+ (local (defthm out1$-is-out1$-base
+ (implies (zp n)
+ (equal (out1$ n $path)
+ (foo$raw::out1$ n $path)))
+ :hints (("Goal" :expand ((out1$ n $path)
+ (foo$raw::out1$ n $path))))))
+ (defthm %%p0-base (implies (zp n) (%%p0 n))
+ :instructions (:promote :x-dumb (:s :normalize nil)))))
+
+(local
+ (encapsulate
+ nil
+ (local (in-theory (disable %%p0 %%p0-base)))
+ (local (deflabel %%induction-start))
+ (local (defthm out2$-is-out2$-induction_step
+ (implies (and (not (zp n)) (%%p0 (1- n)))
+ (equal (out2$ n $path)
+ (foo$raw::out2$ n $path)))
+ :instructions (:promote (:dv 1)
+ :x-dumb
+ :nx :x-dumb
+ :top (:s :normalize nil
+ :backchain-limit 1000
+ :expand :lambdas
+ :repeat 4))))
+ (local (defthm out1$-is-out1$-induction_step
+ (implies (and (not (zp n)) (%%p0 (1- n)))
+ (equal (out1$ n $path)
+ (foo$raw::out1$ n $path)))
+ :instructions (:promote (:dv 1)
+ :x-dumb
+ :nx :x-dumb
+ :top (:s :normalize nil
+ :backchain-limit 1000
+ :expand :lambdas
+ :repeat 4))))
+ (defthm %%p0-induction_step
+ (implies (and (not (zp n)) (%%p0 (1- n)))
+ (%%p0 n))
+ :instructions (:promote :x-dumb (:s :normalize nil)))))
+
+(local
+ (defthm
+ %%p0-holds (%%p0 n)
+ :hints
+ (("Goal" :induct (%%sub1-induction n)
+ :do-not '(preprocess)
+ :in-theory (union-theories '(%%p0-base %%p0-induction_step
+ (:induction %%sub1-induction))
+ (theory 'minimal-theory))))))
+
+(ENCAPSULATE
+ (
+ )
+
+ (local (in-theory (union-theories '(%%p0-holds)
+ (theory '%%p0-implies-f-is-%f-theory))))
+
+ (defthm out2$-is-out2$
+ (equal (out2$ n $path)
+ (foo$raw::out2$ n $path))
+ :hints (("Goal" :do-not '(preprocess))))
+
+ (defthm out1$-is-out1$
+ (equal (out1$ n $path)
+ (foo$raw::out1$ n $path))
+ :hints (("Goal" :do-not '(preprocess))))
+
+)
+
+(deftheory %-removal-theory
+ (union-theories '(out1$-is-out1$ out2$-is-out2$)
+ (theory 'minimal-theory)))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/results/model.lisp b/books/workshops/2003/kaufmann/support/rtl/results/model.lisp
new file mode 100644
index 0000000..2b32103
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/results/model.lisp
@@ -0,0 +1,59 @@
+(in-package "ACL2")
+
+(include-book "ordinals/e0-ordinal"
+ :dir :system)
+
+(set-well-founded-relation e0-ord-<)
+
+(set-inhibit-warnings "THEORY" "DISABLE" "NON-REC")
+
+(include-book "common")
+
+(include-book "model-macros")
+
+(set-irrelevant-formals-ok t)
+
+(set-ignore-ok t)
+
+(deflabel model-start-of-defs)
+
+(set-bogus-mutual-recursion-ok t)
+
+(MUTUAL-RECURSION
+
+(defun out2$ (n $path)
+ (declare (xargs :normalize nil
+ :measure (cons (1+ (nfix n)) 0)))
+ (if (zp n)
+ (reset 'out2 4)
+ (bits (+ 1 (ww (+ -1 n))) 3 0)))
+
+(defun out1$ (n $path)
+ (declare (xargs :normalize nil
+ :measure (cons (1+ (nfix n)) 1)))
+ (cond1 ((log= 0 (sel n)) (in0 n))
+ ((log= 1 (sel n)) (in1 n))
+ ((log= 2 (sel n)) (in2 n))
+ ((log= 3 (sel n)) (in3 n))
+ (t 0)))
+
+)
+
+(add-macro-alias out1 out1$)
+
+(add-macro-alias out2 out2$)
+
+(deflabel model-end-of-defs)
+
+(deftheory tmp-names 'nil)
+
+(deftheory
+ model-defs
+ (union-theories (set-difference-theories (current-theory 'model-end-of-defs)
+ (current-theory 'model-start-of-defs))
+ (union-theories (theory 'loop-defs)
+ (theory 'clock-defs))))
+
+(in-theory (set-difference-theories (current-theory :here)
+ (theory 'model-defs)))
+
diff --git a/books/workshops/2003/kaufmann/support/rtl/tool/Makefile b/books/workshops/2003/kaufmann/support/rtl/tool/Makefile
new file mode 100644
index 0000000..d5fc0f5
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/tool/Makefile
@@ -0,0 +1,2 @@
+include ../../../../../../Makefile-generic
+-include Makefile-deps
diff --git a/books/workshops/2003/kaufmann/support/rtl/tool/file-io-pkgs.lisp b/books/workshops/2003/kaufmann/support/rtl/tool/file-io-pkgs.lisp
new file mode 100644
index 0000000..6fb5c3e
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/tool/file-io-pkgs.lisp
@@ -0,0 +1,188 @@
+(in-package "ACL2")
+
+; There are two ways in which we want to print forms respecting packages. When
+; generating definitions originally, we may prefer to view the symbols as
+; package-less (although they will actually be ACL2 or built-in symbols) and
+; simply port the entire form to a new package, which might not even exist. In
+; the other case we have a form that is considered to have real symbols in it,
+; and we want to print out an equal form that however has a package prefix. So
+; we have write-list-into-pkgs, which prints pkg-name::form when presented with
+; (:pkg pkg-name . form), and write-list-using-pkgs, which prints form as an
+; equal form using pkg-name::form'.
+
+(include-book "misc/file-io" :dir :system)
+
+(set-state-ok t)
+(program)
+
+(defun change-pkg-for-form (form state)
+ (if (and (consp form)
+ (member-eq (car form) '(defun defthm))
+ (consp (cdr form))
+ (symbolp (cadr form)))
+ (let ((package-name (symbol-package-name (cadr form))))
+ (if (equal package-name "ACL2")
+ (value nil)
+ (in-package-fn package-name state)))
+ (value nil)))
+
+(mutual-recursion
+
+(defun pprint-object-or-string-using-pkg (obj indent channel state)
+ (cond
+ ((stringp obj)
+ (princ$ obj channel state))
+ ((and (consp obj)
+ (eq (car obj) 'encapsulate)
+ (consp (cdr obj)))
+ (pprogn (princ$ "(ENCAPSULATE" channel state)
+ (newline channel state)
+ (princ$ " (" channel state)
+ (newline channel state)
+ (write-objects-using-pkgs (cadr obj) (+ indent 2) channel state)
+ (princ$ " )" channel state)
+ (newline channel state)
+ (newline channel state)
+ (write-objects-using-pkgs (cddr obj) (+ indent 1) channel state)
+ (princ$ ")" channel state)))
+ ((and (consp obj)
+ (eq (car obj) 'mutual-recursion))
+ (pprogn (princ$ "(MUTUAL-RECURSION" channel state)
+ (newline channel state)
+ (newline channel state)
+ (write-objects-using-pkgs (cdr obj) indent channel state)
+ (princ$ ")" channel state)))
+ (t
+ (mv-let (erp val state)
+ (state-global-let*
+ ((write-for-read t))
+ (er-let*
+ ((new-pkg (change-pkg-for-form obj state)))
+ (pprogn
+ (if new-pkg
+ (pprogn (spaces indent 0 channel state)
+ (princ$ new-pkg channel state)
+ (princ$ "::" channel state)
+ (newline channel state))
+ state)
+ (if (int= indent 0) ; optimization
+ state
+ (spaces indent 0 channel state))
+ (ppr2 (ppr1 obj (print-base) (print-radix) (- 80 indent) 0 state t)
+ indent channel state t)
+ (if new-pkg
+ (in-package-fn "ACL2" state)
+ (value nil)))))
+ (declare (ignore erp val))
+ state))))
+
+(defun write-objects-using-pkgs (list indent channel state)
+ (if (consp list)
+ (pprogn (pprint-object-or-string-using-pkg (car list) indent channel
+ state)
+ (newline channel state)
+ (newline channel state)
+ (write-objects-using-pkgs (cdr list) indent channel state)
+ state)
+ state))
+
+)
+
+(defun write-list-using-pkgs (list fname ctx state)
+ (mv-let (channel state)
+ (open-output-channel fname :character state)
+ (if channel
+ (mv-let
+ (col state)
+ (fmt1 "Writing file ~x0~%" (list (cons #\0 fname))
+ 0 (standard-co state) state nil)
+ (declare (ignore col))
+ (let ((state (write-objects-using-pkgs list 0 channel state)))
+ (pprogn (close-output-channel channel state)
+ (value :invisible))))
+ (er soft ctx
+ "Unable to open file ~s0 for :character output."
+ fname))))
+
+; Now for write-list-into-pkgs.
+
+(mutual-recursion
+
+(defun pprint-object-or-string-into-pkg (obj indent channel state)
+ (cond
+ ((stringp obj)
+ (princ$ obj channel state))
+ ((and (consp obj)
+ (eq (car obj) 'encapsulate)
+ (consp (cdr obj)))
+ (pprogn (princ$ "(ENCAPSULATE" channel state)
+ (newline channel state)
+ (princ$ " (" channel state)
+ (newline channel state)
+ (write-objects-into-pkgs (cadr obj) (+ indent 2) channel state)
+ (princ$ " )" channel state)
+ (newline channel state)
+ (newline channel state)
+ (write-objects-into-pkgs (cddr obj) (+ indent 1) channel state)
+ (princ$ ")" channel state)))
+ ((and (consp obj)
+ (eq (car obj) 'mutual-recursion))
+ (pprogn (princ$ "(MUTUAL-RECURSION" channel state)
+ (newline channel state)
+ (newline channel state)
+ (write-objects-into-pkgs (cdr obj) indent channel state)
+ (princ$ ")" channel state)))
+ (t
+ (mv-let (erp val state)
+ (state-global-let*
+ ((write-for-read t))
+ (let* ((new-pkg (and (consp obj)
+ (eq (car obj) :pkg)
+ (consp (cdr obj))
+ (stringp (cadr obj))
+ (cadr obj)))
+ (form (if new-pkg (cddr obj) obj)))
+ (pprogn
+ (if new-pkg
+ (pprogn (spaces indent 0 channel state)
+ (princ$ new-pkg channel state)
+ (princ$ "::" channel state)
+ (newline channel state))
+ state)
+ (if (int= indent 0) ; optimization
+ state
+ (spaces indent 0 channel state))
+ (ppr2 (ppr1 form (print-base) (print-radix) (- 80 indent) 0
+ state t)
+ indent channel state t)
+ (value nil))))
+ (declare (ignore erp val))
+ state))))
+
+(defun write-objects-into-pkgs (list indent channel state)
+ (if (consp list)
+ (pprogn (pprint-object-or-string-into-pkg (car list) indent channel
+ state)
+ (newline channel state)
+ (newline channel state)
+ (write-objects-into-pkgs (cdr list) indent channel state)
+ state)
+ state))
+
+)
+
+(defun write-list-into-pkgs (list fname ctx state)
+ (mv-let (channel state)
+ (open-output-channel fname :character state)
+ (if channel
+ (mv-let
+ (col state)
+ (fmt1 "Writing file ~x0~%" (list (cons #\0 fname))
+ 0 (standard-co state) state nil)
+ (declare (ignore col))
+ (let ((state (write-objects-into-pkgs list 0 channel state)))
+ (pprogn (close-output-channel channel state)
+ (value :invisible))))
+ (er soft ctx
+ "Unable to open file ~s0 for :character output."
+ fname))))
diff --git a/books/workshops/2003/kaufmann/support/rtl/tool/simplify-defuns.lisp b/books/workshops/2003/kaufmann/support/rtl/tool/simplify-defuns.lisp
new file mode 100644
index 0000000..c9a1ce1
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/tool/simplify-defuns.lisp
@@ -0,0 +1,1181 @@
+; simplify-defuns.lisp -- see simplify-defuns.txt for documentation
+; Copyright (C) 2002 Matt Kaufmann
+; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; TABLE OF CONTENTS
+;;; -----------------
+;;; Term Simplification
+;;; Creating/Destroying % Symbols
+;;; Definition and Lemma Generation (except lemmas for mutual-recursion)
+;;; Lemma Generation for Mutual-recursion
+;;; Translating Lemmas
+;;; Top Level Routines
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(in-package "ACL2")
+
+(program)
+(set-state-ok t)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Term Simplification
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun simplify-term1 (ttree term hyps equiv thints prove-assumptions ctx wrld
+ state)
+
+; Adapted from tool2-fn in books/misc/expander.lisp.
+
+ (prog2$
+ (initialize-brr-stack state)
+ (let* ((ens (ens state))
+ (saved-pspv (make-pspv ens wrld state
+ :displayed-goal term ; from, e.g., thm-fn
+ :user-supplied-term term ;from, e.g., prove
+ :orig-hints thints)) ;from, e.g., prove
+ (new-lit (fcons-term* 'equal (fcons-term* 'hide 'xxx) term))
+ (current-clause (add-literal new-lit
+ (dumb-negate-lit-lst hyps) t)))
+ (er-let* ;from waterfall1
+ ((pair
+ (find-applicable-hint-settings
+ *initial-clause-id*
+ current-clause
+ nil saved-pspv ctx
+ thints wrld nil state)))
+ (let ((hint-settings (car pair))
+ (thints (cdr pair)))
+ (mv-let
+ (hint-settings state)
+ (cond ((null hint-settings)
+ (mv nil state))
+ (t (thanks-for-the-hint nil hint-settings nil state))) ;BB
+ (er-let* ((pspv (load-hint-settings-into-pspv
+ t hint-settings saved-pspv nil wrld ctx state)))
+ (cond
+ ((intersectp-eq
+ '(:do-not-induct :do-not :induct :use :cases :by)
+ (strip-cars hint-settings))
+ (er soft ctx
+ "It makes no sense for SIMPLIFY-TERM to be given hints for ~
+ \"Goal\" that include any of :do-not-induct, :do-not, ~
+ :induct, :use, :cases, or :by. The hint ~p0 is therefore ~
+ illegal."
+ (cons "Goal" hint-settings)))
+ (t (pprogn
+ (initialize-proof-tree ;from waterfall
+ *initial-clause-id*
+ (list (list (implicate (conjoin hyps) term)))
+ ctx
+ state)
+ (let* ;from simplify-clause1
+ ((rcnst
+ (change rewrite-constant
+ (access prove-spec-var pspv :rewrite-constant)
+ :force-info
+ (if (ffnnamep-lst 'if current-clause)
+ 'weak
+ t)))
+ (pts nil))
+ (mv-let
+ (contradictionp type-alist fc-pair-lst)
+ (forward-chain current-clause
+ pts
+ (access rewrite-constant
+ rcnst :force-info)
+ nil wrld ens (match-free-override wrld)
+ state)
+ (declare (ignore fc-pair-lst))
+ (cond
+ (contradictionp
+ (er soft ctx
+ "Contradiction found in hypotheses using type-set ~
+ reasoning!"))
+ (t
+ (sl-let ;from simplify-clause1
+ (contradictionp simplify-clause-pot-lst)
+ (setup-simplify-clause-pot-lst current-clause
+ (pts-to-ttree-lst
+ pts)
+ nil ; fc-pair-lst ;; RBK:
+ type-alist
+ rcnst
+ wrld state
+ (initial-step-limit
+ wrld state))
+ (cond
+ (contradictionp
+ (er soft ctx
+ "Contradiction found in hypotheses using linear ~
+ reasoning!"))
+ (t
+
+; We skip the call of process-equational-polys in simplify-clause1; I think
+; that we can assume that by the time this is called, that call wouldn't have
+; any effect anyhow. By the way, we skipped remove-trivial-equivalence
+; earlier.
+
+; Now we continue as in rewrite-clause.
+
+ (let ((local-rcnst
+ (change rewrite-constant rcnst
+ :current-literal
+ (make current-literal
+ :not-flg nil
+ :atm term)))
+ (gstack (initial-gstack 'simplify-clause
+ nil
+ current-clause)))
+ (sl-let
+ (rewritten-term ttree)
+ (rewrite-entry
+ (rewrite term nil 1)
+ :rdepth (rewrite-stack-limit wrld)
+ :obj '?
+ :fnstack nil
+ :ancestors nil
+ :backchain-limit 500
+ :step-limit step-limit
+ :geneqv
+ (cadr (car (last (getprop
+ equiv
+ 'congruences
+ nil
+ 'current-acl2-world
+ wrld))))
+ :pequiv-info nil)
+ (sl-let
+ (bad-ass ttree)
+ (resume-suspended-assumption-rewriting
+ ttree
+ nil
+ gstack
+ simplify-clause-pot-lst
+ local-rcnst
+ wrld
+ state
+ step-limit)
+ (cond
+ (bad-ass
+ (er soft ctx
+ "Generated false assumption, ~p0! So, ~
+ rewriting is aborted, just as it would be ~
+ in the course of a regular ACL2 proof."
+ bad-ass))
+ (prove-assumptions
+ (mv-let
+ (pairs pspv state)
+ (process-assumptions
+ 0
+ (change prove-spec-var saved-pspv
+ :tag-tree
+ (set-cl-ids-of-assumptions
+ ttree *initial-clause-id*))
+ wrld state)
+ (er-let*
+ ((ttree
+ (accumulate-ttree-and-step-limit-into-state
+ (access prove-spec-var pspv :tag-tree)
+ step-limit
+ state))
+ (thints (value thints)))
+ (er-let*
+ ((new-ttree
+ (prove-loop1 1 nil pairs pspv
+ thints ens wrld ctx state)))
+ (value (cons rewritten-term
+ (cons-tag-trees
+ ttree
+ new-ttree)))))))
+ (t
+ (value (cons rewritten-term
+ ttree))))))))))))))))))))))))
+
+(defun simplify-term* (remaining-iters ttree term hyps equiv thints
+ prove-assumptions ctx wrld state)
+ (if (zp remaining-iters)
+ (value (list* term t ttree))
+ (er-let*
+ ((term-ttree (simplify-term1 ttree term hyps equiv thints
+ prove-assumptions ctx wrld state)))
+ (if (equal term (car term-ttree))
+ (value (list* term nil ttree))
+ (simplify-term* (1- remaining-iters) (cdr term-ttree) (car term-ttree)
+ hyps equiv thints prove-assumptions ctx wrld state)))))
+
+(defun simplify-term
+ (repeat-limit translate-flg inhibit-output form hyps equiv hints
+ prove-assumptions ctx wrld state)
+ (state-global-let*
+ ((inhibit-output-lst
+ (if inhibit-output
+ (union-eq '(proof-tree prove) (@ inhibit-output-lst))
+ (@ inhibit-output-lst))))
+ (let ((name-tree 'simplify-term))
+ (er-let*
+ ((thints (translate-hints name-tree hints ctx wrld state))
+ (thyps (if translate-flg
+ (translate-term-lst hyps t t t ctx wrld state)
+ (value hyps)))
+ (term (if translate-flg
+ (translate form t t t ctx wrld state)
+ (value form))))
+ (simplify-term* repeat-limit nil term hyps equiv thints prove-assumptions
+ ctx wrld state)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Creating/Destroying % Symbols
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; All the code for dealing with % should be in this section. So, it should be
+; easy enough to modify the code to use other naming schemes.
+
+; Each pkg-alist argument is an alist associating old package names with new
+; package names.
+
+(defun old2new (sym pkg-alist)
+ (let ((name (symbol-name sym)))
+ (if (eq pkg-alist t)
+ (let ((len (length name)))
+ (if (and (not (int= len 0))
+ (eq (char name 0) #\%))
+ (intern-in-package-of-symbol (subseq name 1 len) sym)
+ sym))
+ (let* ((pkg (symbol-package-name sym))
+ (pair (assoc-equal pkg pkg-alist)))
+ (if pair
+ (intern$ name (cdr pair))
+ sym)))))
+
+(defun old2new-list (sym-list pkg-alist acc)
+
+; NOTE: Reverses the list.
+
+ (if (endp sym-list)
+ acc
+ (old2new-list
+ (cdr sym-list)
+ pkg-alist
+ (cons (old2new (car sym-list) pkg-alist)
+ acc))))
+
+(mutual-recursion
+
+(defun old2new-term (term pkg-alist)
+ (cond
+ ((variablep term) term)
+ ((fquotep term) term)
+ ((flambdap (ffn-symb term))
+
+; ((lambda (vars) body) . args)
+
+ (let ((vars (lambda-formals (ffn-symb term)))
+ (body (lambda-body (ffn-symb term)))
+ (args (fargs term)))
+ (fcons-term (make-lambda vars (old2new-term body pkg-alist))
+ (old2new-term-lst args pkg-alist nil))))
+ (t
+ (fcons-term (old2new (ffn-symb term) pkg-alist)
+ (old2new-term-lst (fargs term) pkg-alist nil)))))
+
+(defun old2new-term-lst (x pkg-alist acc)
+ (cond ((endp x) (reverse acc))
+ (t (old2new-term-lst (cdr x)
+ pkg-alist
+ (cons (old2new-term (car x) pkg-alist) acc)))))
+
+)
+
+(defconst *%%p* "%%P")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Definition and Lemma Generation (except lemmas for mutual-recursion)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun sublis-fn! (alist term)
+ (mv-let (erp new-term)
+ (sublis-fn alist term nil)
+ (assert$ (null erp)
+ new-term)))
+
+(defun %f-is-f-lemmas-rev (%f f formals-decls orig-body
+ untranslated-new-body
+ translated-new-body
+ counter old-theory wrld)
+
+; Conses, in reverse order, all new lemmas for proving %f-is-f. This should
+; not be called for mutually recursive functions.
+
+ (let* ((%f-name (symbol-name %f))
+ (f-name (symbol-name f))
+ (%%f-name (concatenate 'string "%" %f-name))
+ (%%f (intern-in-package-of-symbol %%f-name %f))
+ (f-body-is-%f-body_s
+ (intern-in-package-of-symbol
+ (concatenate 'string f-name "-BODY-IS-" %f-name "-BODY_S")
+ %f))
+ (%%f-is-f
+ (intern-in-package-of-symbol
+ (concatenate 'string %%f-name "-IS-" f-name)
+ %f))
+ (f-is-%f
+ (intern-in-package-of-symbol
+ (concatenate 'string f-name "-IS-" %f-name)
+ %f))
+ (new-theory
+ (intern (concatenate 'string "THEORY-"
+ (coerce (explode-atom (1+ counter) 10)
+ 'string))
+ "ACL2"))
+ (recp
+
+; We use %f below even though f might be slightly better, because that way only
+; the input defs need to be included.
+
+ (getprop %f 'recursivep nil 'current-acl2-world wrld))
+ (formals (car formals-decls))
+ (%%f-formals (cons %%f formals))
+ ( %f-formals (cons %f formals))
+ ( f-formals (cons f formals))
+ (equal-bodies (and (not recp)
+ (equal untranslated-new-body orig-body))))
+
+; The lemmas below are in reverse order.
+
+ `((local
+ (deftheory ,new-theory
+ (union-theories '(,f-is-%f)
+ (theory ',old-theory))))
+
+ (defthm ,f-is-%f
+ (equal ,f-formals
+ ,%f-formals)
+ :hints (,(if recp
+ `("Goal"
+ :by
+ (:functional-instance
+ ,%%f-is-f
+ (,%%f ,%f))
+ :do-not '(preprocess) ; avoid dumb clausifier
+ :expand (,%f-formals))
+ `("Goal" :expand
+
+; Uh oh: simplification can replace a formal with a constant. Since %f and f
+; are non-recursive, it is safe to cause all calls to be expanded.
+
+ ((:free ,formals ,%f-formals)
+ (:free ,formals ,f-formals))
+ :in-theory (theory ',old-theory)
+ :do-not '(preprocess) ; avoid dumb clausifier
+ ,@(and (not equal-bodies)
+ `(:use ,f-body-is-%f-body_s))))))
+
+ ,@(cond
+ (recp `((local
+ (defthm ,%%f-is-f
+ (equal ,%%f-formals
+ ,f-formals)
+ :hints (("Goal"
+ :in-theory
+ (union-theories
+ '((:induction ,%%f))
+ (theory ',old-theory))
+ :do-not '(preprocess) ; avoid dumb clausifier
+ :expand (,%%f-formals ,f-formals)
+ :induct t))))
+ (local
+ (defun ,%%f ,formals
+ ,@(cdr formals-decls) ; to include original measure etc.
+ ,(untranslate (sublis-fn! (list (cons %f %%f))
+ translated-new-body)
+ nil wrld)))))
+ (equal-bodies nil)
+ (t `((local
+ (defthm ,f-body-is-%f-body_s
+
+; Presumably the same simplification that created %body_s from %body should
+; prove this theorem.
+
+ (equal ,untranslated-new-body ,orig-body)
+ :hints (("Goal" :do-not '(preprocess) ; avoid dumb clausifier
+ ))
+ :rule-classes nil))))))))
+
+(defun get-state-value (sym state)
+ (if (f-boundp-global sym state)
+ (f-get-global sym state)
+ nil))
+
+(defun simplify-repeat-limit (state)
+
+; This supplies the number of iterations of our calls to the rewriter.
+
+ (or (get-state-value 'simplify-repeat-limit state)
+
+; We could play with this limit. But see the comment about
+; simplify-repeat-limit in f-is-%f-induction-step-lemmas.
+
+ 3))
+
+(defun simplify-inhibit (state)
+ (let ((val (get-state-value 'simplify-inhibit state)))
+ (case val
+ ((t) nil)
+ ((nil) '(prove proof-tree warning observation event summary))
+ (otherwise val))))
+
+(defun simplify-defun (info def lemmas counter old-theory pkg-alist ens wrld
+ state)
+
+; Def is (defun %foo ...) or (defund %foo ...).
+
+; We return (mv erp new-def lemmas-out counter latest-theory state), where
+; lemmas-out extends lemmas but is equal to lemmas if info is 'mut-rec.
+; Except, if def is not intended to be simplified, new-def is nil.
+
+; WARNING: This function does not modify the declare forms of def, even if %f
+; is mentioned in those declare forms.
+
+ (declare (ignore ens))
+ (let* ((fn (cadr def))
+ (new-fn (old2new fn pkg-alist))
+ (orig-body (car (last def))))
+ (if (eq new-fn fn)
+ (mv nil nil lemmas counter old-theory state)
+ (mv-let
+ (erp simp state)
+ (simplify-term (simplify-repeat-limit state)
+ t ; translate-flg
+ (simplify-inhibit state)
+ orig-body
+ nil ;hyps
+ 'equal ; equiv
+ nil ; hints
+ t ; prove-assumptions
+ 'simplify-defun wrld state)
+ (if erp
+ (mv-let (erp val state)
+ (er soft 'simplify-defun
+ "Simplification failed for the definition of ~x0."
+ fn)
+ (declare (ignore erp val))
+ (mv t nil nil counter old-theory state))
+ (let* ((new-body (car simp))
+ (untranslated-new-body
+ (untranslate new-body nil wrld))
+ (new-body-stripped (old2new-term new-body pkg-alist))
+ (untranslated-new-body-stripped
+ (untranslate new-body-stripped nil wrld))
+ (formals-decls (butlast (cddr def) 1))
+ (new-lemmas
+ (if (eq info 'mut-rec)
+ nil
+ (%f-is-f-lemmas-rev fn new-fn formals-decls
+ orig-body
+ untranslated-new-body
+ new-body
+ counter old-theory wrld)))
+ (first-new-lemma (car new-lemmas))
+ (new-theory-p
+ (case-match first-new-lemma
+ (('local ('deftheory . &))
+ t)
+ (& nil)))
+ (new-theory
+ (if new-theory-p
+ (cadr (cadr first-new-lemma))
+ old-theory))
+ (new-counter (if new-theory-p (1+ counter) counter)))
+ (mv nil
+ `(;;,(if (enabled-runep (list :definition fn) ens wrld) 'defun 'defund)
+ defun
+ ,new-fn
+ ,@formals-decls
+ ,untranslated-new-body-stripped)
+ (append new-lemmas lemmas)
+ new-counter
+ new-theory
+ state)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Lemma Generation for Mutual-recursion
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun mut-rec-formals (defs formals)
+
+; We return a list containing the formal parameters common to all the defs
+; (each of the form (defun ...)) if there is one, else nil. We will be
+; assuming that recursion is on the first and the others are unchangeable.
+
+ (if (endp defs)
+ formals
+ (let* ((def (car defs))
+ (new-formals (and (true-listp def) (caddr def))))
+ (and (or (null formals)
+ (equal formals new-formals))
+ (mut-rec-formals (cdr defs) new-formals)))))
+
+(defun f-is-%f-list (defs formals pkg-alist acc)
+
+; Returns a list of (equal (f . formals) (%f . formals)) in forward order.
+
+ (if (endp defs)
+ acc
+ (f-is-%f-list (cdr defs)
+ formals
+ pkg-alist
+ (let* ((%f (cadar defs))
+ (f (old2new %f pkg-alist)))
+ (if (eq %f f)
+ acc
+ (cons `(equal (,f ,@formals)
+ (,%f ,@formals))
+ acc))))))
+
+(defun f-is-%f-base-lemmas (f-is-%f-list formals zp-formals acc)
+
+; Result is in correct order if f-is-%f-list is in reverse order.
+
+ (if (endp f-is-%f-list)
+ acc
+ (f-is-%f-base-lemmas
+ (cdr f-is-%f-list)
+ formals zp-formals
+ (cons (let* ((equality (car f-is-%f-list))
+ ( f (car (cadr equality)))
+ (%f (car (caddr equality)))
+ (lemma-name
+ (intern-in-package-of-symbol
+ (concatenate 'string
+ (symbol-name f)
+ "-IS-"
+ (symbol-name %f)
+ "-BASE")
+ f)))
+ `(local
+ (defthm ,lemma-name
+ (implies ,zp-formals
+ ,equality)
+
+; Experimentation shows that it can be valuable first to expand without doing
+; any real simplification, and then to rewrite. We have seen assumptions get
+; generated when we allow the current-theory in "Goal".
+
+ :hints (("Goal" :expand (( ,f ,@formals)
+ (,%f ,@formals))))
+#|
+ :hints (("Goal" :expand (( ,f ,@formals)
+ (,%f ,@formals))
+ :do-not '(preprocess)
+ :in-theory (theory 'minimal-theory))
+ '(:computed-hint-replacement
+ t
+ :in-theory (current-theory :here)))
+|#
+ )))
+ acc))))
+
+(defun f-is-%f-induction-step-lemmas (f-is-%f-list formals hyp acc)
+
+; Result is in correct order if %f-is-f-list is in reverse order.
+
+ (if (endp f-is-%f-list)
+ acc
+ (f-is-%f-induction-step-lemmas
+ (cdr f-is-%f-list)
+ formals hyp
+ (cons (let* ((equality (car f-is-%f-list))
+ ( f (car (cadr equality)))
+ (%f (car (caddr equality)))
+ (lemma-name
+ (intern-in-package-of-symbol
+ (concatenate 'string
+ (symbol-name f)
+ "-IS-"
+ (symbol-name %f)
+ "-INDUCTION_STEP")
+ f))
+ (f-formals (cons f formals))
+ (%f-formals (cons %f formals)))
+ `(local
+ (defthm ,lemma-name
+ (implies ,hyp
+ (equal ,f-formals ,%f-formals))
+ :instructions
+ (:promote
+ (:dv 1)
+ :x-dumb :nx :x-dumb :top
+ (:s :normalize nil :backchain-limit 1000
+ :expand :lambdas
+ :repeat
+
+; Probably 3 is enough, because of simplify-repeat-limit. At any rate, we need
+; at least 1 in order to apply the earlier such lemmas to the body of f.
+
+ 4)))))
+ acc))))
+
+(defun f-is-%f-lemmas-mut-rec (f-is-%f-list formals acc)
+
+; Result is in correct order if f-is-%f-list is in reverse order.
+
+ (if (endp f-is-%f-list)
+ acc
+ (f-is-%f-lemmas-mut-rec
+ (cdr f-is-%f-list)
+ formals
+ (cons (let* ((equality (car f-is-%f-list))
+ ( f (car (cadr equality)))
+ (%f (car (caddr equality)))
+ (lemma-name
+ (intern-in-package-of-symbol
+ (concatenate 'string
+ (symbol-name f)
+ "-IS-"
+ (symbol-name %f))
+ f)))
+ `(defthm ,lemma-name
+ (equal (,f ,@formals) (,%f ,@formals))
+ :hints (("Goal" :do-not '(preprocess)))))
+ acc))))
+
+(defun mutual-recursion-lemmas (formals f-is-%f-list counter old-theory)
+
+; The lemmas need to be returned in reverse order.
+
+ (let* ((%%p-name (concatenate 'string
+ *%%p*
+ (coerce (explode-atom counter 10)
+ 'string)))
+ (%%p (intern %%p-name "ACL2"))
+ (%%p-aux (intern (concatenate 'string %%p-name "-AUX") "ACL2"))
+ (%%p-implies-%%p-aux
+ (intern (concatenate 'string %%p-name "-IMPLIES-" %%p-name "-AUX")
+ "ACL2"))
+ (%%p-property-lemma
+ (intern (concatenate 'string %%p-name "-PROPERTY-LEMMA") "ACL2"))
+ (%%p-equalities
+ (intern (concatenate 'string %%p-name "-EQUALITIES") "ACL2"))
+ (formal (car formals))
+ (%%p-formal (list %%p formal))
+ (%%p-property (intern (concatenate 'string %%p-name "-PROPERTY")
+ "ACL2"))
+ (%%p-base (intern (concatenate 'string
+ %%p-name
+ "-BASE")
+ "ACL2"))
+ (%%p-induction-step (intern (concatenate 'string
+ %%p-name
+ "-INDUCTION_STEP")
+ "ACL2"))
+ (not-zp-formal `(not (zp ,formal)))
+ (%%p-formal-minus-1 `(,%%p (1- ,formal)))
+ (induction-hyp `(and ,not-zp-formal ,%%p-formal-minus-1))
+ (%%p-holds (intern (concatenate 'string
+ %%p-name
+ "-HOLDS")
+ "ACL2"))
+ (%%p-implies-f-is-%f-theory
+ (intern (concatenate 'string
+ %%p-name
+ "-IMPLIES-F-IS-%F-THEORY")
+ "ACL2"))
+ (new-theory
+ (intern (concatenate 'string "THEORY-"
+ (coerce (explode-atom (1+ counter) 10)
+ 'string))
+ "ACL2")))
+
+; Again, these lemmas are returned in reverse order.
+
+ `((local
+ (deftheory ,new-theory
+ (union-theories (set-difference-theories
+ (current-theory :here)
+ (current-theory ',%%p-holds))
+ (theory ',old-theory))))
+
+ (encapsulate
+ ()
+ (local (in-theory (union-theories
+ '(,%%p-holds)
+ (theory ',%%p-implies-f-is-%f-theory))))
+ ,@(f-is-%f-lemmas-mut-rec f-is-%f-list formals nil))
+
+ (local
+ (defthm ,%%p-holds
+ ,%%p-formal
+ :hints (("Goal" :induct (%%sub1-induction ,formal)
+ :do-not '(preprocess)
+ :in-theory (union-theories '(,%%p-base
+ ,%%p-induction-step
+ (:induction %%sub1-induction))
+ (theory 'minimal-theory))))))
+
+ (local
+ (encapsulate
+ ()
+
+ (local (in-theory (disable ,%%p
+ ,%%p-base ; just an optimization
+ )))
+
+ (local (deflabel %%induction-start))
+
+ ,@(f-is-%f-induction-step-lemmas f-is-%f-list formals induction-hyp
+ nil)
+
+ (defthm ,%%p-induction-step
+ (implies ,induction-hyp
+ ,%%p-formal)
+ :instructions
+ (:promote :x-dumb (:s :normalize nil)))
+ ))
+
+ (local
+ (encapsulate
+ ()
+
+ (local
+ (in-theory (disable ,%%p-property)))
+
+ ,@(f-is-%f-base-lemmas f-is-%f-list formals `(zp ,formal) nil)
+
+ (defthm ,%%p-base
+ (implies (zp ,formal)
+ ,%%p-formal)
+ :instructions
+ (:promote :x-dumb (:s :normalize nil)))
+ ))
+
+ (local
+ (deftheory ,%%p-implies-f-is-%f-theory
+ (union-theories (set-difference-theories (current-theory :here)
+ (current-theory ',%%p))
+ (theory 'minimal-theory))))
+
+ (local
+ (encapsulate
+ ()
+
+ (local (defthm ,%%p-property-lemma
+ (implies (,%%p-aux ,@formals)
+ (,%%p-equalities))
+ :rule-classes nil
+ :instructions
+ ((:dv 1)
+ (:expand nil)
+ :top
+ (:generalize ((,%%p-equalities) eqs))
+ :s)))
+
+ (defthm ,%%p-property
+ (implies (,%%p ,formal)
+ (,%%p-equalities))
+ :instructions
+ ((:use ,%%p-property-lemma)
+ (:generalize ((,%%p-equalities) eqs))
+ :prove))))
+
+ (local
+ (defthm ,%%p-implies-%%p-aux
+ (implies (,%%p ,formal)
+ (,%%p-aux ,@formals))))
+
+ (local
+ (defun-sk ,%%p (,formal)
+ (forall ,(cdr formals) (,%%p-aux ,@formals))))
+
+ (local
+ (defun ,%%p-aux ,formals
+ (declare (xargs :normalize nil))
+ (,%%p-equalities)))
+
+ (local (defmacro ,%%p-equalities ()
+ '(%%AND-TREE ,@f-is-%f-list))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Translating Lemmas
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun my-translate-rule-class-alist (token alist seen orig-name corollary
+ pkg-alist ctx wrld state)
+ (cond
+ ((null alist)
+ (value (alist-to-keyword-alist seen nil)))
+ (t
+ (er-let*
+ ((val (case (car alist)
+ (:COROLLARY
+ (value corollary))
+ (:HINTS
+ (value nil))
+ (:INSTRUCTIONS
+ (value nil))
+ (:OTF-FLG
+ (value (cadr alist)))
+ (:TRIGGER-FNS
+ (value (reverse (old2new-list
+ (cadr alist)
+ pkg-alist
+ nil))))
+ (:TRIGGER-TERMS
+ (er-let*
+ ((terms (translate-term-lst (cadr alist)
+ t t t ctx wrld state)))
+ (value (old2new-term-lst terms pkg-alist nil))))
+ (:TYPED-TERM
+ (er-let*
+ ((term (translate (cadr alist) t t t ctx wrld state)))
+ (value (old2new-term term pkg-alist))))
+ (:BACKCHAIN-LIMIT-LST
+ (value (cadr alist)))
+ (:MATCH-FREE
+ (value (cadr alist)))
+ (:CLIQUE
+ (let ((clique (cond ((null (cadr alist)) nil)
+ ((atom (cadr alist))
+ (old2new (cadr alist) pkg-alist))
+ (t (old2new-list
+ (cadr alist)
+ pkg-alist
+ nil)))))
+ (value clique)))
+ (:TYPE-SET
+ (value (cadr alist)))
+ #|
+ (:CONTROLLER-ALIST
+ (value (cadr alist)))
+ (:LOOP-STOPPER
+ (value (cadr alist)))
+ (:PATTERN
+ (er-let*
+ ((term (translate (cadr alist) t t t ctx wrld state)))
+; known-stobjs = t (stobjs-out = t)
+ (value term)))
+ (:CONDITION
+ (er-let*
+ ((term (translate (cadr alist) t t t ctx wrld state)))
+; known-stobjs = t (stobjs-out = t)
+ (value term)))
+ (:SCHEME
+ (er-let*
+ ((term (translate (cadr alist) t t t ctx wrld state)))
+; known-stobjs = t (stobjs-out = t)
+ (value term)))
+|#
+ (otherwise
+ (er soft ctx
+ "The key ~x0 is not yet implemented for rule class ~
+ translation."
+ (car alist))))))
+ (my-translate-rule-class-alist
+ token
+ (cddr alist)
+ (if val
+ (let ((new-seen (cons (cons (car alist) val) seen)))
+ (if (eq (car alist) :COROLLARY)
+ (cons (cons :HINTS `(("Goal"
+ :use
+
+; !! This is dicey, because the original rule may have more than one
+; :type-prescription corollary. But if that is the case, we will get an error
+; when we try to prove this theorem, and we should see the error.
+
+ (,token ,orig-name))))
+ new-seen)
+ new-seen))
+ seen)
+ orig-name corollary
+ pkg-alist ctx wrld state)))))
+
+(defun my-translate-rule-class1 (name class pkg-alist ctx wrld state)
+ (let ((orig-corollary (cadr (assoc-keyword :corollary (cdr class)))))
+ (er-let*
+ ((corollary
+ (cond (orig-corollary
+ (translate orig-corollary t t t ctx wrld state))
+ (t (value nil))))
+; known-stobjs = t (stobjs-out = t)
+ (alist
+ (my-translate-rule-class-alist (car class)
+ (cdr class)
+ nil
+ name
+ (and corollary
+ (untranslate
+ (old2new-term corollary pkg-alist)
+ t wrld))
+ pkg-alist ctx wrld state)))
+ (value (cons (car class) alist)))))
+
+(defun my-translate-rule-class (name x pkg-alist ctx wrld state)
+ (cond
+ ((symbolp x) (value x))
+ (t (my-translate-rule-class1 name x pkg-alist ctx wrld state))))
+
+(defun my-translate-rule-classes1 (name classes pkg-alist ctx wrld state)
+ (cond
+ ((atom classes)
+ (value nil))
+ (t (er-let*
+ ((class (my-translate-rule-class name (car classes) pkg-alist ctx wrld
+ state))
+ (rst (my-translate-rule-classes1 name (cdr classes) pkg-alist ctx wrld
+ state)))
+ (value (cons class rst))))))
+
+(defun my-translate-rule-classes (name classes pkg-alist ctx wrld state)
+ (cond ((atom classes) (value classes))
+ (t (my-translate-rule-classes1 name classes pkg-alist ctx wrld state))))
+
+(defun old2new-term-from-lemma (lemma pkg-alist ctx wrld state)
+ (case-match lemma
+ (('defbvecp name formals width ':HINTS &)
+ (value `(defbvecp ,(old2new name pkg-alist) ,formals ,width
+ :hints (("Goal"
+ :use
+ ,(intern-in-package-of-symbol
+ (concatenate 'string
+ (if (consp width)
+ "BV-ARRP$"
+ "BVECP$")
+ (symbol-name name))
+ name))))))
+ ((defthm name formula . other)
+ (cond
+ ((member-eq defthm '(defthm defthmd))
+ (let ((new-name (old2new name pkg-alist)))
+ (if (eq name new-name)
+ (value nil)
+ (let ((rcs (cadr (assoc-keyword :rule-classes other))))
+ (er-let*
+ ((term (translate formula t t t ctx wrld state))
+ (classes (my-translate-rule-classes name rcs pkg-alist ctx wrld
+ state)))
+ (value `(,defthm ,new-name
+ ,(untranslate (old2new-term term pkg-alist) t wrld)
+ :hints (("Goal" :use ,name))
+ ,@(and classes
+ (list :rule-classes
+ classes)))))))))
+ (t (value nil))))
+ (& (value nil))))
+
+(defun old2new-term-from-lemmas (lemmas pkg-alist acc ctx wrld state)
+ (if (endp lemmas)
+ (value (reverse acc))
+ (er-let* ((new-lemma (old2new-term-from-lemma (car lemmas) pkg-alist
+ ctx wrld state)))
+ (old2new-term-from-lemmas
+ (cdr lemmas)
+ pkg-alist
+ (if new-lemma (cons new-lemma acc) acc)
+ ctx wrld state))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Top Level Routines
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun simplify-defuns (defs all-defs acc lemmas counter old-theory pkg-alist
+ ens wrld state)
+ (cond
+ ((endp defs)
+ (let ((formals (mut-rec-formals all-defs nil)))
+ (if formals
+ (let* ((new-lemmas ; ((local (deftheory new-theory ...)) ...)
+ (mutual-recursion-lemmas formals
+ (f-is-%f-list all-defs formals
+ pkg-alist nil)
+ counter
+ old-theory))
+ (new-deftheory (cadr (car new-lemmas))))
+ (mv nil
+ (cons 'mutual-recursion (reverse acc))
+ (append new-lemmas lemmas)
+ (1+ counter)
+ (cadr new-deftheory)
+ state))
+ (mv-let (erp val state)
+ (er soft 'simplify-defuns
+ "Did not find a unique singleton list of formals for the ~
+ mutual-recursion nest starting with:~%~x0."
+ (car all-defs))
+ (declare (ignore erp val))
+ (mv t nil nil counter old-theory state)))))
+ (t (mv-let
+ (erp def new-lemmas counter new-theory state)
+ (simplify-defun 'mut-rec (car defs) lemmas counter old-theory pkg-alist
+ ens wrld state)
+ (if erp
+ (mv t nil nil counter new-theory state)
+ (simplify-defuns (cdr defs) all-defs
+ (if def (cons def acc) acc)
+ new-lemmas counter
+ new-theory pkg-alist ens wrld state))))))
+
+(defun simplify-form (form lemmas counter old-theory pkg-alist ens wrld state)
+ (let ((car-form (and (consp form) (car form))))
+ (case car-form
+ ((defun defund) (simplify-defun nil form lemmas counter old-theory
+ pkg-alist ens wrld state))
+ (mutual-recursion
+ (simplify-defuns (cdr form) (cdr form) nil lemmas counter old-theory
+ pkg-alist ens wrld state))
+ (defuns (mv-let (erp val state)
+ (er soft 'simplify-form
+ "Simplify-form does not yet handle DEFUNS, but it ~
+ could.")
+ (declare (ignore erp val))
+ (mv t nil nil counter old-theory state)))
+ (otherwise (mv nil nil lemmas counter old-theory state)))))
+
+(defun simplify-forms (forms defs lemmas counter old-theory pkg-alist ens wrld
+ state)
+ (cond ((endp forms)
+ (pprogn
+ (newline *standard-co* state)
+ (mv nil
+ (reverse defs)
+ (case-match lemmas
+ ((('local ('deftheory . &))
+ . &)
+ (cdr lemmas))
+ (& lemmas))
+ state)))
+ (t (mv-let (erp simp-form lemmas new-counter new-theory state)
+ (simplify-form (car forms) lemmas counter old-theory
+ pkg-alist ens wrld state)
+ (cond
+ (erp (mv t nil nil state))
+ (simp-form (simplify-forms
+ (cdr forms) (cons simp-form defs) lemmas
+ new-counter new-theory pkg-alist ens wrld
+ state))
+ (t (simplify-forms (cdr forms) defs lemmas new-counter
+ new-theory pkg-alist ens wrld
+ state)))))))
+
+(defun final-deftheory-1 (lemmas acc)
+ (cond
+ ((endp lemmas)
+ acc)
+ ((eq (caar lemmas) 'defthm)
+ (final-deftheory-1 (cdr lemmas) (cons (cadar lemmas) acc)))
+ ((eq (caar lemmas) 'encapsulate)
+ (final-deftheory-1 (cdr lemmas)
+ (final-deftheory-1 (cddar lemmas) acc)))
+ (t
+ (final-deftheory-1 (cdr lemmas) acc))))
+
+(defun final-deftheory (lemmas)
+ `(deftheory %-removal-theory
+ (union-theories
+ ',(final-deftheory-1 lemmas nil)
+ (theory 'minimal-theory))))
+
+(defun initial-equality-events (in-defs out-defs)
+
+; Returns an initial list of events, in forward order, for the f-is-%f lemmas.
+; Matt K. mod for v2-9.1: Remove support for pre-v2-7.
+
+ (declare (ignore out-defs))
+ (list (car in-defs) ; first out-def is in-package
+ '(local
+ (defun %%sub1-induction (n)
+ (if (zp n)
+ n
+ (%%sub1-induction (1- n)))))
+ '(local
+ (defun %%and-tree-fn (args len)
+ (declare (xargs :mode :program))
+ (if (< len 20)
+ (cons 'and args)
+ (let* ((len2 (floor len 2)))
+ (list 'and
+ (%%and-tree-fn (take len2 args) len2)
+ (%%and-tree-fn (nthcdr len2 args) (- len len2)))))))
+ '(local
+ (defmacro %%and-tree (&rest args)
+ (%%and-tree-fn args (length args))))))
+
+(include-book "file-io-pkgs")
+
+(defun write-lemma-file (infile outfile initial-events final-events pkg-alist ctx state)
+ (er-let*
+ ((in-lemmas (read-list infile ctx state))
+ (out-lemmas (old2new-term-from-lemmas in-lemmas pkg-alist
+ nil ctx (w state) state)))
+ (write-list-using-pkgs (cons (car in-lemmas) ; in-package form
+ (append initial-events out-lemmas final-events))
+ outfile ctx state)))
+
+(defun write-lemma-files (thm-file-pairs erp pkg-alist ctx state)
+ (if (endp thm-file-pairs)
+ (mv erp nil state)
+ (mv-let (erp val state)
+ (let ((pair (car thm-file-pairs)))
+ (write-lemma-file (nth 0 pair) (nth 1 pair) (nth 2 pair) (nth 3 pair)
+ pkg-alist ctx state))
+ (declare (ignore val))
+ (write-lemma-files (cdr thm-file-pairs) erp pkg-alist ctx state))))
+
+(defun transform-defuns-fn (in-defs-file ; %f definitions
+ out-defs-file ; f definitions
+ equalities-file ; thms (equal (%f ..) (f ..))
+ extra-initial-events-for-defs
+ extra-final-events-for-defs
+ extra-initial-events-for-lemmas
+ extra-final-events-for-lemmas
+ thm-file-pairs ; (.. ( infile ; thms (.. %f ..)
+ ; outfile ; thms (.. f ..)
+ ; initial-events
+ ; final-events
+ ; ) ..
+ ; )
+ pkg-alist
+ state)
+ (let ((ctx 'transform-defuns)
+ (first-lemma '(local
+ (deftheory theory-0 (theory 'minimal-theory)))))
+ (mv-let
+ (erp in-defs state)
+ (read-list in-defs-file ctx state)
+ (if erp
+ (silent-error state)
+ (mv-let
+ (erp out-defs lemmas state)
+ (if (or out-defs-file equalities-file)
+ (simplify-forms in-defs nil (list first-lemma) 0 'theory-0
+ pkg-alist (ens state) (w state) state)
+ (mv nil nil nil state))
+ (if erp
+ (silent-error state)
+ (er-progn
+ (if out-defs-file
+ (write-list-using-pkgs
+ (cons (car in-defs) ; in-package form
+ (append extra-initial-events-for-defs
+ out-defs
+ extra-final-events-for-defs))
+ out-defs-file ctx state)
+ (value nil))
+ (if equalities-file
+ (write-list-using-pkgs
+ (append
+ (initial-equality-events in-defs out-defs)
+ extra-initial-events-for-lemmas
+ (reverse (cons (final-deftheory lemmas)
+ lemmas))
+ extra-final-events-for-lemmas)
+ equalities-file ctx state)
+ (value nil))
+ (write-lemma-files thm-file-pairs nil pkg-alist ctx state))))))))
+
+(defmacro transform-defuns (in-defs-file pkg-alist
+ &key out-defs equalities
+ defs-pre defs-post eq-pre eq-post thm-file-pairs)
+ `(transform-defuns-fn ,in-defs-file ,out-defs ,equalities
+ ,defs-pre ,defs-post ,eq-pre ,eq-post ,thm-file-pairs
+ ,pkg-alist state))
diff --git a/books/workshops/2003/kaufmann/support/rtl/tool/wrapper.lisp b/books/workshops/2003/kaufmann/support/rtl/tool/wrapper.lisp
new file mode 100644
index 0000000..e8075b8
--- /dev/null
+++ b/books/workshops/2003/kaufmann/support/rtl/tool/wrapper.lisp
@@ -0,0 +1,68 @@
+(in-package "ACL2")
+
+; This macro is developed to make it easy to call transform-defuns in the
+; Makefile in support/rtl/, after ld-ing pkgs.lisp there.
+
+(defmacro simplify-model ()
+ (let* ((rel4 "rtl/rel4/")
+ (rel4-lib (concatenate 'string rel4 "lib/"))
+ (rel4-lib-top (concatenate 'string rel4-lib "top"))
+ (rel4-support (concatenate 'string rel4 "support/"))
+ (bvecp-helpers (concatenate 'string rel4-support "bvecp-helpers"))
+ (simplify-model-helpers
+ (concatenate 'string rel4-lib "simplify-model-helpers")))
+ `(state-global-let*
+ ((print-case :downcase set-print-case))
+ (ld
+ '((INCLUDE-BOOK
+ "tool/simplify-defuns")
+ (INCLUDE-BOOK
+ "bvecp-raw")
+ (INCLUDE-BOOK
+ ,rel4-lib-top :dir :system)
+ (INCLUDE-BOOK
+ ,simplify-model-helpers :dir :system)
+ (DISABLE-FORCING)
+ (TRANSFORM-DEFUNS
+ "model-raw.lisp" *OLD2NEW-PKG-ALIST*
+ :out-defs "model-defs.lisp"
+ :defs-pre `((include-book
+ "ordinals/e0-ordinal" :dir :system)
+ (set-well-founded-relation e0-ord-<)
+ (SET-INHIBIT-WARNINGS "THEORY" "DISABLE" "NON-REC")
+ (INCLUDE-BOOK
+ "common")
+ (INCLUDE-BOOK
+ "model-macros")
+ (SET-IRRELEVANT-FORMALS-OK T)
+ (SET-IGNORE-OK T)
+ (DEFLABEL MODEL-START-OF-DEFS)
+ (SET-BOGUS-MUTUAL-RECURSION-OK T))
+ :equalities "model-eq.lisp"
+ :eq-pre '((LOCAL (INCLUDE-BOOK
+ "bvecp-raw"))
+ (LOCAL (INCLUDE-BOOK
+ ,rel4-lib-top :dir :system))
+ (LOCAL (INCLUDE-BOOK
+ ,simplify-model-helpers :dir :system))
+ (INCLUDE-BOOK
+ "model-raw")
+ (INCLUDE-BOOK
+ "model")
+
+; We have seen cases where things blow up at %%P0-PROPERTY-LEMMA because of an
+; attempt to untranslate during preprocess-clause with sigs-btree set.
+
+ (LOCAL (TABLE USER-DEFINED-FUNCTIONS-TABLE NIL NIL :clear))
+ (LOCAL (DISABLE-FORCING)))
+ :thm-file-pairs
+ '(("bvecp-raw.lisp"
+ "bvecp.lisp"
+ ((INCLUDE-BOOK
+ "model")
+ (LOCAL (INCLUDE-BOOK
+ "model-eq"))
+ (LOCAL (INCLUDE-BOOK
+ "bvecp-raw"))
+ (LOCAL (INCLUDE-BOOK
+ ,bvecp-helpers :dir :system)))))))))))
diff --git a/books/workshops/2003/manolios-vroon/ordinals.pdf.gz b/books/workshops/2003/manolios-vroon/ordinals.pdf.gz
new file mode 100644
index 0000000..b79b95b
--- /dev/null
+++ b/books/workshops/2003/manolios-vroon/ordinals.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/manolios-vroon/ordinals.ps.gz b/books/workshops/2003/manolios-vroon/ordinals.ps.gz
new file mode 100644
index 0000000..659c15a
--- /dev/null
+++ b/books/workshops/2003/manolios-vroon/ordinals.ps.gz
Binary files differ
diff --git a/books/workshops/2003/matlin-mccune/final.pdf.gz b/books/workshops/2003/matlin-mccune/final.pdf.gz
new file mode 100644
index 0000000..2a81650
--- /dev/null
+++ b/books/workshops/2003/matlin-mccune/final.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/matlin-mccune/final.ps.gz b/books/workshops/2003/matlin-mccune/final.ps.gz
new file mode 100644
index 0000000..61f678a
--- /dev/null
+++ b/books/workshops/2003/matlin-mccune/final.ps.gz
Binary files differ
diff --git a/books/workshops/2003/matlin-mccune/matlin.ppt.gz b/books/workshops/2003/matlin-mccune/matlin.ppt.gz
new file mode 100644
index 0000000..28d8ab1
--- /dev/null
+++ b/books/workshops/2003/matlin-mccune/matlin.ppt.gz
Binary files differ
diff --git a/books/workshops/2003/matlin-mccune/slides.pdf.gz b/books/workshops/2003/matlin-mccune/slides.pdf.gz
new file mode 100644
index 0000000..3465e9d
--- /dev/null
+++ b/books/workshops/2003/matlin-mccune/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/matlin-mccune/slides.ps.gz b/books/workshops/2003/matlin-mccune/slides.ps.gz
new file mode 100644
index 0000000..c77d885
--- /dev/null
+++ b/books/workshops/2003/matlin-mccune/slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/matlin-mccune/support/simp.lisp b/books/workshops/2003/matlin-mccune/support/simp.lisp
new file mode 100644
index 0000000..60bdbb1
--- /dev/null
+++ b/books/workshops/2003/matlin-mccune/support/simp.lisp
@@ -0,0 +1,908 @@
+;;
+;; Material in this ACL2 book is described in a short paper
+;;
+;; "Encapsulation for Practical Simplification Procedures"
+;; by Olga Shumsky Matlin and William McCune
+;;
+;; submitted to the Fourth International Workshop on the
+;; ACL2 Theorem Prover and Its Applications (ACL2-2003)
+;;
+;; For more information contact
+;; Olga Shumsky Matlin (matlin@mcs.anl.gov)
+;; William McCune (mccune@mcs.anl.gov)
+;;
+;;
+;; Direct Incorporation Algorithm:
+;;
+;; While(Q)
+;; C = dequeue(Q)
+;; C = rewrite(C,S)
+;; if (C != True)
+;; for each D in S rewritable by C
+;; remove D from S
+;; add to Q D simplified by C
+;; S = S + C
+;;
+;; Limbo Incorporation Algorithm:
+;;
+;; preprocess(C, S, Limbo):
+;; C = rewrite(C, S+Limbo)
+;; if (C != TRUE)
+;; return Limbo
+;; else
+;; return Limbo+C
+;;
+;; Loop1: Initial Limbo Computation
+;; while(Q)
+;; C = dequeue(Q)
+;; Limbo = preprocess(C, S, Limbo);
+;;
+;; Loop2: Limbo Processing
+;; while(Limbo)
+;; C = dequeue(Limbo)
+;; for each D in S rewritable by C
+;; S = remove D from S
+;; Limbo = preprocess(D, S, Limbo+C)
+;; S = S + C
+;;
+
+(in-package "ACL2")
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+(encapsulate
+
+ ;;----------------- Signatures (constrained functions)
+
+ (
+ (simplify (x y) t) ; simplify x by element of list y
+
+ (true-symbolp (x) t) ; expression x is a true-symbolp
+
+ (ceval (x i) t) ; evaluate clause x in interpretation i
+
+ (scount (x) t) ; size evaluator for measure functions
+ )
+
+ ;;------------------- Witnesses
+
+ (local (defun simplify (x y)
+ (declare (xargs :guard t)
+ (ignore y))
+ x))
+
+ (local (defun true-symbolp (x)
+ (declare (xargs :guard t)
+ (ignore x))
+ t))
+
+ (local (defun ceval (x i)
+ (declare (xargs :guard t)
+ (ignore x i))
+ t))
+
+ (local (defun scount (x)
+ (declare (xargs :guard t))
+ (acl2-count x)))
+
+ ;;------------------- Properties and Exported Functions
+
+ (defthm scount-natural
+ (and (integerp (scount x))
+ (<= 0 (scount x)))
+ :rule-classes :type-prescription)
+
+ (defthm scount-simplify
+ (or (equal (simplify x y) x)
+ (< (scount (simplify x y))
+ (scount x)))
+ :rule-classes nil)
+
+ (defthm simplify-idempotent
+ (equal (simplify (simplify x y) y)
+ (simplify x y)))
+
+ (defthm simplify-subset
+ (implies (and (not (equal (simplify a x) a))
+ (subsetp-equal x y))
+ (not (equal (simplify a y) a)))
+ :rule-classes ((:rewrite :match-free :all)))
+
+ (defthm simplify-append
+ (implies (and (equal (simplify a x) a)
+ (equal (simplify a y) a))
+ (equal (simplify a (append x y)) a)))
+
+ (defthm ceval-boolean
+ (or (equal (ceval x i) t)
+ (equal (ceval x i) nil))
+ :rule-classes :type-prescription)
+
+ (defthm true-symbolp-ceval
+ (implies (true-symbolp x)
+ (ceval x i)))
+
+ (defun ceval-list (x i)
+ (declare (xargs :guard (true-listp x)
+; Added by Matt Kaufmann after v3-6-1 to because of restriction on guard
+; verification for functions depending on signature functions:
+ :verify-guards nil))
+ (if (endp x)
+ t
+ (and (ceval (car x) i) (ceval-list (cdr x) i))))
+
+; The following was added by Matt Kaufmann after ACL2 Version 3.4 because of
+; a soundness bug fix; see ``subversive'' in :doc note-3-5.
+ (defthm ceval-list-type
+ (booleanp (ceval-list x i))
+ :rule-classes :type-prescription)
+
+ (defthm simplify-sound
+ (implies (ceval-list y i)
+ (equal (ceval (simplify x y) i)
+ (ceval x i))))
+
+ ) ;; end of encapsulate
+
+; Added by Matt Kaufmann after v3-6-1 (see comment for (defun ceval-list ...)
+; above):
+(verify-guards ceval-list)
+
+(defun rewritable (x y)
+ (declare (xargs :guard t))
+ (not (equal (simplify x y) x)))
+
+(defthm scount-simplify-rewritable
+ (implies (rewritable x y)
+ (< (scount (simplify x y)) (scount x)))
+ :hints (("goal" :use scount-simplify)))
+
+(defthm simplified-not-rewritable
+ (not (rewritable (simplify x y) y)))
+
+(defthm simplify-subset-restated
+ (implies (and (rewritable a x)
+ (subsetp-equal x y))
+ (rewritable a y))
+ :rule-classes ((:rewrite :match-free :all)))
+
+(defthm simplify-append-restated
+ (implies (and (not (rewritable a x))
+ (not (rewritable a y)))
+ (not (rewritable a (append x y)))))
+
+(in-theory (disable rewritable))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Direct Formalization
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; produces a list of Ds in S, such that D is rewritable by X
+(defun extract-rewritables (x s)
+ (declare (xargs :guard (true-listp s)))
+ (cond ((endp s) nil)
+ ((rewritable (car s) (list x))
+ (cons (car s) (extract-rewritables x (cdr s))))
+ (t (extract-rewritables x (cdr s)))))
+
+;; produces a list of Ds in S, such that D is rewritable by X
+;; D is simplified by x before being placed on the list
+(defun extract-n-simplify-rewritables (x s)
+ (declare (xargs :guard (true-listp s)))
+ (cond ((endp s) nil)
+ ((rewritable (car s) (list x))
+ (cons (simplify (car s) (list x))
+ (extract-n-simplify-rewritables x (cdr s))))
+ (t (extract-n-simplify-rewritables x (cdr s)))))
+
+;; removes from S elements rewritable by X
+(defun remove-rewritables (x s)
+ (declare (xargs :guard (true-listp s)))
+ (cond ((endp s) nil)
+ ((rewritable (car s) (list x))
+ (remove-rewritables x (cdr s)))
+ (t (cons (car s) (remove-rewritables x (cdr s))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; For the proof of termination of direct-incorporation:
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun lcount (x)
+ (declare (xargs :guard (true-listp x)))
+ (if (endp x)
+ 0
+ (+ 1 (scount (car x)) (lcount (cdr x)))))
+
+(defthm extract-consp
+ (implies (not (consp (extract-rewritables x s)))
+ (not (consp (extract-n-simplify-rewritables x s)))))
+
+(local
+ (include-book "../../../../arithmetic/top-with-meta"))
+
+(defthm small-sum-<-large-sum
+ (implies (and (< x y)
+ (< u v))
+ (< (+ u x) (+ y v))))
+
+(defthm lcount-extract
+ (implies (consp (extract-rewritables x s))
+ (< (lcount (extract-n-simplify-rewritables x s))
+ (lcount (extract-rewritables x s)))))
+
+(defthm lcount-remove
+ (implies (true-listp s)
+ (equal (lcount (remove-rewritables x s))
+ (- (lcount s)
+ (lcount (extract-rewritables x s))))))
+
+(defthm lcount-append
+ (implies (true-listp x)
+ (equal (lcount (append x y))
+ (+ (lcount x) (lcount y)))))
+
+(defthm inequality-helper
+ (implies (and (<= x y)
+ (< u v))
+ (< (+ x u (- v)) y)))
+
+(defthm less-n-greater-equal
+ (implies (and (<= (scount q1) (scount x))
+ (<= (scount x) (scount q1)))
+ (equal (scount q1) (scount x)))
+ :rule-classes ((:rewrite :match-free :all)))
+
+(defthm scount-simplify-combined
+ (<= (scount (simplify x y)) (scount x))
+ :hints (("goal" :use scount-simplify)))
+
+;;;;;; end of termination proof preparations
+(defun direct-incorporation (q s)
+ (declare
+ (xargs
+ :guard (and (true-listp q) (true-listp s))
+ :measure (cons (+ 1 (lcount q) (lcount s)) (+ 1 (lcount q)))
+ :hints (("subgoal 2"
+ :cases
+ ((consp (extract-rewritables (simplify (car q) s) s))
+ (not (consp (extract-rewritables (simplify (car q) s) s))))))))
+ (cond ((or (not (true-listp q)) (not (true-listp s))) 'INPUT-ERROR)
+ ((endp q) s)
+ ((true-symbolp (simplify (car q) s)) (direct-incorporation (cdr q) s))
+ (t (direct-incorporation
+ (append (cdr q)
+ (extract-n-simplify-rewritables (simplify (car q) s) s))
+ (cons (simplify (car q) s)
+ (remove-rewritables (simplify (car q) s) s))))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Proving Correctness of Naive Formalization:
+;; the simple processing function produces a clean database
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; x neither rewrites, nor is rewritable by, anything in s
+(defun mutually-irreducible-el-list (x s)
+ (declare (xargs :guard (true-listp s)))
+ (cond ((endp s) t)
+ ((or (rewritable x (list (car s)))
+ (rewritable (car s) (list x))) nil)
+ (t (mutually-irreducible-el-list x (cdr s)))))
+
+(defun irreducible-list (s)
+ (declare (xargs :guard (true-listp s)))
+ (cond ((endp s) t)
+ ((mutually-irreducible-el-list (car s) (cdr s))
+ (irreducible-list (cdr s)))
+ (t nil)))
+
+(defthm remove-rewritables-mutually-irreducible-el-list
+ (implies (mutually-irreducible-el-list x s)
+ (mutually-irreducible-el-list x (remove-rewritables y s))))
+
+(defthm remove-rewritables-irreducible
+ (implies (irreducible-list s)
+ (irreducible-list (remove-rewritables x s))))
+
+(defthm subsetp-append-1
+ (subsetp-equal s (append x s)))
+
+(defthm subsetp-cons
+ (subsetp-equal s (cons x s))
+ :hints (("goal"
+ :do-not-induct t
+ :in-theory (disable subsetp-append-1)
+ :use ((:instance subsetp-append-1 (x (list x)))))))
+
+(defthm forward-simplify-irreducible
+ (implies (and (irreducible-list s)
+ (not (rewritable x s)))
+ (mutually-irreducible-el-list x (remove-rewritables x s))))
+
+;; top level correctness proof for direct-incorporation
+(defthm direct-incorporation-is-irreducible
+ (implies (irreducible-list s)
+ (irreducible-list (direct-incorporation q s))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Proving Soundness of Naive Formalization
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defthm ceval-append-1
+ (implies (not (ceval-list x i))
+ (not (ceval-list (append x y) i))))
+
+(defthm ceval-append-2
+ (implies (not (ceval-list y i))
+ (not (ceval-list (append x y) i))))
+
+(defthm ceval-append-3
+ (implies (and (ceval-list x i)
+ (ceval-list y i))
+ (ceval-list (append x y) i)))
+
+(defthm ceval-remove-rewritables
+ (implies (ceval-list s i)
+ (ceval-list (remove-rewritables x s) i)))
+
+(defthm ceval-extract-n-simp-1
+ (implies (and (ceval x i)
+ (ceval-list s i))
+ (ceval-list (extract-n-simplify-rewritables x s) i)))
+
+(defthm ceval-extract-n-simp-2
+ (implies (and (ceval-list (remove-rewritables x s) i)
+ (ceval x i)
+ (not (ceval-list s i)))
+ (not (ceval-list (extract-n-simplify-rewritables x s) i))))
+
+(defthm direct-incorporation-sound-iff
+ (implies (and (true-listp q)
+ (true-listp s))
+ (iff (and (ceval-list q i) (ceval-list s i))
+ (ceval-list (direct-incorporation q s) i)))
+ :hints (("Subgoal *1/2"
+ :in-theory (disable true-symbolp-ceval)
+ :use ((:instance true-symbolp-ceval
+ (x (simplify (car q) s)))))
+ ("subgoal *1/3.6"
+ :use ((:instance ceval-extract-n-simp-2
+ (x (simplify (car q) s))))))
+ :rule-classes nil)
+
+;; top soundness lemma
+(defthm direct-incorporation-is-sound
+ (implies (and (true-listp q)
+ (true-listp s))
+ (equal (ceval-list (direct-incorporation q s) i)
+ (and (ceval-list q i) (ceval-list s i))))
+ :hints (("goal" :use direct-incorporation-sound-iff)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Limbo-Based Formalization
+;;
+;; processing with forward and backward
+;; demodulation/subsumption in two separate loops,
+;; using a limbo list
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun preprocess (x s l)
+ (declare (xargs :guard (and (true-listp s)
+ (true-listp l))))
+ (if (true-symbolp (simplify x (append s l)))
+ l
+ (append l (list (simplify x (append s l))))))
+
+(defun initial-limbo (q s l)
+ (declare (xargs :guard (and (true-listp q)
+ (true-listp s)
+ (true-listp l))))
+ (if (endp q)
+ l
+ (initial-limbo (cdr q) s (preprocess (car q) s l))))
+
+(defthm limbo-true-list
+ (implies (true-listp l)
+ (true-listp (initial-limbo q s l))))
+
+(defun preprocess-list (d s r)
+ (declare (xargs :guard (and (true-listp d)
+ (true-listp s)
+ (true-listp r))))
+ (if (endp d)
+ r
+ (preprocess-list (cdr d) s (preprocess (car d)
+ (append s (cdr d))
+ r))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; For the proof of termination of limbo-process:
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; auxiliary function; this function is easier to reason about
+;; than preprocess-list, so it is used in the correctness proof as well
+(defun special-ppd (d s r)
+ (declare (xargs :guard (and (true-listp d)
+ (true-listp s)
+ (true-listp r))))
+ (if (endp d)
+ nil
+ (let ((e (simplify (car d) (append s (cdr d) r))))
+ (if (true-symbolp e)
+ (special-ppd (cdr d) s r)
+ (cons e (special-ppd (cdr d) s (append r (list e))))))))
+
+;; auxiliary function: every element of x is rewritable by something in y
+(defun rewritable-list-by-list (x y)
+ (declare (xargs :guard (and (true-listp x)
+ (true-listp y))))
+ (cond ((endp x) t)
+ ((rewritable (car x) y)
+ (rewritable-list-by-list (cdr x) y))
+ (t nil)))
+
+(defthm subsetp-append-2
+ (subsetp-equal s (append s r)))
+
+(defthm subsetp-append-3
+ (subsetp-equal s (append s c r))
+ :hints (("goal"
+ :use ((:instance subsetp-append-2 (r (append c r)))))))
+
+(defthm scount-rewritable-append
+ (implies (rewritable d s)
+ (< (scount (simplify d (append s r)))
+ (scount d))))
+
+(defthm lcount-special-ppd-consp
+ (implies (and (consp d)
+ (true-listp d)
+ (rewritable-list-by-list d s))
+ (< (lcount (special-ppd d s r))
+ (lcount d))))
+
+(defthm append-nil
+ (implies (true-listp r)
+ (equal (append r nil) r)))
+
+(defthm append-multiple
+ (equal (append (append d s) r)
+ (append d s r)))
+
+(defthm preprocess-list-special-ppd
+ (implies (true-listp r)
+ (equal (preprocess-list d s r)
+ (append r (special-ppd d s r)))))
+
+;; auxiliary function: all elements of l are writable by x
+(defun all-rewritable-list (l x)
+ (declare (xargs :guard (true-listp l)))
+ (cond ((endp l) t)
+ ((rewritable (car l) (list x)) (all-rewritable-list (cdr l) x))
+ (t nil)))
+
+(defthm extract-all-rewritable
+ (all-rewritable-list (extract-rewritables x s) x))
+
+(defthm all-rewritable-append ;; 3 inductions, hint required
+ (implies (all-rewritable-list d x)
+ (rewritable-list-by-list d (append s (cons x l))))
+ :hints (("goal" :do-not fertilize)))
+
+;;;;;; end of termination proof preparations
+
+(defun process-limbo (l s)
+ (declare
+ (xargs
+ :guard (and (true-listp l) (true-listp s))
+ :measure (cons (+ 1 (lcount l) (lcount s)) (+ 1 (lcount l)))
+ :hints (("subgoal 1"
+ :cases ((consp (extract-rewritables (car l) s))
+ (not (consp (extract-rewritables (car l) s))))))))
+ (cond ((or (not (true-listp l)) (not (true-listp s))) 'INPUT-ERROR)
+ ((endp l) s)
+ (t (process-limbo
+ (append
+ (cdr l)
+ (preprocess-list (extract-rewritables (car l) s)
+ (append (remove-rewritables (car l) s) l)
+ nil))
+ (cons (car l)
+ (remove-rewritables (car l) s))))))
+
+;; two-loop processing function
+(defun limbo-incorporation (q s)
+ (declare (xargs :guard (and (true-listp q) (true-listp s))))
+ (process-limbo (initial-limbo q s nil) s))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Proving Correctness:
+;; the split processing function produces a clean
+;; (irreducible) database
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; no element of l is rewritable by an element in s
+(defun irreducible-list-by-list (l s)
+ (declare (xargs :guard (and (true-listp l) (true-listp s))))
+ (cond ((endp l) t)
+ ((rewritable (car l) s) nil)
+ (t (irreducible-list-by-list (cdr l) s))))
+
+;; x rewrites nothing in l
+(defun irreducible-list-by-el (x l)
+ (declare (xargs :guard (true-listp l)))
+ (cond ((endp l) t)
+ ((rewritable (car l) (list x)) nil)
+ (t (irreducible-list-by-el x (cdr l)))))
+
+;; forall A,B in L, pos[A]<pos[B] -> A does not rewrite B
+(defun irreducible-tail-by-head (l)
+ (declare (xargs :guard (true-listp l)))
+ (cond ((endp l) t)
+ ((irreducible-list-by-el (car l) (cdr l))
+ (irreducible-tail-by-head (cdr l)))
+ (t nil)))
+
+;;;;;;;;;;
+(defthm irreducible-list-by-list-append-el
+ (implies (and (irreducible-list-by-list l s)
+ (not (rewritable x s)))
+ (irreducible-list-by-list (append l (list x)) s)))
+
+(defthm rewritable-element-by-list-append-left
+ (implies (rewritable x s)
+ (rewritable x (append s l))))
+
+(defthm simplify-not-rewritable-append-left
+ (not (rewritable (simplify x (append s l)) s))
+ :hints (("Goal" :use ((:instance rewritable-element-by-list-append-left
+ (x (simplify x (append s l))))))))
+
+;; mini-goal
+(defthm limbo-irreducible-list-by-list
+ (implies (irreducible-list-by-list l s)
+ (irreducible-list-by-list (initial-limbo q s l) s)))
+
+;;;;;;;;;;
+
+(defthm append-irreducible-list-by-el
+ (implies (and (irreducible-list-by-el x l)
+ (not (rewritable y (list x))))
+ (irreducible-list-by-el x (append l (list y)))))
+
+(defthm not-rewritable-cons
+ (implies (not (rewritable x (cons l1 l2)))
+ (not (rewritable x (list l1))))
+ :rule-classes ((:rewrite :match-free :all)))
+
+(defthm append-irreducible-tail-by-head
+ (implies (and (not (rewritable x l))
+ (irreducible-tail-by-head l))
+ (irreducible-tail-by-head (append l (list x)))))
+
+(defthm rewritable-element-by-list-append-right
+ (implies (rewritable x l)
+ (rewritable x (append s l))))
+
+(defthm simplify-not-rewritable-append-right
+ (not (rewritable (simplify x (append s l)) l))
+ :hints (("Goal" :use ((:instance rewritable-element-by-list-append-right
+ (x (simplify x (append s l))))))))
+
+;; mini-goal
+(defthm limbo-irreducible-tail-by-head
+ (implies (irreducible-tail-by-head l)
+ (irreducible-tail-by-head (initial-limbo q s l))))
+
+;;;;;;;;;;
+(defthm remove-rewritables-subset
+ (subsetp-equal (remove-rewritables x s) s))
+
+(defthm irreducible-cons-remove-rewritables
+ (implies (and (irreducible-list-by-list l s)
+ (irreducible-list-by-el x l))
+ (irreducible-list-by-list l (cons x (remove-rewritables x s))))
+ :hints (("subgoal *1/2"
+ :use ((:instance simplify-append-restated
+ (a (car l))
+ (x (list x))
+ (y (remove-rewritables x s)))))))
+
+(defthm irreducible-cons
+ (implies (and (irreducible-list-by-list l s)
+ (irreducible-list-by-el x l))
+ (irreducible-list-by-list l (cons x s)))
+ :hints (("Subgoal *1/2"
+ :use ((:instance simplify-append-restated
+ (a (car l))
+ (x (list x))
+ (y s))))))
+
+(defthm irreducible-list-by-list-append-2
+ (implies (and (irreducible-list-by-list l1 s)
+ (irreducible-list-by-list l2 s))
+ (irreducible-list-by-list (append l1 l2) s)))
+
+(defthm irreducible-list-by-el-append-cons
+ (implies (and (not (rewritable x1 (list l1)))
+ (irreducible-list-by-el l1 (append l2 x2)))
+ (irreducible-list-by-el l1 (append l2 (cons x1 x2)))))
+
+(defthm irreducible-tail-by-head-append-cons
+ (implies (and (not (rewritable x1 l))
+ (irreducible-tail-by-head (append l x2))
+ (irreducible-list-by-el x1 x2))
+ (irreducible-tail-by-head (append l (cons x1 x2)))))
+
+(defthm irreducible-tail-by-head-append
+ (implies (and (true-listp l)
+ (true-listp x)
+ (irreducible-tail-by-head l)
+ (irreducible-tail-by-head x)
+ (irreducible-list-by-list x l))
+ (irreducible-tail-by-head (append l x))))
+
+;;;;;;;;;;
+
+(defthm member-append-all ;; several inductions
+ (member-equal x (append s (cons x (append l d2 r)))))
+
+(defthm rewritable-by-member
+ (implies (and (not (rewritable x l))
+ (member-equal y l))
+ (not (rewritable x (list y))))
+ :rule-classes nil)
+
+(defthm rewritable-simplify-append-all
+ (not (rewritable (simplify y (append s (cons x (append l d2 r)))) (list x)))
+ :hints (("goal"
+ :use ((:instance
+ rewritable-by-member
+ (x (simplify y (append s (cons x (append l d2 r)))))
+ (y x)
+ (l (append s (cons x (append l d2 r)))))))))
+
+;; mini-goal
+(defthm special-irreducible-x
+ (irreducible-list-by-el x (special-ppd d (append s (cons x l)) r)))
+
+;;;;;;;;;;
+
+;; mini-goal
+(defthm special-irreducible-s
+ (irreducible-list-by-list (special-ppd d (append s (cons x l)) r) s))
+
+;;;;;;;;;;
+
+(defthm subsetp-append-4
+ (subsetp-equal l (append l d2 r)))
+
+(defthm subsetp-cons-2
+ (implies (subsetp-equal l z)
+ (subsetp-equal l (cons x z))))
+
+(defthm subsetp-append-5
+ (implies (subsetp-equal l z)
+ (subsetp-equal l (append x z))))
+
+(defthm rewritable-element-by-list-append-all
+ (implies (rewritable y l)
+ (rewritable y (append s (cons x (append l d2 r))))))
+
+(defthm simplify-not-rewritable-append-all
+ (not (rewritable
+ (simplify y (append s (cons x (append l d2 r))))
+ l))
+ :hints (("goal"
+ :use ((:instance
+ rewritable-element-by-list-append-all
+ (y (simplify y (append s (cons x (append l d2 r))))))))))
+
+;; mini-goal
+(defthm special-irreducible-l
+ (irreducible-list-by-list (special-ppd d (append s (cons x l)) r) l))
+
+;;;;;;;;;;
+
+(defthm append-subset-7
+ (subsetp-equal r (append l d2 r)))
+
+(defthm rewritable-element-by-list-append-last
+ (implies
+ (rewritable y r)
+ (rewritable y (append s (cons x (append l d2 r))))))
+
+(defthm simplify-not-rewritable-append-last
+ (not (rewritable
+ (simplify y (append s (cons x (append l d2 r)))) r))
+ :hints (("goal"
+ :in-theory (disable rewritable-element-by-list-append-last)
+ :use ((:instance
+ rewritable-element-by-list-append-last
+ (y (simplify y (append s (cons x (append l d2 r))))))))))
+
+(defthm irreducible-list-by-list-append-1
+ (implies (not (irreducible-list-by-list x l))
+ (not (irreducible-list-by-list x (append l z)))))
+
+;; mini-mini-goal
+(defthm special-irreducible-r
+ (irreducible-list-by-list (special-ppd d (append s (cons x l)) r) r)
+ :hints (("goal" :do-not generalize)))
+
+(defthm irreducible-member
+ (implies (and (not (irreducible-list-by-el x l))
+ (member-equal x s))
+ (not (irreducible-list-by-list l s)))
+ :rule-classes nil)
+
+(defthm member-append-el
+ (member-equal x (append r (list x))))
+
+(defthm special-head-tail-helper
+ (implies
+ (irreducible-tail-by-head
+ (special-ppd d (append s (cons x l)) (append r (list y))))
+ (irreducible-list-by-el
+ y (special-ppd d (append s (cons x l)) (append r (list y)))))
+ :hints (("goal"
+ :do-not-induct t
+ :use ((:instance
+ irreducible-member
+ (x y)
+ (l (special-ppd d (append s (cons x l))
+ (append r (list y))))
+ (s (append r (list y))))))))
+
+;; mini-goal
+(defthm special-ppd-irreducible-tail-by-head
+ (irreducible-tail-by-head (special-ppd d (append s (cons x l)) r)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defthm process-limbo-irreducible ;; main theorem of subsection
+ (implies (and (irreducible-list s)
+ (irreducible-tail-by-head l)
+ (irreducible-list-by-list l s))
+ (irreducible-list (process-limbo l s)))
+ :hints (("goal" :induct (process-limbo l s))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; top level correctness proof for limbo-incorporation
+(defthm limbo-incorporation-is-irreducible
+ (implies (irreducible-list s)
+ (irreducible-list (limbo-incorporation q s)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable process-limbo-irreducible)
+ :use ((:instance process-limbo-irreducible
+ (l (initial-limbo q s nil)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Proving Soundness of Two-Step Formalization:
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Computation of initial-limbo list is sound
+(defthm limbo-sound-l
+ (implies (and (not (ceval-list l i))
+ (ceval-list s i))
+ (not (ceval-list (initial-limbo q s l) i))))
+
+(defthm limbo-sound-1
+ (implies (and (not (ceval-list q i))
+ (ceval-list s i)
+ (ceval-list l i))
+ (not (ceval-list (initial-limbo q s l) i)))
+ :hints (("Subgoal *1/2.2"
+ :in-theory (disable true-symbolp-ceval)
+ :use ((:instance true-symbolp-ceval
+ (x (SIMPLIFY (CAR Q) (APPEND S L))))))))
+
+(defthm limbo-sound
+ (implies (and (ceval-list q i) (ceval-list s i) (ceval-list l i))
+ (ceval-list (initial-limbo q s l) i)))
+
+;; Incorporating the limbo list is sound
+
+;; positive direction
+
+(defthm ceval-extract
+ (implies (ceval-list s i)
+ (ceval-list (extract-rewritables x s) i)))
+
+(defthm special-ppd-sound-1
+ (implies (and (ceval-list d i)
+ (ceval-list s i)
+ (ceval-list r i))
+ (ceval-list (special-ppd d s r) i)))
+
+(defthm process-limbo-sound
+ (implies (and (ceval-list l i)
+ (ceval-list s i))
+ (ceval-list (process-limbo l s) i)))
+
+;; negative direction
+
+(defthm special-ppd-sound-2
+ (implies (and (ceval-list r i)
+ (ceval-list s i)
+ (not (ceval-list d i)))
+ (not (ceval-list (special-ppd d s r) i)))
+ :hints (("Subgoal *1/2"
+ :in-theory (disable true-symbolp-ceval)
+ :use ((:instance true-symbolp-ceval
+ (x (simplify (car d) (append s (cdr d) r))))))))
+
+(defthm extract-remove-together
+ (implies (and (ceval-list (extract-rewritables x s) i)
+ (ceval-list (remove-rewritables x s) i))
+ (ceval-list s i))
+ :rule-classes ((:rewrite :match-free :all)))
+
+(defthm ceval-append-big-helper
+ (implies
+ (and (true-listp l)
+ (true-listp s)
+ (ceval-list r i)
+ (not (ceval-list (append l s) i)))
+ (not (ceval-list (append l
+ (special-ppd (extract-rewritables x s)
+ (append (remove-rewritables x s)
+ (cons x l))
+ r)
+ (cons x (remove-rewritables x s)))
+ i)))
+ :hints (("goal" :do-not-induct t
+ :cases ((and (ceval x i)
+ (ceval-list l i)
+ (ceval-list (remove-rewritables x s) i))
+ (not (and (ceval x i)
+ (ceval-list l i)
+ (ceval-list (remove-rewritables x s) i)))))
+ ("subgoal 2"
+ :in-theory (disable special-ppd-sound-2)
+ :use ((:instance
+ special-ppd-sound-2
+ (d (extract-rewritables x s))
+ (s (append (remove-rewritables x s) (cons x l))))))))
+
+(defthm process-limbo-sound-append
+ (implies (and (true-listp l)
+ (true-listp s)
+ (not (ceval-list (append l s) i)))
+ (not (ceval-list (process-limbo l s) i)))
+ :hints (("goal" :induct (process-limbo l s))))
+
+
+;; putting things together
+(defthm split-process-sound-1
+ (implies (and (true-listp s)
+ (ceval-list q i)
+ (ceval-list s i))
+ (ceval-list (limbo-incorporation q s) i)))
+
+(defthm split-process-sound-2
+ (implies (and (true-listp s)
+ (not (ceval-list q i))
+ (ceval-list s i))
+ (not (ceval-list (limbo-incorporation q s) i))))
+
+(defthm limbo-incorporation-sound-iff
+ (implies (true-listp s)
+ (iff (and (ceval-list q i) (ceval-list s i))
+ (ceval-list (limbo-incorporation q s) i)))
+ :hints (("Goal" :use (split-process-sound-1 split-process-sound-2)))
+ :rule-classes nil)
+
+;; top soundness lemma
+(defthm limbo-incorporation-is-sound
+ (implies (true-listp s)
+ (equal (ceval-list (limbo-incorporation q s) i)
+ (and (ceval-list q i) (ceval-list s i))))
+ :hints (("goal"
+ :in-theory (disable limbo-incorporation)
+ :use limbo-incorporation-sound-iff)))
+
diff --git a/books/workshops/2003/moore_rockwell/report.pdf.gz b/books/workshops/2003/moore_rockwell/report.pdf.gz
new file mode 100644
index 0000000..5c8cd9f
--- /dev/null
+++ b/books/workshops/2003/moore_rockwell/report.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/moore_rockwell/report.ps.gz b/books/workshops/2003/moore_rockwell/report.ps.gz
new file mode 100644
index 0000000..c0a268e
--- /dev/null
+++ b/books/workshops/2003/moore_rockwell/report.ps.gz
Binary files differ
diff --git a/books/workshops/2003/moore_rockwell/support/memory-taggings.lisp b/books/workshops/2003/moore_rockwell/support/memory-taggings.lisp
new file mode 100644
index 0000000..8c7a79e
--- /dev/null
+++ b/books/workshops/2003/moore_rockwell/support/memory-taggings.lisp
@@ -0,0 +1,1513 @@
+; Memory Taggings and Dynamic Data Structures}
+
+; J Strother Moore
+
+; Department of Computer Science
+; University of Texas at Austin
+; Austin, Texas 78701
+; moore@cs.utexas.edu
+
+; This book is described in the above paper. I have kept comments pretty
+; sparse.
+
+; (certify-book "memory-taggings")
+
+(in-package "ACL2")
+
+; This file is presumed to be located at:
+
+; /projects/acl2/v2-8/books/workshops/2003/moore_rockwell/support/
+
+(include-book "../../../../misc/records")
+(include-book "../../../../arithmetic/top-with-meta")
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+(defun seq-int (start len)
+ (if (zp len)
+ nil
+ (cons start
+ (seq-int (1+ start) (1- len)))))
+
+(defun unique (list)
+ (if (consp list)
+ (and (not (member (car list) (cdr list)))
+ (unique (cdr list)))
+ t))
+
+(mutual-recursion
+
+(defun collect (typ ptr n ram dcl)
+ (declare (xargs :measure (cons (+ 1 (nfix n)) 0)))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ nil
+ (if (zp ptr)
+ nil
+ (if (atom descriptor)
+ nil
+ (append (seq-int ptr (len descriptor))
+ (collect-lst typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl)))))))
+
+(defun collect-lst (typ ptr i n ram dcl)
+ (declare (xargs :measure
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl))) (nfix i))))))
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+
+; It makes life a little simpler if we always know that ptr is non-zero.
+
+ (cond ((zp ptr) nil)
+ ((<= (len descriptor) i) nil)
+ ((symbolp slot-typ)
+ (append (collect slot-typ
+ (g (+ ptr i) ram)
+ n ram dcl)
+ (collect-lst typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))
+ (t (collect-lst typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))))
+)
+
+; We next deal with marking arbitrary (non-pointer) elements in a
+; given data structure at address ptr of type typ with a given
+; descriptor. We need a constrained function to denote the value we
+; wish to put into field i of that data structure. In actual
+; applications we may wish the value to be a function of other fields,
+; so we allow the function to see the ram.
+
+; We originally declared an unconstrained function to compute the new
+; value:
+
+; (defstub new-field-value (typ ptr i ram) t).
+
+; But then we needed the fact that
+
+; (NEW-FIELD-VALUE TYP PTR K (S ADDR VAL RAM))
+; =
+; (NEW-FIELD-VALUE TYP PTR K RAM)
+
+; in order to prove that we could commute an independent s out of the
+; marking pass. So we provide the following constraint.
+
+(encapsulate
+ (((new-field-value * * * * *) => *))
+ (local (defun new-field-value (typ ptr i ram dcl)
+ (declare (ignore typ ptr i ram dcl))
+ 0))
+ (defthm new-field-value-s-commutes
+ (implies (not (member addr (seq-int ptr (len (cdr (assoc typ dcl))))))
+ (equal (new-field-value typ ptr i (s addr val ram) dcl)
+ (new-field-value typ ptr i ram dcl)))))
+
+; This contraint says that the new field value is impervious to writes
+; ``far away'' from the field being smashed. More precisely, the the
+; new field value is invariant under writes to locations outside the
+; (immediate) data object. This means that it is permitted for the
+; the new field value to look at other fields immediately within the
+; data object.
+
+(defun s* (typ ptr i ram dcl)
+ (declare (xargs :measure (nfix (- (len (cdr (assoc typ dcl)))
+ (nfix i)))))
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor)))
+ (cond
+ ((zp ptr) ram)
+ ((< i (len descriptor))
+ (cond ((symbolp slot-typ)
+ (s* typ ptr (+ 1 i) ram dcl))
+ (t (let ((ram (s (+ ptr i)
+ (new-field-value typ ptr i ram dcl)
+ ram)))
+ (s* typ ptr (+ 1 i) ram dcl)))))
+ (t ram))))
+
+(mutual-recursion
+
+(defun mark (typ ptr n ram dcl)
+ (declare (xargs :measure (cons (+ 1 (nfix n)) 0)))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ ram
+ (if (zp ptr)
+ ram
+ (if (atom descriptor)
+ ram
+ (let ((ram (s* typ ptr 0 ram dcl)))
+ (mark-lst typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl)))))))
+
+(defun mark-lst (typ ptr i n ram dcl)
+ (declare (xargs :measure
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl)))
+ (nfix i))))))
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) ram)
+ ((<= (len descriptor) i) ram)
+ ((symbolp slot-typ)
+ (let ((ram (mark slot-typ
+ (g (+ ptr i) ram)
+ n ram dcl)))
+ (mark-lst typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))
+ (t (mark-lst typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))))
+)
+
+(defun compose-bab (typ1 ptr1 n1 typ2 ptr2 n2 typ3 ptr3 n3 ram dcl)
+ (let ((ram (mark typ1 ptr1 n1 ram dcl)))
+ (let ((ram (mark typ2 ptr2 n2 ram dcl)))
+ (let ((ram (mark typ3 ptr3 n3 ram dcl)))
+ ram))))
+
+; Utility Functions and Lemmas
+
+(defthm g-s
+ (equal (g x (s y v r))
+ (if (equal x y)
+ v
+ (g x r))))
+
+(defthm member-append
+ (iff (member e (append a b))
+ (or (member e a)
+ (member e b))))
+
+; [Removed by Matt K. to handle changes to member, assoc, etc. after ACL2 4.2.]
+; (defun intersectp (x y)
+; (declare (xargs :guard (and (eqlable-listp x)
+; (eqlable-listp y))))
+; (cond ((endp x) nil)
+; ((member (car x) y) t)
+; (t (intersectp (cdr x) y))))
+
+(defthm unique-append
+ (iff (unique (append a b))
+ (and (unique a)
+ (unique b)
+ (not (intersectp a b)))))
+
+(defthm intersectp-append-1
+ (iff (intersectp c (append a b))
+ (or (intersectp c a)
+ (intersectp c b))))
+
+(defthm intersectp-append-2
+ (iff (intersectp (append a b) c)
+ (or (intersectp a c)
+ (intersectp b c))))
+
+; (SET-MATCH-FREE-ERROR NIL)
+
+(defthm member-intersection-1
+ (implies (and (not (intersectp b a))
+ (member ptr b))
+ (not (member ptr a))))
+
+(encapsulate
+ nil
+ (local
+ (defthm intersectp-commutes-1
+ (implies (not (member a1 b))
+ (equal (intersectp b (cons a1 a2))
+ (intersectp b a2)))))
+
+ (local
+ (defthm intersectp-commutes-2
+ (implies (member a1 b)
+ (intersectp b (cons a1 a2)))))
+
+ (defthm intersectp-commutes
+ (iff (intersectp a b)
+ (intersectp b a))))
+
+(defthm member-seq-int
+ (implies (integerp j)
+ (iff (member i (seq-int j n))
+ (if (zp n)
+ nil
+ (and (integerp i)
+ (<= j i)
+ (< i (+ j n)))))))
+
+; ---------------------------------------------------------------------------
+; Some key properties of s*
+
+(defthm s*-s-commutes
+ (implies (not (member addr (seq-int ;(+ i ptr)
+ ptr
+ (len (cdr (assoc typ dcl))))))
+ (equal (s* typ ptr i (s addr val ram) dcl)
+ (s addr val (s* typ ptr i ram dcl)))))
+
+(defthm g-s*
+ (implies (not (member addr (seq-int ptr (len (cdr (assoc typ dcl))))))
+ (equal (g addr (s* typ ptr i ram dcl))
+ (g addr ram))))
+
+(defthm member-intersection-2
+ (implies (and (not (intersectp a b))
+ (member e b))
+ (not (member e a))))
+
+(defthm new-field-value-s*
+ (implies (and (integerp i2)
+ (<= 0 i2)
+ (not (intersectp
+ (seq-int (+ i2 ptr2)
+ (- (len (cdr (assoc typ2 dcl))) i2))
+ (seq-int ptr1 (len (cdr (assoc typ1 dcl)))))))
+ (equal (new-field-value typ1 ptr1 i1 (s* typ2 ptr2 i2 ram dcl) dcl)
+ (new-field-value typ1 ptr1 i1 ram dcl))))
+
+(defthm subsetp-seq-int
+ (implies (and (not (zp ptr1))
+ (integerp i1)
+ (<= 0 i1))
+ (subsetp (seq-int (+ i1 ptr1)
+ (+ (- i1) n1))
+ (seq-int ptr1 n1))))
+
+(defthm intersectp-subsetp
+ (implies (and (not (intersectp a b))
+ (subsetp a1 a))
+ (not (intersectp b a1)))
+ :rule-classes ((:rewrite :match-free :all)))
+
+(defthm s*-s*-commutes
+ (implies (and (not (zp ptr1))
+ (not (zp ptr2))
+ (integerp i1)
+ (<= 0 i1)
+ (integerp i2)
+ (<= 0 i2)
+ (not (intersectp (seq-int ptr1 ;(+ i1 ptr1)
+ (len (cdr (assoc typ1 dcl))))
+ (seq-int ptr2 ;(+ i2 ptr2)
+ (len (cdr (assoc typ2 dcl)))))))
+ (equal (s* typ1 ptr1 i1 (s* typ2 ptr2 i2 ram dcl) dcl)
+ (s* typ2 ptr2 i2 (s* typ1 ptr1 i1 ram dcl) dcl)))
+ :rule-classes ((:rewrite :loop-stopper ((typ1 typ2)))))
+
+
+
+
+; ---------------------------------------------------------------------------
+; More Proof-Specific Lemmas
+
+; Next I eliminate the mutual recursion and deal just with the
+; fundamental functions collect-lst and mark-lst. I rename them ral
+; and mal for brevity.
+
+(defun collect-fn (fn typ ptr i n ram dcl)
+ (declare (xargs :measure
+ (if (equal fn :ALL)
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl))) (nfix i))))
+ (cons (+ 1 (nfix n)) 0))))
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) nil)
+ ((<= (len descriptor) i) nil)
+ ((symbolp slot-typ)
+ (append (collect-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i
+ n ram dcl)
+ (collect-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))
+ (t (collect-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl))))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ nil
+ (if (zp ptr)
+ nil
+ (if (atom descriptor)
+ nil
+ (append (seq-int ptr (len descriptor))
+ (collect-fn :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl))))))))
+
+(defun mark-fn (fn typ ptr i n ram dcl)
+ (declare (xargs :measure
+ (if (equal fn :ALL)
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl)))
+ (nfix i))))
+ (cons (+ 1 (nfix n)) 0))))
+
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) ram)
+ ((<= (len descriptor) i) ram)
+ ((symbolp slot-typ)
+ (let ((ram (mark-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i n ram dcl)))
+ (mark-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))
+ (t (mark-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl))))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ ram
+ (if (zp ptr)
+ ram
+ (if (atom descriptor)
+ ram
+ (let ((ram (s* typ ptr 0 ram dcl)))
+ (mark-fn :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl))))))))
+
+(defun s*-tags-ok (typ ptr i dcl tags)
+ (declare (xargs :measure (nfix (- (len (cdr (assoc typ dcl)))
+ (nfix i)))))
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor)))
+ (cond
+ ((zp ptr) t)
+ ((< i (len descriptor))
+ (cond ((symbolp slot-typ)
+ (cond ((equal (g (+ ptr i) tags) :PTR)
+ (s*-tags-ok typ ptr (+ 1 i) dcl tags))
+ (t nil)))
+ ((equal (g (+ ptr i) tags) :DATA)
+ (s*-tags-ok typ ptr (+ 1 i) dcl tags))
+ (t nil)))
+ (t t))))
+
+(defun tags-ok-fn (fn typ ptr i n ram dcl tags)
+ (declare (xargs :measure
+ (if (equal fn :ALL)
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl))) (nfix i))))
+ (cons (+ 1 (nfix n)) 0))))
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) t)
+ ((<= (len descriptor) i) t)
+ ((symbolp slot-typ)
+ (cond
+ ((equal (g (+ ptr i) tags) :PTR)
+ (and (tags-ok-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i
+ n ram dcl tags)
+ (tags-ok-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl tags)))
+ (t nil)))
+ ((equal (g (+ ptr i) tags) :DATA)
+ (tags-ok-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl tags))
+ (t nil)))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ t
+ (if (zp ptr)
+ t
+ (if (atom descriptor)
+ t
+ (and (s*-tags-ok typ ptr 0 dcl tags)
+ (tags-ok-fn :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl tags))))))))
+
+(defthm auto-open-collect-fn
+ (implies (if (equal fn :ALL)
+ (< (nfix i) (len (cdr (assoc typ dcl))))
+ (not (zp n)))
+ (equal (collect-fn fn typ ptr i n ram dcl)
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond
+ ((zp ptr) nil)
+ ((symbolp slot-typ)
+ (append (collect-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i
+ n ram dcl)
+ (collect-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))
+ (t (collect-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl))))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp ptr)
+ nil
+ (if (atom descriptor)
+ nil
+ (append (seq-int ptr (len descriptor))
+ (collect-fn :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl)))))))))
+
+(defthm auto-open-mark-fn
+ (implies (if (equal fn :ALL)
+ (< (nfix i) (len (cdr (assoc typ dcl))))
+ (not (zp n)))
+ (equal (mark-fn fn typ ptr i n ram dcl)
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) ram)
+ ((<= (len descriptor) i) ram)
+ ((symbolp slot-typ)
+ (let ((ram (mark-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i n ram dcl)))
+ (mark-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))
+ (t (mark-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl))))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ ram
+ (if (zp ptr)
+ ram
+ (if (atom descriptor)
+ ram
+ (let ((ram (s* typ ptr 0 ram dcl)))
+ (mark-fn :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl))))))))))
+
+(defthm auto-open-tags-ok-fn
+ (implies (if (equal fn :ALL)
+ (< (nfix i) (len (cdr (assoc typ dcl))))
+ (not (zp n)))
+ (equal (tags-ok-fn fn typ ptr i n ram dcl tags)
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) t)
+ ((symbolp slot-typ)
+ (cond
+ ((equal (g (+ ptr i) tags) :PTR)
+ (and (tags-ok-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i
+ n ram dcl tags)
+ (tags-ok-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl tags)))
+ (t nil)))
+ ((equal (g (+ ptr i) tags) :DATA)
+ (tags-ok-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl tags))
+ (t nil)))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp ptr)
+ t
+ (if (atom descriptor)
+ t
+ (and (s*-tags-ok typ ptr 0 dcl tags)
+ (tags-ok-fn :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl tags)))))))))
+
+
+(defthm assoc-append
+ (equal (append (append a b) c)
+ (append a (append b c))))
+
+(defthm equal-len-0
+ (equal (equal (len x) 0)
+ (not (consp x))))
+
+(defthm collect-s
+ (implies (and (tags-ok-fn fn typ ptr i n ram dcl tags)
+ (equal (g addr tags) :DATA))
+ (equal (collect-fn fn typ ptr i n (s addr val ram) dcl)
+ (collect-fn fn typ ptr i n ram dcl))))
+
+(defthm intersectp-seq-int-cons
+ (implies (and (not (zp ptr1))
+ (integerp ptr2)
+ (<= ptr1 ptr2)
+ (< ptr2 (+ (nfix n) ptr1)))
+ (intersectp (seq-int ptr1 n)
+ (cons ptr2 lst))))
+
+(defthm tags-ok-fn-s
+ (implies (equal (g ptr1 tags) :DATA)
+ (equal (tags-ok-fn fn typ ptr i n
+ (s ptr1 val ram)
+ dcl tags)
+ (tags-ok-fn fn typ ptr i n
+ ram dcl tags))))
+
+(defthm collect-fn-s*
+ (implies (and (tags-ok-fn fn typ ptr i n ram dcl tags)
+ (s*-tags-ok typ1 ptr1 k1 dcl tags))
+ (equal (collect-fn fn typ ptr i n
+ (s* typ1 ptr1 k1 ram dcl)
+ dcl)
+ (collect-fn fn typ ptr i n ram dcl))))
+
+(defthm hack2a
+ (implies (and (integerp k)
+ (integerp kmax)
+ (<= 0 k)
+ (< k kmax)
+ (integerp ptr))
+ (member (+ k ptr) (seq-int ptr kmax))))
+
+(defthm hack2b
+ (implies (and (not (intersectp a b))
+ (member e b))
+ (not (member e a))))
+
+(defthm hack2
+ (implies
+ (and (not (intersectp a
+ (seq-int ptr1 k1max)))
+ (not (zp ptr1))
+ (integerp k1)
+ (<= 0 k1)
+ (< k1 k1max)
+ (integerp k1max))
+ (not (member (+ k1 ptr1) a))))
+
+(defthm unique-seq-int-lemma
+ (implies (< e ptr)
+ (not (member e (seq-int ptr n)))))
+
+(defthm unique-seq-int
+ (unique (seq-int ptr n)))
+
+(defthm intersectp-hack1
+ (implies (intersectp a b)
+ (intersectp a (cons ptr1 b))))
+
+(defthm intersectp-x-x
+ (iff (intersectp x x)
+ (consp x)))
+
+(defthm consp-seq-int
+ (equal (consp (seq-int ptr n))
+ (not (zp n))))
+
+(defthm tags-ok-fn-s*
+ (implies (s*-tags-ok typ ptr i dcl tags)
+ (equal (tags-ok-fn fn1 typ1 ptr1 i1 n1
+ (s* typ ptr i ram dcl)
+ dcl tags)
+ (tags-ok-fn fn1 typ1 ptr1 i1 n1 ram dcl tags))))
+
+(defthm g-s*-new
+ (implies (and (s*-tags-ok typ ptr i dcl tags)
+ (equal (g ptr1 tags) :ptr))
+ (equal (g ptr1 (s* typ ptr i ram dcl))
+ (g ptr1 ram))))
+
+
+(defun tags-ok-fn-mark-fn-hint (fn typ ptr i n ram dcl tags
+ fn1 typ1 ptr1 i1 n1)
+ (declare (xargs :measure
+ (if (equal fn :ALL)
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl)))
+ (nfix i))))
+ (cons (+ 1 (nfix n)) 0))))
+
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) (list tags fn1 typ1 ptr1 i1 n1))
+ ((<= (len descriptor) i) ram)
+ ((symbolp slot-typ)
+ (let ((ram1 (mark-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i n ram dcl)))
+ (list
+ (tags-ok-fn-mark-fn-hint :ONE slot-typ
+ (g (+ ptr i) ram)
+ i n ram dcl tags
+ fn1 typ1 ptr1 i1 n1)
+ (tags-ok-fn-mark-fn-hint :ONE slot-typ
+ (g (+ ptr i) ram)
+ i n ram dcl tags
+ :ALL typ ptr (+ i 1) n)
+ (tags-ok-fn-mark-fn-hint :ALL typ
+ ptr
+ (+ 1 i)
+ n ram1 dcl tags
+ fn1 typ1 ptr1 i1 n1)
+ )))
+ (t (tags-ok-fn-mark-fn-hint :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl tags
+ fn1 typ1 ptr1 i1 n1))))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ ram
+ (if (zp ptr)
+ ram
+ (if (atom descriptor)
+ ram
+ (let ((ram (s* typ ptr 0 ram dcl)))
+ (tags-ok-fn-mark-fn-hint :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl tags
+ fn1 typ1 ptr1 i1 n1))))))))
+
+(defthm tags-ok-fn-mark-fn
+ (implies (tags-ok-fn fn2 typ2 ptr2 i2 n2 ram dcl tags)
+ (equal (tags-ok-fn fn1 typ1 ptr1 i1 n1
+ (mark-fn fn2 typ2 ptr2 i2 n2 ram dcl)
+ dcl tags)
+ (tags-ok-fn fn1 typ1 ptr1 i1 n1 ram dcl tags)))
+ :hints (("Goal"
+ :induct
+ (tags-ok-fn-mark-fn-hint fn2 typ2 ptr2 i2 n2 ram dcl tags
+ fn1 typ1 ptr1 i1 n1))))
+
+
+; Generalized Challenge Theorem 1 (first of two parts)
+(defthm g-mark-fn-1
+ (implies (and (tags-ok-fn fn typ ptr i n ram dcl tags)
+ (equal (g addr tags) :PTR))
+ (equal (g addr (mark-fn fn typ ptr i n ram dcl))
+ (g addr ram)))
+ :hints (("Goal" :induct (mark-fn fn typ ptr i n ram dcl))))
+
+(defthm collect-fn-mark-fn
+ (implies (and (tags-ok-fn fn1 typ1 ptr1 i1 n1 ram dcl tags)
+ (tags-ok-fn fn2 typ2 ptr2 i2 n2 ram dcl tags))
+ (equal (collect-fn fn1 typ1 ptr1 i1 n1
+ (mark-fn fn2 typ2 ptr2 i2 n2 ram dcl)
+ dcl)
+ (collect-fn fn1 typ1 ptr1 i1 n1 ram dcl)))
+ :hints (("Goal" :induct (mark-fn fn2 typ2 ptr2 i2 n2 ram dcl))))
+
+; Generalized Challenge Theorem 1 (second part)
+(defthm g-mark-fn-2
+ (implies (and (not (member addr (collect-fn fn typ ptr i n ram dcl)))
+ (tags-ok-fn fn typ ptr i n ram dcl tags))
+ (equal (g addr (mark-fn fn typ ptr i n ram dcl))
+ (g addr ram)))
+ :hints (("Goal" :induct (mark-fn fn typ ptr i n ram dcl))))
+
+; Now I will relate collect and collect-lst to collect-fn, etc.
+
+(defthm collect-is-collect-fn-main
+ (equal (collect-fn fn typ ptr i n ram dcl)
+ (if (equal fn :ALL)
+ (collect-lst typ ptr i n ram dcl)
+ (collect typ ptr n ram dcl)))
+ :rule-classes nil)
+
+(defthm collect-is-collect-fn
+ (and (equal (collect typ ptr n ram dcl)
+ (collect-fn :ONE typ ptr i n ram dcl))
+ (equal (collect-lst typ ptr i n ram dcl)
+ (collect-fn :ALL typ ptr i n ram dcl)))
+ :hints (("Goal" :use ((:instance collect-is-collect-fn-main (fn ':ONE))
+ (:instance collect-is-collect-fn-main (fn :ALL))))))
+
+(defthm mark-is-mark-fn-main
+ (equal (mark-fn fn typ ptr i n ram dcl)
+ (if (equal fn :ALL)
+ (mark-lst typ ptr i n ram dcl)
+ (mark typ ptr n ram dcl)))
+ :rule-classes nil)
+
+(defthm mark-is-mark-fn
+ (and (equal (mark typ ptr n ram dcl)
+ (mark-fn :ONE typ ptr i n ram dcl))
+ (equal (mark-lst typ ptr i n ram dcl)
+ (mark-fn :ALL typ ptr i n ram dcl)))
+ :hints (("Goal" :use ((:instance mark-is-mark-fn-main (fn ':ONE))
+ (:instance mark-is-mark-fn-main (fn :ALL))))))
+
+; Generalized Challenge Theorem 2
+(defthm read-over-bab
+ (implies
+ (and (tags-ok-fn :ONE typ1 ptr1 i n1 ram dcl tags)
+ (tags-ok-fn :ONE typ2 ptr2 i n2 ram dcl tags)
+ (tags-ok-fn :ONE typ3 ptr3 i n3 ram dcl tags)
+ (not (member addr (append (collect typ1 ptr1 n1 ram dcl)
+ (collect typ2 ptr2 n2 ram dcl)
+ (collect typ3 ptr3 n3 ram dcl)))))
+ (equal
+ (g addr (compose-bab typ1 ptr1 n1
+ typ2 ptr2 n2
+ typ3 ptr3 n3
+ ram dcl))
+ (g addr ram)))
+ :hints (("Goal" :restrict ((g-mark-fn-2 ((tags tags)))
+ (TAGS-OK-FN-MARK-FN ((tags tags)))
+ (COLLECT-FN-MARK-FN ((tags tags)))))))
+
+(defthm mark-fn-s
+ (implies (and (equal (g addr tags) :DATA)
+ (not (member addr
+ (collect-fn fn typ ptr i n ram dcl)))
+ (tags-ok-fn fn typ ptr i n ram dcl tags))
+ (equal (mark-fn fn typ ptr i n (s addr val ram) dcl)
+ (s addr val (mark-fn fn typ ptr i n ram dcl))))
+ :hints (("Goal" :induct (mark-fn fn typ ptr i n ram dcl))))
+
+(defthm new-field-value-s*
+ (implies
+ (and
+ (integerp i2)
+ (<= 0 i2)
+ (not
+ (intersectp (seq-int (+ i2 ptr2)
+ (- (len (cdr (assoc typ2 dcl))) i2))
+ (seq-int ptr1 (len (cdr (assoc typ1 dcl)))))))
+ (equal
+ (new-field-value typ1 ptr1 i1 (s* typ2 ptr2 i2 ram dcl)
+ dcl)
+ (new-field-value typ1 ptr1 i1 ram dcl))))
+
+(defthm new-field-value-mark-fn
+ (implies (and (not (intersectp (seq-int ptr2
+ (len (cdr (assoc typ2 dcl))))
+ (collect-fn fn typ ptr i n ram dcl)))
+ (tags-ok-fn fn typ ptr i n ram dcl tags))
+ (equal
+ (new-field-value typ2
+ ptr2 i2 (mark-fn fn typ ptr i n ram dcl)
+ dcl)
+ (new-field-value typ2 ptr2 i2 ram dcl)))
+ :hints (("Goal" :induct (mark-fn fn typ ptr i n ram dcl))))
+
+; It ain't pretty, but I'm just trying to finish!
+
+(defthm mark-fn-s*
+ (implies (and (not (intersectp (seq-int ptr2 ;(+ ptr2 i2)
+ (len (cdr (assoc typ2 dcl))) ;(- i2)
+ )
+ (collect-fn fn typ ptr i n ram dcl)))
+ (tags-ok-fn fn typ ptr i n ram dcl tags)
+ (s*-tags-ok typ2 ptr2 i2 dcl tags))
+ (equal (mark-fn fn typ ptr i n (s* typ2 ptr2 i2 ram dcl) dcl)
+ (s* typ2 ptr2 i2 (mark-fn fn typ ptr i n ram dcl) dcl)))
+ :hints (("Goal" :restrict ((new-field-value-mark-fn ((tags tags)))
+ (mark-fn-s ((tags tags)))))))
+
+(defthm g-mark-fn
+ (implies (and (not (member ptr2
+ (collect-fn fn typ ptr i n ram dcl)))
+ (tags-ok-fn fn typ ptr i n ram dcl tags))
+ (equal (g ptr2 (mark-fn fn
+ typ ptr i n ram
+ dcl))
+ (g ptr2 ram)))
+ :hints (("Goal" :induct (MARK-FN FN TYP PTR I N RAM DCL))))
+
+; Generalized Challenge Theorem 3
+
+(defthm mark-fn-mark-fn
+ (implies (and (tags-ok-fn fn1 typ1 ptr1 i1 n1 ram dcl tags)
+ (tags-ok-fn fn2 typ2 ptr2 i2 n2 ram dcl tags)
+ (not (intersectp (collect-fn fn1 typ1 ptr1 i1 n1 ram dcl)
+ (collect-fn fn2 typ2 ptr2 i2 n2 ram dcl))))
+ (equal (mark-fn fn1 typ1 ptr1 i1 n1
+ (mark-fn fn2 typ2 ptr2 i2 n2 ram dcl)
+ dcl)
+ (mark-fn fn2 typ2 ptr2 i2 n2
+ (mark-fn fn1 typ1 ptr1 i1 n1 ram dcl)
+ dcl)))
+ :hints (("Goal"
+ :induct (MARK-FN FN2 TYP2 PTR2 I2 N2 RAM DCL)
+ :restrict ((g-mark-fn ((tags tags)))
+ (MARK-FN-S* ((tags tags)))))))
+
+; ----
+
+; What makes the above work relevant to the Rockwell challenge, which
+; may be characterized by its focus on the collection of relevant
+; addresses and their disjointness? The key observations are two.
+
+; First, if the collection of addresses is unique, then there exists a
+; tagging that satisfies tags-ok-fn. The idea is that if the collection
+; is unique, each address is visited only once and the tagging can
+; assign which ever tag is used.
+
+; Second, if you have a tagging for each of two pointers and the corresponding
+; collections are disjoint, you can assemble a tagging that works for both.
+; The idea here is that you take one of the working taggings and move into it
+; all the taggings from the other one, exploiting the disjointness to know that
+; you have not disturbed the other tagging.
+
+; I prove the second result first.
+
+(defun merge-tags (addrs tags1 tags2)
+ (cond ((endp addrs) tags2)
+ (t (s (car addrs)
+ (g (car addrs) tags1)
+ (merge-tags (cdr addrs) tags1 tags2)))))
+
+(defthm g-merge-tags
+ (equal (g addr (merge-tags addrs tags1 tags2))
+ (if (member addr addrs)
+ (g addr tags1)
+ (g addr tags2))))
+
+(defthm merge-tags-append
+ (equal (merge-tags (append a b) tags1 tags2)
+ (merge-tags a tags1 (merge-tags b tags1 tags2))))
+
+(defthm merge-tags-s
+ (equal (merge-tags a tags1 (s addr (g addr tags1) tags))
+ (s addr (g addr tags1) (merge-tags a tags1 tags)))
+ :hints (("Subgoal *1/2''" :cases ((equal (car a) addr)))))
+
+(defthm merge-tags-commutes
+ (equal (merge-tags a tags1 (merge-tags b tags1 tags2))
+ (merge-tags b tags1 (merge-tags a tags1 tags2))))
+
+(defthm s*-tags-ok-merge-tags-1
+ (implies (and (s*-tags-ok typ ptr i dcl tags)
+ (not (intersectp addrs
+ (seq-int ptr (len (cdr (assoc typ dcl)))))))
+ (s*-tags-ok typ ptr i dcl
+ (merge-tags addrs tags1 tags))))
+
+(defthm s*-tags-ok-s
+ (implies (force
+ (not (member addr (seq-int (+ ptr (nfix i))
+ (- (len (cdr (assoc typ dcl)))
+ (nfix i))))))
+ (equal (s*-tags-ok typ ptr i dcl (s addr val tags))
+ (s*-tags-ok typ ptr i dcl tags))))
+
+; I just proved the theorem below. When I first tried it, I used the
+; hypothesis that addr was not a member of
+
+; (collect-fn fn typ ptr i n ram dcl).
+
+; But that is not a theorem. I then changed that collection to
+
+; (append
+; (if (equal fn :ALL)
+; (seq-int ptr (len (cdr (assoc typ dcl))))
+; nil)
+; (collect-fn fn typ ptr i n ram dcl))
+
+; You might ask why I need the stronger hypothesis? Suppose we use
+; the weaker hypothesis. Then it might be that addr is ptr and fn is
+; :ALL. The reason is that ptr does not generally occur in the :ALL
+; collection from ptr. So if we smash ptr with (s addr val tags) --
+; when addr is ptr -- then the :ALL collect ends up treating ptr as of
+; type val. instead of its old type. Because I will need this
+; hypothesis repeatedly, I define a stronger version of collect-fn.
+
+(defun kollect-fn (fn typ ptr i n ram dcl)
+ (append
+ (if (equal fn :ALL)
+ (seq-int (+ ptr (nfix i))
+ (- (len (cdr (assoc typ dcl)))
+ (nfix i)))
+ nil)
+ (collect-fn fn typ ptr i n ram dcl)))
+
+(defthm tags-ok-fn-s-tags
+ (implies (not (member addr (kollect-fn fn typ ptr i n ram dcl)))
+ (equal (tags-ok-fn fn typ ptr i n ram dcl
+ (s addr tag tags))
+ (tags-ok-fn fn typ ptr i n ram dcl tags))))
+
+(defthm s*-tags-ok-merge-tags
+ (implies (not (intersectp addrs
+ (seq-int (+ ptr (nfix i))
+ (- (len (cdr (assoc typ dcl)))
+ (nfix i)))))
+ (equal (s*-tags-ok typ ptr i dcl (merge-tags addrs tag1 tags))
+ (s*-tags-ok typ ptr i dcl tags))))
+
+
+(defthm tags-ok-fn-merge-tags-2
+ (implies (not (intersectp addrs
+ (kollect-fn fn typ ptr i n ram dcl)))
+ (equal (tags-ok-fn fn typ ptr i n ram dcl
+ (merge-tags addrs tags1 tags))
+ (tags-ok-fn fn typ ptr i n ram dcl tags))))
+
+(defthm s*-tags-ok-merge-tags-2
+ (implies (and (not (zp ptr))
+ (integerp i)
+ (<= 0 i)
+ (< i (len (cdr (assoc typ dcl)))))
+ (equal (s*-tags-ok typ ptr i dcl
+ (merge-tags
+ (seq-int (+ i ptr)
+ (- (len (cdr (assoc typ dcl)))
+ i))
+ tags1 tags2))
+ (s*-tags-ok typ ptr i dcl tags1))))
+
+(defthm s*-tags-ok-merge-tags-2-0
+ (implies (and (not (zp ptr))
+ (consp (cdr (assoc typ dcl))))
+ (equal (s*-tags-ok typ ptr 0 dcl
+ (merge-tags
+ (seq-int ptr
+ (len (cdr (assoc typ dcl))))
+ tags1 tags2))
+ (s*-tags-ok typ ptr 0 dcl tags1)))
+ :hints (("Goal" :use (:instance s*-tags-ok-merge-tags-2 (i 0)))))
+
+(defthm s-merge-tags-noop-1
+ (implies (member addr addrs)
+ (equal (s addr (g addr tags1) (merge-tags addrs tags1 tags2))
+ (merge-tags addrs tags1 tags2)))
+ :hints (("Goal" :induct (member addr addrs))))
+
+(defthm s-merge-tags-noop-2
+ (implies (not (member addr addrs))
+ (equal (s addr (g addr tags2) (merge-tags addrs tags1 tags2))
+ (merge-tags addrs tags1 tags2)))
+ :hints (("Goal" :induct (member addr addrs))))
+
+(defthm s-merge-tags-noop-val-1
+ (implies (and (member addr addrs)
+ (equal (g addr tags1) val))
+ (equal (s addr val (merge-tags addrs tags1 tags2))
+ (merge-tags addrs tags1 tags2))))
+
+(defthm s-merge-tags-noop-val-2
+ (implies (and (not (member addr addrs))
+ (equal (g addr tags2) val))
+ (equal (s addr val (merge-tags addrs tags1 tags2))
+ (merge-tags addrs tags1 tags2))))
+
+(defthm merge-tags-s-commutes-val
+ (implies (equal (g addr tags1) val)
+ (equal (merge-tags a tags1 (s addr val tags2))
+ (s addr val (merge-tags a tags1 tags2)))))
+
+(defthm s-merge-tags-noop-val-kb-hack
+ (implies (and (member addr addrs1)
+ (equal (g addr tags1) val))
+ (equal (s addr
+ val
+ (merge-tags addrs3
+ tags1
+ (merge-tags addrs2
+ tags1
+ (merge-tags addrs1 tags1 tags2))))
+ (merge-tags addrs3
+ tags1
+ (merge-tags addrs2
+ tags1
+ (merge-tags addrs1 tags1 tags2))))))
+
+(defun tags-ok-fn-merge-tags-3-hint (fn typ ptr i n ram dcl tags addrs2)
+ (declare (xargs :measure
+ (if (equal fn :ALL)
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl))) (nfix i))))
+ (cons (+ 1 (nfix n)) 0))))
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) (list addrs2))
+ ((<= (len descriptor) i) t)
+ ((symbolp slot-typ)
+ (cond
+ ((equal (g (+ ptr i) tags) :PTR)
+ (list (tags-ok-fn-merge-tags-3-hint
+ :ONE slot-typ (g (+ ptr i) ram) i n ram dcl tags
+ (cons (+ ptr i)
+ (append (kollect-fn :ALL typ ptr (+ i 1) n ram dcl)
+ addrs2)))
+
+ (tags-ok-fn-merge-tags-3-hint
+ :ONE slot-typ (g (+ ptr i) ram) i n ram dcl tags
+ (append (kollect-fn :ALL typ ptr (+ i 1) n ram dcl)
+ addrs2))
+
+ (tags-ok-fn-merge-tags-3-hint
+ :ALL typ ptr (+ 1 i) n ram dcl tags
+ (cons (+ ptr i)
+ (append (collect-fn :ONE
+ (nth i (cdr (assoc typ dcl)))
+ (g (+ ptr i) ram)
+ i n ram dcl)
+ addrs2)))
+
+ (tags-ok-fn-merge-tags-3-hint
+ :ALL typ ptr (+ 1 i) n ram dcl tags
+ (append (collect-fn :ONE
+ (nth i (cdr (assoc typ dcl)))
+ (g (+ ptr i) ram)
+ i n ram dcl)
+ addrs2))))
+ (t nil)))
+ ((equal (g (+ ptr i) tags) :DATA)
+ (list (tags-ok-fn-merge-tags-3-hint
+ :ALL typ ptr (+ 1 i) n ram dcl tags
+ (cons (+ ptr i)
+ addrs2))
+ (tags-ok-fn-merge-tags-3-hint
+ :ALL typ ptr (+ 1 i) n ram dcl tags
+ addrs2)))
+
+ (t nil)))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ t
+ (if (zp ptr)
+ t
+ (if (atom descriptor)
+ t
+ (list (s*-tags-ok typ ptr 0 dcl tags)
+ (tags-ok-fn-merge-tags-3-hint
+ :ALL typ ptr 0 (- n 1) ram dcl tags
+ addrs2))))))))
+
+(defthm tags-ok-fn-merge-tags-3-main-lemma
+ (equal (tags-ok-fn fn typ ptr i n ram dcl
+ (merge-tags (append (kollect-fn fn typ ptr i n ram dcl)
+ addrs2)
+ tags1
+ tags2))
+ (tags-ok-fn fn typ ptr i n ram dcl tags1))
+ :hints (("Goal"
+ :induct
+ (tags-ok-fn-merge-tags-3-hint fn typ ptr i n ram dcl tags1 addrs2))
+ ("Subgoal *1/10" :in-theory (disable merge-tags-commutes)))
+ :rule-classes nil)
+
+(defthm true-listp-kollect-fn
+ (true-listp (kollect-fn fn typ ptr i n ram dcl)))
+
+(defthm append-right-id
+ (implies (true-listp lst) (equal (append lst nil) lst)))
+
+; The following theorem establishes that if you have a tagging for a
+; given pointer then merging preserves it as a tagging. This
+; preservation is assured provided the good tagging is first of the
+; two taggings merged. Note that tags-ok-fn-merge-tags-2 handles the
+; other case. That is, if the merging maps over a list that has no
+; intersection with the kollection, then the second tagging is
+; preserved.
+
+(defthm tags-ok-fn-merge-tags-3
+ (equal (tags-ok-fn fn typ ptr i n ram dcl
+ (merge-tags (kollect-fn fn typ ptr i n ram dcl)
+ tags1
+ tags2))
+ (tags-ok-fn fn typ ptr i n ram dcl tags1))
+ :hints (("Goal" :in-theory (disable kollect-fn)
+ :use (:instance tags-ok-fn-merge-tags-3-main-lemma
+ (addrs2 nil)))))
+
+(defthm tags-ok-fn-merge-tags-3-corollary
+ (equal (tags-ok-fn :ONE typ ptr i n ram dcl
+ (merge-tags (collect-fn :ONE typ ptr i n ram dcl)
+ tags1
+ tags2))
+ (tags-ok-fn :ONE typ ptr i n ram dcl tags1))
+ :hints (("Goal"
+ :use (:instance tags-ok-fn-merge-tags-3-main-lemma
+ (addrs2 nil)
+ (fn :ONE)))))
+
+
+; Next, I turn to the problem of generating a tagging. I will use
+; merge-tags to define the constructor. This allows me to decompose
+; the recursive into simple recursion instead of reflexive recursion.
+
+(defun s*-tags-witness (typ ptr i dcl)
+ (declare (xargs :measure (nfix (- (len (cdr (assoc typ dcl)))
+ (nfix i)))))
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (i (nfix i))
+ (slot-typ (nth i descriptor)))
+ (cond
+ ((zp ptr) nil)
+ ((< i (len descriptor))
+ (cond ((symbolp slot-typ)
+ (s (+ ptr i) :PTR
+ (s*-tags-witness typ ptr (+ 1 i) dcl)))
+ (t
+ (s (+ ptr i) :DATA
+ (s*-tags-witness typ ptr (+ 1 i) dcl)))))
+ (t nil))))
+
+(defthm g-s*-tags-witness
+ (implies (and (not (zp ptr))
+ (integerp i)
+ (<= 0 i)
+ (< i (len (cdr (assoc typ dcl)))))
+ (EQUAL (G addr
+ (S*-TAGS-WITNESS TYP PTR I DCL))
+ (if (member addr
+ (seq-int (+ ptr i)
+ (- (len (cdr (assoc typ dcl))) i)))
+ (if (symbolp (nth (- addr ptr)
+ (cdr (assoc typ dcl))))
+ :PTR
+ :DATA)
+ nil))))
+
+(defthm s*-tags-ok-s-unforced
+ (implies
+ (not (member addr
+ (seq-int (+ ptr (nfix i))
+ (- (len (cdr (assoc typ dcl)))
+ (nfix i)))))
+ (equal (s*-tags-ok typ ptr i dcl (s addr val tags))
+ (s*-tags-ok typ ptr i dcl tags))))
+
+(in-theory (disable s*-tags-ok-s))
+
+(defthm s*-tags-ok-s*-tags-witness
+ (s*-tags-ok typ ptr i dcl
+ (s*-tags-witness typ ptr i dcl)))
+
+(defun tags-witness-fn (fn typ ptr i n ram dcl)
+ (declare (xargs :measure
+ (if (equal fn :ALL)
+ (cons (+ 1 (nfix n))
+ (nfix (- (len (cdr (assoc typ dcl))) (nfix i))))
+ (cons (+ 1 (nfix n)) 0))))
+ (if (equal fn :ALL)
+ (let* ((descriptor (cdr (assoc typ dcl)))
+ (slot-typ (nth i descriptor))
+ (i (nfix i)))
+ (cond ((zp ptr) nil)
+ ((<= (len descriptor) i) nil)
+ ((symbolp slot-typ)
+ (s (+ ptr i) :PTR
+ (merge-tags (collect-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i
+ n ram dcl)
+ (tags-witness-fn :ONE slot-typ
+ (g (+ ptr i) ram)
+ i
+ n ram dcl)
+ (tags-witness-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl))))
+ (t
+ (s (+ ptr i) :DATA
+ (tags-witness-fn :ALL typ
+ ptr
+ (+ 1 i)
+ n ram dcl)))))
+ (let ((descriptor (cdr (assoc typ dcl))))
+ (if (zp n)
+ nil
+ (if (zp ptr)
+ nil
+ (if (atom descriptor)
+ nil
+ (merge-tags (seq-int ptr (len (cdr (assoc typ dcl))))
+ (s*-tags-witness typ ptr 0 dcl)
+ (tags-witness-fn :ALL typ
+ ptr
+ 0
+ (- n 1)
+ ram
+ dcl))))))))
+
+(defthm weird-optimization-lemma-1
+ (implies (and (not (member addr addrs))
+ (equal (g addr tags2) val))
+ (equal (merge-tags addrs
+ (s addr val tags1)
+ tags2)
+ (merge-tags addrs
+ tags1
+ tags2))))
+
+(defthm weird-optimization
+ (implies (and (not (zp ptr))
+ (integerp i)
+ (<= 0 i)
+ (< i (len (cdr (assoc typ dcl))))
+ (tags-ok-fn :ALL typ ptr i n ram dcl tags))
+ (equal (merge-tags (seq-int (+ ptr i)
+ (- (len (cdr (assoc typ dcl))) i))
+ (s*-tags-witness typ ptr i dcl)
+ tags)
+ tags))
+ :hints
+
+; Subgoal numbers changed by Matt K. for v2-9 (probably needed because of
+; change to call-stack).
+
+ (("Subgoal *1/2.7''" :expand (SEQ-INT (+ I PTR) 1))
+ ("Subgoal *1/1.7''" :expand (SEQ-INT (+ I PTR) 1))))
+
+(defthm weird-optimization-corollary
+ (implies (and (not (zp ptr))
+ (consp (cdr (assoc typ dcl)))
+ (tags-ok-fn :ALL typ ptr 0 n ram dcl tags))
+ (equal (merge-tags (seq-int ptr
+ (len (cdr (assoc typ dcl))))
+ (s*-tags-witness typ ptr 0 dcl)
+ tags)
+ tags))
+ :hints (("Goal" :use (:instance weird-optimization (i 0)))))
+
+
+(defthm weird-optimization-part-2
+ (implies (and (not (zp ptr))
+ (integerp i)
+ (<= 0 i)
+ (< i (len (cdr (assoc typ dcl))))
+ (tags-ok-fn :ALL typ ptr i n ram dcl tags))
+ (s*-tags-ok typ ptr i dcl tags)))
+
+(defthm positive-len
+ (equal (< 0 (len x))
+ (consp x)))
+
+(defthm unique-implies-tags-exists
+ (implies (unique (kollect-fn fn typ ptr i n ram dcl))
+ (tags-ok-fn fn typ ptr i n ram dcl
+ (tags-witness-fn fn typ ptr i n ram dcl))))
+
+
+(in-theory (disable kollect-fn))
+
+; Now we assemble the various pieces.
+
+(defthm g-mark-fn-2-via-kollect-fn
+ (implies (and (unique (kollect-fn fn typ ptr i n ram dcl))
+ (not (member addr (collect-fn fn typ ptr i n ram dcl))))
+ (equal (g addr (mark-fn fn typ ptr i n ram dcl))
+ (g addr ram)))
+ :hints (("Goal" :use unique-implies-tags-exists
+ :in-theory (disable unique-implies-tags-exists)))
+ :rule-classes nil)
+
+(defthm collect-fn-mark-fn-via-kollect-fn
+ (implies (and (unique (kollect-fn fn2 typ2 ptr2 i2 n2 ram dcl))
+ (unique (kollect-fn fn1 typ1 ptr1 i1 n1 ram dcl))
+ (not (intersectp (kollect-fn fn2 typ2 ptr2 i2 n2 ram dcl)
+ (kollect-fn fn1 typ1 ptr1 i1 n1 ram dcl))))
+ (equal (collect-fn fn1 typ1 ptr1 i1 n1
+ (mark-fn fn2 typ2 ptr2 i2 n2 ram dcl)
+ dcl)
+ (collect-fn fn1 typ1 ptr1 i1 n1 ram dcl)))
+
+ :hints (("Goal"
+ :use
+ ((:instance unique-implies-tags-exists
+ (fn fn2) (typ typ2) (ptr ptr2) (i i2) (n n2))
+ (:instance unique-implies-tags-exists
+ (fn fn1) (typ typ1) (ptr ptr1) (i i1) (n n1))
+ (:instance
+ collect-fn-mark-fn
+ (tags (merge-tags
+ (kollect-fn fn2 typ2 ptr2 i2 n2 ram dcl)
+ (TAGS-WITNESS-FN FN2 TYP2 PTR2 I2 N2 RAM DCL)
+ (TAGS-WITNESS-FN FN1 TYP1 PTR1 I1 N1 RAM DCL)))))
+ :in-theory (disable unique-implies-tags-exists
+ collect-fn-mark-fn)))
+ :rule-classes nil)
+
+; Now I get rid of kollect-fn by focusing on the fn=:ONE case only.
+
+(defthm challenge-theorem-1-lemma
+ (implies (and (not (member addr (collect-fn :ONE typ ptr i n ram dcl)))
+ (unique (collect-fn :ONE typ ptr i n ram dcl)))
+ (equal (g addr (mark-fn :ONE typ ptr i n ram dcl))
+ (g addr ram)))
+
+ :hints (("Goal" :use
+ (:instance g-mark-fn-2-via-kollect-fn (fn :ONE))
+ :in-theory (enable kollect-fn))))
+
+(defthm challenge-theorem-1
+ (implies (and (not (member addr (collect typ ptr n ram dcl)))
+ (unique (collect typ ptr n ram dcl)))
+ (equal (g addr (mark typ ptr n ram dcl))
+ (g addr ram))))
+
+(defthm challenge-theorem-2-lemma
+ (implies (unique (append (collect-fn :ONE typ2 ptr2 i2 n2 ram dcl)
+ (collect-fn :ONE typ1 ptr1 i1 n1 ram dcl)))
+ (equal (collect-fn :ONE typ1 ptr1 i1 n1
+ (mark-fn :ONE typ2 ptr2 i2 n2 ram dcl)
+ dcl)
+ (collect-fn :ONE typ1 ptr1 i1 n1 ram dcl)))
+
+ :hints (("Goal" :use
+ (:instance collect-fn-mark-fn-via-kollect-fn
+ (fn2 :ONE)
+ (fn1 :ONE))
+ :in-theory (enable kollect-fn))))
+
+(defthm challenge-theorem-2
+ (implies
+ (and (unique (append (collect typ1 ptr1 n1 ram dcl)
+ (collect typ2 ptr2 n2 ram dcl)
+ (collect typ3 ptr3 n3 ram dcl)))
+ (not (member addr (append (collect typ1 ptr1 n1 ram dcl)
+ (collect typ2 ptr2 n2 ram dcl)
+ (collect typ3 ptr3 n3 ram dcl)))))
+ (equal
+ (g addr (compose-bab typ1 ptr1 n1
+ typ2 ptr2 n2
+ typ3 ptr3 n3
+ ram dcl))
+ (g addr ram))))
+
+
+(defthm challenge-theorem-3
+ (implies (unique (append (collect typ1 ptr1 n1 ram dcl)
+ (collect typ2 ptr2 n2 ram dcl)))
+ (equal (mark typ1 ptr1 n1 (mark typ2 ptr2 n2 ram dcl)
+ dcl)
+ (mark typ2 ptr2 n2 (mark typ1 ptr1 n1 ram dcl)
+ dcl)))
+ :hints
+ (("Goal"
+ :use
+ ((:instance unique-implies-tags-exists (fn :ONE)
+ (typ typ1)
+ (ptr ptr1)
+ (i i)
+ (n n1))
+ (:instance unique-implies-tags-exists (fn :ONE)
+ (typ typ2)
+ (ptr ptr2)
+ (i i)
+ (n n2))
+ (:instance
+ mark-fn-mark-fn (fn1 :ONE)
+ (fn2 :ONE)
+ (i2 i)
+ (i1 i)
+ (tags (merge-tags (collect-fn :ONE typ1 ptr1 i n1 ram dcl)
+ (tags-witness-fn :ONE typ1 ptr1 i n1 ram dcl)
+ (tags-witness-fn :ONE typ2 ptr2 i n2 ram dcl)))))
+ :in-theory
+ (e/d (kollect-fn)
+ (unique-implies-tags-exists mark-fn-mark-fn)))))
+
+
+; This theorem is proved just to illustrate the basic link between
+; unique disjoint collection and the existence of a consistent tagging
+; for two pointer structures.
+
+(defthm unique-collection-implies-exists-ok-tagging
+ (implies (unique (append (collect typ1 ptr1 n1 ram dcl)
+ (collect typ2 ptr2 n2 ram dcl)))
+ (let ((tags
+ (merge-tags (collect typ1 ptr1 n1 ram dcl)
+ (tags-witness-fn :ONE typ1 ptr1 0 n1 ram dcl)
+ (tags-witness-fn :ONE typ2 ptr2 0 n2 ram dcl))))
+ (and (tags-ok-fn :ONE typ1 ptr1 0 n1 ram dcl tags)
+ (tags-ok-fn :ONE typ2 ptr2 0 n2 ram dcl tags))))
+ :hints
+ (("Goal"
+ :use ((:instance collect-is-collect-fn
+ (typ typ1) (ptr ptr1) (i 0) (n n1))
+ (:instance collect-is-collect-fn
+ (typ typ2) (ptr ptr2) (i 0) (n n2))
+ (:instance unique-implies-tags-exists
+ (fn :ONE) (typ typ1) (ptr ptr1) (i 0) (n n1))
+ (:instance unique-implies-tags-exists
+ (fn :ONE) (typ typ2) (ptr ptr2) (i 0) (n n2))
+ (:instance mark-fn-mark-fn
+ (fn1 :ONE)
+ (fn2 :ONE)
+ (i2 0)
+ (i1 0)
+ (tags
+ (merge-tags
+ (collect-fn :ONE typ1 ptr1 0 n1 ram dcl)
+ (tags-witness-fn :ONE typ1 ptr1 0 n1 ram dcl)
+ (tags-witness-fn :ONE typ2 ptr2 0 n2 ram dcl)))))
+ :in-theory (e/d (kollect-fn)
+ (unique-implies-tags-exists
+ mark-fn-mark-fn
+ collect-is-collect-fn)))))
+
+
diff --git a/books/workshops/2003/moore_vcg/report.pdf.gz b/books/workshops/2003/moore_vcg/report.pdf.gz
new file mode 100644
index 0000000..50a0798
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/report.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/moore_vcg/report.ps.gz b/books/workshops/2003/moore_vcg/report.ps.gz
new file mode 100644
index 0000000..8bb55c3
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/report.ps.gz
Binary files differ
diff --git a/books/workshops/2003/moore_vcg/support/README b/books/workshops/2003/moore_vcg/support/README
new file mode 100644
index 0000000..ba50c33
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/README
@@ -0,0 +1,11 @@
+; Tail-Recursive Completion of Inductive Assertions
+; in an Operational Semantics Setting
+
+; J Strother Moore
+
+; This directory contains supporting material for the paper above.
+; To recertify the books here, type make to the linux prompt or
+; get into ACL2 while standing on this directory and type
+
+; (ld "certify.lsp" :ld-pre-eval-print t)
+
diff --git a/books/workshops/2003/moore_vcg/support/certify.lsp b/books/workshops/2003/moore_vcg/support/certify.lsp
new file mode 100644
index 0000000..93d7d98
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/certify.lsp
@@ -0,0 +1,172 @@
+
+;(certify-book "defpun")
+;(u)
+
+(defpkg "LABEL" '(nil t))
+(defpkg "JVM" '(nil t))
+(defpkg "M5"
+ (set-difference-equal
+ (union-eq
+ '(JVM::SCHEDULED
+ JVM::UNSCHEDULED
+ JVM::REF
+ JVM::LOCKED
+ JVM::S_LOCKED
+ JVM::UNLOCKED
+ JVM::AALOAD
+ JVM::AASTORE
+ JVM::ACONST_NULL
+ JVM::ALOAD
+ JVM::ALOAD_0
+ JVM::ALOAD_1
+ JVM::ALOAD_2
+ JVM::ALOAD_3
+ JVM::ANEWARRAY
+ JVM::ARETURN
+ JVM::ARRAYLENGTH
+ JVM::ASTORE
+ JVM::ASTORE_0
+ JVM::ASTORE_1
+ JVM::ASTORE_2
+ JVM::ASTORE_3
+ JVM::BALOAD
+ JVM::BASTORE
+ JVM::BIPUSH
+ JVM::CALOAD
+ JVM::CASTORE
+ JVM::DUP
+ JVM::DUP_X1
+ JVM::DUP_X2
+ JVM::DUP2
+ JVM::DUP2_X1
+ JVM::DUP2_X2
+ JVM::GETFIELD
+ JVM::GETSTATIC
+ JVM::GOTO
+ JVM::GOTO_W
+ JVM::I2B
+ JVM::I2C
+ JVM::I2L
+ JVM::I2S
+ JVM::IADD
+ JVM::IALOAD
+ JVM::IAND
+ JVM::IASTORE
+ JVM::ICONST_M1
+ JVM::ICONST_0
+ JVM::ICONST_1
+ JVM::ICONST_2
+ JVM::ICONST_3
+ JVM::ICONST_4
+ JVM::ICONST_5
+ JVM::IDIV
+ JVM::IF_ACMPEQ
+ JVM::IF_ACMPNE
+ JVM::IF_ICMPEQ
+ JVM::IF_ICMPGE
+ JVM::IF_ICMPGT
+ JVM::IF_ICMPLE
+ JVM::IF_ICMPLT
+ JVM::IF_ICMPNE
+ JVM::IFEQ
+ JVM::IFGE
+ JVM::IFGT
+ JVM::IFLE
+ JVM::IFLT
+ JVM::IFNE
+ JVM::IFNONNULL
+ JVM::IFNULL
+ JVM::IINC
+ JVM::ILOAD
+ JVM::ILOAD_0
+ JVM::ILOAD_1
+ JVM::ILOAD_2
+ JVM::ILOAD_3
+ JVM::IMUL
+ JVM::INEG
+ JVM::INSTANCEOF
+ JVM::INVOKESPECIAL
+ JVM::INVOKESTATIC
+ JVM::INVOKEVIRTUAL
+ JVM::IOR
+ JVM::IREM
+ JVM::IRETURN
+ JVM::ISHL
+ JVM::ISHR
+ JVM::ISTORE
+ JVM::ISTORE_0
+ JVM::ISTORE_1
+ JVM::ISTORE_2
+ JVM::ISTORE_3
+ JVM::ISUB
+ JVM::IUSHR
+ JVM::IXOR
+ JVM::JSR
+ JVM::JSR_W
+ JVM::L2I
+ JVM::LADD
+ JVM::LALOAD
+ JVM::LAND
+ JVM::LASTORE
+ JVM::LCMP
+ JVM::LCONST_0
+ JVM::LCONST_1
+ JVM::LDC
+ JVM::LDC_W
+ JVM::LDC2_W
+ JVM::LDIV
+ JVM::LLOAD
+ JVM::LLOAD_0
+ JVM::LLOAD_1
+ JVM::LLOAD_2
+ JVM::LLOAD_3
+ JVM::LMUL
+ JVM::LNEG
+ JVM::LOR
+ JVM::LREM
+ JVM::LRETURN
+ JVM::LSHL
+ JVM::LSHR
+ JVM::LSTORE
+ JVM::LSTORE_0
+ JVM::LSTORE_1
+ JVM::LSTORE_2
+ JVM::LSTORE_3
+ JVM::LSUB
+ JVM::LUSHR
+ JVM::LXOR
+ JVM::MONITORENTER
+ JVM::MONITOREXIT
+ JVM::MULTIANEWARRAY
+ JVM::NEW
+ JVM::NEWARRAY
+ JVM::NOP
+ JVM::POP
+ JVM::POP2
+ JVM::PUTFIELD
+ JVM::PUTSTATIC
+ JVM::RET
+ JVM::RETURN
+ JVM::SALOAD
+ JVM::SASTORE
+ JVM::SIPUSH
+ JVM::SWAP
+ ASSOC-EQUAL LEN NTH ZP SYNTAXP
+ QUOTEP FIX NFIX E0-ORDINALP E0-ORD-<)
+ (union-eq *acl2-exports*
+ *common-lisp-symbols-from-main-lisp-package*))
+ '(PC PROGRAM PUSH POP RETURN REVERSE STEP ++)))
+(certify-book "m5" 3)
+(u) (u) (u) (u)
+
+(include-book "m5")
+(certify-book "utilities" 1)
+(u) (u)
+
+(include-book "utilities")
+(certify-book "demo" 1)
+(u) (u)
+
+(include-book "utilities")
+(certify-book "vcg-examples" 1)
+(u) (u)
diff --git a/books/workshops/2003/moore_vcg/support/demo.acl2 b/books/workshops/2003/moore_vcg/support/demo.acl2
new file mode 100644
index 0000000..4b92f00
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/demo.acl2
@@ -0,0 +1,7 @@
+(value :q)
+
+(lp)
+
+(include-book "utilities")
+
+(certify-book "demo" ? t)
diff --git a/books/workshops/2003/moore_vcg/support/demo.lisp b/books/workshops/2003/moore_vcg/support/demo.lisp
new file mode 100644
index 0000000..8d07589
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/demo.lisp
@@ -0,0 +1,714 @@
+; Copyright (C) 2001, Regents of the University of Texas
+; Written by J Strother Moore
+; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
+
+; This book proves the correctness of a recursive static method
+; for factorial on M5.
+
+#|
+; Certification Instructions.
+
+(include-book
+ "utilities")
+
+(certify-book "demo" 1)
+
+J Moore
+
+Here is the Java for a factorial method.
+
+class Demo {
+
+ static int ans;
+
+ public static int fact(int n){
+ if (n>0)
+ {return n*fact(n-1);}
+ else return 1;
+ }
+
+ public static void main(String[] args){
+ int k = 4;
+ ans = fact(k+1);
+ return;
+ }
+ }
+
+If you put this into Demo.java and run
+
+% javac Demo.java
+% javap -o Demo
+
+you get the following:
+
+Compiled from Demo.java
+synchronized class Demo extends java.lang.Object
+ /* ACC_SUPER bit set */
+{
+ static int ans;
+ public static int fact(int);
+ public static void main(java.lang.String[]);
+ Demo();
+}
+
+Method int fact(int)
+ 0 iload_0
+ 1 ifle 13
+ 4 iload_0
+ 5 iload_0
+ 6 iconst_1
+ 7 isub
+ 8 invokestatic #5 <Method int fact(int)>
+ 11 imul
+ 12 ireturn
+ 13 iconst_1
+ 14 ireturn
+
+Method void main(java.lang.String[])
+ 0 iconst_4
+ 1 istore_1
+ 2 iload_1
+ 3 iconst_1
+ 4 iadd
+ 5 invokestatic #5 <Method int fact(int)>
+ 8 putstatic #4 <Field int ans>
+ 11 return
+
+Method Demo()
+ 0 aload_0
+ 1 invokespecial #3 <Method java.lang.Object()>
+ 4 return
+
+Below is the output of jvm2acl2 for M5.
+
+|#
+
+(in-package "M5")
+
+(defconst *Demo-class-table-in-tagged-form*
+ (make-class-def
+ (list
+ (make-class-decl
+ "Demo"
+ '("java.lang.Object")
+ '()
+ '("ans")
+ '()
+ (list
+ '("<init>" () nil
+ (aload_0)
+ (invokespecial "java.lang.Object" "<init>" 0)
+ (return))
+ '("fact" (int) nil
+ (iload_0)
+ (ifle LABEL::TAG_0)
+ (iload_0)
+ (iload_0)
+ (iconst_1)
+ (isub)
+ (invokestatic "Demo" "fact" 1)
+ (imul)
+ (ireturn)
+ (LABEL::TAG_0 iconst_1)
+ (ireturn))
+ '("main" (java.lang.String[]) nil
+ (iconst_4)
+ (istore_1)
+ (iload_1)
+ (iconst_1)
+ (iadd)
+ (invokestatic "Demo" "fact" 1)
+ (putstatic "Demo" "ans" nil)
+ (return)))
+ '(REF -1)))))
+
+(defconst *Demo-main*
+ '((iconst_4)
+ (istore_1)
+ (iload_1)
+ (iconst_1)
+ (iadd)
+ (invokestatic "Demo" "fact" 1)
+ (putstatic "Demo" "ans" nil)
+ (return)))
+
+(defun Demo-ms ()
+ (make-state
+ (make-tt (push (make-frame 0
+ nil
+ nil
+ *Demo-main*
+ 'UNLOCKED
+ "Demo")
+ nil))
+ nil
+ *Demo-class-table-in-tagged-form*))
+
+(defun Demo ()
+ (m5_load (Demo-ms)))
+
+; Here is the state created by (Demo):
+#|
+(((0 ((0 NIL NIL
+ ((ICONST_4)
+ (ISTORE_1)
+ (ILOAD_1)
+ (ICONST_1)
+ (IADD)
+ (INVOKESTATIC "Demo" "fact" 1)
+ (PUTSTATIC "Demo" "ans" NIL)
+ (RETURN))
+ UNLOCKED "Demo"))
+ SCHEDULED NIL))
+ ((0 ("java.lang.Class" ("<name>" . "java.lang.Object"))
+ ("java.lang.Object" ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0)))
+ (1 ("java.lang.Class" ("<name>" . "ARRAY"))
+ ("java.lang.Object" ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0)))
+ (2 ("java.lang.Class" ("<name>" . "java.lang.Thread"))
+ ("java.lang.Object" ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0)))
+ (3 ("java.lang.Class" ("<name>" . "java.lang.String"))
+ ("java.lang.Object" ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0)))
+ (4 ("java.lang.Class" ("<name>" . "java.lang.Class"))
+ ("java.lang.Object" ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0)))
+ (5 ("java.lang.Class" ("<name>" . "Demo")
+ ("ans" . 0))
+ ("java.lang.Object" ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0))))
+ (("java.lang.Object" NIL ("monitor" "mcount" "wait-set")
+ NIL NIL (("<init>" NIL NIL (RETURN)))
+ (REF 0))
+ ("ARRAY" ("java.lang.Object")
+ (("<array>" . *ARRAY*))
+ NIL NIL NIL (REF 1))
+ ("java.lang.Thread"
+ ("java.lang.Object")
+ NIL NIL NIL
+ (("run" NIL NIL (RETURN))
+ ("start" NIL NIL NIL)
+ ("stop" NIL NIL NIL)
+ ("<init>" NIL NIL (ALOAD_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN)))
+ (REF 2))
+ ("java.lang.String"
+ ("java.lang.Object")
+ ("strcontents")
+ NIL NIL
+ (("<init>" NIL NIL (ALOAD_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN)))
+ (REF 3))
+ ("java.lang.Class" ("java.lang.Object")
+ NIL NIL NIL
+ (("<init>" NIL NIL (ALOAD_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN)))
+ (REF 4))
+ ("Demo" ("java.lang.Object")
+ NIL ("ans")
+ NIL
+ (("<init>" NIL NIL (ALOAD_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN))
+ ("fact" (INT)
+ NIL (ILOAD_0)
+ (IFLE 12)
+ (ILOAD_0)
+ (ILOAD_0)
+ (ICONST_1)
+ (ISUB)
+ (INVOKESTATIC "Demo" "fact" 1)
+ (IMUL)
+ (IRETURN)
+ (ICONST_1)
+ (IRETURN))
+ ("main" (|JAVA.LANG.STRING[]|)
+ NIL (ICONST_4)
+ (ISTORE_1)
+ (ILOAD_1)
+ (ICONST_1)
+ (IADD)
+ (INVOKESTATIC "Demo" "fact" 1)
+ (PUTSTATIC "Demo" "ans" NIL)
+ (RETURN)))
+ (REF 5))))
+|#
+
+; But in the paper we discuss it component by component and
+; define constants for each. Note that we can write ICONST_4 or
+; ICONST\_4 in Common Lisp. We use the latter so that we can
+; pick these forms up and dump them into LaTeX.
+
+(defconst *Demo-thread-table*
+ (list
+ (cons 0
+ (make-thread
+ (push
+ (make-frame
+ 0
+ nil
+ nil
+ '((ICONST\_4)
+ (ISTORE\_1)
+ (ILOAD\_1)
+ (ICONST\_1)
+ (IADD)
+ (INVOKESTATIC "Demo" "fact" 1)
+ (PUTSTATIC "Demo" "ans" NIL)
+ (RETURN))
+ 'UNLOCKED
+ "Demo")
+ nil)
+ 'SCHEDULED
+ nil))))
+
+(defconst *Demo-heap*
+ '((0 . (("java.lang.Class"
+ ("<name>" . "java.lang.Object"))
+ ("java.lang.Object"
+ ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0))))
+ (1 . (("java.lang.Class"
+ ("<name>" . "ARRAY"))
+ ("java.lang.Object"
+ ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0))))
+ (2 . (("java.lang.Class"
+ ("<name>" . "java.lang.Thread"))
+ ("java.lang.Object"
+ ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0))))
+ (3 . (("java.lang.Class"
+ ("<name>" . "java.lang.String"))
+ ("java.lang.Object"
+ ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0))))
+ (4 . (("java.lang.Class"
+ ("<name>" . "java.lang.Class"))
+ ("java.lang.Object"
+ ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0))))
+ (5 . (("java.lang.Class"
+ ("<name>" . "Demo")
+ ("ans" . 0))
+ ("java.lang.Object"
+ ("monitor" . 0)
+ ("mcount" . 0)
+ ("wait-set" . 0))))))
+
+(defconst *Demo-class-table*
+ '(("java.lang.Object"
+ NIL
+ ("monitor" "mcount" "wait-set")
+ NIL
+ NIL
+ (("<init>" NIL NIL (RETURN)))
+ (REF 0))
+ ("ARRAY"
+ ("java.lang.Object")
+ (("<array>" . *ARRAY*))
+ NIL
+ NIL
+ NIL
+ (REF 1))
+ ("java.lang.Thread"
+ ("java.lang.Object")
+ NIL
+ NIL
+ NIL
+ (("run" NIL NIL (RETURN))
+ ("start" NIL NIL NIL)
+ ("stop" NIL NIL NIL)
+ ("<init>" NIL NIL (ALOAD\_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN)))
+ (REF 2))
+ ("java.lang.String"
+ ("java.lang.Object")
+ ("strcontents")
+ NIL
+ NIL
+ (("<init>" NIL NIL
+ (ALOAD\_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN)))
+ (REF 3))
+ ("java.lang.Class"
+ ("java.lang.Object")
+ NIL
+ NIL
+ NIL
+ (("<init>" NIL NIL
+ (ALOAD\_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN)))
+ (REF 4))
+ ("Demo"
+ ("java.lang.Object")
+ NIL
+ ("ans")
+ NIL
+ (("<init>" NIL NIL
+ (ALOAD\_0)
+ (INVOKESPECIAL "java.lang.Object" "<init>" 0)
+ (RETURN))
+ ("fact" (INT) NIL
+ (ILOAD\_0)
+ (IFLE 12)
+ (ILOAD\_0)
+ (ILOAD\_0)
+ (ICONST\_1)
+ (ISUB)
+ (INVOKESTATIC "Demo" "fact" 1)
+ (IMUL)
+ (IRETURN)
+ (ICONST\_1)
+ (IRETURN))
+ ("main" (|JAVA.LANG.STRING[]|) NIL
+ (ICONST\_4)
+ (ISTORE\_1)
+ (ILOAD\_1)
+ (ICONST\_1)
+ (IADD)
+ (INVOKESTATIC "Demo" "fact" 1)
+ (PUTSTATIC "Demo" "ans" NIL)
+ (RETURN)))
+ (REF 5))))
+
+(defconst *Demo-state*
+ (make-state *demo-thread-table*
+ *demo-heap*
+ *demo-class-table*))
+
+(defthm demo-state-is-demo
+ (equal (Demo)
+ *Demo-state*)
+ :rule-classes nil)
+
+; The Mathematical Function
+
+(defun factorial (n)
+ (if (zp n)
+ 1
+ (* n (factorial (- n 1)))))
+
+(defthm integerp-factorial
+ (integerp (factorial n))
+ :rule-classes :type-prescription)
+
+; A Schedule that Runs fact to Completion
+
+(defun fact-sched (th n)
+ (if (zp n)
+ (repeat th 5)
+ (append (repeat th 7)
+ (fact-sched th (- n 1))
+ (repeat th 2))))
+
+(defthm len-repeat
+ (equal (len (repeat th n)) (nfix n)))
+
+(defthm len-append
+ (equal (len (append a b))
+ (+ (len a) (len b))))
+
+(defthm len-fact-sched
+ (equal (len (fact-sched th n))
+ (+ 5 (* 9 (nfix n)))))
+
+; Playing Around with Main
+
+; This schedule executes main to termination.
+
+(defun main-sched (th)
+ (append (repeat th 5)
+ (fact-sched th 5)
+ (repeat th 2)))
+
+(defthm sample-execution
+ (equal (static-field-value "Demo" "ans"
+ (run (main-sched 0) *Demo-state*))
+ 120)
+ :rule-classes nil)
+
+#|
+
+; Below is a fact-test function. I define it in raw Lisp rather
+; than ACL2 so that I can time the execution of the JVM model
+; without timing the construction of the schedule. To define
+; this function, exit the loop with :q and do these two forms.
+
+(in-package "M5")
+(compile
+ (defun fact-test (n)
+ (format t "Computing schedule for ~a.~%" n)
+ (let ((sched (append (repeat 0 1)
+ (fact-sched 0 n)
+ (repeat 0 2))))
+ (format t "Schedule length: ~a.~%" (len sched))
+ (time
+ (static-field-value
+ "Demo" "ans"
+ (run sched
+ (make-state
+ (list
+ (cons 0
+ (make-thread
+ (push
+ (make-frame
+ 0
+ (list n)
+ nil
+ '((ILOAD\_0)
+ (INVOKESTATIC "Demo" "fact" 1)
+ (PUTSTATIC "Demo" "ans" NIL)
+ (RETURN))
+ 'UNLOCKED
+ "Demo")
+ nil)
+ 'SCHEDULED
+ nil)))
+ *demo-heap*
+ *demo-class-table*)))))))
+; Allocate additional bignum space
+(si::allocate 'lisp::bignum 400 t)
+T
+
+; Then do things like (fact-test 17) or (fact-test 1000). On a 797
+; MHz Pentium III, the latter requires a schedule of length 9008 and
+; takes 0.100 seconds to execute, provided no (BIGNUM) gcs occur.
+; This gives a simulation speed of 90K JVM bytecodes per second.
+
+|#
+
+; Proving Fact Correct
+
+(defconst *fact-def*
+ '("fact" (INT) NIL
+ (ILOAD_0) ;;; 0
+ (IFLE 12) ;;; 1
+ (ILOAD_0) ;;; 4
+ (ILOAD_0) ;;; 5
+ (ICONST_1) ;;; 6
+ (ISUB) ;;; 7
+ (INVOKESTATIC "Demo" "fact" 1) ;;; 8
+ (IMUL) ;;; 11
+ (IRETURN) ;;; 12
+ (ICONST_1) ;;; 13
+ (IRETURN))) ;;; 14
+
+(defun poised-to-invoke-fact (th s n)
+ (and (equal (status th s) 'SCHEDULED)
+ (equal (next-inst th s) '(invokestatic "Demo" "fact" 1))
+ (equal n (top (stack (top-frame th s))))
+ (intp n)
+ (equal (lookup-method "fact" "Demo" (class-table s))
+ *fact-def*)))
+
+(defun induction-hint (th s n)
+ (if (zp n)
+ s
+ (induction-hint
+ th
+ (make-state ;;; (run (repeat th 7) s)
+ (bind
+ th
+ (make-thread
+ (push
+ (make-frame
+ 8
+ (list (top (stack (top-frame th s))))
+ (push (- (top (stack (top-frame th s))) 1)
+ (push (top (stack (top-frame th s)))
+ nil))
+ (method-program *fact-def*)
+ 'UNLOCKED
+ "Demo")
+ (push (make-frame (+ 3 (pc (top (call-stack th s))))
+ (locals (top (call-stack th s)))
+ (pop (stack (top (call-stack th s))))
+ (program (top (call-stack th s)))
+ (sync-flg (top (call-stack th s)))
+ (cur-class (top (call-stack th s))))
+ (pop (call-stack th s))))
+ 'scheduled
+ (rref th s))
+ (thread-table s))
+ (heap s)
+ (class-table s))
+ (- n 1))))
+
+; The make-state in the induction-hint above is equivalent to
+; (run (repeat th 7) s), under the hypotheses that s is poised to
+; invoke fact and that n is non-0. We prove that below, just to
+; demonstrate this claim. The import of this claim is that we
+; could use this to help generate the induction hint, i.e., the
+; make-state is not "magic."
+
+(defthm induction-hint-explanation
+ (implies (and (poised-to-invoke-fact th s n)
+ (not (zp n)))
+ (equal (run (repeat th 7) s)
+ (make-state ;;; (run (repeat th 7) s)
+ (bind
+ th
+ (make-thread
+ (push
+ (make-frame
+ 8
+ (list (top (stack (top-frame th s))))
+ (push (- (top (stack (top-frame th s))) 1)
+ (push (top (stack (top-frame th s)))
+ nil))
+ (method-program *fact-def*)
+ 'UNLOCKED
+ "Demo")
+ (push (make-frame (+ 3 (pc (top (call-stack th s))))
+ (locals (top (call-stack th s)))
+ (pop (stack (top (call-stack th s))))
+ (program (top (call-stack th s)))
+ (sync-flg (top (call-stack th s)))
+ (cur-class (top (call-stack th s))))
+ (pop (call-stack th s))))
+ 'scheduled
+ (rref th s))
+ (thread-table s))
+ (heap s)
+ (class-table s))))
+ :rule-classes nil)
+
+(defthm fact-is-correct
+ (implies (poised-to-invoke-fact th s n)
+ (equal
+ (run (fact-sched th n) s)
+ (modify th s
+ :pc (+ 3 (pc (top-frame th s)))
+ :stack (push (int-fix (factorial n))
+ (pop (stack (top-frame th s)))))))
+ :hints (("Goal"
+ :induct (induction-hint th s n))))
+
+(in-theory (disable fact-sched))
+
+(defthm weak-version-of-fact-is-correct
+ (implies (poised-to-invoke-fact th s n)
+ (equal (top
+ (stack
+ (top-frame
+ th
+ (run (fact-sched th n) s))))
+ (int-fix (factorial n)))))
+
+; Symbolic Computation and Use of fact as a Subroutine
+
+(defthm symbolic-computation
+ (implies
+ (intp (+ 1 k))
+ (equal
+ (nth 3
+ (locals
+ (top-frame 0
+ (run (append (repeat 0 4)
+ (fact-sched 0 (+ 1 k))
+ (repeat 0 2))
+ (make-state
+ (make-tt
+ (push
+ (make-frame 0
+ (list v0 v1 v2 k)
+ stk
+ '((iconst_2)
+ (iload_3)
+ (iconst_1)
+ (iadd)
+ (invokestatic "Demo" "fact" 1)
+ (imul)
+ (istore_3))
+ 'UNLOCKED
+ "Test")
+ nil))
+ *demo-heap*
+ *demo-class-table*)))))
+
+ (int-fix (* 2 (factorial (+ 1 k)))))))
+
+; In the steps below we demonstrate the key steps in the
+; simplification above, to check the claims made in the paper.
+
+(defun alpha (pc locals stk)
+ (make-state
+ (make-tt
+ (push (make-frame pc
+ locals
+ stk
+ '((iconst_2)
+ (iload_3)
+ (iconst_1)
+ (iadd)
+ (invokestatic "Demo" "fact" 1)
+ (imul)
+ (istore_3))
+ 'UNLOCKED
+ "Test")
+ nil))
+ *demo-heap*
+ *demo-class-table*))
+
+(defthm symbolic-computation-step1
+ (implies
+ (intp (+ 1 k))
+ (equal (run (append (repeat 0 4)
+ (fact-sched 0 (+ 1 k))
+ (repeat 0 2))
+ (alpha 0 (list v0 v1 v2 k) stk))
+ (run (repeat 0 2)
+ (run (fact-sched 0 (+ 1 k))
+ (run (repeat 0 4)
+ (alpha 0 (list v0 v1 v2 k) stk)))))))
+
+(defthm symbolic-computation-step2
+ (implies
+ (intp (+ 1 k))
+ (equal (run (repeat 0 4)
+ (alpha 0 (list v0 v1 v2 k) stk))
+ (alpha 4 (list v0 v1 v2 k)
+ (push (+ 1 k) (push 2 stk))))))
+
+(defthm symbolic-computation-step3
+ (implies
+ (intp (+ 1 k))
+ (equal (run (fact-sched 0 (+ 1 k))
+ (alpha 4 (list v0 v1 v2 k)
+ (push (+ 1 k) (push 2 stk))))
+ (alpha 7 (list v0 v1 v2 k)
+ (push (int-fix (factorial (+ 1 k)))
+ (push 2 stk))))))
+
+
+(defthm symbolic-computation-step4
+ (implies
+ (intp (+ 1 k))
+ (equal (run (repeat 0 2)
+ (alpha 7 (list v0 v1 v2 k)
+ (push (int-fix (factorial (+ 1 k)))
+ (push 2 stk))))
+ (alpha 9 (list v0 v1 v2
+ (int-fix
+ (* 2 (factorial (+ 1 k))))) stk))))
+
diff --git a/books/workshops/2003/moore_vcg/support/m5.acl2 b/books/workshops/2003/moore_vcg/support/m5.acl2
new file mode 100644
index 0000000..3113f2e
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/m5.acl2
@@ -0,0 +1,160 @@
+(value :q)
+
+(lp)
+
+(defpkg "LABEL" '(nil t))
+(defpkg "JVM" '(nil t))
+
+(DEFPKG "M5"
+ (set-difference-equal
+ (union-eq '(JVM::SCHEDULED
+ JVM::UNSCHEDULED
+ JVM::REF
+ JVM::LOCKED
+ JVM::S_LOCKED
+ JVM::UNLOCKED
+ JVM::AALOAD
+ JVM::AASTORE
+ JVM::ACONST_NULL
+ JVM::ALOAD
+ JVM::ALOAD_0
+ JVM::ALOAD_1
+ JVM::ALOAD_2
+ JVM::ALOAD_3
+ JVM::ANEWARRAY
+ JVM::ARETURN
+ JVM::ARRAYLENGTH
+ JVM::ASTORE
+ JVM::ASTORE_0
+ JVM::ASTORE_1
+ JVM::ASTORE_2
+ JVM::ASTORE_3
+ JVM::BALOAD
+ JVM::BASTORE
+ JVM::BIPUSH
+ JVM::CALOAD
+ JVM::CASTORE
+ JVM::DUP
+ JVM::DUP_X1
+ JVM::DUP_X2
+ JVM::DUP2
+ JVM::DUP2_X1
+ JVM::DUP2_X2
+ JVM::GETFIELD
+ JVM::GETSTATIC
+ JVM::GOTO
+ JVM::GOTO_W
+ JVM::I2B
+ JVM::I2C
+ JVM::I2L
+ JVM::I2S
+ JVM::IADD
+ JVM::IALOAD
+ JVM::IAND
+ JVM::IASTORE
+ JVM::ICONST_M1
+ JVM::ICONST_0
+ JVM::ICONST_1
+ JVM::ICONST_2
+ JVM::ICONST_3
+ JVM::ICONST_4
+ JVM::ICONST_5
+ JVM::IDIV
+ JVM::IF_ACMPEQ
+ JVM::IF_ACMPNE
+ JVM::IF_ICMPEQ
+ JVM::IF_ICMPGE
+ JVM::IF_ICMPGT
+ JVM::IF_ICMPLE
+ JVM::IF_ICMPLT
+ JVM::IF_ICMPNE
+ JVM::IFEQ
+ JVM::IFGE
+ JVM::IFGT
+ JVM::IFLE
+ JVM::IFLT
+ JVM::IFNE
+ JVM::IFNONNULL
+ JVM::IFNULL
+ JVM::IINC
+ JVM::ILOAD
+ JVM::ILOAD_0
+ JVM::ILOAD_1
+ JVM::ILOAD_2
+ JVM::ILOAD_3
+ JVM::IMUL
+ JVM::INEG
+ JVM::INSTANCEOF
+ JVM::INVOKESPECIAL
+ JVM::INVOKESTATIC
+ JVM::INVOKEVIRTUAL
+ JVM::IOR
+ JVM::IREM
+ JVM::IRETURN
+ JVM::ISHL
+ JVM::ISHR
+ JVM::ISTORE
+ JVM::ISTORE_0
+ JVM::ISTORE_1
+ JVM::ISTORE_2
+ JVM::ISTORE_3
+ JVM::ISUB
+ JVM::IUSHR
+ JVM::IXOR
+ JVM::JSR
+ JVM::JSR_W
+ JVM::L2I
+ JVM::LADD
+ JVM::LALOAD
+ JVM::LAND
+ JVM::LASTORE
+ JVM::LCMP
+ JVM::LCONST_0
+ JVM::LCONST_1
+ JVM::LDC
+ JVM::LDC_W
+ JVM::LDC2_W
+ JVM::LDIV
+ JVM::LLOAD
+ JVM::LLOAD_0
+ JVM::LLOAD_1
+ JVM::LLOAD_2
+ JVM::LLOAD_3
+ JVM::LMUL
+ JVM::LNEG
+ JVM::LOR
+ JVM::LREM
+ JVM::LRETURN
+ JVM::LSHL
+ JVM::LSHR
+ JVM::LSTORE
+ JVM::LSTORE_0
+ JVM::LSTORE_1
+ JVM::LSTORE_2
+ JVM::LSTORE_3
+ JVM::LSUB
+ JVM::LUSHR
+ JVM::LXOR
+ JVM::MONITORENTER
+ JVM::MONITOREXIT
+ JVM::MULTIANEWARRAY
+ JVM::NEW
+ JVM::NEWARRAY
+ JVM::NOP
+ JVM::POP
+ JVM::POP2
+ JVM::PUTFIELD
+ JVM::PUTSTATIC
+ JVM::RET
+ JVM::RETURN
+ JVM::SALOAD
+ JVM::SASTORE
+ JVM::SIPUSH
+ JVM::SWAP
+ ASSOC-EQUAL LEN NTH ZP SYNTAXP
+ QUOTEP FIX NFIX E0-ORDINALP E0-ORD-<)
+ (union-eq *acl2-exports*
+ *common-lisp-symbols-from-main-lisp-package*))
+ '(PC PROGRAM PUSH POP RETURN REVERSE STEP ++)))
+
+(certify-book "m5" ? t)
diff --git a/books/workshops/2003/moore_vcg/support/m5.lisp b/books/workshops/2003/moore_vcg/support/m5.lisp
new file mode 100644
index 0000000..80a75ec
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/m5.lisp
@@ -0,0 +1,3032 @@
+; Copyright (C) 2001, Regents of the University of Texas
+; Written by J Strother Moore and George Porter
+; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
+
+; M5.lisp
+; J Strother Moore <moore@cs.utexas.edu>
+; George Porter <george@cs.utexas.edu>
+;
+; Fixed arithmetic work by Robert Krug <rkrug@cs.utexas.edu>
+; Support for Arrays by Hanbing Liu <hbl@cs.utexas.edu>
+;
+; $Id: m5.lisp,v 1.1 2001/07/10 17:37:06 george Exp $
+
+#|
+
+(defpkg "LABEL" '(nil t))
+(defpkg "JVM" '(nil t))
+
+(DEFPKG "M5"
+ (set-difference-equal
+ (union-eq '(JVM::SCHEDULED
+ JVM::UNSCHEDULED
+ JVM::REF
+ JVM::LOCKED
+ JVM::S_LOCKED
+ JVM::UNLOCKED
+ JVM::AALOAD
+ JVM::AASTORE
+ JVM::ACONST_NULL
+ JVM::ALOAD
+ JVM::ALOAD_0
+ JVM::ALOAD_1
+ JVM::ALOAD_2
+ JVM::ALOAD_3
+ JVM::ANEWARRAY
+ JVM::ARETURN
+ JVM::ARRAYLENGTH
+ JVM::ASTORE
+ JVM::ASTORE_0
+ JVM::ASTORE_1
+ JVM::ASTORE_2
+ JVM::ASTORE_3
+ JVM::BALOAD
+ JVM::BASTORE
+ JVM::BIPUSH
+ JVM::CALOAD
+ JVM::CASTORE
+ JVM::DUP
+ JVM::DUP_X1
+ JVM::DUP_X2
+ JVM::DUP2
+ JVM::DUP2_X1
+ JVM::DUP2_X2
+ JVM::GETFIELD
+ JVM::GETSTATIC
+ JVM::GOTO
+ JVM::GOTO_W
+ JVM::I2B
+ JVM::I2C
+ JVM::I2L
+ JVM::I2S
+ JVM::IADD
+ JVM::IALOAD
+ JVM::IAND
+ JVM::IASTORE
+ JVM::ICONST_M1
+ JVM::ICONST_0
+ JVM::ICONST_1
+ JVM::ICONST_2
+ JVM::ICONST_3
+ JVM::ICONST_4
+ JVM::ICONST_5
+ JVM::IDIV
+ JVM::IF_ACMPEQ
+ JVM::IF_ACMPNE
+ JVM::IF_ICMPEQ
+ JVM::IF_ICMPGE
+ JVM::IF_ICMPGT
+ JVM::IF_ICMPLE
+ JVM::IF_ICMPLT
+ JVM::IF_ICMPNE
+ JVM::IFEQ
+ JVM::IFGE
+ JVM::IFGT
+ JVM::IFLE
+ JVM::IFLT
+ JVM::IFNE
+ JVM::IFNONNULL
+ JVM::IFNULL
+ JVM::IINC
+ JVM::ILOAD
+ JVM::ILOAD_0
+ JVM::ILOAD_1
+ JVM::ILOAD_2
+ JVM::ILOAD_3
+ JVM::IMUL
+ JVM::INEG
+ JVM::INSTANCEOF
+ JVM::INVOKESPECIAL
+ JVM::INVOKESTATIC
+ JVM::INVOKEVIRTUAL
+ JVM::IOR
+ JVM::IREM
+ JVM::IRETURN
+ JVM::ISHL
+ JVM::ISHR
+ JVM::ISTORE
+ JVM::ISTORE_0
+ JVM::ISTORE_1
+ JVM::ISTORE_2
+ JVM::ISTORE_3
+ JVM::ISUB
+ JVM::IUSHR
+ JVM::IXOR
+ JVM::JSR
+ JVM::JSR_W
+ JVM::L2I
+ JVM::LADD
+ JVM::LALOAD
+ JVM::LAND
+ JVM::LASTORE
+ JVM::LCMP
+ JVM::LCONST_0
+ JVM::LCONST_1
+ JVM::LDC
+ JVM::LDC_W
+ JVM::LDC2_W
+ JVM::LDIV
+ JVM::LLOAD
+ JVM::LLOAD_0
+ JVM::LLOAD_1
+ JVM::LLOAD_2
+ JVM::LLOAD_3
+ JVM::LMUL
+ JVM::LNEG
+ JVM::LOR
+ JVM::LREM
+ JVM::LRETURN
+ JVM::LSHL
+ JVM::LSHR
+ JVM::LSTORE
+ JVM::LSTORE_0
+ JVM::LSTORE_1
+ JVM::LSTORE_2
+ JVM::LSTORE_3
+ JVM::LSUB
+ JVM::LUSHR
+ JVM::LXOR
+ JVM::MONITORENTER
+ JVM::MONITOREXIT
+ JVM::MULTIANEWARRAY
+ JVM::NEW
+ JVM::NEWARRAY
+ JVM::NOP
+ JVM::POP
+ JVM::POP2
+ JVM::PUTFIELD
+ JVM::PUTSTATIC
+ JVM::RET
+ JVM::RETURN
+ JVM::SALOAD
+ JVM::SASTORE
+ JVM::SIPUSH
+ JVM::SWAP
+ ASSOC-EQUAL LEN NTH ZP SYNTAXP
+ QUOTEP FIX NFIX E0-ORDINALP E0-ORD-<)
+ (union-eq *acl2-exports*
+ *common-lisp-symbols-from-main-lisp-package*))
+ '(PC PROGRAM PUSH POP RETURN REVERSE STEP ++)))
+
+(certify-book "m5" 3)
+
+J & George
+|#
+
+(in-package "M5")
+
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+; -----------------------------------------------------------------------------
+; Utilities
+
+(defun push (obj stack) (cons obj stack))
+(defun top (stack) (car stack))
+(defun pop (stack) (cdr stack))
+
+(defun popn (n stack)
+ (if (zp n)
+ stack
+ (popn (- n 1) (pop stack))))
+
+(defun bound? (x alist) (assoc-equal x alist))
+
+(defun bind (x y alist)
+ (cond ((endp alist) (list (cons x y)))
+ ((equal x (car (car alist)))
+ (cons (cons x y) (cdr alist)))
+ (t (cons (car alist) (bind x y (cdr alist))))))
+
+(defun binding (x alist) (cdr (assoc-equal x alist)))
+
+(defun op-code (inst) (car inst))
+(defun arg1 (inst) (car (cdr inst)))
+(defun arg2 (inst) (car (cdr (cdr inst))))
+(defun arg3 (inst) (car (cdr (cdr (cdr inst)))))
+
+(defun nullrefp (ref)
+ (equal ref '(ref -1)))
+
+; Imported from ACL2
+
+(defun reverse (x)
+ (if (consp x)
+ (append (reverse (cdr x)) (list (car x)))
+ nil))
+
+; The following are constants and functions related to fixed integer sizes
+
+(defconst *largest-integer-value* (- (expt 2 31) 1))
+(defconst *largest-long-value* (- (expt 2 63) 1))
+(defconst *most-negative-integer* (- (expt 2 31)))
+(defconst *most-negative-long* (- (expt 2 63)))
+
+; Coerce x to an unsigned integer which will fit in n bits.
+(defun u-fix (x n)
+ (mod (ifix x) (expt 2 n)))
+
+; Coerce x to a signed integer which will fit in n bits.
+(defun s-fix (x n)
+ (let ((temp (mod (ifix x) (expt 2 n))))
+ (if (< temp (expt 2 (1- n)))
+ temp
+ (- temp (expt 2 n)))))
+
+(defun byte-fix (x)
+ (s-fix x 8))
+
+(defun ubyte-fix (x)
+ (u-fix x 8))
+
+(defun short-fix (x)
+ (s-fix x 16))
+
+(defun int-fix (x)
+ (s-fix x 32))
+
+(defun uint-fix (x)
+ (u-fix x 32))
+
+(defun long-fix (x)
+ (s-fix x 64))
+
+(defun ulong-fix (x)
+ (u-fix x 64))
+
+(defun char-fix (x)
+ (u-fix x 16))
+
+(defun 6-bit-fix (x)
+ (u-fix x 6))
+
+(defun 5-bit-fix (x)
+ (u-fix x 5))
+
+(defun expt2 (n)
+ (expt 2 n))
+
+(defun shl (x n)
+ (* x (expt2 n)))
+
+(defun shr (x n)
+ (floor (* x (expt2 (- n))) 1))
+
+; -----------------------------------------------------------------------------
+; States
+
+(defun make-state (thread-table heap class-table)
+ (list thread-table heap class-table))
+(defun thread-table (s) (nth 0 s))
+(defun heap (s) (nth 1 s))
+(defun class-table (s) (nth 2 s))
+
+(defun make-thread (call-stack status rref)
+ (list call-stack status rref))
+
+(defun call-stack (th s)
+ (nth 0 (binding th (thread-table s))))
+
+(defun status (th s)
+ (nth 1 (binding th (thread-table s))))
+
+(defun rref (th s)
+ (nth 2 (binding th (thread-table s))))
+
+; -----------------------------------------------------------------------------
+; Class Declarations and the Class Table
+
+; The class table of a state is an alist. Each entry in a class table is
+; a "class declaration" and is of the form
+
+; (class-name super-class-names fields defs)
+
+; Note that the definition below of the Thread class includes a 'run' method,
+; which most applications will override. The definition is consistent
+; with the default run method provided by the Thread class [O'Reily]
+
+(defun make-class-decl (name superclasses fields sfields cp methods href)
+ (list name superclasses fields sfields cp methods href))
+
+(defun class-decl-name (dcl)
+ (nth 0 dcl))
+(defun class-decl-superclasses (dcl)
+ (nth 1 dcl))
+(defun class-decl-fields (dcl)
+ (nth 2 dcl))
+(defun class-decl-sfields (dcl)
+ (nth 3 dcl))
+(defun class-decl-cp (dcl)
+ (nth 4 dcl))
+(defun class-decl-methods (dcl)
+ (nth 5 dcl))
+(defun class-decl-heapref (dcl)
+ (nth 6 dcl))
+
+(defun base-class-def ()
+ (list (make-class-decl "java.lang.Object"
+ nil
+ '("monitor" "mcount" "wait-set")
+ '()
+ '()
+ '(("<init>" () nil (RETURN)))
+ '(REF -1))
+ (make-class-decl "ARRAY"
+ '("java.lang.Object")
+ '(("<array>" . *ARRAY*))
+ '()
+ '()
+ '()
+ '(REF -1))
+ (make-class-decl "java.lang.Thread"
+ '("java.lang.Object")
+ '()
+ '()
+ '()
+ '(("run" () nil
+ (RETURN))
+ ("start" () nil ())
+ ("stop" () nil ())
+ ("<init>" ()
+ nil
+ (aload_0)
+ (invokespecial "java.lang.Object" "<init>" 0)
+ (return)))
+ '(REF -1))
+ (make-class-decl "java.lang.String"
+ '("java.lang.Object")
+ '("strcontents")
+ '()
+ '()
+ '(("<init>" ()
+ nil
+ (aload_0)
+ (invokespecial "java.lang.Object" "<init>" 0)
+ (return)))
+ '(REF -1))
+ (make-class-decl "java.lang.Class"
+ '("java.lang.Object")
+ '()
+ '()
+ '()
+ '(("<init>" ()
+ nil
+ (aload_0)
+ (invokespecial "java.lang.Object" "<init>" 0)
+ (return)))
+ '(REF -1))))
+
+(defun make-class-def (list-of-class-decls)
+ (append (base-class-def) list-of-class-decls))
+
+; -----------------------------------------------------------------------------
+; A Constant Pool
+;
+; There is one constant pool per class
+
+; A constant pool is a list of entries. Each entry is either:
+;
+; '(INT n)
+; Where n is a 32-bit number, in the range specified by the JVM spec
+;
+; '(STRING (REF -1) "Hello, World!")
+; The 3rd element (a string) is resolved to a heap reference the
+; first time it is used. Once it is resolved, its reference is placed
+; as the second element (displacing the null ref currently there).
+
+(defun cp-make-int-entry (n)
+ (list 'INT n))
+
+(defun cp-make-string-entry (str)
+ (list 'STRING '(REF -1) str))
+
+(defun cp-string-resolved? (entry)
+ (not (equal (cadr (caddr entry)) -1)))
+
+(defun retrieve-cp (class-name class-table)
+ (class-decl-cp (bound? class-name class-table)))
+
+(defun update-ct-string-ref (class idx newval ct)
+ (let* ((class-entry (bound? class ct))
+ (oldstrval (caddr (nth idx (retrieve-cp class ct))))
+ (newstrentry (list 'STRING newval oldstrval))
+ (new-cp (update-nth idx
+ newstrentry
+ (class-decl-cp class-entry)))
+ (new-class-entry
+ (make-class-decl (class-decl-name class-entry)
+ (class-decl-superclasses class-entry)
+ (class-decl-fields class-entry)
+ (class-decl-sfields class-entry)
+ new-cp
+ (class-decl-methods class-entry)
+ (class-decl-heapref class-entry))))
+ (bind class (cdr new-class-entry) ct)))
+
+; -----------------------------------------------------------------------------
+; Thread Tables
+;
+; A "thread table" might be used to represent threads in m5. It consists of
+; a reference, a call stack, a flag to indicate whether its call-stack
+; should be stepped by the scheduler, and a ref to the original object
+; in the heap.
+;
+; Thread table:
+; ((n . (call-stack flag reverse-ref))
+; (n+1 . (call-stack flag reverse-ref)))
+;
+; The flags 'SCHEDULED and 'UNSCHEDULED correspond to two of the
+; four states threads can be in (according to [O'Reily]). For our
+; model, this will suffice.
+
+(defun make-tt (call-stack)
+ (bind 0 (list call-stack 'SCHEDULED nil) nil))
+
+(defun addto-tt (call-stack status heapRef tt)
+ (bind (len tt) (list call-stack status heapRef) tt))
+
+(defun mod-thread-scheduling (th sched tt)
+ (let* ((thrd (binding th tt))
+ (oldcs (car thrd))
+ (oldhr (caddr thrd))
+ (newTH (list oldcs sched oldhr)))
+ (bind th newTH tt)))
+
+(defun schedule-thread (th tt)
+ (mod-thread-scheduling th 'SCHEDULED tt))
+
+(defun unschedule-thread (th tt)
+ (mod-thread-scheduling th 'UNSCHEDULED tt))
+
+(defun rrefToThread (ref tt)
+ (cond ((endp tt) nil)
+ ((equal ref (cadddr (car tt))) (caar tt))
+ (t (rrefToThread ref (cdr tt)))))
+
+; ----------------------------------------------------------------------------
+; Helper function for determining if an object is a 'Thread' object
+
+(defun in-list (item list)
+ (cond ((endp list) nil)
+ ((equal item (car list)) t)
+ (t (in-list item (cdr list)))))
+
+(defun isThreadObject? (class-name class-table)
+ (let* ((class (bound? class-name class-table))
+ (psupers (class-decl-superclasses class))
+ (supers (cons class-name psupers)))
+ (or (in-list "java.lang.Thread" supers)
+ (in-list "java.lang.ThreadGroup" supers))))
+
+; ----------------------------------------------------------------------------
+; Helper functions for locking and unlocking objects
+
+; lock-object and unlock-object will obtain a lock on an instance
+; of an object, using th as the locking id (a thread owns a lock). If th
+; already has a lock on an object, then the mcount of the object is
+; incremented. Likewise if you unlock an object with mcount > 0, then
+; the lock will be decremented. Note: you must make sure that th can
+; and should get the lock, since this function will blindly go ahead and
+; get the lock
+
+(defun lock-object (th obj-ref heap)
+ (let* ((obj-ref-num (cadr obj-ref))
+ (instance (binding (cadr obj-ref) heap))
+ (obj-fields (binding "java.lang.Object" instance))
+ (new-mcount (+ 1 (binding "mcount" obj-fields)))
+ (new-obj-fields
+ (bind "monitor" th
+ (bind "mcount" new-mcount obj-fields)))
+ (new-object (bind "java.lang.Object" new-obj-fields instance)))
+ (bind obj-ref-num new-object heap)))
+
+(defun unlock-object (th obj-ref heap)
+ (let* ((obj-ref-num (cadr obj-ref))
+ (instance (binding (cadr obj-ref) heap))
+ (obj-fields (binding "java.lang.Object" instance))
+ (old-mcount (binding "mcount" obj-fields))
+ (new-mcount (ACL2::max 0 (- old-mcount 1)))
+ (new-monitor (if (zp new-mcount)
+ 0
+ th))
+ (new-obj-fields
+ (bind "monitor" new-monitor
+ (bind "mcount" new-mcount obj-fields)))
+ (new-object (bind "java.lang.Object" new-obj-fields instance)))
+ (bind obj-ref-num new-object heap)))
+
+; objectLockable? is used to determine if th can unlock instance. This
+; occurs when either mcount is zero (nobody has a lock), or mcount is
+; greater than zero, but monitor is equal to th. This means that th
+; already has a lock on the object, and when the object is locked yet again,
+; monitor will remain the same, but mcount will be incremented.
+;
+; objectUnLockable? determins if a thread can unlock an object (ie if it
+; has a lock on that object)
+(defun objectLockable? (instance th)
+ (let* ((obj-fields (binding "java.lang.Object" instance))
+ (monitor (binding "monitor" obj-fields))
+ (mcount (binding "mcount" obj-fields)))
+ (or (zp mcount)
+ (equal monitor th))))
+
+(defun objectUnLockable? (instance th)
+ (let* ((obj-fields (binding "java.lang.Object" instance))
+ (monitor (binding "monitor" obj-fields)))
+ (equal monitor th)))
+
+; -----------------------------------------------------------------------------
+; Frames
+
+(defun make-frame (pc locals stack program sync-flg cur-class)
+ (list pc locals stack program sync-flg cur-class))
+
+(defun top-frame (th s) (top (call-stack th s)))
+
+(defun pc (frame) (nth 0 frame))
+(defun locals (frame) (nth 1 frame))
+(defun stack (frame) (nth 2 frame))
+(defun program (frame) (nth 3 frame))
+(defun sync-flg (frame) (nth 4 frame))
+(defun cur-class (frame) (nth 5 frame))
+
+; -----------------------------------------------------------------------------
+; Method Declarations
+
+; The methods component of a class declaration is a list of method definitions.
+; A method definition is a list of the form
+
+; (name formals sync-status . program)
+
+; We never build these declarations but just enter list constants for them,
+
+; Note the similarity to our old notion of a program definition. We
+; will use strings to name methods now.
+
+; sync-status is 't' if the method is synchronized, 'nil' if not
+
+; Method definitions will be constructed by expressions such as:
+; (Note: all of the symbols below are understood to be in the pkg "JVM".)
+
+; ("move" (dx dy) nil
+; (load this)
+; (load this)
+; (getfield "Point" "x")
+; (load dx)
+; (add)
+; (putfield "Point" "x") ; this.x = this.x + dx;
+; (load :this)
+; (load :this)
+; (getfield "Point" "y")
+; (load dy)
+; (add)
+; (putfield "Point" "y") ; this.y = this.y + dy;
+; (push 1)
+; (xreturn))) ; return 1;
+
+; Provided this method is defined in the class "Point" it can be invoked by
+
+; (invokevirtual "Point" "move" 2)
+
+; This assumes that the stack, at the time of invocation, contains an
+; reference to an object of type "Point" and two numbers, dx and dy.
+
+; If a method declaration has an empty list for the program (ie- there are
+; no bytecodes associated with the method), then the method is considered
+; native. Native methods are normally written in something like C or
+; assembly language. The JVM would normally ensure that the correct number
+; and type of arguments are passed to the native method, and would then hand
+; over control to C. In our model, we simply "hardwire" invokevirtual to
+; to handle these methods.
+; * Note that a method in Java will never have 0 bytecodes, since even if
+; it has no body, it will consist of at least the (xreturn) bytecode.
+
+; The accessors for methods are:
+
+(defun method-name (m)
+ (nth 0 m))
+(defun method-formals (m)
+ (nth 1 m))
+(defun method-sync (m)
+ (nth 2 m))
+(defun method-program (m)
+ (cdddr m))
+(defun method-isNative? (m)
+ (equal '(NIL)
+ (method-program m)))
+
+; The Standard Modify
+
+(defun suppliedp (key args)
+ (cond ((endp args) nil)
+ ((equal key (car args)) t)
+ (t (suppliedp key (cdr args)))))
+
+(defun actual (key args)
+ (cond ((endp args) nil)
+ ((equal key (car args)) (cadr args))
+ (t (actual key (cdr args)))))
+
+(defmacro modify (th s &rest args)
+ (list 'make-state
+ (cond
+ ((or (suppliedp :call-stack args)
+ (suppliedp :pc args)
+ (suppliedp :locals args)
+ (suppliedp :stack args)
+ (suppliedp :program args)
+ (suppliedp :sync-flg args)
+ (suppliedp :cur-class args)
+ (suppliedp :status args))
+ (list 'bind
+ th
+ (list 'make-thread
+ (cond
+ ((suppliedp :call-stack args)
+ (actual :call-stack args))
+ ((and (suppliedp :status args)
+ (null (cddr args)))
+ (list 'call-stack th s))
+ (t
+ (list 'push
+ (list 'make-frame
+ (if (suppliedp :pc args)
+ (actual :pc args)
+ (list 'pc (list 'top-frame th s)))
+ (if (suppliedp :locals args)
+ (actual :locals args)
+ (list 'locals (list 'top-frame th s)))
+ (if (suppliedp :stack args)
+ (actual :stack args)
+ (list 'stack (list 'top-frame th s)))
+ (if (suppliedp :program args)
+ (actual :program args)
+ (list 'program (list 'top-frame th s)))
+ (if (suppliedp :sync-flg args)
+ (actual :sync-flg args)
+ (list 'sync-flg (list 'top-frame th s)))
+ (if (suppliedp :cur-class args)
+ (actual :cur-class args)
+ (list 'cur-class
+ (list 'top-frame th s))))
+ (list 'pop (list 'call-stack th s)))))
+ (if (suppliedp :status args)
+ (actual :status args)
+ (list 'status th s))
+ (list 'rref th s))
+ (list 'thread-table s)))
+ ((suppliedp :thread-table args)
+ (actual :thread-table args))
+ (t (list 'thread-table s)))
+ (if (suppliedp :heap args)
+ (actual :heap args)
+ (list 'heap s))
+ (if (suppliedp :class-table args)
+ (actual :class-table args)
+ (list 'class-table s))))
+
+; -----------------------------------------------------------------------------
+; Helper functions related to building instances of objects
+
+(defun deref (ref heap)
+ (binding (cadr ref) heap))
+
+(defun field-value (class-name field-name instance)
+ (binding field-name
+ (binding class-name instance)))
+
+(defun build-class-field-bindings (field-names)
+ (if (endp field-names)
+ nil
+ (cons (cons (car field-names) 0)
+ (build-class-field-bindings (cdr field-names)))))
+
+(defun build-class-object-field-bindings ()
+ '(("monitor" . 0) ("monitor-count" . 0) ("wait-set" . nil)))
+
+(defun build-immediate-instance-data (class-name class-table)
+ (cons class-name
+ (build-class-field-bindings
+ (class-decl-fields
+ (bound? class-name class-table)))))
+
+(defun build-an-instance (class-names class-table)
+ (if (endp class-names)
+ nil
+ (cons (build-immediate-instance-data (car class-names) class-table)
+ (build-an-instance (cdr class-names) class-table))))
+
+(defun build-class-data (sfields)
+ (cons "java.lang.Class"
+ (build-class-field-bindings
+ (cons "<name>" sfields))))
+
+(defun build-a-class-instance (sfields class-table)
+ (list (build-class-data sfields)
+ (build-immediate-instance-data "java.lang.Object" class-table)))
+
+
+; -----------------------------------------------------------------------------
+; Arrays
+
+(defun value-of (obj)
+ (cdr obj))
+
+(defun superclasses-of (class ct)
+ (class-decl-superclasses (bound? class ct)))
+
+(defun array-content (array)
+ (value-of (field-value "ARRAY" "<array>" array)))
+
+(defun array-type (array)
+ (nth 0 (array-content array)))
+
+(defun array-bound (array)
+ (nth 1 (array-content array)))
+
+(defun array-data (array)
+ (nth 2 (array-content array)))
+
+(defun element-at (index array)
+ (nth index (array-data array)))
+
+(defun makearray (type bound data class-table)
+ (cons (list "ARRAY"
+ (cons "<array>" (cons '*array* (list type bound data))))
+ (build-an-instance
+ (superclasses-of "ARRAY" class-table)
+ class-table)))
+
+(defun set-element-at (value index array class-table)
+ (makearray (array-type array)
+ (array-bound array)
+ (update-nth index value (array-data array))
+ class-table))
+
+(defun primitive-type (type)
+ (cond ((equal type 'T_BYTE) t)
+ ((equal type 'T_SHORT) t)
+ ((equal type 'T_INT) t)
+ ((equal type 'T_LONG) t)
+ ((equal type 'T_FLOAT) t)
+ ((equal type 'T_DOUBLE) t)
+ ((equal type 'T_CHAR) t)
+ ((equal type 'T_BOOLEAN) t)
+ (t nil)))
+
+(defun atype-to-identifier (atype-num)
+ (cond ((equal atype-num 4) 'T_BOOLEAN)
+ ((equal atype-num 5) 'T_CHAR)
+ ((equal atype-num 6) 'T_FLOAT)
+ ((equal atype-num 7) 'T_DOUBLE)
+ ((equal atype-num 8) 'T_BYTE)
+ ((equal atype-num 9) 'T_SHORT)
+ ((equal atype-num 10) 'T_INT)
+ ((equal atype-num 11) 'T_LONG)
+ (t nil)))
+
+(defun identifier-to-atype (ident)
+ (cond ((equal ident 'T_BOOLEAN) 4)
+ ((equal ident 'T_CHAR) 5)
+ ((equal ident 'T_FLOAT) 6)
+ ((equal ident 'T_DOUBLE) 7)
+ ((equal ident 'T_BYTE) 8)
+ ((equal ident 'T_SHORT) 9)
+ ((equal ident 'T_INT) 10)
+ ((equal ident 'T_LONG) 11)
+ (t nil)))
+
+(defun default-value1 (type)
+ (if (primitive-type type)
+ 0
+ nil))
+
+(defun init-array (type count)
+ (if (zp count)
+ nil
+ (cons (default-value1 type) (init-array type (- count 1)))))
+
+; The following measure is due to J
+(defun natural-sum (lst)
+ (cond ((endp lst) 0)
+ (t (+ (nfix (car lst)) (natural-sum (cdr lst))))))
+
+(mutual-recursion
+
+ ; makemultiarray2 :: num, counts, s, ac --> [refs]
+ (defun makemultiarray2 (car-counts cdr-counts s ac)
+ (declare (xargs :measure (cons (len (cons car-counts cdr-counts))
+ (natural-sum (cons car-counts cdr-counts)))))
+ (if (zp car-counts)
+ (mv (heap s) ac)
+ (mv-let (new-addr new-heap)
+ (makemultiarray cdr-counts s)
+ (makemultiarray2 (- car-counts 1)
+ cdr-counts
+ (make-state (thread-table s)
+ new-heap
+ (class-table s))
+ (cons (list 'REF new-addr) ac)))))
+
+ ; makemultiarray :: [counts], s --> addr, new-heap
+ (defun makemultiarray (counts s)
+ (declare (xargs :measure (cons (+ 1 (len counts))
+ (natural-sum counts))))
+ (if (<= (len counts) 1)
+
+ ; "Base case" Handles initializing the final dimension
+ (mv (len (heap s))
+ (bind (len (heap s))
+ (makearray 'T_REF
+ (car counts)
+ (init-array 'T_REF (car counts))
+ (class-table s))
+ (heap s)))
+
+ ; "Recursive Case"
+ (mv-let (heap-prime lst-of-refs)
+ (makemultiarray2 (car counts)
+ (cdr counts)
+ s
+ nil)
+ (let* ((obj (makearray 'T_REF
+ (car counts)
+ lst-of-refs
+ (class-table s)))
+ (new-addr (len heap-prime))
+ (new-heap (bind new-addr obj heap-prime)))
+ (mv new-addr new-heap)))))
+)
+
+; -----------------------------------------------------------------------------
+; Instruction length table -- PCs are now in bytes, not # of instructions
+
+(defun inst-length (inst)
+ (case (op-code inst)
+ (AALOAD 1)
+ (AASTORE 1)
+ (ACONST_NULL 1)
+ (ALOAD 2)
+ (ALOAD_0 1)
+ (ALOAD_1 1)
+ (ALOAD_2 1)
+ (ALOAD_3 1)
+ (ANEWARRAY 3)
+ (ARETURN 1)
+ (ARRAYLENGTH 1)
+ (ASTORE 2)
+ (ASTORE_0 1)
+ (ASTORE_1 1)
+ (ASTORE_2 1)
+ (ASTORE_3 1)
+ (BALOAD 1)
+ (BASTORE 1)
+ (BIPUSH 2)
+ (CALOAD 1)
+ (CASTORE 1)
+ (DUP 1)
+ (DUP_X1 1)
+ (DUP_X2 1)
+ (DUP2 1)
+ (DUP2_X1 1)
+ (DUP2_X2 1)
+ (GETFIELD 3)
+ (GETSTATIC 3)
+ (GOTO 3)
+ (GOTO_W 5)
+ (I2B 1)
+ (I2C 1)
+ (I2L 1)
+ (I2S 1)
+ (IADD 1)
+ (IALOAD 1)
+ (IAND 1)
+ (IASTORE 1)
+ (ICONST_M1 1)
+ (ICONST_0 1)
+ (ICONST_1 1)
+ (ICONST_2 1)
+ (ICONST_3 1)
+ (ICONST_4 1)
+ (ICONST_5 1)
+ (IDIV 1)
+ (IF_ACMPEQ 3)
+ (IF_ACMPNE 3)
+ (IF_ICMPEQ 3)
+ (IF_ICMPGE 3)
+ (IF_ICMPGT 3)
+ (IF_ICMPLE 3)
+ (IF_ICMPLT 3)
+ (IF_ICMPNE 3)
+ (IFEQ 3)
+ (IFGE 3)
+ (IFGT 3)
+ (IFLE 3)
+ (IFLT 3)
+ (IFNE 3)
+ (IFNONNULL 3)
+ (IFNULL 3)
+ (IINC 3)
+ (ILOAD 2)
+ (ILOAD_0 1)
+ (ILOAD_1 1)
+ (ILOAD_2 1)
+ (ILOAD_3 1)
+ (IMUL 1)
+ (INEG 1)
+ (INSTANCEOF 3)
+ (INVOKESPECIAL 3)
+ (INVOKESTATIC 3)
+ (INVOKEVIRTUAL 3)
+ (IOR 1)
+ (IREM 1)
+ (IRETURN 1)
+ (ISHL 1)
+ (ISHR 1)
+ (ISTORE 2)
+ (ISTORE_0 1)
+ (ISTORE_1 1)
+ (ISTORE_2 1)
+ (ISTORE_3 1)
+ (ISUB 1)
+ (IUSHR 1)
+ (IXOR 1)
+ (JSR 3)
+ (JSR_W 5)
+ (L2I 1)
+ (LADD 1)
+ (LALOAD 1)
+ (LAND 1)
+ (LASTORE 1)
+ (LCMP 1)
+ (LCONST_0 1)
+ (LCONST_1 1)
+ (LDC 2)
+ (LDC_W 3)
+ (LDC2_W 3)
+ (LDIV 1)
+ (LLOAD 2)
+ (LLOAD_0 1)
+ (LLOAD_1 1)
+ (LLOAD_2 1)
+ (LLOAD_3 1)
+ (LMUL 1)
+ (LNEG 1)
+ (LOR 1)
+ (LREM 1)
+ (LRETURN 1)
+ (LSHL 1)
+ (LSHR 1)
+ (LSTORE 2)
+ (LSTORE_0 1)
+ (LSTORE_1 1)
+ (LSTORE_2 1)
+ (LSTORE_3 1)
+ (LSUB 1)
+ (LUSHR 1)
+ (LXOR 1)
+ (MONITORENTER 1)
+ (MONITOREXIT 1)
+ (MULTIANEWARRAY 4)
+ (NEW 3)
+ (NEWARRAY 2)
+ (NOP 1)
+ (POP 1)
+ (POP2 1)
+ (PUTFIELD 3)
+ (PUTSTATIC 3)
+ (RET 2)
+ (RETURN 1)
+ (SALOAD 1)
+ (SASTORE 1)
+ (SIPUSH 3)
+ (SWAP 1)
+ (t 1)))
+
+
+; =============================================================================
+; JVM INSTRUCTIONS BEGIN HERE
+; =============================================================================
+
+; -----------------------------------------------------------------------------
+; (AALOAD) Instruction
+
+(defun execute-AALOAD (inst th s)
+ (let* ((index (top (stack (top-frame th s))))
+ (arrayref (top (pop (stack (top-frame th s)))))
+ (array (deref arrayref (heap s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (element-at index array)
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (AASTORE) Instruction
+
+(defun execute-AASTORE (inst th s)
+ (let* ((value (top (stack (top-frame th s))))
+ (index (top (pop (stack (top-frame th s)))))
+ (arrayref (top (pop (pop (stack (top-frame th s)))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (pop (pop (stack (top-frame th s)))))
+ :heap (bind (cadr arrayref)
+ (set-element-at value
+ index
+ (deref arrayref (heap s))
+ (class-table s))
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (ACONST_NULL) Instruction
+
+(defun execute-ACONST_NULL (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push '(REF -1)
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ALOAD idx) Instruction - load a reference from the locals
+
+(defun execute-ALOAD (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (nth (arg1 inst)
+ (locals (top-frame th s)))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ALOAD_X) Instruction - load a reference from the locals
+; covers ALOAD_{0, 1, 2, 3}
+
+(defun execute-ALOAD_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (nth n (locals (top-frame th s)))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ANEWARRAY) Instruction
+
+(defun execute-ANEWARRAY (inst th s)
+ (let* ((type 'T_REF)
+ (count (top (stack (top-frame th s))))
+ (addr (len (heap s)))
+ (obj (makearray type
+ count
+ (init-array type count)
+ (class-table s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (list 'REF addr)
+ (pop (stack (top-frame th s))))
+ :heap (bind addr
+ obj
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (ARETURN) Instruction - return a reference to the preceeding frame
+
+(defun execute-ARETURN (inst th s)
+ (declare (ignore inst))
+ (let* ((val (top (stack (top-frame th s))))
+ (obj-ref (nth 0 (locals (top-frame th s))))
+ (sync-status (sync-flg (top-frame th s)))
+ (class (cur-class (top-frame th s)))
+ (ret-ref (class-decl-heapref (bound? class (class-table s))))
+ (new-heap (cond ((equal sync-status 'LOCKED)
+ (unlock-object th obj-ref (heap s)))
+ ((equal sync-status 'S_LOCKED)
+ (unlock-object th ret-ref (heap s)))
+ (t (heap s))))
+ (s1 (modify th s
+ :call-stack (pop (call-stack th s))
+ :heap new-heap)))
+ (modify th s1
+ :stack (push val (stack (top-frame th s1))))))
+
+; -----------------------------------------------------------------------------
+; (ARRAYLENGTH) Instruction
+
+(defun execute-ARRAYLENGTH (inst th s)
+ (let* ((arrayref (top (stack (top-frame th s))))
+ (array (deref arrayref (heap s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (array-bound array)
+ (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (ASTORE idx) Instruction - store a reference into the locals
+
+(defun execute-ASTORE (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :locals (update-nth (arg1 inst)
+ (top (stack (top-frame th s)))
+ (locals (top-frame th s)))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ASTORE_X) Instruction - store a reference into the locals
+; covers ASTORE_{0, 1, 2, 3}
+
+(defun execute-ASTORE_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :locals (update-nth n
+ (top (stack (top-frame th s)))
+ (locals (top-frame th s)))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (BALOAD) Instruction
+
+(defun execute-BALOAD (inst th s)
+ (let* ((index (top (stack (top-frame th s))))
+ (arrayref (top (pop (stack (top-frame th s)))))
+ (array (deref arrayref (heap s)))
+ (element (if (equal (array-type array)
+ 'T_BOOLEAN)
+ (ubyte-fix (element-at index array))
+ (byte-fix (element-at index array)))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push element
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (BASTORE) Instruction
+
+(defun execute-BASTORE (inst th s)
+ (let* ((value (top (stack (top-frame th s))))
+ (index (top (pop (stack (top-frame th s)))))
+ (arrayref (top (pop (pop (stack (top-frame th s))))))
+ (element (if (equal (array-type (deref arrayref (heap s)))
+ 'T_BYTE)
+ (byte-fix value)
+ (u-fix value 1))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (pop (pop (stack (top-frame th s)))))
+ :heap (bind (cadr arrayref)
+ (set-element-at element
+ index
+ (deref arrayref (heap s))
+ (class-table s))
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (BIPUSH const) Instruction
+
+(defun execute-BIPUSH (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (byte-fix (arg1 inst))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (CALOAD) Instruction
+
+(defun execute-CALOAD (inst th s)
+ (let* ((index (top (stack (top-frame th s))))
+ (arrayref (top (pop (stack (top-frame th s)))))
+ (array (deref arrayref (heap s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (char-fix (element-at index array))
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (CASTORE) Instruction
+
+(defun execute-CASTORE (inst th s)
+ (let* ((value (top (stack (top-frame th s))))
+ (index (top (pop (stack (top-frame th s)))))
+ (arrayref (top (pop (pop (stack (top-frame th s)))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (pop (pop (stack (top-frame th s)))))
+ :heap (bind (cadr arrayref)
+ (set-element-at (char-fix value)
+ index
+ (deref arrayref (heap s))
+ (class-table s))
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (DUP) Instruction
+
+(defun execute-DUP (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (top (stack (top-frame th s)))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (DUP_X1) Instruction
+
+(defun execute-DUP_X1 (inst th s)
+ (let* ((val1 (top (stack (top-frame th s))))
+ (val2 (top (pop (stack (top-frame th s)))))
+ (stack_prime (pop (pop (stack (top-frame th s))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push val1 (push val2 (push val1 stack_prime))))))
+
+; -----------------------------------------------------------------------------
+; (DUP_X2) Instruction
+
+(defun execute-DUP_X2 (inst th s)
+ (let* ((val1 (top (stack (top-frame th s))))
+ (val2 (top (pop (stack (top-frame th s)))))
+ (val3 (top (popn 2 (stack (top-frame th s)))))
+ (stack_prime (popn 3 (stack (top-frame th s)))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push val1
+ (push val2
+ (push val3
+ (push val1 stack_prime)))))))
+
+; -----------------------------------------------------------------------------
+; (DUP2) Instruction
+
+(defun execute-DUP2 (inst th s)
+ (let* ((val1 (top (stack (top-frame th s))))
+ (val2 (top (pop (stack (top-frame th s)))))
+ (stack_prime (pop (pop (stack (top-frame th s))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push val1
+ (push val2
+ (push val1
+ (push val2 stack_prime)))))))
+
+; -----------------------------------------------------------------------------
+; (DUP2_X1) Instruction
+
+(defun execute-DUP2_X1 (inst th s)
+ (let* ((val1 (top (stack (top-frame th s))))
+ (val2 (top (pop (stack (top-frame th s)))))
+ (val3 (top (popn 2 (stack (top-frame th s)))))
+ (stack_prime (popn 3 (stack (top-frame th s)))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push val1
+ (push val2
+ (push val3
+ (push val1
+ (push val2 stack_prime))))))))
+
+; -----------------------------------------------------------------------------
+; (DUP2_X2) Instruction
+
+(defun execute-DUP2_X2 (inst th s)
+ (let* ((val1 (top (stack (top-frame th s))))
+ (val2 (top (pop (stack (top-frame th s)))))
+ (val3 (top (popn 2 (stack (top-frame th s)))))
+ (val4 (top (popn 3 (stack (top-frame th s)))))
+ (stack_prime (popn 4 (stack (top-frame th s)))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push val1
+ (push val2
+ (push val3
+ (push val4
+ (push val1
+ (push val2 stack_prime)))))))))
+
+; -----------------------------------------------------------------------------
+; (GETFIELD "class" "field" ?long-flag?) Instruction
+
+(defun execute-GETFIELD (inst th s)
+ (let* ((class-name (arg1 inst))
+ (field-name (arg2 inst))
+ (long-flag (arg3 inst))
+ (instance (deref (top (stack (top-frame th s))) (heap s)))
+ (field-value (field-value class-name field-name instance)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (if long-flag
+ (push 0 (push field-value
+ (pop (stack (top-frame th s)))))
+ (push field-value
+ (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (GETSTATIC "class" "field" ?long-flag?) Instruction
+
+(defun static-field-value (class-name field-name s)
+ (let* ((class-ref (class-decl-heapref
+ (bound? class-name (class-table s))))
+ (instance (deref class-ref (heap s))))
+ (field-value "java.lang.Class" field-name instance)))
+
+(defun execute-GETSTATIC (inst th s)
+ (let* ((class-name (arg1 inst))
+ (field-name (arg2 inst))
+ (long-flag (arg3 inst))
+ (class-ref (class-decl-heapref
+ (bound? class-name (class-table s))))
+ (instance (deref class-ref (heap s)))
+ (field-value (field-value "java.lang.Class" field-name instance)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (if long-flag
+ (push 0 (push field-value (stack (top-frame th s))))
+ (push field-value (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (GOTO pc) Instruction
+
+(defun execute-GOTO (inst th s)
+ (modify th s
+ :pc (+ (arg1 inst) (pc (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (GOTO_W pc) Instruction
+
+(defun execute-GOTO_W (inst th s)
+ (modify th s
+ :pc (+ (arg1 inst) (pc (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (I2B) Instruction - int to byte narrowing conversion
+
+(defun execute-I2B (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (byte-fix (top (stack (top-frame th s))))
+ (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (I2C) Instruction - int to char narrowing conversion
+
+(defun execute-I2C (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (char-fix (top (stack (top-frame th s))))
+ (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (I2L) Instruction - int to long conversion
+
+(defun execute-I2L (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (long-fix (top (stack (top-frame th s))))
+ (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (I2S) Instruction - int to short narrowing conversion
+
+(defun execute-I2S (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (short-fix (top (stack (top-frame th s))))
+ (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IADD) Instruction
+
+(defun execute-IADD (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix
+ (+ (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s)))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (IALOAD) Instruction
+
+(defun execute-IALOAD (inst th s)
+ (let* ((index (top (stack (top-frame th s))))
+ (arrayref (top (pop (stack (top-frame th s)))))
+ (array (deref arrayref (heap s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (element-at index array)
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (IAND) Instruction
+
+(defun execute-IAND (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (logand (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (IASTORE) Instruction
+
+(defun execute-IASTORE (inst th s)
+ (let* ((value (top (stack (top-frame th s))))
+ (index (top (pop (stack (top-frame th s)))))
+ (arrayref (top (pop (pop (stack (top-frame th s)))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (pop (pop (stack (top-frame th s)))))
+ :heap (bind (cadr arrayref)
+ (set-element-at value
+ index
+ (deref arrayref (heap s))
+ (class-table s))
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (ICONST_X) Instruction - push a certain constant onto the stack
+; covers ICONST_{M1, 0, 1, 2, 3, 4, 5}
+
+(defun execute-ICONST_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push n (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IDIV) Instruction
+
+(defun execute-IDIV (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix
+ (truncate (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s)))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ACMPEQ pc) Instruction
+
+(defun execute-IF_ACMPEQ (inst th s)
+ (modify th s
+ :pc (if (equal (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ACMPNE pc) Instruction
+
+(defun execute-IF_ACMPNE (inst th s)
+ (modify th s
+ :pc (if (equal (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (inst-length inst) (pc (top-frame th s)))
+ (+ (arg1 inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ICMPEQ pc) Instruction
+
+(defun execute-IF_ICMPEQ (inst th s)
+ (modify th s
+ :pc (if (equal (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ICMPGE pc) Instruction
+
+(defun execute-IF_ICMPGE (inst th s)
+ (modify th s
+ :pc (if (>= (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ICMPGT pc) Instruction
+
+(defun execute-IF_ICMPGT (inst th s)
+ (modify th s
+ :pc (if (> (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ICMPLT pc) Instruction
+
+(defun execute-IF_ICMPLT (inst th s)
+ (modify th s
+ :pc (if (< (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ICMPLE pc) Instruction
+
+(defun execute-IF_ICMPLE (inst th s)
+ (modify th s
+ :pc (if (<= (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IF_ICMPNE pc) Instruction
+
+(defun execute-IF_ICMPNE (inst th s)
+ (modify th s
+ :pc (if (equal (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (+ (inst-length inst) (pc (top-frame th s)))
+ (+ (arg1 inst) (pc (top-frame th s))))
+ :stack (pop (pop (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (IFEQ pc) Instruction
+
+(defun execute-IFEQ (inst th s)
+ (modify th s
+ :pc (if (equal (top (stack (top-frame th s))) 0)
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IFGE pc) Instruction
+
+(defun execute-IFGE (inst th s)
+ (modify th s
+ :pc (if (>= (top (stack (top-frame th s))) 0)
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IFGT pc) Instruction
+
+(defun execute-IFGT (inst th s)
+ (modify th s
+ :pc (if (> (top (stack (top-frame th s))) 0)
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IFLE pc) Instruction
+
+(defun execute-IFLE (inst th s)
+ (modify th s
+ :pc (if (<= (top (stack (top-frame th s))) 0)
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IFLT pc) Instruction
+
+(defun execute-IFLT (inst th s)
+ (modify th s
+ :pc (if (< (top (stack (top-frame th s))) 0)
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IFNE pc) Instruction
+
+(defun execute-IFNE (inst th s)
+ (modify th s
+ :pc (if (equal (top (stack (top-frame th s))) 0)
+ (+ (inst-length inst) (pc (top-frame th s)))
+ (+ (arg1 inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IFNONNULL pc) Instruction
+
+(defun execute-IFNONNULL (inst th s)
+ (modify th s
+ :pc (if (equal (top (stack (top-frame th s))) '(REF -1))
+ (+ (inst-length inst) (pc (top-frame th s)))
+ (+ (arg1 inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IFNULL pc) Instruction
+
+(defun execute-IFNULL (inst th s)
+ (modify th s
+ :pc (if (equal (top (stack (top-frame th s))) '(REF -1))
+ (+ (arg1 inst) (pc (top-frame th s)))
+ (+ (inst-length inst) (pc (top-frame th s))))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IINC idx const) Instruction - Increment local variable by a constant
+
+(defun execute-IINC (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :locals (update-nth (arg1 inst)
+ (int-fix
+ (+ (arg2 inst)
+ (nth (arg1 inst)
+ (locals (top-frame th s)))))
+ (locals (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ILOAD idx) Instruction - Push a local onto the stack
+
+(defun execute-ILOAD (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (nth (arg1 inst)
+ (locals (top-frame th s)))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ILOAD_X) Instruction - Push a local onto the stack
+; covers ILOAD_{0, 1, 2, 3}
+
+(defun execute-ILOAD_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (nth n (locals (top-frame th s)))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (IMUL) Instruction
+
+(defun execute-IMUL (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix
+ (* (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s)))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (INEG) Instruction
+; Because of the way the JVM represents 2's complement ints,
+; the negation of the most negative int is itself
+
+(defun execute-INEG (inst th s)
+ (let* ((result (if (equal (top (stack (top-frame th s)))
+ *most-negative-integer*)
+ *most-negative-integer*
+ (- (top (stack (top-frame th s)))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push result (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (INSTANCEOF) Instruction
+
+(defun execute-INSTANCEOF (inst th s)
+ (let* ((ref (top (stack (top-frame th s))))
+ (obj (deref ref (heap s)))
+ (obj-class (caar obj))
+ (obj-supers (cons obj-class (class-decl-superclasses
+ (bound? obj-class (class-table s)))))
+ (value (if (nullrefp ref)
+ 0
+ (if (member-equal (arg1 inst) obj-supers)
+ 1
+ 0))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push value (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (IOR) Instruction
+
+(defun execute-IOR (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (logior (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (IREM) Instruction
+
+(defun execute-IREM (inst th s)
+ (let* ((val1 (top (pop (stack (top-frame th s)))))
+ (val2 (top (stack (top-frame th s))))
+ (result (- val1 (* (truncate val1 val2) val2))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push result
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (IRETURN) Instruction - return an int
+
+(defun execute-IRETURN (inst th s)
+ (declare (ignore inst))
+ (let* ((val (top (stack (top-frame th s))))
+ (obj-ref (nth 0 (locals (top-frame th s))))
+ (sync-status (sync-flg (top-frame th s)))
+ (class (cur-class (top-frame th s)))
+ (ret-ref (class-decl-heapref (bound? class (class-table s))))
+ (new-heap (cond ((equal sync-status 'LOCKED)
+ (unlock-object th obj-ref (heap s)))
+ ((equal sync-status 'S_LOCKED)
+ (unlock-object th ret-ref (heap s)))
+ (t (heap s))))
+ (s1 (modify th s
+ :call-stack (pop (call-stack th s))
+ :heap new-heap)))
+ (modify th s1
+ :stack (push val (stack (top-frame th s1))))))
+
+; -----------------------------------------------------------------------------
+; (ISHL) Instruction
+
+(defun execute-ISHL (inst th s)
+ (let* ((val1 (top (pop (stack (top-frame th s)))))
+ (val2 (top (stack (top-frame th s))))
+ (shiftval (5-bit-fix val2))
+ (result (shl val1 shiftval)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix result)
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (ISHR) Instruction
+
+(defun execute-ISHR (inst th s)
+ (let* ((val1 (top (pop (stack (top-frame th s)))))
+ (val2 (top (stack (top-frame th s))))
+ (shiftval (5-bit-fix val2))
+ (result (shr val1 shiftval)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix result)
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (ISTORE idx) Instruction - store an int into the locals
+
+(defun execute-ISTORE (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :locals (update-nth (arg1 inst)
+ (top (stack (top-frame th s)))
+ (locals (top-frame th s)))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ISTORE_X) Instruction - store an int into the locals
+; covers ISTORE_{0, 1, 2, 3}
+
+(defun execute-ISTORE_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :locals (update-nth n
+ (top (stack (top-frame th s)))
+ (locals (top-frame th s)))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (ISUB) Instruction
+
+(defun execute-ISUB (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix (- (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s)))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (IUSHR) Instruction
+
+(defun execute-IUSHR (inst th s)
+ (let* ((val1 (top (pop (stack (top-frame th s)))))
+ (val2 (top (stack (top-frame th s))))
+ (shiftval (5-bit-fix val2))
+ (result (shr val1 shiftval)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix result)
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (IXOR) Instruction
+
+(defun execute-IXOR (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (logxor (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (JSR) Instruction
+
+(defun execute-JSR (inst th s)
+ (modify th s
+ :pc (+ (arg1 inst) (pc (top-frame th s)))
+ :stack (push (list 'RETURNADDRESS
+ (+ (inst-length inst)
+ (pc (top-frame th s))))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (JSR_W) Instruction
+
+(defun execute-JSR_W (inst th s)
+ (modify th s
+ :pc (+ (arg1 inst) (pc (top-frame th s)))
+ :stack (push (list 'RETURNADDRESS
+ (+ (inst-length inst)
+ (pc (top-frame th s))))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (INVOKESPECIAL "class" "name" n) Instruction
+
+(defun class-name-of-ref (ref heap)
+ (car (car (deref ref heap))))
+
+(defun bind-formals (n stack)
+ (if (zp n)
+ nil
+ (cons (top stack)
+ (bind-formals (- n 1) (pop stack)))))
+
+(defun lookup-method-in-superclasses (name classes class-table)
+ (cond ((endp classes) nil)
+ (t (let* ((class-name (car classes))
+ (class-decl (bound? class-name class-table))
+ (method (bound? name (class-decl-methods class-decl))))
+ (if method
+ method
+ (lookup-method-in-superclasses name (cdr classes)
+ class-table))))))
+
+(defun lookup-method (name class-name class-table)
+ (lookup-method-in-superclasses name
+ (cons class-name
+ (class-decl-superclasses
+ (bound? class-name class-table)))
+ class-table))
+
+(defun execute-INVOKESPECIAL (inst th s)
+ (let* ((method-name (arg2 inst))
+ (nformals (arg3 inst))
+ (obj-ref (top (popn nformals (stack (top-frame th s)))))
+ (instance (deref obj-ref (heap s)))
+ (obj-class-name (arg1 inst))
+ (closest-method
+ (lookup-method method-name
+ obj-class-name
+ (class-table s)))
+ (prog (method-program closest-method))
+ (s1 (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (popn (+ nformals 1)
+ (stack (top-frame th s)))))
+ (tThread (rrefToThread obj-ref (thread-table s))))
+ (cond
+ ((method-isNative? closest-method)
+ (cond ((equal method-name "start")
+ (modify tThread s1 :status 'SCHEDULED))
+ ((equal method-name "stop")
+ (modify tThread s1
+ :status 'UNSCHEDULED))
+ (t s)))
+ ((and (method-sync closest-method)
+ (objectLockable? instance th))
+ (modify th s1
+ :call-stack
+ (push (make-frame 0
+ (reverse
+ (bind-formals (+ nformals 1)
+ (stack (top-frame th s))))
+ nil
+ prog
+ 'LOCKED
+ (arg1 inst))
+ (call-stack th s1))
+ :heap (lock-object th obj-ref (heap s))))
+ ((method-sync closest-method)
+ s)
+ (t
+ (modify th s1
+ :call-stack
+ (push (make-frame 0
+ (reverse
+ (bind-formals (+ nformals 1)
+ (stack (top-frame th s))))
+ nil
+ prog
+ 'UNLOCKED
+ (arg1 inst))
+ (call-stack th s1)))))))
+
+; -----------------------------------------------------------------------------
+; (INVOKESTATIC "class" "name" n) Instruction
+
+(defun execute-INVOKESTATIC (inst th s)
+ (let* ((class (arg1 inst))
+ (method-name (arg2 inst))
+ (nformals (arg3 inst))
+ (obj-ref (class-decl-heapref (bound? class (class-table s))))
+ (instance (deref obj-ref (heap s)))
+ (closest-method
+ (lookup-method method-name
+ (arg1 inst)
+ (class-table s)))
+ (prog (method-program closest-method))
+ (s1 (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (popn nformals (stack (top-frame th s))))))
+ (cond
+ ((and (method-sync closest-method)
+ (objectLockable? instance th))
+ (modify th s1
+ :call-stack
+ (push (make-frame 0
+ (reverse
+ (bind-formals nformals
+ (stack (top-frame th s))))
+ nil
+ prog
+ 'S_LOCKED
+ (arg1 inst))
+ (call-stack th s1))
+ :heap (lock-object th obj-ref (heap s))))
+ ((method-sync closest-method)
+ s)
+ (t
+ (modify th s1
+ :call-stack
+ (push (make-frame 0
+ (reverse
+ (bind-formals nformals
+ (stack (top-frame th s))))
+ nil
+ prog
+ 'UNLOCKED
+ (arg1 inst))
+ (call-stack th s1)))))))
+
+; -----------------------------------------------------------------------------
+; (INVOKEVIRTUAL "class" "name" n) Instruction
+
+(defun execute-INVOKEVIRTUAL (inst th s)
+ (let* ((method-name (arg2 inst))
+ (nformals (arg3 inst))
+ (obj-ref (top (popn nformals (stack (top-frame th s)))))
+ (instance (deref obj-ref (heap s)))
+ (obj-class-name (class-name-of-ref obj-ref (heap s)))
+ (closest-method
+ (lookup-method method-name
+ obj-class-name
+ (class-table s)))
+ (prog (method-program closest-method))
+ (s1 (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (popn (+ nformals 1)
+ (stack (top-frame th s)))))
+ (tThread (rrefToThread obj-ref (thread-table s))))
+ (cond
+ ((method-isNative? closest-method)
+ (cond ((equal method-name "start")
+ (modify tThread s1 :status 'SCHEDULED))
+ ((equal method-name "stop")
+ (modify tThread s1
+ :status 'UNSCHEDULED))
+ (t s)))
+ ((and (method-sync closest-method)
+ (objectLockable? instance th))
+ (modify th s1
+ :call-stack
+ (push (make-frame 0
+ (reverse
+ (bind-formals (+ nformals 1)
+ (stack (top-frame th s))))
+ nil
+ prog
+ 'LOCKED
+ (arg1 inst))
+ (call-stack th s1))
+ :heap (lock-object th obj-ref (heap s))))
+ ((method-sync closest-method)
+ s)
+ (t
+ (modify th s1
+ :call-stack
+ (push (make-frame 0
+ (reverse
+ (bind-formals (+ nformals 1)
+ (stack (top-frame th s))))
+ nil
+ prog
+ 'UNLOCKED
+ (arg1 inst))
+ (call-stack th s1)))))))
+
+; -----------------------------------------------------------------------------
+; (L2I) Instruction - long to int narrowing conversion
+
+(defun execute-L2I (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (int-fix (top (pop (stack (top-frame th s)))))
+ (pop (pop (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (LADD) Instruction - Add to longs from the top of the stack
+
+(defun execute-LADD (inst th s)
+ (let* ((val1 (top (pop (stack (top-frame th s)))))
+ (val2 (top (popn 3 (stack (top-frame th s))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (long-fix (+ val1 val2))
+ (popn 4 (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (LALOAD) Instruction
+
+(defun execute-LALOAD (inst th s)
+ (let* ((index (top (stack (top-frame th s))))
+ (arrayref (top (pop (stack (top-frame th s)))))
+ (array (deref arrayref (heap s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (element-at index array)
+ (pop (pop (stack (top-frame th s)))))))))
+
+; -----------------------------------------------------------------------------
+; (LAND) Instruction
+
+(defun execute-LAND (inst th s)
+ (let* ((val1 (top (pop (stack (top-frame th s)))))
+ (val2 (top (popn 3 (stack (top-frame th s))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (logand val1 val2)
+ (popn 4 (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (LASTORE) Instruction
+
+(defun execute-LASTORE (inst th s)
+ (let* ((value (top (pop (stack (top-frame th s)))))
+ (index (top (pop (pop (stack (top-frame th s))))))
+ (arrayref (top (popn 3 (stack (top-frame th s))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (popn 4 (stack (top-frame th s)))
+ :heap (bind (cadr arrayref)
+ (set-element-at value
+ index
+ (deref arrayref (heap s))
+ (class-table s))
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (LCMP) Instruction - compare two longs
+; val1 > val2 --> 1
+; val1 = val2 --> 0
+; val1 < val2 --> -1
+
+(defun execute-LCMP (inst th s)
+ (let* ((val2 (top (pop (stack (top-frame th s)))))
+ (val1 (top (popn 3 (stack (top-frame th s)))))
+ (result (cond ((> val1 val2) 1)
+ ((< val1 val2) -1)
+ (t 0))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push result
+ (popn 4 (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (LCONST_X) Instruction - push a certain long constant onto the stack
+; covers LCONST_{0, 1}
+
+(defun execute-LCONST_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push n (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (LDC) Instruction
+
+(defun set-instance-field (class-name field-name value instance)
+ (bind class-name
+ (bind field-name value
+ (binding class-name instance))
+ instance))
+
+(defun execute-LDC (inst th s)
+ (let* ((class (cur-class (top-frame th s)))
+ (cp (retrieve-cp class (class-table s)))
+ (entry (nth (arg1 inst) cp))
+ (value (cadr entry)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push value (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (LDC2_W) Instruction
+
+(defun execute-LDC2_W (inst th s)
+ (let* ((class (cur-class (top-frame th s)))
+ (cp (retrieve-cp class (class-table s)))
+ (entry (nth (arg1 inst) cp))
+ (value (cadr entry)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push value (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (LDIV) Instruction
+
+(defun execute-LDIV (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push
+ (long-fix
+ (truncate (top (popn 3 (stack (top-frame th s))))
+ (top (pop (stack (top-frame th s))))))
+ (popn 4 (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (LLOAD idx) Instruction - Push a long local onto the stack
+
+(defun execute-LLOAD (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (nth (arg1 inst)
+ (locals (top-frame th s)))
+ (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (LLOAD_X) Instruction - Push a long local onto the stack
+; covers LLOAD_{0, 1, 2, 3}
+
+(defun execute-LLOAD_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (nth n (locals (top-frame th s)))
+ (stack (top-frame th s))))))
+
+; -----------------------------------------------------------------------------
+; (LMUL) Instruction
+
+(defun execute-LMUL (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (ulong-fix
+ (* (top (pop (stack (top-frame th s))))
+ (top (popn 3 (stack (top-frame th s))))))
+ (popn 4 (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (LNEG) Instruction
+; Because of the way the JVM represents 2's complement ints,
+; the negation of the most negative int is itself
+
+(defun execute-LNEG (inst th s)
+ (let* ((result (if (equal (top (pop (stack (top-frame th s))))
+ *most-negative-long*)
+ *most-negative-long*
+ (- (top (pop (stack (top-frame th s))))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push result (popn 2 (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (LOR) Instruction
+
+(defun execute-LOR (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (logior (top (pop (stack (top-frame th s))))
+ (top (popn 3 (stack (top-frame th s)))))
+ (popn 4 (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (LREM) Instruction
+
+(defun execute-LREM (inst th s)
+ (let* ((val1 (top (pop (stack (top-frame th s)))))
+ (val2 (top (popn 3 (stack (top-frame th s)))))
+ (result (- val1 (* (truncate val1 val2) val2))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push result
+ (popn 4 (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (LRETURN) Instruction - return a long
+
+(defun execute-LRETURN (inst th s)
+ (declare (ignore inst))
+ (let* ((val (top (pop (stack (top-frame th s)))))
+ (obj-ref (nth 0 (locals (top-frame th s))))
+ (sync-status (sync-flg (top-frame th s)))
+ (class (cur-class (top-frame th s)))
+ (ret-ref (class-decl-heapref (bound? class (class-table s))))
+ (new-heap (cond ((equal sync-status 'LOCKED)
+ (unlock-object th obj-ref (heap s)))
+ ((equal sync-status 'S_LOCKED)
+ (unlock-object th ret-ref (heap s)))
+ (t (heap s))))
+ (s1 (modify th s
+ :call-stack (pop (call-stack th s))
+ :heap new-heap)))
+ (modify th s1
+ :stack (push 0 (push val (stack (top-frame th s1)))))))
+
+; -----------------------------------------------------------------------------
+; (LSHL) Instruction
+
+(defun execute-LSHL (inst th s)
+ (let* ((val1 (top (popn 2 (stack (top-frame th s)))))
+ (val2 (top (stack (top-frame th s))))
+ (shiftval (6-bit-fix val2))
+ (result (shl val1 shiftval)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (long-fix result)
+ (popn 3 (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (LSHR) Instruction
+
+(defun execute-LSHR (inst th s)
+ (let* ((val1 (top (popn 2 (stack (top-frame th s)))))
+ (val2 (top (stack (top-frame th s))))
+ (shiftval (6-bit-fix val2))
+ (result (shr val1 shiftval)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (long-fix result)
+ (popn 3 (pop (stack (top-frame th s)))))))))
+
+; -----------------------------------------------------------------------------
+; (LSTORE idx) Instruction - store a long into the locals
+
+(defun execute-LSTORE (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :locals (update-nth (arg1 inst)
+ (top (pop (stack (top-frame th s))))
+ (locals (top-frame th s)))
+ :stack (popn 2 (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (LSTORE_X) Instruction - store a long into the locals
+; covers LSTORE_{0, 1, 2, 3}
+
+(defun execute-LSTORE_X (inst th s n)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :locals (update-nth n
+ (top (pop (stack (top-frame th s))))
+ (locals (top-frame th s)))
+ :stack (popn 2 (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (LSUB) Instruction
+
+(defun execute-LSUB (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push
+ (ulong-fix (- (top (popn 3 (stack (top-frame th s))))
+ (top (pop (stack (top-frame th s))))))
+ (popn 4 (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (LUSHR) Instruction
+
+(defun execute-LUSHR (inst th s)
+ (let* ((val1 (top (popn 2 (stack (top-frame th s)))))
+ (val2 (top (stack (top-frame th s))))
+ (shiftval (6-bit-fix val2))
+ (result (shr val1 shiftval)))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (long-fix result)
+ (popn 3 (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (LXOR) Instruction
+
+(defun execute-LXOR (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push 0
+ (push (logxor (top (pop (stack (top-frame th s))))
+ (top (popn 3 (stack (top-frame th s)))))
+ (popn 4 (stack (top-frame th s)))))))
+
+; -----------------------------------------------------------------------------
+; (MONITORENTER) Instruction
+
+(defun execute-MONITORENTER (inst th s)
+ (let* ((obj-ref (top (stack (top-frame th s))))
+ (instance (deref obj-ref (heap s))))
+ (cond
+ ((objectLockable? instance th)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (stack (top-frame th s)))
+ :heap (lock-object th obj-ref (heap s))))
+ (t s))))
+
+; -----------------------------------------------------------------------------
+; (MONITOREXIT) Instruction
+
+(defun execute-MONITOREXIT (inst th s)
+ (let* ((obj-ref (top (stack (top-frame th s))))
+ (instance (deref obj-ref (heap s))))
+ (cond
+ ((objectUnLockable? instance th)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (stack (top-frame th s)))
+ :heap (unlock-object th obj-ref (heap s))))
+ (t s))))
+
+; -----------------------------------------------------------------------------
+; (MULTIANEWARRAY) Instruction
+
+(defun execute-MULTIANEWARRAY (inst th s)
+ (let* ((dimentions (arg1 inst))
+ (counts (reverse (take dimentions (stack (top-frame th s))))))
+ (mv-let (addr new-heap)
+ (makemultiarray counts s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (list 'REF addr)
+ (nthcdr dimentions (stack (top-frame th s))))
+ :heap new-heap))))
+
+; -----------------------------------------------------------------------------
+; (NEW "class") Instruction
+
+(defun execute-NEW (inst th s)
+ (let* ((class-name (arg1 inst))
+ (class-table (class-table s))
+ (closest-method (lookup-method "run" class-name class-table))
+ (prog (method-program closest-method))
+ (new-object (build-an-instance
+ (cons class-name
+ (class-decl-superclasses
+ (bound? class-name class-table)))
+ class-table))
+ (new-address (len (heap s)))
+ (s1 (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (list 'REF new-address)
+ (stack (top-frame th s)))
+ :heap (bind new-address new-object (heap s)))))
+ (if (isThreadObject? class-name class-table)
+ (modify nil s1
+ :thread-table
+ (addto-tt
+ (push
+ (make-frame 0
+ (list (list 'REF new-address))
+ nil
+ prog
+ 'UNLOCKED
+ class-name)
+ nil)
+ 'UNSCHEDULED
+ (list 'REF new-address)
+ (thread-table s1)))
+ s1)))
+
+; -----------------------------------------------------------------------------
+; (NEWARRAY) Instruction
+
+(defun execute-NEWARRAY (inst th s)
+ (let* ((type (arg1 inst))
+ (count (top (stack (top-frame th s))))
+ (addr (len (heap s)))
+ (obj (makearray type
+ count
+ (init-array type count)
+ (class-table s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (list 'REF addr)
+ (pop (stack (top-frame th s))))
+ :heap (bind addr
+ obj
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (NOP) Instruction
+
+(defun execute-NOP (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (POP) Instruction
+
+(defun execute-POP (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (POP2) Instruction
+
+(defun execute-POP2 (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (popn 2 (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (PUTFIELD "class" "field" ?long-flag?) Instruction
+
+(defun execute-PUTFIELD (inst th s)
+ (let* ((class-name (arg1 inst))
+ (field-name (arg2 inst))
+ (long-flag (arg3 inst))
+ (value (if long-flag
+ (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s)))))
+ (instance (if long-flag
+ (deref (top (popn 2 (stack (top-frame th s)))) (heap s))
+ (deref (top (pop (stack (top-frame th s)))) (heap s))))
+ (address (cadr (if long-flag
+ (top (popn 2 (stack (top-frame th s))))
+ (top (pop (stack (top-frame th s))))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (if long-flag
+ (popn 3 (stack (top-frame th s)))
+ (pop (pop (stack (top-frame th s)))))
+ :heap (bind address
+ (set-instance-field class-name
+ field-name
+ value
+ instance)
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (PUTSTATIC "class" "field" ?long-flag?) Instruction
+
+(defun execute-PUTSTATIC (inst th s)
+ (let* ((class-name (arg1 inst))
+ (field-name (arg2 inst))
+ (long-flag (arg3 inst))
+ (class-ref (class-decl-heapref
+ (bound? class-name (class-table s))))
+ (value (if long-flag
+ (top (pop (stack (top-frame th s))))
+ (top (stack (top-frame th s)))))
+ (instance (deref class-ref (heap s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (if long-flag
+ (popn 2 (stack (top-frame th s)))
+ (pop (stack (top-frame th s))))
+ :heap (bind (cadr class-ref)
+ (set-instance-field "java.lang.Class"
+ field-name
+ value
+ instance)
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (RET) Instruction
+
+(defun execute-RET (inst th s)
+ (let* ((ret-addr (nth (arg1 inst) (locals (top-frame th s))))
+ (addr (cadr ret-addr)))
+ (modify th s :pc addr)))
+
+; -----------------------------------------------------------------------------
+; (RETURN) Instruction - Void Return
+
+(defun execute-RETURN (inst th s)
+ (declare (ignore inst))
+ (let* ((obj-ref (nth 0 (locals (top-frame th s))))
+ (sync-status (sync-flg (top-frame th s)))
+ (class (cur-class (top-frame th s)))
+ (ret-ref (class-decl-heapref (bound? class (class-table s))))
+ (new-heap (cond ((equal sync-status 'LOCKED)
+ (unlock-object th obj-ref (heap s)))
+ ((equal sync-status 'S_LOCKED)
+ (unlock-object th ret-ref (heap s)))
+ (t (heap s)))))
+ (modify th s
+ :call-stack (pop (call-stack th s))
+ :heap new-heap)))
+
+; -----------------------------------------------------------------------------
+; (SALOAD) Instruction
+
+(defun execute-SALOAD (inst th s)
+ (let* ((index (top (stack (top-frame th s))))
+ (arrayref (top (pop (stack (top-frame th s)))))
+ (array (deref arrayref (heap s))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (element-at index array)
+ (pop (pop (stack (top-frame th s))))))))
+
+; -----------------------------------------------------------------------------
+; (SASTORE) Instruction
+
+(defun execute-SASTORE (inst th s)
+ (let* ((value (top (stack (top-frame th s))))
+ (index (top (pop (stack (top-frame th s)))))
+ (arrayref (top (pop (pop (stack (top-frame th s)))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (pop (pop (pop (stack (top-frame th s)))))
+ :heap (bind (cadr arrayref)
+ (set-element-at (short-fix value)
+ index
+ (deref arrayref (heap s))
+ (class-table s))
+ (heap s)))))
+
+; -----------------------------------------------------------------------------
+; (SIPUSH const) Instruction
+
+(defun execute-SIPUSH (inst th s)
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push (short-fix (arg1 inst))
+ (stack (top-frame th s)))))
+
+; -----------------------------------------------------------------------------
+; (SWAP) Instruction
+
+(defun execute-SWAP (inst th s)
+ (let* ((val1 (top (stack (top-frame th s))))
+ (val2 (top (pop (stack (top-frame th s))))))
+ (modify th s
+ :pc (+ (inst-length inst) (pc (top-frame th s)))
+ :stack (push val2
+ (push val1
+ (pop (pop (stack (top-frame th s)))))))))
+
+; -----------------------------------------------------------------------------
+; Putting it all together
+
+(defun index-into-program (byte-offset program)
+ (declare (xargs :measure (len program)))
+ (if (endp program)
+ nil
+ (if (zp byte-offset)
+ (car program)
+ (index-into-program (- byte-offset
+ (inst-length (car program)))
+ (cdr program)))))
+
+(defun next-inst (th s)
+ (index-into-program (pc (top-frame th s))
+ (program (top-frame th s))))
+
+(defun do-inst (inst th s)
+ (case (op-code inst)
+ (AALOAD (execute-AALOAD inst th s))
+ (AASTORE (execute-AASTORE inst th s))
+ (ACONST_NULL (execute-ACONST_NULL inst th s))
+ (ALOAD (execute-ALOAD inst th s))
+ (ALOAD_0 (execute-ALOAD_X inst th s 0))
+ (ALOAD_1 (execute-ALOAD_X inst th s 1))
+ (ALOAD_2 (execute-ALOAD_X inst th s 2))
+ (ALOAD_3 (execute-ALOAD_X inst th s 3))
+ (ANEWARRAY (execute-ANEWARRAY inst th s))
+ (ARETURN (execute-ARETURN inst th s))
+ (ARRAYLENGTH (execute-ARRAYLENGTH inst th s))
+ (ASTORE (execute-ASTORE inst th s))
+ (ASTORE_0 (execute-ASTORE_X inst th s 0))
+ (ASTORE_1 (execute-ASTORE_X inst th s 1))
+ (ASTORE_2 (execute-ASTORE_X inst th s 2))
+ (ASTORE_3 (execute-ASTORE_X inst th s 3))
+ (BALOAD (execute-BALOAD inst th s))
+ (BASTORE (execute-BASTORE inst th s))
+ (BIPUSH (execute-BIPUSH inst th s))
+ (CALOAD (execute-CALOAD inst th s))
+ (CASTORE (execute-CASTORE inst th s))
+ (DUP (execute-DUP inst th s))
+ (DUP_X1 (execute-DUP_X1 inst th s))
+ (DUP_X2 (execute-DUP_X2 inst th s))
+ (DUP2 (execute-DUP2 inst th s))
+ (DUP2_X1 (execute-DUP2_X1 inst th s))
+ (DUP2_X2 (execute-DUP2_X2 inst th s))
+ (GETFIELD (execute-GETFIELD inst th s))
+ (GETSTATIC (execute-GETSTATIC inst th s))
+ (GOTO (execute-GOTO inst th s))
+ (GOTO_W (execute-GOTO_W inst th s))
+ (I2B (execute-I2B inst th s))
+ (I2C (execute-I2C inst th s))
+ (I2L (execute-I2L inst th s))
+ (I2S (execute-I2S inst th s))
+ (IADD (execute-IADD inst th s))
+ (IALOAD (execute-IALOAD inst th s))
+ (IAND (execute-IAND inst th s))
+ (IASTORE (execute-IASTORE inst th s))
+ (ICONST_M1 (execute-ICONST_X inst th s -1))
+ (ICONST_0 (execute-ICONST_X inst th s 0))
+ (ICONST_1 (execute-ICONST_X inst th s 1))
+ (ICONST_2 (execute-ICONST_X inst th s 2))
+ (ICONST_3 (execute-ICONST_X inst th s 3))
+ (ICONST_4 (execute-ICONST_X inst th s 4))
+ (ICONST_5 (execute-ICONST_X inst th s 5))
+ (IDIV (execute-IDIV inst th s))
+ (IF_ACMPEQ (execute-IF_ACMPEQ inst th s))
+ (IF_ACMPNE (execute-IF_ACMPNE inst th s))
+ (IF_ICMPEQ (execute-IF_ICMPEQ inst th s))
+ (IF_ICMPGE (execute-IF_ICMPGE inst th s))
+ (IF_ICMPGT (execute-IF_ICMPGT inst th s))
+ (IF_ICMPLE (execute-IF_ICMPLE inst th s))
+ (IF_ICMPLT (execute-IF_ICMPLT inst th s))
+ (IF_ICMPNE (execute-IF_ICMPNE inst th s))
+ (IFEQ (execute-IFEQ inst th s))
+ (IFGE (execute-IFGE inst th s))
+ (IFGT (execute-IFGT inst th s))
+ (IFLE (execute-IFLE inst th s))
+ (IFLT (execute-IFLT inst th s))
+ (IFNE (execute-IFNE inst th s))
+ (IFNONNULL (execute-IFNONNULL inst th s))
+ (IFNULL (execute-IFNULL inst th s))
+ (IINC (execute-IINC inst th s))
+ (ILOAD (execute-ILOAD inst th s))
+ (ILOAD_0 (execute-ILOAD_X inst th s 0))
+ (ILOAD_1 (execute-ILOAD_X inst th s 1))
+ (ILOAD_2 (execute-ILOAD_X inst th s 2))
+ (ILOAD_3 (execute-ILOAD_X inst th s 3))
+ (IMUL (execute-IMUL inst th s))
+ (INEG (execute-INEG inst th s))
+ (INSTANCEOF (execute-INSTANCEOF inst th s))
+ (INVOKESPECIAL (execute-INVOKESPECIAL inst th s))
+ (INVOKESTATIC (execute-INVOKESTATIC inst th s))
+ (INVOKEVIRTUAL (execute-INVOKEVIRTUAL inst th s))
+ (IOR (execute-IOR inst th s))
+ (IREM (execute-IREM inst th s))
+ (IRETURN (execute-IRETURN inst th s))
+ (ISHL (execute-ISHL inst th s))
+ (ISHR (execute-ISHR inst th s))
+ (ISTORE (execute-ISTORE inst th s))
+ (ISTORE_0 (execute-ISTORE_X inst th s 0))
+ (ISTORE_1 (execute-ISTORE_X inst th s 1))
+ (ISTORE_2 (execute-ISTORE_X inst th s 2))
+ (ISTORE_3 (execute-ISTORE_X inst th s 3))
+ (ISUB (execute-ISUB inst th s))
+ (IUSHR (execute-IUSHR inst th s))
+ (IXOR (execute-IXOR inst th s))
+ (JSR (execute-JSR inst th s))
+ (JSR_W (execute-JSR_W inst th s))
+ (L2I (execute-L2I inst th s))
+ (LADD (execute-LADD inst th s))
+ (LALOAD (execute-LALOAD inst th s))
+ (LAND (execute-LAND inst th s))
+ (LASTORE (execute-LASTORE inst th s))
+ (LCMP (execute-LCMP inst th s))
+ (LCONST_0 (execute-LCONST_X inst th s 0))
+ (LCONST_1 (execute-LCONST_X inst th s 1))
+ (LDC (execute-LDC inst th s))
+ (LDC_W (execute-LDC inst th s))
+ (LDC2_W (execute-LDC2_W inst th s))
+ (LDIV (execute-LDIV inst th s))
+ (LLOAD (execute-LLOAD inst th s))
+ (LLOAD_0 (execute-LLOAD_X inst th s 0))
+ (LLOAD_1 (execute-LLOAD_X inst th s 1))
+ (LLOAD_2 (execute-LLOAD_X inst th s 2))
+ (LLOAD_3 (execute-LLOAD_X inst th s 3))
+ (LMUL (execute-LMUL inst th s))
+ (LNEG (execute-LNEG inst th s))
+ (LOR (execute-LOR inst th s))
+ (LREM (execute-LREM inst th s))
+ (LRETURN (execute-LRETURN inst th s))
+ (LSHL (execute-LSHL inst th s))
+ (LSHR (execute-LSHR inst th s))
+ (LSTORE (execute-LSTORE inst th s))
+ (LSTORE_0 (execute-LSTORE_X inst th s 0))
+ (LSTORE_1 (execute-LSTORE_X inst th s 1))
+ (LSTORE_2 (execute-LSTORE_X inst th s 2))
+ (LSTORE_3 (execute-LSTORE_X inst th s 3))
+ (LSUB (execute-LSUB inst th s))
+ (LUSHR (execute-LUSHR inst th s))
+ (LXOR (execute-LXOR inst th s))
+ (MONITORENTER (execute-MONITORENTER inst th s))
+ (MONITOREXIT (execute-MONITOREXIT inst th s))
+ (MULTIANEWARRAY (execute-MULTIANEWARRAY inst th s))
+ (NEW (execute-NEW inst th s))
+ (NEWARRAY (execute-NEWARRAY inst th s))
+ (NOP (execute-NOP inst th s))
+ (POP (execute-POP inst th s))
+ (POP2 (execute-POP2 inst th s))
+ (PUTFIELD (execute-PUTFIELD inst th s))
+ (PUTSTATIC (execute-PUTSTATIC inst th s))
+ (RET (execute-RET inst th s))
+ (RETURN (execute-RETURN inst th s))
+ (SALOAD (execute-SALOAD inst th s))
+ (SASTORE (execute-SASTORE inst th s))
+ (SIPUSH (execute-SIPUSH inst th s))
+ (SWAP (execute-SWAP inst th s))
+ (HALT s)
+ (otherwise s)))
+
+(defun step (th s)
+ (if (equal (status th s) 'SCHEDULED)
+ (do-inst (next-inst th s) th s)
+ s))
+
+(defun run (sched s)
+ (if (endp sched)
+ s
+ (run (cdr sched) (step (car sched) s))))
+
+; Begin the simulator
+;
+
+(defun ack2 (num n lst)
+ (if (zp n)
+ lst
+ (ack2 num (- n 1) (cons num lst))))
+
+(defun ack0 (n)
+ (ack2 0 n nil))
+
+(acl2::set-state-ok t)
+
+(defun sim-loop (s acl2::state)
+ (declare (acl2::xargs :mode :program))
+ (prog2$
+ (acl2::cw "~%>>") ;;; Print prompt
+ (acl2::mv-let
+ (flg cmd acl2::state)
+ (acl2::read-object acl2::*standard-oi* acl2::state) ;;; read next command
+ (declare (ignore flg))
+ (cond
+ ((equal cmd :q) (acl2::value t)) ;;; quit on :q
+ ((and (consp cmd) ;;; recognize (step i) and (step i j)
+ (acl2::eq (car cmd) 'step) ;;; where i and j are integers
+ (true-listp cmd)
+ (consp (cdr cmd))
+ (integerp (cadr cmd))
+ (or (acl2::null (cddr cmd))
+ (and (integerp (caddr cmd))
+ (acl2::null (cdddr cmd)))))
+ (let ((thread (cadr cmd))
+ (n (if (cddr cmd) (caddr cmd) 1)))
+ (sim-loop (run (ack2 thread n nil) s) acl2::state)))
+ (t (acl2::mv-let (flg val acl2::state)
+ (acl2::simple-translate-and-eval cmd
+ (list (cons 's s))
+ nil
+ "Your command" 'sim
+ (acl2::w acl2::state)
+ acl2::state
+ nil)
+ (prog2$
+ (cond (flg nil)
+ (t (acl2::cw "~x0~%" (cdr val))))
+ (sim-loop s acl2::state))))))))
+
+(defun sim (s acl2::state)
+ (declare (acl2::xargs :mode :program))
+ (prog2$
+ (acl2::cw "~%M5 Simulator.~%~%")
+ (sim-loop s acl2::state)))
+
+; A small assembler to resolve labels into relative byte addresses
+;
+; Labels are symbols in the "LABEL" package. Examples include:
+; LABEL::JUMP LABEL::FOR LABEL::START1
+;
+; To denote the jump-to point, insert a label before the opcode
+;
+; '((aconst_null) '((aconst_null)
+; (goto LABEL::TARGET) (goto 5)
+; (iconst_0) =====> (iconst_0)
+; (iconst_2) (iconst_2)
+; (LABEL::TARGET ADD) (add)
+; (ireturn)) (ireturn))
+
+(defun isLabel? (sym)
+ (and (symbolp sym)
+ (equal (symbol-package-name sym) "LABEL")))
+
+(defun isLabeledInst? (inst)
+ (isLabel? (car inst)))
+
+(defun gen_label_alist (bytecodes cur_pc label_alist)
+ (if (endp bytecodes)
+ label_alist
+ (let* ((bare_inst (if (isLabeledInst? (car bytecodes))
+ (cdr (car bytecodes))
+ (car bytecodes))))
+ (gen_label_alist (cdr bytecodes)
+ (+ cur_pc
+ (inst-length bare_inst))
+ (if (isLabeledInst? (car bytecodes))
+ (bind (car (car bytecodes))
+ cur_pc
+ label_alist)
+ label_alist)))))
+
+(defun resolve_labels (bytecodes cur_pc label_alist)
+ (if (endp bytecodes)
+ nil
+ (let* ((inst (car bytecodes))
+ (bare-inst (if (isLabeledInst? inst)
+ (cdr inst)
+ inst))
+ (resolved-inst (if (isLabel? (arg1 bare-inst))
+ (list (op-code bare-inst)
+ (- (binding (arg1 bare-inst)
+ label_alist)
+ cur_pc))
+ bare-inst)))
+ (append (list resolved-inst)
+ (resolve_labels (cdr bytecodes)
+ (+ cur_pc
+ (inst-length bare-inst))
+ label_alist)))))
+
+; resolve_basic_block takes a method and resolves all of the labels
+;
+; note that the JVM restricts jumps to within the method
+
+(defun resolve_basic_block (bytecodes)
+ (resolve_labels bytecodes
+ 0
+ (gen_label_alist bytecodes 0 nil)))
+
+; The following functions are used to strip a state down to resolve
+; all of the basic blocks and build up the newly resolved state
+
+; resolving thread tables
+;
+(defun assemble_frame (frame)
+ (make-frame (pc frame)
+ (locals frame)
+ (stack frame)
+ (resolve_basic_block (program frame))
+ (sync-flg frame)
+ (cur-class frame)))
+
+(defun assemble_call_stack (cs)
+ (if (endp cs)
+ nil
+ (cons (assemble_frame (car cs))
+ (assemble_call_stack (cdr cs)))))
+
+(defun assemble_thread (thread)
+ (list (assemble_call_stack (car thread))
+ (cadr thread)
+ (caddr thread)))
+
+(defun assemble_thread_table (tt)
+ (if (endp tt)
+ nil
+ (cons (cons (caar tt)
+ (assemble_thread (cdar tt)))
+ (assemble_thread_table (cdr tt)))))
+
+; resolving class tables
+;
+(defun assemble_method (method)
+ (append (list (method-name method)
+ (method-formals method)
+ (method-sync method))
+ (resolve_basic_block (method-program method))))
+
+(defun assemble_methods (methods)
+ (if (endp methods)
+ nil
+ (cons (assemble_method (car methods))
+ (assemble_methods (cdr methods)))))
+
+(defun assemble_class (class)
+ (make-class-decl (class-decl-name class)
+ (class-decl-superclasses class)
+ (class-decl-fields class)
+ (class-decl-sfields class)
+ (class-decl-cp class)
+ (assemble_methods (class-decl-methods class))
+ (class-decl-heapref class)))
+
+(defun assemble_class_table (ct)
+ (if (endp ct)
+ nil
+ (cons (assemble_class (car ct))
+ (assemble_class_table (cdr ct)))))
+
+(defun assemble_state (s)
+ (make-state (assemble_thread_table (thread-table s))
+ (heap s)
+ (assemble_class_table (class-table s))))
+
+; -----------------------------------------------------------------------------
+; load_class_library: a utility for populating the heap with Class and
+; String objects
+
+(defun make-string-obj (class cpentry s idx)
+ (let* ((new-object (build-an-instance
+ (cons "java.lang.String"
+ (class-decl-superclasses
+ (bound? "java.lang.String" (class-table s))))
+ (class-table s)))
+ (stuffed-obj (set-instance-field "java.lang.String"
+ "strcontents"
+ (caddr cpentry)
+ new-object))
+ (new-address (len (heap s))))
+ (modify th s
+ :heap (bind new-address stuffed-obj (heap s))
+ :class-table (update-ct-string-ref
+ class
+ idx
+ (list 'REF new-address)
+ (class-table s)))))
+
+
+(defun resolve-string-constants (class cp s idx)
+ (cond ((endp cp) s)
+ ((equal (caar cp) 'STRING)
+ (resolve-string-constants class
+ (cdr cp)
+ (make-string-obj class (car cp) s idx)
+ (+ idx 1)))
+ (t (resolve-string-constants class (cdr cp) s (+ idx 1)))))
+
+
+(defun gen_class_obj (class s)
+ (let* ((new-state (resolve-string-constants class
+ (retrieve-cp class (class-table s))
+ s
+ 0))
+ (new-heap (heap new-state))
+ (new-ct (class-table new-state))
+ (new-object (build-a-class-instance
+ (class-decl-sfields (bound? class new-ct))
+ new-ct))
+ (stuffed-obj (set-instance-field "java.lang.Class"
+ "<name>"
+ class
+ new-object))
+ (new-address (len new-heap))
+ (old-class-ent (bound? class new-ct))
+ (new-class-ent
+ (make-class-decl (class-decl-name old-class-ent)
+ (class-decl-superclasses old-class-ent)
+ (class-decl-fields old-class-ent)
+ (class-decl-sfields old-class-ent)
+ (class-decl-cp old-class-ent)
+ (class-decl-methods old-class-ent)
+ (list 'REF new-address)))
+ (new-class-table (bind class
+ (cdr new-class-ent)
+ new-ct)))
+ (make-state (thread-table s)
+ (bind new-address stuffed-obj new-heap)
+ new-class-table)))
+
+(defun ld_class_lib (classes s)
+ (if (endp classes)
+ s
+ (ld_class_lib (cdr classes) (gen_class_obj (car classes) s))))
+
+(defun load_class_library (s)
+ (ld_class_lib (strip-cars (class-table s)) s))
+
+; -----------------------------------------------------------------------------
+; m5_load: both load and resolve a given state
+
+(defun m5_load (s)
+ (load_class_library (assemble_state s)))
+
diff --git a/books/workshops/2003/moore_vcg/support/utilities.acl2 b/books/workshops/2003/moore_vcg/support/utilities.acl2
new file mode 100644
index 0000000..af0e795
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/utilities.acl2
@@ -0,0 +1,7 @@
+(value :q)
+
+(lp)
+
+(include-book "m5")
+
+(certify-book "utilities" ? t)
diff --git a/books/workshops/2003/moore_vcg/support/utilities.lisp b/books/workshops/2003/moore_vcg/support/utilities.lisp
new file mode 100644
index 0000000..ea8c44b
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/utilities.lisp
@@ -0,0 +1,209 @@
+; Copyright (C) 2001, Regents of the University of Texas
+; Written by J Strother Moore
+; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
+
+#|
+; Certification Instructions.
+
+(include-book
+ "m5")
+
+(certify-book "utilities" 1)
+
+J Moore
+|#
+
+(in-package "M5")
+
+; Here we develop the general theory for proving things about the
+; M5 bytecode.
+
+; Arithmetic
+
+(include-book "../../../../arithmetic/top-with-meta")
+
+; We prove a few things about int arithmetic. We ought to prove
+; many more, but I just put enough here to get the factorial
+; proof to go through.
+
+(include-book "../../../../ihs/quotient-remainder-lemmas")
+
+(defun intp (x)
+ (and (integerp x)
+ (<= (- (expt 2 31)) x)
+ (< x (expt 2 31))))
+
+(defthm int-lemma0
+ (implies (intp x)
+ (integerp x))
+ :rule-classes (:rewrite :forward-chaining))
+
+(defthm int-lemma1
+ (intp (int-fix x)))
+
+(local (in-theory (cons 'zp (disable mod))))
+
+(defthm int-lemma2
+ (implies (and (intp x)
+ (not (zp x)))
+ (equal (int-fix (+ -1 x))
+ (+ -1 x))))
+
+(defthm int-lemma3
+ (implies (and (intp x)
+ (not (zp x)))
+ (intp (+ -1 x))))
+
+(defthm int-lemma4a
+ (implies (and (integerp x)
+ (integerp y))
+ (equal (int-fix (* x (int-fix y)))
+ (int-fix (* x y)))))
+
+(defthm int-lemma5a
+ (implies (and (integerp x)
+ (integerp y))
+ (equal (int-fix (+ x (int-fix y)))
+ (int-fix (+ x y)))))
+
+; This is a special case of the above. I need a more general
+; handling of this, but this will do for the moment.
+
+(defthm int-lemma5a1
+ (implies (and (integerp x1)
+ (integerp x2)
+ (integerp y))
+ (equal (int-fix (+ x1 x2 (int-fix y)))
+ (int-fix (+ x1 x2 y))))
+ :hints (("Goal" :use (:instance int-lemma5a (x (+ x1 x2))))))
+
+(defthm int-lemma6
+ (implies (intp x)
+ (equal (int-fix x) x)))
+
+(in-theory (disable intp int-fix))
+
+(defthm int-lemma4b
+ (implies (and (integerp x)
+ (integerp y))
+ (equal (int-fix (* (int-fix y) x))
+ (int-fix (* y x)))))
+
+(defthm int-lemma5b
+ (implies (and (integerp x)
+ (integerp y))
+ (equal (int-fix (+ (int-fix y) x))
+ (int-fix (+ y x)))))
+
+; Structures
+
+(defthm states
+ (and (equal (thread-table (make-state tt h c)) tt)
+ (equal (heap (make-state tt h c)) h)
+ (equal (class-table (make-state tt h c)) c)))
+
+(in-theory (disable make-state thread-table heap class-table))
+
+(defthm frames
+ (and
+ (equal (pc (make-frame pc l s prog sync-flg cur-class))
+ pc)
+ (equal (locals (make-frame pc l s prog sync-flg cur-class))
+ l)
+ (equal (stack (make-frame pc l s prog sync-flg cur-class))
+ s)
+ (equal (program (make-frame pc l s prog sync-flg cur-class))
+ prog)
+ (equal (sync-flg (make-frame pc l s prog sync-flg cur-class))
+ sync-flg)
+ (equal (cur-class (make-frame pc l s prog sync-flg cur-class))
+ cur-class)))
+
+(in-theory
+ (disable make-frame pc locals stack program sync-flg cur-class))
+
+(defthm stacks
+ (and (equal (top (push x s)) x)
+ (equal (pop (push x s)) s)))
+
+(in-theory (disable push top pop))
+
+; Mappings
+
+(defthm assoc-equal-bind
+ (equal (assoc-equal key1 (bind key2 val alist))
+ (if (equal key1 key2)
+ (cons key1 val)
+ (assoc-equal key1 alist))))
+
+(defthm bind-bind
+ (equal (bind x v (bind x w a))
+ (bind x v a)))
+
+; Semi-Ground Terms
+
+(defthm bind-formals-opener
+ (implies (and (integerp n)
+ (<= 0 n))
+ (equal (bind-formals (+ 1 n) stack)
+ (cons (top stack)
+ (bind-formals n (pop stack))))))
+
+(defthm nth-opener
+ (and (equal (nth 0 lst) (car lst))
+ (implies (and (integerp n)
+ (<= 0 n))
+ (equal (nth (+ 1 n) lst)
+ (nth n (cdr lst))))))
+
+(in-theory (disable nth))
+
+(defthm popn-opener
+ (implies (and (integerp n)
+ (<= 0 n))
+ (equal (popn (+ 1 n) stack)
+ (popn n (pop stack)))))
+
+(defun repeat (th n)
+ (if (zp n)
+ nil
+ (cons th (repeat th (- n 1)))))
+
+(defthm repeat-opener
+ (implies (and (integerp n)
+ (<= 0 n))
+ (equal (repeat th (+ 1 n))
+ (cons th (repeat th n)))))
+
+; The nil conjunct below is needed because we will disable run.
+
+(defthm run-opener
+ (and (equal (run nil s) s)
+ (equal (run (cons th sched) s)
+ (run sched (step th s))))
+ :hints (("Goal" :in-theory (disable step))))
+
+;(in-theory (enable top pop push lookup-method))
+
+; Step Stuff
+
+(defthm step-opener
+ (implies (consp (next-inst th s))
+ (equal (step th s)
+ (if (equal (status th s) 'SCHEDULED)
+ (do-inst (next-inst th s) th s)
+ s)))
+ :hints (("Goal" :in-theory (disable do-inst))))
+
+(in-theory (disable step))
+
+; Clocks
+
+
+
+(defthm run-append
+ (equal (run (append sched1 sched2) s)
+ (run sched2 (run sched1 s))))
+
+(in-theory (disable run))
+
diff --git a/books/workshops/2003/moore_vcg/support/vcg-examples.acl2 b/books/workshops/2003/moore_vcg/support/vcg-examples.acl2
new file mode 100644
index 0000000..ce63104
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/vcg-examples.acl2
@@ -0,0 +1,6 @@
+(value :q)
+
+(lp)
+
+(include-book "utilities")
+(certify-book "vcg-examples" ? t)
diff --git a/books/workshops/2003/moore_vcg/support/vcg-examples.lisp b/books/workshops/2003/moore_vcg/support/vcg-examples.lisp
new file mode 100644
index 0000000..d3e17a4
--- /dev/null
+++ b/books/workshops/2003/moore_vcg/support/vcg-examples.lisp
@@ -0,0 +1,904 @@
+; Copyright (C) 2003, Regents of the University of Texas
+; Written by J Strother Moore
+; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
+
+; Use of Tail-Recursion to Propagate Inductive Assertions
+; J Strother Moore
+; February 26, 2003
+
+; cd /u/moore/m5/tolquhon
+; (include-book "utilities")
+; (ld "vcg-examples.lisp" :ld-pre-eval-print t)
+
+; Certification:
+; (include-book "utilities")
+; (certify-book "vcg-examples" 1)
+
+; ---------------------------------------------------------------------------
+; Preliminaries
+
+; This first part is just ``prelude''. It has nothing to do with the
+; specific programs we will verify.
+
+(in-package "M5")
+
+(include-book "../../../../misc/defpun")
+
+(defmacro defpun (g args &rest tail)
+ `(acl2::defpun ,g ,args ,@tail))
+
+;(ACL2::SET-MATCH-FREE-ERROR NIL)
+
+(defthm update-nth-opener
+ (and (equal (update-nth 0 x a) (cons x (cdr a)))
+ (implies (not (zp n))
+ (equal (update-nth n x a)
+ (cons (car a) (update-nth (- n 1) x (cdr a)))))))
+
+; ---------------------------------------------------------------------------
+; Some Preliminaries for Our First Program
+
+(defthm int-evenp-inv-a
+ (implies (intp i)
+ (iff (evenp (int-fix (- i 2)))
+ (evenp i)))
+ :hints
+ (("Goal" :in-theory (e/d (intp int-fix)
+ (floor)))))
+
+(defthm int-evenp-inv-b
+ (implies (intp i)
+ (iff (evenp (- i 2))
+ (evenp i)))
+ :hints
+ (("Goal" :in-theory (e/d (intp int-fix)
+ (floor)))))
+
+(in-theory (disable evenp))
+
+(defthm int-lemma2a
+ (implies (and (intp x)
+ (<= 0 x))
+ (equal (int-fix (+ -2 x))
+ (+ -2 x)))
+ :hints (("Goal" :in-theory (e/d (intp) nil))))
+
+(defthm int-lemma2b
+ (implies (and (intp x)
+ (<= 0 x))
+ (intp (+ -2 x)))
+ :hints (("Goal" :in-theory (e/d (intp) nil))))
+
+; ---------------------------------------------------------------------------
+; Our First Program
+
+; Below is an m5 program that decrements its first local, n, by 2 and
+; iterates until the result is 0. On each iteration it adds 1 to a
+; local variable, a, which is initialized to 0. The program ends with
+; a HALT instruction, which puts the machine in an infinite loop, i.e.,
+; executing HALT doesn't change the pc and the machine "stops." Later
+; we deal with the more realistic situation of a RETURN to some caller.
+; We will prove that if the program below reaches the HALT instruction,
+; the initial value, n0, of n was even and the result on the stack is
+; n0/2. This program does not terminate when n0 is odd.
+
+; To make the program slightly simpler to deal with, I only consider
+; the case where n0 is a non-negative int. (Java programmers will note
+; that the program actually halts for even negative ints, because of
+; wrap-around.)
+
+(defconst *flat-prog*
+ '((iconst_0) ; 0
+ (istore_1) ; 1 a := 0;
+ (iload_0) ; 2 top of loop:
+ (ifeq 14) ; 3 if n=0, goto 17;
+ (iload_1) ; 6
+ (iconst_1) ; 7
+ (iadd) ; 8
+ (istore_1) ; 9 a := a+1;
+ (iload_0) ;10
+ (iconst_2) ;11
+ (isub) ;12
+ (istore_0) ;13 n := n-2;
+ (goto -12) ;14 goto top of loop
+ (iload_1) ;17
+ (halt))) ;18
+
+; Here is the ``semantics'' of the loop, in the case in interest.
+
+(defun halfa (n a)
+ (declare (xargs :measure (nfix n)))
+ (if (zp n)
+ a
+ (halfa (- n 2) (int-fix (+ a 1)))))
+
+; ---------------------------------------------------------------------------
+; The Assertions at the Three Cut Points
+
+; We will use a classic ``inductive assertion'' method. The following
+; function takes a state, s, and the ``initial'' value of n, n0, and
+; states the assertions we wish to attach to pcs 0, 2, and 18. These
+; are the so-called ``cut points'' of my choice: the entry to the
+; program, the top of the loop, and exit from the program.
+
+; The particular assertions are not my main interest in this paper.
+; You can read them if you want. The real nugget in this paper is not
+; the assertions but the fact that I use tail recursion by step to
+; propagate assertions from the cut points to all the pcs.
+
+; That said, let me note that the assertions are complicated because
+; they have to handle the fact that halfa tracks the program only as
+; long as n stays non-negative. Things would be simpler if I assumed
+; that n0 was even. But I like illustrating the capability of
+; establishing conditions that hold for n0 in the event of
+; termination.
+
+(defun flat-pre-condition (n0 n)
+ (and (equal n n0)
+ (intp n0)
+ (<= 0 n0)))
+
+(defun flat-loop-invariant (n0 n a)
+ (and (intp n0)
+ (<= 0 n0)
+ (intp n)
+ (if (and (<= 0 n)
+ (evenp n))
+ (equal (halfa n a)
+ (halfa n0 0))
+ (not (evenp n)))
+ (iff (evenp n0) (evenp n))))
+
+(defun flat-post-condition (n0 value)
+ (and (evenp n0)
+ (equal value (halfa n0 0))))
+
+(defun flat-assertion (n0 th s)
+ (let ((n (nth 0 (locals (top-frame th s))))
+ (a (nth 1 (locals (top-frame th s)))))
+ (and (equal (program (top-frame th s)) *flat-prog*)
+ (case (pc (top-frame th s))
+ (0 (flat-pre-condition n0 n))
+ (2 (flat-loop-invariant n0 n a))
+ (18 (let ((value (top (stack (top-frame th s)))))
+ (flat-post-condition n0 value)))
+ (otherwise nil)))))
+
+; Observe that the output condition is that n0 is even and that the
+; top of the stack contains the semantic expression (halfa n0 0).
+; We will later convert this to n0/2.
+
+; ---------------------------------------------------------------------------
+; The Invariant -- The Only New Idea in this Note
+
+; Here is the new idea. I define the invariant for the program by
+; using defpun. The assertions are attached at the three cut points
+; and all other statements inherit the invariant of the next
+; statement.
+
+(defpun flat-inv (n0 th s)
+ (if (or (equal (pc (top-frame th s)) 0)
+ (equal (pc (top-frame th s)) 2)
+ (equal (pc (top-frame th s)) 18))
+ (flat-assertion n0 th s)
+ (flat-inv n0 th (step th s))))
+
+; In one sense, the next lemma is just a technical lemma to force
+; flat-inv to keep opening if it hasn't reached a cut point yet. But
+; in another sense, this lemma highlights the nice feature of this
+; approach. Suppose that in our function flat-assertion we had failed
+; to supply a cut point for some loop. Then we'll get a stack
+; overflow from the repeated indefinite application of this rewrite
+; rule. But we do not have to prove we've cut every loop, because the
+; flat-inv function is tail recursive and so was admitted by defpun.
+
+; In the past when I've used the classic inductive invariant approach
+; and used recursion in flat-inv to avoid an assertion at every pc, I
+; had to invent some kind of measure (``distance to the next cut
+; point'') to prove that I had cut every loop. That annoyed me
+; because in the classic inductive invariant approach that burden is
+; merely pragmatic -- you had to cut every loop or you couldn't
+; generate verification conditions. But you didn't have to prove you
+; had cut every loop. In my past attempts to mimic this, I had to
+; prove more stuff!
+
+(defthm flat-inv-opener
+ (implies (and (equal pc (pc (top-frame th s)))
+ (syntaxp (quotep pc))
+ (not (equal pc 0))
+ (not (equal pc 2))
+ (not (equal pc 18)))
+ (equal (flat-inv n0 th s)
+ (flat-inv n0 th (step th s)))))
+
+; ---------------------------------------------------------------------------
+; The Verification Conditions
+
+(defthm VC1
+ (implies (flat-pre-condition n0 n) (flat-loop-invariant n0 n 0)))
+
+
+(defthm VC2
+ (implies (and (flat-loop-invariant n0 n a)
+ (not (equal n 0)))
+ (flat-loop-invariant n0 (int-fix (- n 2)) (int-fix (+ 1 a)))))
+
+(defthm VC3
+ (implies (and (flat-loop-invariant N0 n a)
+ (EQUAL n 0))
+ (flat-post-condition N0 a)))
+
+(in-theory (disable flat-pre-condition
+ flat-loop-invariant
+ flat-post-condition))
+
+; ---------------------------------------------------------------------------
+; Using the VCs in the Operational Semantics
+
+; So here is the key theorem of the inductive invariant approach, showing
+; that inv is an invariant.
+
+(defthm flat-inv-step
+ (implies (flat-inv n0 th s)
+ (flat-inv n0 th (step th s))))
+
+; We can immediately conclude that flat-inv is an invariant under run,
+; as long as the only thread we step is th.
+
+(defun mono-threadedp (th sched)
+ (if (endp sched)
+ t
+ (and (equal th (car sched))
+ (mono-threadedp th (cdr sched)))))
+
+(defthm flat-inv-run
+ (implies (and (mono-threadedp th sched)
+ (flat-inv n0 th s))
+ (flat-inv n0 th (run sched s)))
+ :rule-classes nil
+ :hints (("Goal" :in-theory (e/d (run)(flat-inv-def)))))
+
+; And so we're done. If we plug in an initial state satisfying the
+; invariant we get a final state satisfying it. If the final state is
+; supposed to have pc 18, then we can read out what the invariant
+; tells us about that cut point.
+
+(defthm flat-main
+ (let ((s1 (run sched s0)))
+ (implies (and (intp n0)
+ (<= 0 n0)
+ (equal (pc (top-frame th s0)) 0)
+ (equal (locals (top-frame th s0)) (list n0 any))
+ (equal (program (top-frame th s0)) *flat-prog*)
+ (mono-threadedp th sched)
+ (equal (pc (top-frame th s1)) 18))
+ (and (evenp n0)
+ (equal (top (stack (top-frame th s1)))
+ (halfa n0 0)))))
+
+ :hints (("Goal" :use
+ (:instance flat-inv-run
+ (n0 n0)
+ (s s0)
+ (th th)
+ (sched sched))
+ :in-theory (enable flat-pre-condition flat-post-condition)))
+ :rule-classes nil)
+
+; ---------------------------------------------------------------------------
+; Getting Rid of the Semantic Function
+
+; Now, following our standard paradigm, we get rid of halfa and
+; introduce n/2 instead. There is nothing new here, but I have to
+; fight intp and int-fix.
+
+(defthm int-back
+ (implies (and (intp (+ a x))
+ (integerp a)
+ (<= 0 a)
+ (integerp x)
+ (<= 0 x)
+ (integerp y)
+ (<= 0 y)
+ (<= y x))
+ (intp (+ y a)))
+ :hints (("Goal" :in-theory (enable intp))))
+
+(defthm halfa-is-half
+ (implies (and (intp n)
+ (<= 0 n)
+ (evenp n)
+ (integerp a)
+ (<= 0 a)
+ (intp (+ (/ n 2) a)))
+ (equal (halfa n a)
+ (+ (/ n 2) a)))
+ :hints (("Goal" :in-theory (enable evenp))))
+
+(defthm intp-half-n
+ (implies (and (intp n)
+ (<= 0 n)
+ (evenp n))
+ (intp (* 1/2 n)))
+ :hints (("Goal" :in-theory (enable evenp intp))))
+
+; ---------------------------------------------------------------------------
+; The (Partial) Correctness Theorem for Half
+
+; The following theorem summarizes what we now know. Start with a a
+; state running *flat-prog* from pc 0 with initial n=n0 and run it
+; under an arbitrary mono-threaded schedule to get to s1. Suppose n0
+; is a non-negative int and the pc of s1 is 18.
+
+; Then we conclude that n0 is even and that the top of the stack is
+; n0/2.
+
+(defthm flat-is-partially-correct
+ (let ((s1 (run sched s0)))
+ (implies (and (intp n0)
+ (<= 0 n0)
+ (equal (pc (top-frame th s0)) 0)
+ (equal (locals (top-frame th s0)) (list n0 any))
+ (equal (program (top-frame th s0)) *flat-prog*)
+ (mono-threadedp th sched)
+ (equal (pc (top-frame th s1)) 18))
+ (and (evenp n0)
+ (equal (top (stack (top-frame th s1)))
+ (/ n0 2)))))
+ :rule-classes nil
+ :hints (("Goal"
+ :use ((:instance flat-main)))))
+
+; Note that at no point in this exercise have we counted instructions
+; or defined a clock or schedule generator.
+
+; ---------------------------------------------------------------------------
+; Dealing with Return
+
+(defconst *half-prog*
+ '((iconst_0) ; 0
+ (istore_1) ; 1 a := 0;
+ (iload_0) ; 2 top of loop:
+ (ifeq 14) ; 3 if n=0, goto 17;
+ (iload_1) ; 6
+ (iconst_1) ; 7
+ (iadd) ; 8
+ (istore_1) ; 9 a := a+1;
+ (iload_0) ;10
+ (iconst_2) ;11
+ (isub) ;12
+ (istore_0) ;13 n := n-2;
+ (goto -12) ;14 goto top of loop
+ (iload_1) ;17
+ (ireturn))) ;18 return a;
+
+(defun sdepth (stk)
+ (declare (xargs :hints (("Goal" :in-theory (enable pop)))))
+ (if (endp stk)
+ 0
+ (+ 1 (sdepth (pop stk)))))
+
+(defun half-assertion (n0 d0 th s)
+ (cond
+ ((< (sdepth (call-stack th s)) d0)
+ (let ((value (top (stack (top-frame th s)))))
+ (flat-post-condition n0 value)))
+ (t
+ (let ((n (nth 0 (locals (top-frame th s))))
+ (a (nth 1 (locals (top-frame th s)))))
+ (and (equal (sdepth (call-stack th s)) d0)
+ (equal (program (top-frame th s)) *half-prog*)
+ (equal (sync-flg (top-frame th s)) 'UNLOCKED)
+ (case (pc (top-frame th s))
+ (0 (flat-pre-condition n0 n))
+ (2 (flat-loop-invariant n0 n a))
+ (18 (let ((value (top (stack (top-frame th s)))))
+ (flat-post-condition n0 value)))
+ (otherwise nil)))))))
+
+(defpun half-inv (n0 d0 th s)
+ (if (or (< (sdepth (call-stack th s)) d0)
+ (equal (pc (top-frame th s)) 0)
+ (equal (pc (top-frame th s)) 2)
+ (equal (pc (top-frame th s)) 18))
+ (half-assertion n0 d0 th s)
+ (half-inv n0 d0 th (step th s))))
+
+(defthm half-inv-opener
+ (implies (and (equal pc (pc (top-frame th s)))
+ (syntaxp (quotep pc))
+ (not (equal pc 0))
+ (not (equal pc 2))
+ (not (equal pc 18)))
+ (equal (half-inv n0 d0 th s)
+ (if (< (sdepth (call-stack th s)) d0)
+ (half-assertion n0 d0 th s)
+ (half-inv n0 d0 th (step th s))))))
+
+(defthm half-inv-step
+ (implies (and (integerp d0)
+ (< 1 d0)
+ (<= d0 (sdepth (call-stack th s)))
+ (half-inv n0 d0 th s))
+ (half-inv n0 d0 th (step th s)))
+ :hints (("Goal" :in-theory (disable halfa-is-half))))
+
+(defun run-to-return (sched th d0 s)
+ (cond ((endp sched) s)
+ ((<= d0 (sdepth (call-stack th s)))
+ (run-to-return (cdr sched) th d0 (step (car sched) s)))
+ (t s)))
+
+(defthm half-inv-run-to-return
+ (implies (and (mono-threadedp th sched)
+ (integerp d0)
+ (< 1 d0)
+ (half-inv n0 d0 th s))
+ (half-inv n0 d0 th (run-to-return sched th d0 s)))
+ :rule-classes nil
+ :hints (("Goal" :in-theory (disable half-inv-def))))
+
+; And so we're done. If we plug in an initial state satisfying the
+; invariant we get a final state satisfying it. If the final state is
+; supposed to have pc 18, then we can read out what the invariant
+; tells us about that cut point.
+
+(defthm half-main
+ (let ((s1 (run-to-return sched th (sdepth (call-stack th s0)) s0)))
+ (implies (and (intp n0)
+ (<= 0 n0)
+ (equal (pc (top-frame th s0)) 0)
+ (equal (locals (top-frame th s0)) (list n0 any))
+ (equal (program (top-frame th s0)) *half-prog*)
+ (equal (sync-flg (top-frame th s0)) 'unlocked)
+ (< 1 (sdepth (call-stack th s0)))
+ (mono-threadedp th sched)
+ (< (sdepth (call-stack th s1))
+ (sdepth (call-stack th s0))))
+ (and (evenp n0)
+ (equal (top (stack (top-frame th s1)))
+ (halfa n0 0)))))
+ :hints (("Goal" :use
+ (:instance half-inv-run-to-return
+ (n0 n0)
+ (d0 (sdepth (call-stack th s0)))
+ (s s0)
+ (th th)
+ (sched sched))
+ :in-theory (enable flat-pre-condition
+ flat-post-condition)))
+ :rule-classes nil)
+
+(defthm half-partially-correct
+ (let ((s1 (run-to-return sched th (sdepth (call-stack th s0)) s0)))
+ (implies (and (intp n0)
+ (<= 0 n0)
+ (equal (pc (top-frame th s0)) 0)
+ (equal (locals (top-frame th s0)) (list n0 any))
+ (equal (program (top-frame th s0)) *half-prog*)
+ (equal (sync-flg (top-frame th s0)) 'unlocked)
+ (< 1 (sdepth (call-stack th s0)))
+ (mono-threadedp th sched)
+ (< (sdepth (call-stack th s1))
+ (sdepth (call-stack th s0))))
+ (and (evenp n0)
+ (equal (top (stack (top-frame th s1)))
+ (/ n0 2)))))
+ :hints (("Goal" :use half-main))
+ :rule-classes nil)
+
+; ---------------------------------------------------------------------------
+; Doing a Sum Program
+
+; To re-illustrate the same methodology, without worrying about
+; demonstrating that we can conclude things about the input if we're
+; told we terminate, here is a program that sums the ints from n0 down
+; to 0.
+
+(defconst *sum-prog*
+ ; We name local[0] n and local[1] a.
+ '((iconst_0) ; 0
+ (istore_1) ; 1 a := 0;
+ (iload_0) ; 2 top of loop:
+ (ifeq 14) ; 3 if n=0, goto 17;
+ (iload_0) ; 6
+ (iload_1) ; 7
+ (iadd) ; 8
+ (istore_1) ; 9 a := n+a;
+ (iload_0) ;10
+ (iconst_m1) ;11
+ (iadd) ;12
+ (istore_0) ;13 n := n-1;
+ (goto -12) ;14 goto top of loop
+ (iload_1) ;17
+ (ireturn))) ;18 return a;
+
+(defun suma (n a)
+ (if (zp n)
+ a
+ (suma (- n 1) (int-fix (+ n a)))))
+
+(defun sum-pre-condition (n0 n)
+ (and (equal n n0)
+ (intp n0)
+ (<= 0 n0)))
+
+(defun sum-loop-invariant (n0 n a)
+ (and (intp n0)
+ (intp n)
+ (<= 0 n)
+ (<= n n0)
+ (equal (suma n a)
+ (suma n0 0))))
+
+(defun sum-post-condition (n0 value)
+ (equal value (suma n0 0)))
+
+(defun sum-assertion (n0 d0 th s)
+ (cond ((< (sdepth (call-stack th s)) d0)
+ (let ((value (top (stack (top-frame th s)))))
+ (sum-post-condition n0 value)))
+ (t
+ (let ((n (nth 0 (locals (top-frame th s))))
+ (a (nth 1 (locals (top-frame th s)))))
+ (and (equal (sdepth (call-stack th s)) d0)
+ (equal (program (top-frame th s)) *sum-prog*)
+ (equal (sync-flg (top-frame th s)) 'UNLOCKED)
+ (case (pc (top-frame th s))
+ (0 (sum-pre-condition n0 n))
+ (2 (sum-loop-invariant n0 n a))
+ (18 (let ((value (top (stack (top-frame th s)))))
+ (sum-post-condition n0 value)))
+ (otherwise nil)))))))
+
+(defpun sum-inv (n0 d0 th s)
+ (if (or (< (sdepth (call-stack th s)) d0)
+ (equal (pc (top-frame th s)) 0)
+ (equal (pc (top-frame th s)) 2)
+ (equal (pc (top-frame th s)) 18))
+ (sum-assertion n0 d0 th s)
+ (sum-inv n0 d0 th (step th s))))
+
+(defthm sum-inv-opener
+ (implies (and (equal pc (pc (top-frame th s)))
+ (syntaxp (quotep pc))
+ (not (equal pc 0))
+ (not (equal pc 2))
+ (not (equal pc 18)))
+ (equal (sum-inv n0 d0 th s)
+ (if (< (sdepth (call-stack th s)) d0)
+ (sum-assertion n0 d0 th s)
+ (sum-inv n0 d0 th (step th s))))))
+
+(defthm sum-VC1
+ (implies (sum-pre-condition n0 n) (sum-loop-invariant n0 n 0)))
+
+(defthm sum-VC2
+ (implies (and (sum-loop-invariant n0 n a)
+ (not (equal n 0)))
+ (sum-loop-invariant n0 (int-fix (- n 1)) (int-fix (+ n a)))))
+
+(defthm sum-VC3
+ (implies (and (sum-loop-invariant N0 n a)
+ (EQUAL n 0))
+ (sum-post-condition N0 a)))
+
+(in-theory (disable sum-pre-condition
+ sum-loop-invariant
+ sum-post-condition))
+
+(defthm sum-inv-step
+ (implies (and (integerp d0)
+ (< 1 d0)
+ (<= d0 (sdepth (call-stack th s)))
+ (sum-inv n0 d0 th s))
+ (sum-inv n0 d0 th (step th s))))
+
+(defthm sum-inv-run-to-return
+ (implies (and (mono-threadedp th sched)
+ (integerp d0)
+ (< 1 d0)
+ (sum-inv n0 d0 th s))
+ (sum-inv n0 d0 th (run-to-return sched th d0 s)))
+ :rule-classes nil
+ :hints (("Goal" :in-theory (disable sum-inv-def))))
+
+(defthm sum-main
+ (let ((s1 (run-to-return sched th (sdepth (call-stack th s0)) s0)))
+ (implies (and (intp n0)
+ (<= 0 n0)
+ (equal (pc (top-frame th s0)) 0)
+ (equal (locals (top-frame th s0)) (list n0 any))
+ (equal (program (top-frame th s0)) *sum-prog*)
+ (equal (sync-flg (top-frame th s0)) 'unlocked)
+ (< 1 (sdepth (call-stack th s0)))
+ (mono-threadedp th sched)
+ (< (sdepth (call-stack th s1))
+ (sdepth (call-stack th s0))))
+ (equal (top (stack (top-frame th s1)))
+ (suma n0 0))))
+ :hints (("Goal" :use
+ (:instance sum-inv-run-to-return
+ (n0 n0)
+ (d0 (sdepth (call-stack th s0)))
+ (s s0)
+ (th th)
+ (sched sched))
+ :in-theory (enable sum-pre-condition
+ sum-post-condition)))
+ :rule-classes nil)
+
+; We don't bother to eliminate suma, though we could if we hacked around
+; with intp long enough!
+
+; ---------------------------------------------------------------------------
+; A Recursive Method
+
+; Now let's do recursive factorial. We'll bring in the clocked work
+; we have already done, just to have the *demo-state* etc.
+
+(include-book "demo")
+
+(defun ! (n)
+ (if (zp n)
+ 1
+ (* n (! (- n 1)))))
+
+; Here is the (redundant) definition of the program.
+
+(defconst *fact-def*
+ '("fact" (INT) NIL
+ (ILOAD_0) ;;; 0
+ (IFLE 12) ;;; 1
+ (ILOAD_0) ;;; 4
+ (ILOAD_0) ;;; 5
+ (ICONST_1) ;;; 6
+ (ISUB) ;;; 7
+ (INVOKESTATIC "Demo" "fact" 1) ;;; 8
+ (IMUL) ;;; 11
+ (IRETURN) ;;; 12
+ (ICONST_1) ;;; 13
+ (IRETURN))) ;;; 14
+
+; The following function recognizes the call stack (cs) of a call of
+; the "fact" method on n0. The function is not applied to the
+; top-most frame, because the constraints on the frame are so
+; pc-sensitive and the top-most frame may have "any" pc. So the
+; function actually recognizes the rest of the "fact" call stack.
+; Here is a picture of the entire call stack.
+
+; ------------------- top-most frame
+; pc: any
+; locals: (n) 5 <- suppose n=5
+; stack: any
+; program: fact prog
+; ------------------- caller-frame
+; pc: 11
+; locals: (n+1) 6 this is caller-frame 3
+; stack: (n+1)
+; program: fact prog
+; ------------------- caller-frame
+; pc: 11
+; locals: (n+2) 7 this is caller-frame 2
+; stack: (n+2)
+; program: fact prog
+; ------------------- caller-frame
+; ...
+; ------------------- caller-frame
+; pc: 11
+; locals: (n0) 8 <- suppose n0 = 8 ; this is caller frame 1
+; stack: (n0)
+; program: fact prog
+; ------------------- the frame below called fact on n0
+; ... this is caller frame 0
+
+; Note that there are n0-n fact caller frames. We number them from
+; n0-n down to 1. Caller frame 0 is actually the ``external'' entry
+; into fact on n0. We don't know (or care) whether fact or some other
+; program is running there. Let k be the number of the caller frame.
+; Then note that the value of n in that frame is n0-k+1.
+
+(defun fact-caller-framesp (cs n0 k)
+ (declare (xargs :measure (acl2-count k)))
+ (cond ((zp k) t)
+ ((and (equal (pc (top cs)) 11)
+ (equal (program (top cs)) (cdddr *fact-def*))
+ (equal (sync-flg (top cs)) 'UNLOCKED)
+ (intp (nth 0 (locals (top cs))))
+ (equal (+ n0 (- k)) (- (nth 0 (locals (top cs))) 1))
+ (equal (nth 0 (locals (top cs)))
+ (top (stack (top cs)))))
+ (fact-caller-framesp (pop cs) n0 (- k 1)))
+ (t nil)))
+
+(defun fact-assertion (n0 d0 th s)
+ (cond
+ ((< (sdepth (call-stack th s)) d0)
+ (equal (top (stack (top-frame th s)))
+ (int-fix (! n0))))
+ (t
+ (let ((n (nth 0 (locals (top-frame th s)))))
+ (and (equal (program (top-frame th s)) (cdddr *fact-def*))
+ (equal (lookup-method "fact" "Demo" (class-table s))
+ *fact-def*)
+ (equal (sync-flg (top-frame th s)) 'UNLOCKED)
+ (intp n0)
+ (intp n)
+ (<= 0 n)
+ (<= n n0)
+ (equal (sdepth (call-stack th s)) (+ d0 (- n0 n)))
+ (fact-caller-framesp (pop (call-stack th s)) n0 (- n0 n))
+ (case (pc (top-frame th s))
+ (0 t)
+ ((12 14) (equal (top (stack (top-frame th s)))
+ (int-fix (! n))))
+ (otherwise nil)))))))
+
+(defpun fact-inv (n0 d0 th s)
+ (if (or (< (sdepth (call-stack th s)) d0)
+ (equal (pc (top-frame th s)) 0)
+ (equal (pc (top-frame th s)) 12)
+ (equal (pc (top-frame th s)) 14))
+ (fact-assertion n0 d0 th s)
+ (fact-inv n0 d0 th (step th s))))
+
+(defthm fact-inv-opener
+ (implies (and (equal pc (pc (top-frame th s)))
+ (syntaxp (quotep pc))
+ (not (equal pc 0))
+ (not (equal pc 12))
+ (not (equal pc 14)))
+ (equal (fact-inv n0 d0 th s)
+ (if (< (sdepth (call-stack th s)) d0)
+ (fact-assertion n0 d0 th s)
+ (fact-inv n0 d0 th (step th s))))))
+
+; These next three lemmas are technical. The first two force
+; substitutions. The last opens the stack predicate when we're
+; returning and need to know what we're being told about the caller.
+
+(DEFTHM KB-HACK1
+ (IMPLIES
+ (AND
+ (FACT-CALLER-FRAMESP
+ (POP (POP (CADR (ASSOC-EQUAL TH (THREAD-TABLE S)))))
+ N0
+ (+ -1 N0 (- NNN)))
+ (EQUAL
+ NNN
+ (+ -1
+ (CAR (LOCALS (TOP (POP (CADR (ASSOC-EQUAL TH (THREAD-TABLE S))))))))))
+ (FACT-CALLER-FRAMESP
+ (POP (POP (CADR (ASSOC-EQUAL TH (THREAD-TABLE S)))))
+ N0
+ (+
+ N0
+ (-
+ (CAR (LOCALS (TOP (POP (CADR (ASSOC-EQUAL TH (THREAD-TABLE S))))))))))))
+
+(defthm kb-hack2
+ (implies
+ (and (integerp n)
+ (EQUAL
+ tos
+ (INT-FIX
+ (! (CAR (LOCALS (TOP (CADR (ASSOC-EQUAL TH (THREAD-TABLE S))))))))))
+
+ (EQUAL
+ (INT-FIX (* tos n))
+ (INT-FIX
+ (* (! (CAR (LOCALS (TOP (CADR (ASSOC-EQUAL TH (THREAD-TABLE S)))))))
+ n)))))
+
+(defthm fact-caller-framesp-opener-1
+ (implies (and (syntaxp
+ (equal cs
+ '(POP (CAR (CDR (ASSOC-EQUAL TH (THREAD-TABLE S)))))))
+ (EQUAL (PC (TOP (CADR (ASSOC-EQUAL TH (THREAD-TABLE S))))) pc0)
+ (syntaxp (or (equal pc0 ''12) (equal pc0 ''14))))
+ (equal (fact-caller-framesp cs n0 k)
+ (COND ((ZP K) T)
+ ((AND (EQUAL (PC (TOP CS)) 11)
+ (EQUAL (PROGRAM (TOP CS))
+ (CDDDR *FACT-DEF*))
+ (EQUAL (SYNC-FLG (TOP CS)) 'UNLOCKED)
+ (INTP (NTH 0 (LOCALS (TOP CS))))
+ (EQUAL (+ N0 (- K))
+ (- (NTH 0 (LOCALS (TOP CS))) 1))
+ (EQUAL (NTH 0 (LOCALS (TOP CS)))
+ (TOP (STACK (TOP CS)))))
+ (FACT-CALLER-FRAMESP (POP CS)
+ N0 (- K 1)))
+ (T NIL)))))
+
+(defthm fact-inv-step
+ (implies (and (integerp d0)
+ (< 1 d0)
+ (<= d0 (sdepth (call-stack th s)))
+ (fact-inv n0 d0 th s))
+ (fact-inv n0 d0 th (step th s))))
+
+(defthm fact-inv-run-to-return
+ (implies (and (mono-threadedp th sched)
+ (integerp d0)
+ (< 1 d0)
+ (fact-inv n0 d0 th s))
+ (fact-inv n0 d0 th (run-to-return sched th d0 s)))
+ :rule-classes nil
+ :hints (("Goal" :in-theory (disable fact-inv-def))))
+
+; Here is the main theorem. It opens by letting s1 be a run-to-return
+; of s0. That particular call runs s0 with an abitrarily long
+; schedule, sched. Note that run-to-return does not always return a
+; state that has returned to a shorter call-stack depth -- if the
+; schedule is exhausted before that happens, the final state may still
+; be as deep or deeper than the initial state. In any case, s0 is the
+; initial state and s1 is the final state.
+
+; Now let's read the hypotheses of the implication. There are five
+; blocks of hypotheses. The first says that n0 is a positive intp.
+; The second says that the top-frame of thread th of s0 is a call of
+; our "fact" method on n0. The third says that the depth of the
+; call-stack of thread th is greater than 1. That means there is a
+; frame under the call of "fact". We will call that frame the
+; ``caller's frame.'' Of course, if s1 has a shorter call-stack than
+; s0, then the caller's frame will be its top-frame, since
+; run-to-return stops as soon as we've returned to that depth. The
+; fourth says the schedule consists of nothing but th steps. Note
+; that otherwise we say nothing about the schedule -- it may be
+; arbitrarily long. The fifth block says that the depth of the call
+; stack of s1 is less than that of s0, so we know the initial state
+; did run long enough to return and hence, the caller's frame is the
+; top-frame of s1.
+
+; Then the conclusion is that (int-fix (! n0)) is on top of
+; the stack of the caller's frame.
+
+(defthm fact-main
+ (let ((s1 (run-to-return sched th (sdepth (call-stack th s0)) s0)))
+ (implies (and (intp n0)
+ (<= 0 n0)
+
+ (equal (pc (top-frame th s0)) 0)
+ (equal (locals (top-frame th s0)) (list n0))
+ (equal (program (top-frame th s0))
+ (cdddr *fact-def*))
+ (equal (sync-flg (top-frame th s0)) 'unlocked)
+ (equal (lookup-method "fact" "Demo" (class-table s0))
+ *fact-def*)
+
+ (< 1 (sdepth (call-stack th s0)))
+
+ (mono-threadedp th sched)
+
+ (< (sdepth (call-stack th s1))
+ (sdepth (call-stack th s0))))
+ (equal (top (stack (top-frame th s1)))
+ (int-fix (! n0)))))
+
+ :hints (("Goal"
+ :use
+ (:instance fact-inv-run-to-return
+ (n0 n0)
+ (d0 (sdepth (call-stack th s0)))
+ (s s0)
+ (th th)
+ (sched sched))))
+ :rule-classes nil)
+
+; ---------------------------------------------------------------------------
+; The Basic Relation Between Run-to-Return and Run
+
+(defun sched-to-return (sched th d0 s)
+ (cond ((endp sched) sched)
+ ((<= d0 (sdepth (call-stack th s)))
+ (sched-to-return (cdr sched) th d0 (step (car sched) s)))
+ (t sched)))
+
+(defthm run-to-return-v-run
+ (equal (run sched s)
+ (run (sched-to-return sched th d0 s)
+ (run-to-return sched th d0 s)))
+ :rule-classes nil)
+
+; I need to develop the compositional rules.
diff --git a/books/workshops/2003/ray-matthews-tuttle/handouts.pdf.gz b/books/workshops/2003/ray-matthews-tuttle/handouts.pdf.gz
new file mode 100644
index 0000000..c5f9167
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/handouts.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/ray-matthews-tuttle/handouts.ps.gz b/books/workshops/2003/ray-matthews-tuttle/handouts.ps.gz
new file mode 100644
index 0000000..df1e66f
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/handouts.ps.gz
Binary files differ
diff --git a/books/workshops/2003/ray-matthews-tuttle/ltl-redux.pdf.gz b/books/workshops/2003/ray-matthews-tuttle/ltl-redux.pdf.gz
new file mode 100644
index 0000000..6dca40e
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/ltl-redux.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/ray-matthews-tuttle/ltl-redux.ps.gz b/books/workshops/2003/ray-matthews-tuttle/ltl-redux.ps.gz
new file mode 100644
index 0000000..14dc5d0
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/ltl-redux.ps.gz
Binary files differ
diff --git a/books/workshops/2003/ray-matthews-tuttle/slides.pdf.gz b/books/workshops/2003/ray-matthews-tuttle/slides.pdf.gz
new file mode 100644
index 0000000..8840ad9
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/ray-matthews-tuttle/slides.ps.gz b/books/workshops/2003/ray-matthews-tuttle/slides.ps.gz
new file mode 100644
index 0000000..e7408b3
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/apply-total-order.lisp b/books/workshops/2003/ray-matthews-tuttle/support/apply-total-order.lisp
new file mode 100644
index 0000000..6d03373
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/apply-total-order.lisp
@@ -0,0 +1,111 @@
+(in-package "ACL2")
+
+#|
+
+ apply-total-order.lisp
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+In this book, we describe some simple functions like insert and drop
+on a totally ordered list, and provide rules to manipulate them. The
+functions that we introduce are insert, drop, memberp, orderedp, and
+uniquep. Then we prove some theorems that we wish to export from this
+book.
+
+|#
+
+(include-book "total-order")
+
+(defun memberp (a x)
+ (and (consp x)
+ (or (equal a (first x))
+ (memberp a (rest x)))))
+
+(defun drop (a x)
+ (cond ((endp x) ())
+ ((equal a (first x))
+ (drop a (rest x)))
+ (t (cons (first x)
+ (drop a (rest x))))))
+
+(defun insert (a x)
+ (cond ((endp x) (list a))
+ ((equal a (first x)) x)
+ ((<< a (first x)) (cons a x))
+ (t (cons (first x)
+ (insert a (rest x))))))
+
+(defun orderedp (x)
+ (or (endp (rest x))
+ (and (<< (first x) (second x))
+ (orderedp (rest x)))))
+
+(defun uniquep (x)
+ (or (endp x)
+ (and (not (memberp (first x) (rest x)))
+ (uniquep (rest x)))))
+
+;;;; some simple properties about insert, drop, and member
+
+(defthm memberp-insert-same
+ (equal (memberp a (insert a x)) T))
+
+(defthm memberp-insert-diff
+ (implies (not (equal a b))
+ (equal (memberp a (insert b x))
+ (memberp a x))))
+
+(defthm memberp-drop-same
+ (equal (memberp a (drop a x)) nil))
+
+(defthm memberp-drop-diff
+ (implies (not (equal a b))
+ (equal (memberp a (drop b x))
+ (memberp a x))))
+
+(defthm ordered-implies-unique
+ (implies (orderedp x)
+ (uniquep x))
+ :rule-classes (:forward-chaining
+ :rewrite))
+
+(defthm memberp-yes-reduce-insert
+ (implies (and (orderedp x)
+ (memberp a x))
+ (equal (insert a x) x)))
+
+(defthm memberp-no-reduce-drop
+ (implies (and (true-listp x)
+ (not (memberp a x)))
+ (equal (drop a x) x)))
+
+(local
+(defthm drop-is-monotonic
+ (implies (and (orderedp x)
+ (<< y (first x))
+ (consp (drop a x)))
+ (<< y (first (drop a x)))))
+)
+
+(defthm drop-preserves-orderedp
+ (implies (orderedp x)
+ (orderedp (drop a x))))
+
+(defthm insert-preserves-orderedp
+ (implies (orderedp x)
+ (orderedp (insert a x))))
+
+(defthm drop-of-insert-is-same
+ (implies (and (true-listp x)
+ (not (memberp a x)))
+ (equal (drop a (insert a x)) x)))
+
+(defthm insert-of-drop-is-same
+ (implies (and (orderedp x)
+ (true-listp x)
+ (memberp a x))
+ (equal (insert a (drop a x)) x)))
+
+(defthm insert-returns-true-lists
+ (implies (true-listp x)
+ (true-listp (insert a x)))
+ :rule-classes :type-prescription)
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/bis.lisp b/books/workshops/2003/ray-matthews-tuttle/support/bis.lisp
new file mode 100644
index 0000000..571dd42
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/bis.lisp
@@ -0,0 +1,156 @@
+(in-package "ACL2")
+
+#|
+
+ bisimulation implies matching paths in ACL2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+OK, the following book is an ACL2 formalization (i.e. hack) for demonstrating
+that bisimilarity implies that any infinite path from one state can be matched
+by an infinite path in the other state. Roughly, we would like to prove the
+following:
+
+(1) (implies (bisimilar x y)
+ (forall p : (path x)
+ (exists p' : (path y)
+ (match p p'))))
+
+But, this is a non-trivial higher-order theorem. First, the notion that x and y
+are bisimilar is in fact a higher-order statement that there exists a relation
+between states which can be proven to be a bisimulation. We "prove" this in
+ACL2 by creating an encapsulation which constrains the set of universally
+quantified functions in the above theorem and then show that we can construct
+another function which is the witness for the (exists p' ..) and claim that we
+have proven the intended theorem (1).
+
+While this is not a closed-form theorem in ACL2, there is a reasonable argument
+that the definitions and theorems in this book do demonstrate that any
+application of the higher-order theorem (1) can be "simulated" by a series of
+first-order definitions and theorems in ACL2 (which is about the best we could
+hope for). Further, the events in this file could be wrapped up into a macro
+which performed the necessary instantiation of (1) and generated the
+corresponding definitions and theorems.
+
+|# ; |
+
+; The following two are now built-in (different variable name, though).
+
+; (defun natp (n)
+; (and (integerp n)
+; (>= n 0))))
+
+; (defthm natp-compound-recognizer
+; (iff (natp n)
+; (and (integerp n)
+; (>= n 0)))
+; :rule-classes :compound-recognizer)
+
+(in-theory (disable natp))
+
+; The following two are now built-in (different variable name, though).
+
+; (local ; ACL2 primitive
+; (defun posp (n)
+; (and (integerp n)
+; (> n 0))))
+
+; (defthm posp-compound-recognizer
+; (iff (posp n)
+; (and (integerp n)
+; (> n 0)))
+; :rule-classes :compound-recognizer)
+
+(in-theory (disable posp))
+
+(encapsulate
+ (((transit * *) => *) ;; a transition relation between states
+ ((label *) => *) ;; a labeling of atomic prop.s to states
+ ((bisim * *) => *) ;; a bisimulation relation between states
+
+ ;; we need a witnessing function for the choice in the bisimulation
+ ;; we could use defun-sk, but choose to just go ahead and constrain
+ ;; it here since the encapsulate is handy..
+ ((bisim-witness * * *) => *)
+
+ ;; an arbitrary path from a given initial state for the path
+ ((path * *) => *))
+
+ (local (defun transit (x y)
+ (declare (ignore x y))
+ t))
+
+ (local (defun label (x)
+ (declare (ignore x))
+ t))
+
+ (local (defun bisim (x y)
+ (declare (ignore x y))
+ t))
+
+ (local (defun bisim-witness (x y z)
+ (declare (ignore x y z))
+ t))
+
+ (defthm bisim-is-symmetric
+ (implies (bisim x y)
+ (bisim y x)))
+
+ (defthm bisim-preserves-labels
+ (implies (bisim x y)
+ (equal (label x) (label y))))
+
+ (defthm bisim-witness-is-always-step
+ (implies (transit x z)
+ (transit y (bisim-witness x y z))))
+
+ (defthm bisim-states-can-match-transit
+ (implies (and (bisim x y)
+ (transit x z))
+ (bisim z (bisim-witness x y z))))
+
+ (local (defun path (x n)
+ (declare (ignore n))
+ x))
+
+ (defthm path-starts-at-x
+ (equal (path x 0) x))
+
+ (defthm path-takes-steps
+ (implies (posp n)
+ (transit (path x (1- n))
+ (path x n))))
+)
+
+;; We construct a "matching" path from some arbitrary y
+
+(defun path+ (y i x)
+ (if (zp i) y
+ (bisim-witness (path x (1- i))
+ (path+ y (1- i) x)
+ (path x i))))
+
+(defun matches (x y i)
+ (equal (label (path x i))
+ (label (path+ y i x))))
+
+(defthm path+-starts-at-y
+ (equal (path+ y 0 x) y))
+
+(defthm path+-takes-steps
+ (implies (posp i)
+ (transit (path+ y (1- i) x)
+ (path+ y i x))))
+
+(defthm bisim-implies-bisim-along-path
+ (implies (and (natp i)
+ (bisim x y))
+ (bisim (path x i)
+ (path+ y i x)))
+ :rule-classes ((:forward-chaining
+ :trigger-terms ((path+ y i x)))))
+
+(defthm bisim-implies-matches
+ (implies (and (natp i)
+ (bisim x y))
+ (matches x y i)))
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp b/books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp
new file mode 100644
index 0000000..f01e2cb
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp
@@ -0,0 +1,2780 @@
+(in-package "ACL2")
+
+;; The following two lines are added for portability to v2-7.
+
+
+#|
+
+ bisimilarity.lisp
+ ~~~~~~~~~~~~~~~~~
+
+We take a step back now, and define the concepts of bisimilarity inside
+ACL2. The text-book definition of bisimilarity is as follows. A relation B
+between states of two Kripke Structures m and n is a bisimilarity relation if
+for every initial state of m there is an initial state in n such that B holds,
+and for every pair of states in which B holds, there is a next state for which
+B holds. Two models are said to be bisimulation equivalent if such a relation
+exists between the two models.
+
+The theory of bisimulation, frankly, is a higher order theory and, ACL2 (my
+apologies to Matt and J) cannot deal with it. However, we do what feeble
+efforts we can possibly master, and try to do as much work as possible with the
+encapsulations in ACL2. However, I strongly believe that treatment like this in
+ACL2 is nothing more than a hack.
+
+As an afterthought, we implement bisimilarity here, with respect to a given
+collection of variables. What this means is that two states will be called
+bisimilar if they have the same value for the given set of variables in the
+label, and for every next state of these states, the next states are bisimilar
+wrt the same set of variables. This is useful for reduction algorithms for
+model-checking that we are interested in, and will let us do away with
+hand-waving statements of the form that two states are bisimilar with labelling
+restricted to C.
+
+|#
+
+;; Since we do not want to see ACL2 reduce mv-nth 0 to car etc. we do the
+;; following tricks. I should ask Matt to have these as macro's or as a syntaxp
+;; hypothesis and disable mv-nth.
+
+(defthm mv-nth-0-reduce
+ (equal (mv-nth 0 (mv x y z)) x))
+
+(defthm mv-nth-1-reduce
+ (equal (mv-nth 1 (mv x y z)) y))
+
+(defthm mv-nth-2-reduce
+ (equal (mv-nth 2 (mv x y z)) z))
+
+(in-theory (disable mv-nth)) ;; We do not need to disable mv since mv is a
+ ;; macro.
+
+;; End of macros for mv-nth.
+
+;; The book ltl is included here since I will use the Kripke Structures there
+;; to define my bisimilarity.
+
+(include-book "ltl")
+
+;; These two rules are found to be expensive, which is obvious given what these
+;; rules are. I disable them here and in cone-of-influence.lisp and the proof
+;; is much much faster.
+
+(in-theory (disable subset-of-empty-is-empty
+ subset-of-nil-is-nil))
+
+;; Now we encapsulate the property of bisimilarity for two states. Briefly, two
+;; states are bisimilar if they have labels equal within vars, and for every
+;; next state of one, there exists a next state of another that is bisimilar.
+
+(encapsulate
+ (((bisimilar * * * * *) => *)
+ ((bisimilar-transition-witness-m->n * * * * * *) => *)
+ ((bisimilar-initial-state-witness-m->n * * * *) => *)
+ ((bisimilar-transition-witness-n->m * * * * * *) => *)
+ ((bisimilar-initial-state-witness-n->m * * * *) => *)
+ ((bisimilar-equiv * * *) => *))
+
+ (local
+ (defun bisimilar (p m q n vars)
+ (declare (ignore vars))
+ (and (equal p q)
+ (equal m n)))
+ )
+
+ (local
+ (defun bisimilar-transition-witness-m->n (p r m q n vars)
+ (declare (ignore p m q n vars))
+ r)
+ )
+
+ (local
+ (defun bisimilar-initial-state-witness-m->n (s m n vars)
+ (declare (ignore m n vars))
+ s)
+ )
+
+
+ (local
+ (defun bisimilar-transition-witness-n->m (p m q r n vars)
+ (declare (ignore p m q n vars))
+ r)
+ )
+
+ (local
+ (defun bisimilar-initial-state-witness-n->m (m s n vars)
+ (declare (ignore m n vars))
+ s)
+ )
+
+ (local
+ (defun bisimilar-equiv (m n vars)
+ (declare (ignore vars))
+ (equal m n))
+ )
+
+
+ ;; If two Kripke Structures m and n are equivalent with respect to a bisimilar
+ ;; relation B, then for every initial-state of m there is a initial-state of n
+ ;; that is bisimilar.
+
+ (defthm bisimilar-equiv-implies-init->init-m->n
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states m)))
+ (memberp (bisimilar-initial-state-witness-m->n s m n vars)
+ (initial-states n))))
+
+ (defthm bisimilar-equiv-implies-bisimilar-initial-states-m->n
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states m)))
+ (bisimilar s m
+ (bisimilar-initial-state-witness-m->n s m n vars)
+ n vars)))
+
+ ;; And the same result holds for n to m
+
+ (defthm bisimilar-equiv-implies-init->init-n->m
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states n)))
+ (memberp (bisimilar-initial-state-witness-n->m m s n vars)
+ (initial-states m))))
+
+ (defthm bisimilar-equiv-implies-bisimilar-initial-states-n->m
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states n)))
+ (bisimilar (bisimilar-initial-state-witness-n->m m s n vars)
+ m s n vars)))
+
+ ;; Bisimilar states have the same label with respect to vars. I just use
+ ;; set-equality because they might not have "equal" labels. BTW, I might not
+ ;; need the modelp hypothesis here. But I plug it in, just so that I can keep
+ ;; the (functional instance of) bisimilarity relation as simple as possible.
+
+ (defthm bisimilar-states-have-labels-equal
+ (implies (and (bisimilar p m q n vars)
+ (modelp m)
+ (modelp n))
+ (set-equal (set-intersect (label-of p m) vars)
+ (set-intersect (label-of q n) vars))))
+
+
+
+ ;; Of course bisimilarity witness is a member of states of the corresponding model.
+
+ (defthm bisimilar-witness-member-of-states-m->n
+ (implies (and (bisimilar p m q n vars)
+ (next-statep p r m)
+ (memberp r (states m)))
+ (memberp (bisimilar-transition-witness-m->n p r m q n vars)
+ (states n))))
+
+ ;; Again this part may not be required.
+
+ (defthm bisimilar-witness-member-of-states-n->m
+ (implies (and (bisimilar p m q n vars)
+ (next-statep q r n)
+ (memberp r (states n)))
+ (memberp (bisimilar-transition-witness-n->m p m q r n vars)
+ (states m))))
+
+ ;; And if two states are bisimilar, then for every next state of one, there is
+ ;; a next state of another which is bisimilar.
+
+ (defthm bisimilar-witness-matches-transition-m->n
+ (implies (and (bisimilar p m q n vars)
+ (next-statep p r m))
+ (next-statep q (bisimilar-transition-witness-m->n p r m q n vars)
+ n)))
+
+ (defthm bisimilar-witness-produces-bisimilar-states-m->n
+ (implies (and (bisimilar p m q n vars)
+ (next-statep p r m))
+ (bisimilar r m
+ (bisimilar-transition-witness-m->n p r m q n vars)
+ n vars)))
+
+ ;; Again this part may not be required.
+
+ (defthm bisimilar-witness-matches-transition-n->m
+ (implies (and (bisimilar p m q n vars)
+ (next-statep q r n))
+ (next-statep p (bisimilar-transition-witness-n->m p m q r n vars)
+ m)))
+
+
+
+ (defthm bisimilar-witness-produces-bisimilar-states-n->m
+ (implies (and (bisimilar p m q n vars)
+ (next-statep q r n))
+ (bisimilar (bisimilar-transition-witness-n->m p m q r n vars)
+ m r n vars)))
+
+)
+
+;; The next phase of the book is to show that if two Kripke Structures are
+;; bisim-equiv, then for each periodic path of one, there exists a periodic
+;; path of another that has the same labels within vars. This finally will show
+;; that for any LTL formula restricted to the variable set in vars, the
+;; evaluation of the formula wrt bisimilar structures is identical.
+
+
+;; In find-matching-path-for-path, we create a finite path in n that is
+;; bisimilar to a (finite) path in m.
+
+(defun find-matching-path-for-path-m->n (path m q n vars)
+ (cond ((endp path) nil)
+ ((endp (rest path)) (list q))
+ (t (cons q (find-matching-path-for-path-m->n
+ (rest path) m
+ (bisimilar-transition-witness-m->n
+ (first path) (second path) m q n vars)
+ n vars)))))
+
+;; And a similar function from n to m. This is really unfortunate. We could
+;; have gotten rid of this duplication if we could rely on symmetry. But I want
+;; the encapsulation to provide me with as little constraint as possible.
+
+(defun find-matching-path-for-path-n->m (p m path n vars)
+ (cond ((endp path) nil)
+ ((endp (rest path)) (list p))
+ (t (cons p (find-matching-path-for-path-n->m
+ (bisimilar-transition-witness-n->m
+ p m (first path) (second path) n vars)
+ m (rest path)
+ n vars)))))
+
+
+;; The function to handle periodic paths is rather complicated, and needs to be
+;; decomposed. Here is our solution.
+
+(defun snoc (x e)
+ (if (endp x) (list e)
+ (cons (first x) (snoc (rest x) e))))
+
+(defun del-last (x)
+ (if (endp x) nil
+ (if (endp (rest x)) nil
+ (cons (first x) (del-last (rest x))))))
+
+(defthm del-last-snoc-reduction
+ (implies (true-listp x)
+ (equal (del-last (snoc x e)) x)))
+
+
+(defun find-prefix (cycle seen witness path)
+ (cond ((endp path) nil)
+ ((endp seen) path) ;; should not arise
+ ((equal witness (first seen)) nil)
+ (t (append (first-n (len cycle) path) (find-prefix
+ cycle (rest seen) witness
+ (last-n (len cycle) path))))))
+
+(defun find-cycle (cycle seen witness path)
+ (cond ((endp seen) nil) ;; should not arise
+ ((endp path) nil)
+ ((equal witness (first seen)) path)
+ (t (find-cycle cycle (rest seen) witness (last-n (len cycle) path)))))
+
+;; ACL2 is really stupid in arithmetic. I just add Robert's collection of
+;; arithmetic books to get it thru with what I want. I need arithmetic really for
+;; very weird reasons, but well, what the heck, I dont want to deal with
+;; arithmetic myself any ways.
+
+(local
+(include-book "../../../../arithmetic-2/meta/top")
+)
+
+(local
+(defthm len-of-snoc-is-more
+ (< (len x) (len (snoc x e)))
+ :rule-classes :linear)
+)
+
+;; The following function determines a weird path in n, when given a cycle in
+;; m. The weird path is a finite path compatible with n, and can be thought of
+;; as the append of the prefix and cycle.
+
+(defun find-matching-prefix-and-cycle-for-cycle-m->n (cycle m seen q states n vars path)
+ (declare (xargs :measure (nfix (- (1+ (len states)) (len seen)))))
+ ;; for termination using Pigeon-hole arguments
+ (if (< (len states) (len seen)) (mv seen q path)
+ (let* ((path-produced (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ (node-witness (bisimilar-transition-witness-m->n
+ (last-val cycle) (first cycle) m
+ (last-val path-produced) n vars)))
+ (if (memberp node-witness seen)
+ (mv (snoc seen node-witness) node-witness (append path path-produced))
+ (find-matching-prefix-and-cycle-for-cycle-m->n cycle m (snoc seen node-witness)
+ node-witness states n
+ vars (append path
+ path-produced))))))
+
+(defun find-matching-prefix-and-cycle-for-cycle-n->m (seen q states m cycle n vars path)
+ (declare (xargs :measure (nfix (- (1+ (len states)) (len seen)))))
+ ;; for termination using Pigeon-hole arguments
+ (if (< (len states) (len seen)) (mv seen q path)
+ (let* ((path-produced (find-matching-path-for-path-n->m
+ q m cycle n vars))
+ (node-witness (bisimilar-transition-witness-n->m
+ (last-val path-produced) m
+ (last-val cycle) (first cycle) n vars)))
+ (if (memberp node-witness seen)
+ (mv (snoc seen node-witness) node-witness (append path path-produced))
+ (find-matching-prefix-and-cycle-for-cycle-n->m (snoc seen node-witness)
+ node-witness states m
+ cycle n
+ vars (append path
+ path-produced))))))
+
+
+;; And we pick up the prefix from the weird path
+
+(defun find-matching-prefix-for-cycle-m->n (cycle m q n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil)
+ (find-prefix cycle (del-last seen) witness path)))
+
+(defun find-matching-prefix-for-cycle-n->m (q m cycle n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil)
+ (find-prefix cycle (del-last seen) witness path)))
+
+
+;; and also the cycle.
+
+(defun find-matching-cycle-for-cycle-m->n (cycle m q n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil)
+ (find-cycle cycle (del-last seen) witness path)))
+
+(defun find-matching-cycle-for-cycle-n->m (q m cycle n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil)
+ (find-cycle cycle (del-last seen) witness path)))
+
+;; So we can now produce the matching periodic path by appending the prefix
+;; after the matching path for the prefix and the cycle as we obtained.
+
+(defun find-matching-periodic-path-m->n (ppath m n vars)
+ (let* ((init-p (initial-state ppath))
+ (prefix-p (prefix ppath))
+ (first-p (first prefix-p))
+ (cycle-p (cycle ppath))
+ (init-q (bisimilar-initial-state-witness-m->n init-p m n vars))
+ (first-q (bisimilar-transition-witness-m->n init-p first-p m init-q n
+ vars))
+ (match-path (find-matching-path-for-path-m->n prefix-p m first-q n
+ vars))
+ (last-p (last-val prefix-p))
+ (last-q (last-val match-path))
+ (first-cp (first cycle-p))
+ (first-cq (bisimilar-transition-witness-m->n last-p first-cp m last-q
+ n vars))
+ (match-prefix (find-matching-prefix-for-cycle-m->n
+ cycle-p m first-cq n vars))
+ (match-cycle (find-matching-cycle-for-cycle-m->n
+ cycle-p m first-cq n vars)))
+ (>_ :initial-state init-q
+ :prefix (append match-path match-prefix)
+ :cycle match-cycle)))
+
+(defun find-matching-periodic-path-n->m (m ppath n vars)
+ (let* ((init-q (initial-state ppath))
+ (prefix-q (prefix ppath))
+ (first-q (first prefix-q))
+ (cycle-q (cycle ppath))
+ (init-p (bisimilar-initial-state-witness-n->m m init-q n vars))
+ (first-p (bisimilar-transition-witness-n->m init-p m init-q first-q n
+ vars))
+ (match-path (find-matching-path-for-path-n->m first-p m prefix-q n
+ vars))
+ (last-q (last-val prefix-q))
+ (last-p (last-val match-path))
+ (first-cq (first cycle-q))
+ (first-cp (bisimilar-transition-witness-n->m last-p m last-q first-cq
+ n vars))
+ (match-prefix (find-matching-prefix-for-cycle-n->m
+ first-cp m cycle-q n vars))
+ (match-cycle (find-matching-cycle-for-cycle-n->m
+ first-cp m cycle-q n vars)))
+ (>_ :initial-state init-p
+ :prefix (append match-path match-prefix)
+ :cycle match-cycle)))
+
+
+;; Now we bite the bullet and start showing that this dirty bad function suits
+;; our purpose. Any suggestions for improvement will be greatly appreciated.
+
+;; Let us define the general concept of what we mean by two paths (or segments
+;; being bisimilar.
+
+
+(local
+(defun bisimilar-segments-p (p m q n vars)
+ (if (endp p) (endp q)
+ (and (consp q)
+ (bisimilar (first p) m (first q) n vars)
+ (bisimilar-segments-p (rest p) m (rest q) n vars))))
+)
+
+;; And of course we can then define when a sequence of segments appended
+;; together is bisimilar.
+
+
+(local
+(defun bisimilar-segments-sequence-p (p m q n vars)
+ (declare (xargs :measure (len q)))
+ (if (endp q) T
+ (if (or (endp p) (< (len q) (len p))) nil
+ (and (bisimilar-segments-p p m (first-n (len p) q) n vars)
+ (bisimilar-segments-sequence-p p m (last-n (len p) q) n vars)))))
+)
+
+(local
+(defun bisimilar-segments-sequence-p-2 (p m q n vars)
+ (declare (xargs :measure (len p)))
+ (if (endp p) T
+ (if (or (endp q) (< (len p) (len q))) nil
+ (and (bisimilar-segments-p (first-n (len q) p) m q n vars)
+ (bisimilar-segments-sequence-p-2 (last-n (len q) p) m q n vars)))))
+)
+
+
+;; Of course now, we know that find-matching-path produces a bisimilar path.
+
+(local
+(defthm find-matching-path-produces-bisimilar-segments
+ (implies (and (compatible-path-p p m)
+ (bisimilar (first p) m q n vars))
+ (bisimilar-segments-p
+ p m
+ (find-matching-path-for-path-m->n p m q n vars)
+ n vars)))
+)
+
+(local
+(defthm find-matching-path-produces-bisimilar-segments-2
+ (implies (and (compatible-path-p q n)
+ (bisimilar p m (first q) n vars))
+ (bisimilar-segments-p
+ (find-matching-path-for-path-n->m p m q n vars)
+ m q
+ n vars)))
+)
+
+;; and bisimilar paths have the same length.
+
+(local
+(defthm bisimilar-to-length
+ (implies (bisimilar-segments-p p m q n vars)
+ (equal (len p) (len q)))
+ :rule-classes :forward-chaining)
+)
+
+(local
+(defthm len-of-append
+ (equal (len (append x y))
+ (+ (len x) (len y))))
+)
+
+(local
+(defthm last-n-is-true-listp
+ (implies (true-listp p)
+ (true-listp (last-n i p))))
+)
+
+(local
+(defthm first-last-append-reduction-2
+ (implies (<= i (len x))
+ (equal (append x y)
+ (append (first-n i x) (append (last-n i x) y)))))
+)
+
+(local
+(defthm first-n-reduced
+ (implies (and (equal (len x) i)
+ (true-listp x))
+ (equal (first-n i x) x)))
+)
+
+(local
+(defthm last-n-reduced
+ (implies (and (<= (len x) i)
+ (integerp i)
+ (true-listp x))
+ (equal (last-n i x) nil)))
+)
+
+;; and bisimilar segements would also be bisimilar-segments-sequence.
+
+(local
+(defthm bisimilar-segments-are-bisimilar-segment-sequences
+ (implies (and (bisimilar-segments-p p m q n vars)
+ (true-listp p)
+ (true-listp q)
+ (consp p))
+ (bisimilar-segments-sequence-p p m q n vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :induct (bisimilar-segments-sequence-p p m q n vars)
+ :do-not-induct t)))
+)
+
+(local
+(defthm bisimilar-segments-are-bisimilar-segment-sequences-2
+ (implies (and (bisimilar-segments-p p m q n vars)
+ (true-listp p)
+ (true-listp q)
+ (consp q))
+ (bisimilar-segments-sequence-p-2 p m q n vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :induct (bisimilar-segments-sequence-p-2 p m q n vars)
+ :do-not-induct t)))
+)
+
+;; which when appended will produce bisimilar segments sequence.
+
+(local
+(defthm append-of-bisimilar-segments-produces-bisimilar-segment-list
+ (implies (and (bisimilar-segments-p p m r n vars)
+ (consp p)
+ (true-listp r)
+ (true-listp p)
+ (true-listp q)
+ (bisimilar-segments-sequence-p p m q n vars))
+ (bisimilar-segments-sequence-p p m (append q r) n vars))
+ :hints (("Goal"
+ :do-not '(generalize eliminate-destructors)
+ :do-not-induct t
+ :induct (bisimilar-segments-sequence-p p m q n vars))))
+)
+
+(local
+(defthm append-of-bisimilar-segments-produces-bisimilar-segment-list-2
+ (implies (and (bisimilar-segments-p r m q n vars)
+ (consp q)
+ (true-listp r)
+ (true-listp p)
+ (true-listp q)
+ (bisimilar-segments-sequence-p-2 p m q n vars))
+ (bisimilar-segments-sequence-p-2 (append p r) m q n vars))
+ :hints (("Goal"
+ :do-not '(generalize eliminate-destructors)
+ :do-not-induct t
+ :induct (bisimilar-segments-sequence-p-2 p m q n vars))))
+)
+
+;; and the prefix of bisimilar segements sequence is a
+;; bisimialr-segments-sequence
+
+(local
+(defthm prefix-produces-bisimilar-segment-list
+ (implies (bisimilar-segments-sequence-p p m q n vars)
+ (bisimilar-segments-sequence-p p m (find-prefix p seen witness q) n
+ vars)))
+)
+
+(local
+(defthm prefix-produces-bisimilar-segment-list-2
+ (implies (bisimilar-segments-sequence-p-2 p m q n vars)
+ (bisimilar-segments-sequence-p-2 (find-prefix q seen witness p) m q n
+ vars)))
+
+)
+
+;; and so is the cycle.
+
+(local
+(defthm cycle-produces-bisimilar-segment-list
+ (implies (bisimilar-segments-sequence-p p m q n vars)
+ (bisimilar-segments-sequence-p p m (find-cycle p seen witness q) n
+ vars)))
+)
+
+(local
+(defthm cycle-produces-bisimilar-segment-list-2
+ (implies (bisimilar-segments-sequence-p-2 p m q n vars)
+ (bisimilar-segments-sequence-p-2 (find-cycle q seen witness p) m q n
+ vars)))
+)
+
+;; Also the last-vals of compatible paths is bisimilar.
+
+(local
+(defthm last-vals-are-bisimilar
+ (implies (and (compatible-path-p path m)
+ (consp path)
+ (bisimilar (first path) m q n vars))
+ (bisimilar (last-val path) m
+ (last-val (find-matching-path-for-path-m->n path m q n
+ vars))
+ n vars)))
+)
+
+(local
+(defthm last-vals-are-bisimilar-2
+ (implies (and (compatible-path-p path n)
+ (consp path)
+ (bisimilar p m (first path) n vars))
+ (bisimilar (last-val (find-matching-path-for-path-n->m p m path n
+ vars))
+ m (last-val path)
+ n vars)))
+)
+
+
+
+(local
+(defthm true-listp-append-reduction
+ (implies (true-listp y)
+ (true-listp (append x y))))
+)
+
+;; and therefore, finally, the segment produced by find-prefix-and-cycle is
+;; bisimilar segments sequence-p
+
+(local
+(defthm matching-prefix-and-cycle-produces-bisimilar-segment-list
+ (implies (and (consp cycle)
+ (true-listp path)
+ (bisimilar-segments-sequence-p cycle m path n vars)
+ (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars))
+ (bisimilar-segments-sequence-p
+ cycle m
+ (mv-nth
+ 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q
+ states n vars path))
+ n vars)))
+)
+
+(local
+(defthm matching-prefix-and-cycle-produces-bisimilar-segment-list-2
+ (implies (and (consp cycle)
+ (true-listp path)
+ (bisimilar-segments-sequence-p-2 path m cycle n vars)
+ (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars))
+ (bisimilar-segments-sequence-p-2
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ m cycle
+ n vars))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n
+ vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+
+;; which means that the prefix is bisimilar segments sequence
+
+(local
+(defthm find-matching-prefix-is-bisimilar-segments-p
+ (implies (and (consp cycle)
+ (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (car cycle) m)
+ (bisimilar (first cycle) m q n vars))
+ (bisimilar-segments-sequence-p
+ cycle m (find-matching-prefix-for-cycle-m->n cycle m q n vars) n
+ vars)))
+)
+
+(local
+(defthm find-matching-prefix-is-bisimilar-segments-p-2
+ (implies (and (consp cycle)
+ (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (car cycle) n)
+ (bisimilar q m (first cycle) n vars))
+ (bisimilar-segments-sequence-p-2
+ (find-matching-prefix-for-cycle-n->m q m cycle n vars) m cycle n
+ vars)))
+)
+
+;; and so is the cycle.
+
+(local
+(defthm find-matching-cycle-is-bisimilar-segments-p
+ (implies (and (consp cycle)
+ (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (car cycle) m)
+ (bisimilar (first cycle) m q n vars))
+ (bisimilar-segments-sequence-p
+ cycle m (find-matching-cycle-for-cycle-m->n cycle m q n vars) n
+ vars)))
+
+)
+
+(local
+(defthm find-matching-cycle-is-bisimilar-segments-p-2
+ (implies (and (consp cycle)
+ (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (car cycle) n)
+ (bisimilar q m (first cycle) n vars))
+ (bisimilar-segments-sequence-p-2
+ (find-matching-cycle-for-cycle-n->m q m cycle n vars) m cycle n
+ vars)))
+
+)
+
+;; Now of course, a periodic path is bisimilar to another if the following
+;; holds.
+
+(local
+(defun bisimilar-periodic-paths-p (p m q n vars)
+ (and (bisimilar (initial-state p) m (initial-state q) n vars)
+ (or (and (bisimilar-segments-p (prefix p) m
+ (first-n (len (prefix p)) (prefix q))
+ n vars)
+ (bisimilar-segments-sequence-p
+ (cycle p) m
+ (last-n (len (prefix p)) (prefix q)) n vars)
+ (bisimilar-segments-sequence-p (cycle p) m (cycle q) n vars))
+ (and (bisimilar-segments-p (first-n (len (prefix q)) (prefix p)) m
+ (prefix q) n vars)
+ (bisimilar-segments-sequence-p-2 (last-n (len (prefix q))
+ (prefix p))
+ m (cycle q) n vars)
+ (bisimilar-segments-sequence-p-2
+ (cycle p) m (cycle q) n vars)))))
+
+)
+
+;; We need to show that find-matching-periodic-path-m->ns produce
+;; bisimilar-periodic-paths-p.
+
+
+;; And we need to append things the other way around to get it through.
+
+(local
+(in-theory (disable find-matching-prefix-for-cycle-m->n
+ find-matching-cycle-for-cycle-m->n
+ find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m))
+)
+
+(local
+(defthm find-matching-path-for-path-has-same-len
+ (equal (len (find-matching-path-for-path-m->n p m q n vars))
+ (len p)))
+)
+
+(local
+(defthm find-matching-path-for-path-has-same-len-2
+ (equal (len (find-matching-path-for-path-n->m p m q n vars))
+ (len q)))
+)
+
+(local
+(defthm find-matching-periodic-path-m->n-produces-bisimilar-periodic-paths
+ (implies (and (compatible-ppath-p ppath m)
+ (bisimilar-equiv m n vars))
+ (bisimilar-periodic-paths-p ppath m
+ (find-matching-periodic-path-m->n
+ ppath m n
+ vars)
+ n vars))
+ :hints (("Goal"
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-matching-periodic-path-m->n-produces-bisimilar-periodic-paths-2
+ (implies (and (compatible-ppath-p ppath n)
+ (bisimilar-equiv m n vars))
+ (bisimilar-periodic-paths-p
+ (find-matching-periodic-path-n->m m ppath n
+ vars)
+ m ppath
+ n vars))
+ :hints (("Goal"
+ :do-not-induct t)))
+)
+
+;; Now let us prove that bisimilar periodic paths have labels equal.
+
+
+(local
+ (in-theory (disable set-equal set-intersect))
+ )
+
+(local
+(defthm bisimilar-segments-have-equal-labels
+ (implies (and (bisimilar-segments-p p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-label-segments-p p m q n vars)))
+)
+
+(local
+(defthm bisimilar-segments-sequence-p-have-equal-labels
+ (implies (and (bisimilar-segments-sequence-p p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-label-segments-sequence-p-small-p p m q n vars)))
+)
+
+(local
+(defthm bisimilar-segments-sequence-p-have-equal-labels-2
+ (implies (and (bisimilar-segments-sequence-p-2 p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-label-segments-sequence-p-large-p p m q n vars)))
+)
+
+(local
+(defthm bisimilar-periodic-paths-have-equal-labels
+ (implies (and (bisimilar-periodic-paths-p p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-labels-periodic-path-p p m q n vars)))
+)
+
+(local
+(in-theory (disable bisimilar-periodic-paths-p equal-labels-periodic-path-p))
+)
+
+(local
+(defthm ppath-and-its-matching-ppath-have-same-labels
+ (implies (and (compatible-ppath-p ppath m)
+ (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n))
+ (equal-labels-periodic-path-p
+ ppath m (find-matching-periodic-path-m->n ppath m n vars) n vars))
+ :hints (("Goal"
+ :in-theory (disable compatible-ppath-p
+ find-matching-periodic-path-m->n))))
+
+)
+
+(local
+(defthm ppath-and-its-matching-ppath-have-same-labels-2
+ (implies (and (compatible-ppath-p ppath n)
+ (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n))
+ (equal-labels-periodic-path-p
+ (find-matching-periodic-path-n->m m ppath n vars) m ppath n vars))
+ :hints (("Goal"
+ :in-theory (disable compatible-ppath-p
+ find-matching-periodic-path-n->m))))
+
+)
+
+
+;; OK let us now think over what I proved so far. Briefly I have proved that if
+;; P is a periodic path in m, and m and n are bisimilar-equivalent, then there
+;; is a periodic path which has the same labels. Now what do we need to
+;; prove? We need to prove that the periodic path we have proved to have the
+;; same label must be a path of n. That is it is compatible with n. If we do
+;; that, then we would know that for every path in m there is a path in n that
+;; has the same labels. hence we will know that ltl-semantics of m and n for a
+;; restricted formula f is same.
+
+
+;; Unfortunately, this property (though trivial intuitively) is not an easy
+;; property for a theorem-proving exercise. It needs a lot of work showing (for
+;; example) pigeon-hole principle. I will discuss the issues as we get
+;; there. For now, let us start proving each of the constraints of
+;; compatible-ppath-p separately. There is no real mystery here, --- I took a
+;; printout of ltl.lisp, and decided to prove each of the constraints
+;; separately.
+
+;; To prove these constraints separately, I will bear in mind that in the final
+;; theorem compatible-ppath-p is going to be enabled. This being a recursive
+;; function, we will have to be careful that in the lemmas, we do not have
+;; compatible-ppath-p as a hypothesis.
+
+;; The first theorem in our agenda is to show that initial-state of matching
+;; ppath is a member of initial states. That is obvious, from the constraints
+;; of bisimilar-initial-state-witness.
+
+
+;; The next theorem is to show that the prefix is a consp. This is because we
+;; start with a matching-path of a consp prefix and append of a consp with
+;; something is a consp. This is established by the next two theorems.
+
+(local
+(defthm prefix-is-a-consp
+ (equal (consp (find-matching-path-for-path-m->n path m q n vars))
+ (consp path)))
+)
+
+(local
+(defthm prefix-is-a-consp-2
+ (equal (consp (find-matching-path-for-path-n->m q m path n vars))
+ (consp path)))
+)
+
+
+(local
+(defthm append-expands-to-consp
+ (equal (consp (append x y))
+ (if (consp x) T (consp y))))
+)
+
+;; The next constraint says that the first of the prefix is next state of
+;; init. This is trivial from property of bisimilar-transition-witness and the
+;; fact that inits of the two models are bisimilar.
+
+
+
+;; The next constraint is to show that the cycle is a consp. In other words, we
+;; have to show the consp property for find-matching-cycle-for-cyle. Now why
+;; is the cycle consp. Roughly, the reason is as follows. The length of the
+;; path produced by prefix and cycle is (len seen) * (len cycle). And the
+;; witness is a member of path. seen. Hence the cycle produced is a consp by
+;; the next two theorems.
+
+(local
+(defthm last-n-len-reduction
+ (implies (and (equal (len path) (+ i j))
+ (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j))
+ (equal (len (last-n i path))
+ j)))
+)
+
+(local
+(defthm witness-member-of-seen-implies-consp
+ (implies (and (memberp witness seen)
+ (consp cycle)
+ (force (equal (len path) (* (len cycle) (len seen)))))
+ (consp (find-cycle cycle seen witness path))))
+)
+
+;; However, this leads us to two more proof requirements. Why should the
+;; witness be a member of seen, and why should the length of the big path be
+;; the product of the length of seen and cycle. We address these two issues
+;; below.
+
+(local
+(defthm snoc-produces-memberp
+ (memberp e (snoc x e)))
+)
+
+(local
+(defthm snoc-len-reduction
+ (equal (len (snoc x e))
+ (1+ (len x))))
+)
+
+;; We show that the value returned as the seen list has 1 less than what we
+;; need, and this will just be figured out by deducting 1 again from the seen
+;; list since we remove the last guy.
+
+(local
+(defthm len-of-path-is-product-of-two
+ (implies (equal (len path) (* (len cycle) (1- (len seen))))
+ (equal (len (mv-nth
+ 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)))
+ (* (len cycle)
+ (1- (len (mv-nth
+ 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars
+ path))))))))
+
+)
+
+(local
+(defthm len-of-path-is-product-of-two-2
+ (implies (equal (len path) (* (len cycle) (1- (len seen))))
+ (equal (len (mv-nth
+ 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)))
+ (* (len cycle)
+ (1- (len (mv-nth
+ 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars
+ path))))))))
+
+)
+
+
+(local
+(defthm del-last-len-reduction
+ (implies (consp x)
+ (equal (len (del-last x))
+ (1- (len x)))))
+)
+
+;; And finally that the seen list is consp
+
+(local
+(defthm seen-list-is-consp
+ (implies (memberp q seen)
+ (consp (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n cycle m seen
+ q states n
+ vars path))))
+
+)
+
+(local
+(defthm seen-list-is-consp-2
+ (implies (memberp q seen)
+ (consp (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m seen
+ q states m
+ cycle n
+ vars path))))
+
+)
+
+;; Now why should the witness be a member of the seen? The reason is kind of a
+;; pigeon-hole argument. The high-level argument is that witness is producing a
+;; a member of states all the time, and a new guy every time it produces a
+;; non-member of seen so it will exhaust out eventually.
+
+
+;; First a few reductions using snoc and uniquep. I am lucky that uniquep is
+;; already in records which helps a lot.
+
+(local
+(defthm snoc-member-reduction
+ (equal (memberp a (snoc x e))
+ (or (memberp a x)
+ (equal a e))))
+)
+
+(local
+(defthm uniquep-snoc-reduction
+ (implies (and (uniquep seen)
+ (not (memberp e seen)))
+ (uniquep (snoc seen e))))
+)
+
+(local
+(defthm memberp-del-last-reduction
+ (equal (memberp a (del-last (snoc x e)))
+ (memberp a x)))
+)
+
+(local
+(defthm uniquep-dellast-reduction
+ (implies (uniquep x)
+ (uniquep (del-last (snoc x e)))))
+)
+
+(local
+(defthm not-memberp-del-reduction
+ (implies (not (memberp e x))
+ (not (memberp e (del-last x)))))
+)
+
+(local
+(defthm uniquep-del-last-true
+ (implies (uniquep x)
+ (uniquep (del-last x))))
+)
+
+;; So now, we can show that the seen list is uniquep.
+
+(local
+(defthm del-last-seen-is-unique-p
+ (implies (uniquep seen)
+ (uniquep (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm del-last-seen-is-unique-p-2
+ (implies (uniquep seen)
+ (uniquep (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm len-<-states-implies-<witness-memberp
+ (implies (case-split (<= (len (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)))
+ (len states)))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))
+ (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))))))
+)
+
+(local
+(defthm len-<-states-implies-<witness-memberp-2
+ (implies (case-split (<= (len (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)))
+ (len states)))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))))))
+)
+
+(local
+(in-theory (enable subset))
+)
+
+;; Again, we need to define del. This is because it will be used in the
+;; induction hint. I am rpetty sure this is not the shortest path to the proof,
+;; but this is how I would have reasoned without ACL2.
+
+(local
+(defun del (e x)
+ (if (endp x) nil
+ (if (equal e (car x)) (cdr x)
+ (cons (car x) (del e (cdr x))))))
+)
+
+(local
+(defthm uniquep-to-not-member
+ (implies (uniquep x)
+ (not (memberp e (del e x)))))
+)
+
+(local
+(defthm member-del-reduction
+ (implies (not (equal a e))
+ (equal (memberp a (del e y))
+ (memberp a y))))
+)
+
+(local
+(defthm del-subset-reduction
+ (implies (and (uniquep x)
+ (subset x y))
+ (subset (del e x) (del e y))))
+)
+
+(local
+(defthm len-del-reduction
+ (implies (memberp e x)
+ (equal (len (del e x))
+ (1- (len x)))))
+)
+
+(local
+(defun induction-hint (x y)
+ (if (endp x) y
+ (induction-hint (rest x) (del (first x) y))))
+)
+
+(local
+(defthm not-memberp-del-reduction-2
+ (implies (not (memberp e x))
+ (subset x (del e x))))
+)
+
+(local
+(defthm unique-p-del-subset-reduction
+ (implies (and (uniquep x)
+ (not (memberp e x))
+ (subset x y))
+ (subset x (del e y)))
+ :hints (("Goal"
+ :do-not-induct t
+ :use ((:instance subset-is-transitive
+ (y (del e x))
+ (z (del e y)))))))
+)
+
+(local
+(defthm uniquep-subset-reduction
+ (implies (and (uniquep x)
+ (subset x y))
+ (<= (len x) (len y)))
+ :hints (("Goal"
+ :induct (induction-hint x y))))
+)
+
+(local
+(defthm car-append-reduction
+ (equal (car (append x y))
+ (if (consp x) (car x) (car y))))
+)
+
+(local
+(defthm consp-to-car-find-matching-path
+ (implies (consp path)
+ (equal (car (find-matching-path-for-path-m->n path m q n vars))
+ q)))
+)
+
+(local
+(defthm consp-to-car-find-matching-path-2
+ (implies (consp path)
+ (equal (car (find-matching-path-for-path-n->m q m path n vars))
+ q)))
+)
+
+(local
+(defthm last-val-append-reduction
+ (equal (last-val (append x y))
+ (if (consp y) (last-val y) (last-val x))))
+)
+
+(local
+(defthm subset-snoc-reduction
+ (implies (and (subset x y)
+ (memberp e y))
+ (subset (snoc x e) y)))
+)
+
+(local
+(defthm last-val-bisimilar-reduction
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (compatible-path-p cycle m))
+ (bisimilar (last-val cycle) m (last-val
+ (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ n vars)))
+)
+
+(local
+(defthm last-val-bisimilar-reduction-2
+ (implies (and (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (compatible-path-p cycle n))
+ (bisimilar (last-val (find-matching-path-for-path-n->m q m cycle n
+ vars))
+ m
+ (last-val cycle)
+ n vars)))
+)
+
+(local
+(defthm find-matching-path-produces-compatible-path
+ (implies (and (compatible-path-p cycle m)
+ (consp cycle)
+ (memberp q (states n))
+ (bisimilar (first cycle) m q n vars))
+ (compatible-path-p (find-matching-path-for-path-m->n
+ cycle m q n vars)
+ n)))
+)
+
+(local
+(defthm find-matching-path-produces-compatible-path-2
+ (implies (and (compatible-path-p cycle n)
+ (consp cycle)
+ (memberp q (states m))
+ (bisimilar q m (first cycle) n vars))
+ (compatible-path-p (find-matching-path-for-path-n->m
+ q m cycle n vars)
+ m)))
+)
+
+;; And finally, I am saying that seen list is a subset of states. (Basically a
+;; slightly stronger thing, but that is ok.)
+
+
+(local
+(defthm seen-list-subset-of-states
+ (implies (and (subset seen (states n))
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (compatible-path-p cycle m))
+ (subset (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))
+ (states n)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm seen-list-subset-of-states-2
+ (implies (and (subset seen (states m))
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (compatible-path-p cycle n))
+ (subset (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ (states m)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+;; And also that witness is a member of states.
+
+(local
+(defthm witness-member-of-states
+ (implies (and (memberp q (states n))
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (compatible-path-p cycle m))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))
+ (states n)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm witness-member-of-states-2
+ (implies (and (memberp q (states m))
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (compatible-path-p cycle n))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ (states m)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm subset-remains-for-del
+ (implies (subset x y)
+ (subset (del-last x) y)))
+)
+
+(local
+(defthm del-creates-subset
+ (subset (del-last x) x))
+)
+
+(local
+(defthm memberp-to-subset
+ (implies (memberp q states)
+ (subset (list q) states))
+ :rule-classes nil)
+)
+
+(local
+(defthm uniquep-and-=-and-implies-member
+ (implies (and (uniquep x)
+ (equal (len x) (len y))
+ (subset x y)
+ (memberp e y))
+ (memberp e x))
+ :hints (("Goal"
+ :induct (induction-hint x y))))
+)
+
+;; Then finally, I am done. I am saying here that the matching cycle is a
+;; consp. Matt might just not like the use hints I force, but there seems to be
+;; no simpler route. I would be interested to know if someone can simplify this
+;; proof.
+
+(local
+(defthm find-matching-cycle-for-cycle-is-consp
+ (implies (and (memberp q (states n))
+ (consp cycle)
+ (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (next-statep (last-val cycle) (first cycle) m))
+ (consp (find-matching-cycle-for-cycle-m->n cycle m q n vars)))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :expand (find-matching-cycle-for-cycle-m->n cycle m q n vars)
+ :do-not-induct t
+ :in-theory (disable witness-member-of-seen-implies-consp)
+ :use ((:instance witness-member-of-seen-implies-consp
+ (witness (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n)
+ n vars nil)))
+ (seen (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (path (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance uniquep-subset-reduction
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil))))
+ (y (states n)))
+ (:instance uniquep-and-=-and-implies-member
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n)
+ n vars nil))))
+ (y (states n))
+ (e (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n)
+ n vars nil))))))))
+)
+
+
+(local
+(defthm find-matching-cycle-for-cycle-is-consp-2
+ (implies (and (memberp q (states m))
+ (consp cycle)
+ (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (next-statep (last-val cycle) (first cycle) n))
+ (consp (find-matching-cycle-for-cycle-n->m q m cycle n vars)))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :expand (find-matching-cycle-for-cycle-n->m q m cycle n vars)
+ :do-not-induct t
+ :in-theory (disable witness-member-of-seen-implies-consp)
+ :use ((:instance witness-member-of-seen-implies-consp
+ (witness (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle
+ n vars nil)))
+ (seen (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (path (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance uniquep-subset-reduction
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (y (states m)))
+ (:instance uniquep-and-=-and-implies-member
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle
+ n vars nil))))
+ (y (states m))
+ (e (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n vars nil))))))))
+)
+
+;; The next theorem in our agenda is to prove that the prefix of the matching
+;; path is compatible-path-p. Notice we have already proved that
+;; find-matching-path produces a compatible-path-p. So we need to prove that
+;; prefix-and-cycle produces the same, and then say that append of two "good"
+;; compatible paths is a compatible path.
+
+(local
+(defthm compatible-path-append-reduction
+ (implies (force (and (true-listp x)
+ (true-listp y)))
+ (equal (compatible-path-p (append x y) m)
+ (if (not (consp x)) (compatible-path-p y m)
+ (if (not (consp y)) (compatible-path-p x m)
+ (and (compatible-path-p x m)
+ (compatible-path-p y m)
+ (next-statep (last-val x) (first y) m)))))))
+)
+
+
+;; While we are at it, let us show that the first-n and last-n are
+;; compatible-paths
+
+(local
+(defthm consp-and-i>=-first-n-reduction
+ (implies (and (consp p)
+ (integerp i)
+ (< 0 i))
+ (equal (car (first-n i p))
+ (car p))))
+)
+
+(local
+(defthm compatible-path-first-n-reduction
+ (implies (and (compatible-path-p p m)
+ (integerp i)
+ (<= 0 i)
+ (<= i (len p)))
+ (compatible-path-p (first-n i p) m))
+ :hints (("Goal"
+ :induct (first-n i p)
+ :in-theory (enable zp)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :cases ((zp (1- i))))))
+)
+
+(local
+(defthm compatible-path-last-n-reduction
+ (implies (and (compatible-path-p p m)
+ (integerp i)
+ (<= 0 i)
+ (<= i (len p)))
+ (compatible-path-p (last-n i p) m))
+ :hints (("Goal"
+ :induct (last-n i p)
+ :in-theory (enable zp)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :cases ((zp (1- i))))))
+)
+
+;; The theorems above just say that if we could (somehow) prove that
+;; find-prefix-and-cycle produces a compatible path then I would immediately
+;; know that the prefix and cycle are both compatible.
+
+;; Now why should find-prefix-and-cycle produce a compatible path? For
+;; something to be a compatible path, what we need is that every state in the
+;; path is a member of states and the next state is a next-statep. So let us
+;; prove these properties separately.
+
+;; Informally here is what happens. I know that the last-val of
+;; find-matching-path is bisimilar to last-val of cycle. and is a member of
+;; states. Hence, the bisimilar witness it produces with the first of cycle is
+;; a next-statep (Notice that next-statep is true for last-val and car of
+;; cycle.) Hence the paths produced by recursive calls can be appended together
+;; to produce a compatible path if path (the initial segment of the accumulator
+;; is known to be a compatible path.
+
+
+(local
+(defthm last-val-of-find-matching-prefix-is-member-of-states
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (compatible-path-p cycle m)
+ (memberp q (states n)))
+ (memberp (last-val (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ (states n))))
+)
+
+(local
+(defthm find-prefix-and-cycle-produces-compatible-path
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (compatible-path-p path n)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ n)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m)
+ (compatible-path-p cycle m))
+ (compatible-path-p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path))
+ n))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-prefix-and-cycle-produces-compatible-path-2
+ (implies (and (bisimilar q m (first cycle) n vars)
+ (compatible-path-p path m)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-n->m
+ q m cycle n vars))
+ m)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n)
+ (compatible-path-p cycle n))
+ (compatible-path-p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path))
+ m))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+;; Now that we know that find-prefix-and-cycle-is-a-compatible-path-p, and also
+;; that first-n of a compatible path is a compatible path, and also append
+;; produces compatible paths, we should be able to prove that
+;; find-matching-prefix and find-matching-cycle produce compatible paths.
+
+;; Well, it does not seem to be as simple as it looks. The problem is in
+;; getting the induction working right.
+
+;; To do work with find-matching-prefix we define the index such that
+;; find-prefix produces that index.
+
+
+(local
+(defun find-prefix-index (cycle seen witness path)
+ (cond ((endp path) 0)
+ ((endp seen) (len path))
+ ((equal witness (first seen)) 0)
+ (t (+ (len cycle)
+ (find-prefix-index cycle (rest seen) witness (last-n (len cycle) path))))))
+)
+
+(local
+(defthm first-n+-reduction
+ (implies (and (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j))
+ (equal (first-n (+ i j) x)
+ (append (first-n i x) (first-n j (last-n i x))))))
+)
+
+(local
+(defthm last-n+-reduction
+ (implies (and (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j))
+ (equal (last-n (+ i j) x)
+ (last-n j (last-n i x)))))
+)
+
+(local
+(defthm find-prefix-with-index
+ (implies (and (true-listp path)
+ (equal (len path) (* (len cycle) (len seen))))
+ (equal (find-prefix cycle seen witness path)
+ (first-n (find-prefix-index cycle seen witness path) path))))
+)
+
+(local
+(defthm find-cycle-with-index
+ (implies (and (equal (len path) (* (len cycle) (len seen)))
+ (true-listp path))
+ (equal (find-cycle cycle seen witness path)
+ (last-n (find-prefix-index cycle seen witness path) path))))
+)
+
+(local
+(defthm index-is-an-integer->=0
+ (and (integerp (find-prefix-index cycle seen witness path))
+ (<= 0 (find-prefix-index cycle seen witness path)))
+ :rule-classes :type-prescription)
+)
+
+(local
+(defthm prefix-and-cycle-produces-true-listp
+ (implies (true-listp path)
+ (true-listp (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m q seen states n vars path)))))
+)
+
+(local
+(defthm prefix-and-cycle-produces-true-listp-2
+ (implies (true-listp path)
+ (true-listp (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ q seen states m cycle n vars path)))))
+)
+
+(local
+(in-theory (enable find-matching-cycle-for-cycle-m->n
+ find-matching-prefix-for-cycle-m->n))
+)
+
+(local
+(defthm last-consp-implies-first-<=len
+ (implies (and (consp (last-n i x))
+ (integerp i))
+ (<= i (len x)))
+ :rule-classes :linear)
+)
+
+(local
+(defthm find-matching-prefix-is-a-compatible-path
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m))
+ (compatible-path-p (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars)
+ n))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-first-n-reduction
+ find-matching-cycle-for-cycle-is-consp)
+ :use ((:instance compatible-path-first-n-reduction
+ (i (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (m n)
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp)))))
+)
+
+(local
+(defthm find-matching-cycle-is-a-compatible-path
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m))
+ (compatible-path-p (find-matching-cycle-for-cycle-m->n cycle m q n
+ vars)
+ n))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-first-n-reduction
+ find-matching-cycle-for-cycle-is-consp)
+ :use ((:instance compatible-path-last-n-reduction
+ (i (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (m n)
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp)))))
+)
+
+(local
+(in-theory (enable find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m))
+)
+
+(local
+(defthm find-matching-prefix-is-a-compatible-path-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n))
+ (compatible-path-p (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars)
+ m))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-first-n-reduction
+ find-matching-cycle-for-cycle-is-consp-2)
+ :use ((:instance compatible-path-first-n-reduction
+ (i (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q)
+ q
+ (states
+ m) m
+ cycle n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states
+ m)
+ m
+ cycle n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m) m
+ cycle n
+ vars nil))))
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp-2)))))
+)
+
+
+(local
+(defthm find-matching-cycle-is-a-compatible-path-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n))
+ (compatible-path-p (find-matching-cycle-for-cycle-n->m q m cycle n
+ vars)
+ m))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-last-n-reduction
+ find-matching-cycle-for-cycle-is-consp-2)
+ :use ((:instance compatible-path-last-n-reduction
+ (i (find-prefix-index
+ cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q)
+ q
+ (states
+ m) m
+ cycle n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states
+ m)
+ m
+ cycle n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m) m
+ cycle n
+ vars nil))))
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp-2)))))
+)
+
+(local
+(defthm consp-last-next-state-p-reduction
+ (implies (and (compatible-path-p (append p q) m)
+ (true-listp p)
+ (true-listp q)
+ (consp p)
+ (consp q))
+ (next-statep (last-val p) (first q) m))
+ :rule-classes nil)
+)
+
+(local
+(defthm append-of-prefix-and-cycle-is-weird-path
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (equal (append (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars)
+ (find-matching-cycle-for-cycle-m->n cycle m q n
+ vars))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n cycle m
+ (list q)
+ q
+ (states n) n
+ vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp)
+ :use ((:instance first-last-append-reduction
+ (n (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (x (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp)))))
+)
+
+(local
+(defthm append-of-prefix-and-cycle-is-weird-path-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (equal (append (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars)
+ (find-matching-cycle-for-cycle-n->m q m cycle n
+ vars))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m (list q)
+ q
+ (states m) m
+ cycle n
+ vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp-2)
+ :use ((:instance first-last-append-reduction
+ (n (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m)
+ m
+ cycle n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states
+ m)
+ m
+ cycle n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m) m
+ cycle n
+ vars nil))))
+ (x (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp-2)))))
+)
+
+(local
+(in-theory (disable append-of-prefix-and-cycle-is-weird-path
+ append-of-prefix-and-cycle-is-weird-path-2))
+)
+
+(local
+(defthm matching-cycle-is-true-listp
+ (true-listp (find-matching-cycle-for-cycle-m->n cycle m q n vars)))
+)
+
+(local
+(defthm matching-cycle-is-true-listp-2
+ (true-listp (find-matching-cycle-for-cycle-n->m q m cycle n vars)))
+)
+
+(local
+(defthm matching-prefix-is-true-listp
+ (true-listp (find-matching-prefix-for-cycle-m->n cycle m q n vars)))
+)
+
+(local
+(defthm matching-prefix-is-true-listp-2
+ (true-listp (find-matching-prefix-for-cycle-n->m q m cycle n vars)))
+)
+
+(local
+(defthm next-state-of-prefix-is-first-cycle
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (implies (consp (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars))
+ (next-statep (last-val (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (first (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ n)))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-prefix-with-index
+ find-prefix-and-cycle-produces-compatible-path
+ find-matching-prefix-for-cycle-m->n
+ find-matching-cycle-for-cycle-m->n
+ find-cycle-with-index
+ find-matching-cycle-for-cycle-is-consp
+ find-matching-prefix-and-cycle-for-cycle-m->n)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path)
+ (:instance find-matching-cycle-for-cycle-is-consp)
+ (:instance find-prefix-and-cycle-produces-compatible-path
+ (seen (list q))
+ (path nil))
+ (:instance consp-last-next-state-p-reduction
+ (m n)
+ (p (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (q (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars)))))))
+)
+
+(local
+(defthm next-state-of-prefix-is-first-cycle-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (implies (consp (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars))
+ (next-statep (last-val (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (first (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ m)))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-prefix-with-index
+ find-prefix-and-cycle-produces-compatible-path-2
+ find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m
+ find-cycle-with-index
+ find-matching-cycle-for-cycle-is-consp-2
+ find-matching-prefix-and-cycle-for-cycle-n->m)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path-2)
+ (:instance find-matching-cycle-for-cycle-is-consp-2)
+ (:instance find-prefix-and-cycle-produces-compatible-path-2
+ (seen (list q))
+ (path nil))
+ (:instance consp-last-next-state-p-reduction
+;; (m n)
+ (p (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (q (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars)))))))
+)
+
+;; So we have proved that matching-path is consp and that find-matching-prefix
+;; is compatible. Now we need to prove that last-val of matching-path and first
+;; of find-matching-prefix are next-states. Why is that? This is because
+;; last-val of find-matching-prefix is bisimilar to last-val of prefix, and we
+;; know that car of find-matching-prefix is the bisimilar witness.
+
+
+(local
+(defthm car-of-prefix-and-cycle
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (force (<= (len seen) (len (states n))))
+ (compatible-path-p path n)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ n)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m)
+ (compatible-path-p cycle m))
+ (equal (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)))
+ (if (consp path) (car path) q)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n cycle m seen q (states
+ n) n
+ vars
+ path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm car-of-prefix-and-cycle-2
+ (implies (and (bisimilar q m (first cycle) n vars)
+ (force (<= (len seen) (len (states m))))
+ (compatible-path-p path m)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-n->m
+ q m cycle n vars))
+ m)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n)
+ (compatible-path-p cycle n))
+ (equal (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)))
+ (if (consp path) (car path) q)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m seen q (states
+ m)
+ m
+ cycle n
+ vars
+ path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(in-theory (disable find-matching-prefix-for-cycle-m->n
+ find-matching-cycle-for-cycle-m->n
+ find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m))
+)
+
+(local
+(defthm matching-prefix-consp
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (true-listp cycle)
+ (consp cycle)
+ (memberp q (states n))
+ (consp (find-matching-prefix-for-cycle-m->n cycle m q n vars)))
+ (equal (car (find-matching-prefix-for-cycle-m->n cycle m q n vars))
+ (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable car-of-prefix-and-cycle
+ car-append-reduction
+ find-prefix-with-index find-cycle-with-index)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path)
+ (:instance car-append-reduction
+ (x (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (y (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars)))))))
+
+)
+
+(local
+(defthm matching-prefix-consp-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (true-listp cycle)
+ (consp cycle)
+ (memberp q (states m))
+ (consp (find-matching-prefix-for-cycle-n->m q m cycle n vars)))
+ (equal (car (find-matching-prefix-for-cycle-n->m q m cycle n vars))
+ (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable car-of-prefix-and-cycle-2
+ car-append-reduction
+ find-prefix-with-index find-cycle-with-index)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path-2)
+ (:instance car-append-reduction
+ (x (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (y (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars)))))))
+
+)
+
+(local
+(defthm matching-prefix-not-consp
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states n))
+ (not (consp (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars))))
+ (equal (find-matching-cycle-for-cycle-m->n cycle m q n vars)
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :use append-of-prefix-and-cycle-is-weird-path)))
+)
+
+(local
+(defthm matching-prefix-not-consp-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states m))
+ (not (consp (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars))))
+ (equal (find-matching-cycle-for-cycle-n->m q m cycle n vars)
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :use append-of-prefix-and-cycle-is-weird-path-2)))
+)
+
+;; The next and final property should be that the next state of the last of the
+;; cycle is the first of the cycle. Once I do that, I would go home-free with
+;; the final theorems.
+
+
+(local
+(defthm witness-is-next-state-of-last-val
+ (implies (and (consp cycle)
+ (true-listp cycle)
+ (subset seen (states n))
+ (uniquep seen)
+ (compatible-path-p cycle m)
+ (memberp q (states n))
+ (bisimilar (first cycle) m q n vars)
+ (next-statep (last-val cycle) (first cycle) m))
+ (next-statep (last-val
+ (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)))
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path))
+ n)))
+)
+
+(local
+(defthm witness-is-next-state-of-last-val-2
+ (implies (and (consp cycle)
+ (true-listp cycle)
+ (subset seen (states m))
+ (uniquep seen)
+ (compatible-path-p cycle n)
+ (memberp q (states m))
+ (bisimilar q m (first cycle) n vars)
+ (next-statep (last-val cycle) (first cycle) n))
+ (next-statep (last-val
+ (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)))
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path))
+ m)))
+)
+
+;; OK, so we have proved that the witness is the next state of the
+;; last-val. Now of course, we have to know that the witness is the first thing
+;; that is picked up by find-cycle.
+
+
+(local
+(defun seen-compatible-with-path (cycle seen path)
+ (if (endp seen) (endp path)
+ (and (equal (car path) (car seen))
+ (seen-compatible-with-path cycle (rest seen) (last-n (len cycle) path)))))
+)
+
+(local
+(defthm consp-len-consp
+ (implies (and (consp cycle)
+ (<= (len cycle) (len q)))
+ (consp q))
+ :rule-classes nil)
+)
+
+(local
+(defthm consp-last-n-append-reduction
+ (implies (and (consp q)
+ (consp p))
+ (consp (last-n (len q) (append p q)))))
+)
+
+(local
+(defthm car-to-car-for-append
+ (implies (and (seen-compatible-with-path cycle seen (append p q))
+ (consp seen)
+ (force (consp p)))
+ (equal (car p) (car seen))))
+)
+
+(local
+(defthm snoc-car
+ (equal (car (snoc x e))
+ (if (consp x) (car x) e)))
+)
+
+(local
+(defthm last-n-not-consp
+ (not (consp (last-n (len p) p))))
+)
+
+(local
+(defthm last-append-reduction
+ (implies (and (integerp i)
+ (<= 0 i)
+ (<= i (len p)))
+ (equal (last-n i (append p q))
+ (append (last-n i p) q))))
+)
+
+(local
+(defthm len-<-1=>not-consp
+ (implies (< (len x) 1)
+ (not (consp x))))
+)
+
+(local
+(defthm snoc-append-compatible-reduction
+ (implies (and (seen-compatible-with-path cycle seen path)
+ (equal e (car q))
+ (consp q)
+ (force (equal (len path) (* (len cycle) (len seen))))
+ (force (<= (len cycle) (len path)))
+ (equal (len cycle) (len q)))
+ (seen-compatible-with-path cycle (snoc seen e) (append path q)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (seen-compatible-with-path cycle seen path)
+ :in-theory (disable first-last-append-reduction-2)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-prefix-and-cycle-has-seen-compatible
+ (implies (and (consp cycle)
+ (memberp q seen)
+ (true-listp seen)
+ (equal (len path) (* (len cycle) (1- (len seen))))
+ (seen-compatible-with-path cycle seen (append path
+ (find-matching-path-for-path-m->n
+ cycle m q n vars)))
+ (bisimilar (first cycle) m q n vars)
+ (<= (len seen) (len (states n)))
+ (next-statep (last-val cycle) (first cycle) m)
+ (compatible-path-p cycle m))
+ (seen-compatible-with-path cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars
+ path)))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars
+ path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-prefix-and-cycle-has-seen-compatible-2
+ (implies (and (consp cycle)
+ (memberp q seen)
+ (true-listp seen)
+ (equal (len path) (* (len cycle) (1- (len seen))))
+ (seen-compatible-with-path cycle seen (append path
+ (find-matching-path-for-path-n->m
+ q m cycle n vars)))
+ (bisimilar q m (first cycle) n vars)
+ (<= (len seen) (len (states m)))
+ (next-statep (last-val cycle) (first cycle) n)
+ (compatible-path-p cycle n))
+ (seen-compatible-with-path cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m
+ cycle n vars
+ path)))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m
+ cycle n vars
+ path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+
+(local
+(defthm car-is-witness
+ (implies (and (consp (find-cycle cycle seen witness path))
+ (seen-compatible-with-path cycle seen path))
+ (equal (car (find-cycle cycle seen witness path))
+ witness)))
+)
+
+(local
+(defthm last-val-of-cycle-is-last-val-of-prefix-and-cycle
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (equal (last-val (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ (last-val (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars
+ nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-prefix-and-cycle-for-cycle-m->n)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path)
+ (:instance find-matching-cycle-for-cycle-is-consp)
+ (:instance last-val-append-reduction
+ (x (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (y (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars)))))))
+)
+
+(local
+(defthm last-val-of-cycle-is-last-val-of-prefix-and-cycle-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (equal (last-val (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ (last-val (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars
+ nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-prefix-and-cycle-for-cycle-n->m)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path-2)
+ (:instance find-matching-cycle-for-cycle-is-consp-2)
+ (:instance last-val-append-reduction
+ (x (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (y (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars)))))))
+)
+
+(local
+(in-theory (disable find-prefix-with-index find-cycle-with-index))
+)
+
+(local
+(defthm del-last-has-len-<=-states
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (<= (len (del-last
+ (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil))))
+ (len (states n))))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable uniquep-subset-reduction
+ del-last-seen-is-unique-p)
+ :use ((:instance uniquep-subset-reduction
+ (x (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars
+ nil))))
+ (y (states n)))
+ (:instance del-last-seen-is-unique-p
+ (seen (list q))
+ (states (states n))
+ (path nil)))))
+ :rule-classes :linear)
+)
+
+(local
+(defthm next-state-of-last-of-find-cycle-is-first-of-find-cycle
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (next-statep (last-val (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ (first (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ n))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp
+ uniquep-subset-reduction
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle
+ car-is-witness
+ witness-is-next-state-of-last-val)
+ :do-not-induct t
+ :expand (find-matching-cycle-for-cycle-m->n cycle m q n vars)
+ :use ((:instance find-matching-cycle-for-cycle-is-consp)
+ (:instance witness-is-next-state-of-last-val
+ (path nil)
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil)))))
+ (:instance car-is-witness
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (witness (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil)))
+ (path (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle)))
+ ("Subgoal 2.2"
+ :in-theory (disable find-prefix-and-cycle-has-seen-compatible)
+ :use ((:instance find-prefix-and-cycle-has-seen-compatible
+ (seen (list q))
+ (path nil))))
+ ("Subgoal 1"
+ :in-theory (enable find-matching-cycle-for-cycle-m->n))))
+)
+
+(local
+(defthm next-state-of-last-of-find-cycle-is-first-of-find-cycle-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (next-statep (last-val (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ (first (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ m))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp-2
+ uniquep-subset-reduction
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle-2
+ car-is-witness
+ witness-is-next-state-of-last-val-2)
+ :do-not-induct t
+ :expand (find-matching-cycle-for-cycle-n->m q m cycle n vars)
+ :use ((:instance find-matching-cycle-for-cycle-is-consp-2)
+ (:instance witness-is-next-state-of-last-val-2
+ (path nil)
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil)))))
+ (:instance car-is-witness
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (witness (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil)))
+ (path (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle-2)))
+ ("Subgoal 2.2"
+ :in-theory (disable find-prefix-and-cycle-has-seen-compatible-2)
+ :use ((:instance find-prefix-and-cycle-has-seen-compatible-2
+ (seen (list q))
+ (path nil))))
+ ("Subgoal 1"
+ :in-theory (enable find-matching-cycle-for-cycle-n->m))))
+)
+
+(local
+(in-theory (disable witness-is-next-state-of-last-val
+ witness-is-next-state-of-last-val-2
+ consp-last-n-append-reduction
+ car-to-car-for-append
+ snoc-car
+ last-n-not-consp
+ last-n-append-reduction
+ len-<-1=>not-consp
+ snoc-append-compatible-reduction
+ find-prefix-and-cycle-has-seen-compatible
+ find-prefix-and-cycle-has-seen-compatible-2
+ car-is-witness
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle-2))
+)
+
+(local
+(defthm matching-ppath-is-compatible
+ (implies (and (compatible-ppath-p p m)
+ (modelp m)
+ (modelp n)
+ (bisimilar-equiv m n vars))
+ (compatible-ppath-p (find-matching-periodic-path-m->n p m n vars)
+ n))
+ :hints (("Goal"
+ :in-theory (disable modelp-characterization)
+ :use ((:instance modelp-characterization)
+ (:instance modelp-characterization (m n))))))
+
+)
+
+(local
+(defthm matching-ppath-is-compatible-2
+ (implies (and (compatible-ppath-p p n)
+ (modelp n)
+ (modelp m)
+ (bisimilar-equiv m n vars))
+ (compatible-ppath-p (find-matching-periodic-path-n->m m p n vars)
+ m))
+ :hints (("Goal"
+ :in-theory (disable modelp-characterization)
+ :use ((:instance modelp-characterization)
+ (:instance modelp-characterization (m n))))))
+)
+
+(local
+(in-theory (disable compatible-ppath-p find-matching-periodic-path-m->n
+ modelp-characterization restricted-formulap
+ find-matching-periodic-path-n->m))
+)
+
+(local
+(defthm bisimilar-models-have-same-ltl-semantics-1
+ (implies (and (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (restricted-formulap f vars))
+ (implies (ltl-semantics f m)
+ (ltl-semantics f n)))
+ :hints (("Goal"
+ :cases ((compatible-ppath-p (ltl-semantics-witness f n) n)))
+ ("Subgoal 1"
+ :in-theory (disable ltl-semantics-necc ltl-semantics-necc-expanded
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ matching-ppath-is-compatible-2
+ ppath-and-its-matching-ppath-have-same-labels-2)
+ :use ((:instance ppath-and-its-matching-ppath-have-same-labels-2
+ (ppath (ltl-semantics-witness f n)))
+ (:instance ltl-semantics-necc-expanded
+ (ppath (find-matching-periodic-path-n->m
+ m (ltl-semantics-witness f n) n vars)))
+ (:instance matching-ppath-is-compatible-2
+ (p (ltl-semantics-witness f n)))
+ (:instance
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ (p (find-matching-periodic-path-n->m
+ m (ltl-semantics-witness f n) n vars))
+ (q (ltl-semantics-witness f n)))))))
+)
+
+(local
+(defthm bisimilar-models-have-same-ltl-semantics-2
+ (implies (and (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (restricted-formulap f vars))
+ (implies (ltl-semantics f n)
+ (ltl-semantics f m)))
+ :hints (("Goal"
+ :cases ((compatible-ppath-p (ltl-semantics-witness f m) m)))
+ ("Subgoal 1"
+ :in-theory (disable ltl-semantics-necc ltl-semantics-necc-expanded
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ matching-ppath-is-compatible
+ ppath-and-its-matching-ppath-have-same-labels)
+ :use ((:instance ppath-and-its-matching-ppath-have-same-labels
+ (ppath (ltl-semantics-witness f m)))
+ (:instance ltl-semantics-necc-expanded
+ (m n)
+ (ppath (find-matching-periodic-path-m->n
+ (ltl-semantics-witness f m) m n vars)))
+ (:instance matching-ppath-is-compatible
+ (p (ltl-semantics-witness f m)))
+ (:instance
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ (q (find-matching-periodic-path-m->n
+ (ltl-semantics-witness f m) m n vars))
+ (p (ltl-semantics-witness f m)))))))
+)
+
+(local
+(in-theory (disable ltl-semantics ltl-semantics-necc ltl-semantics-necc-expanded))
+)
+
+(DEFTHM bisimilar-models-have-same-ltl-semantics
+ (implies (and (bisimilar-equiv m n vars)
+ (restricted-formulap f vars)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (modelp m)
+ (modelp n))
+ (equal (ltl-semantics f m)
+ (ltl-semantics f n)))
+ :hints (("Goal"
+ :use ((:instance bisimilar-models-have-same-ltl-semantics-1)
+ (:instance bisimilar-models-have-same-ltl-semantics-2))))
+ :rule-classes nil)
+
+
+
+
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/certify.lsp b/books/workshops/2003/ray-matthews-tuttle/support/certify.lsp
new file mode 100644
index 0000000..1d649ac
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/certify.lsp
@@ -0,0 +1,123 @@
+#|
+
+ certify.lisp
+ ~~~~~~~~~~~~
+
+The collection of events below provides a proof of our compositional reduction
+algorithm in ACL2. The script works in v2-7, but takes an inordinate amount of
+time (about 24 hours on a 1.8GHz P3 machine running GCL on top of
+linux). Admittedly, the proof is not optimized and the rewrite rules are not
+that great, but I am too tired to look at that at this moment.
+
+To see the proof silently go thru, just type (ld "certify.lisp") and that will
+work. To see ACL2 work thru the proof, simply comment out the first line of
+this file and do the ld.
+
+|#
+
+(set-inhibit-output-lst '(proof-tree prove))
+
+(ubt! 1)
+
+;; This is simply Pete's total order book. I have it in the directory so that I
+;; dont have to change the path-names in the different books that call it.
+
+(certify-book "total-order")
+(u)
+
+;; We add some other functionality to total-order, including keys etc. to
+;; support reasoning about vectors. We use this book here since it has
+;; definitions of memberp.
+
+(certify-book "apply-total-order")
+(u)
+
+;; This is the records book provide with the distribution of ACL2. This book is
+;; terribly important for us, since everything we do is with respect to this book.
+
+(certify-book "records")
+(u)
+
+;; We just define a collection of functions for flat sets in ACL2. This book is
+;; used in the context of our proof. This is not intended to be a general-purpose
+;; book on (even flat) sets.
+
+(certify-book "sets")
+(u)
+
+;; This book models the syntax and semantics of LTL. We have managed to define
+;; the semantics with respect to eventually periodic paths. Of course, we moved
+;; the actual function in concrete-ltl.lisp. Please see the accompanying note
+;; for concrete-ltl, and the actual file ltl.lisp, for explanation as to what we
+;; did and why.
+
+(certify-book "ltl")
+(u)
+
+;; Just a trivial book justifying that conjunctive reduction is sound.
+
+(certify-book "conjunction")
+(u)
+
+;; This is one hell of a book. It should be cleaned up when I have time, but I
+;; have not done that yet. This book proves that bisimilar Kripke Structures
+;; have the same ltl-semantics. Notice we needed to define bisimilarity with
+;; respect to vars. For explanation, please refer to our paper.
+
+(certify-book "bisimilarity")
+(u)
+
+;; We define the bisimulation relation for circuit models, which are special
+;; types of Kripke Structures built out of our finite state machine
+;; representations defined below.
+
+(certify-book "circuit-bisim")
+(u)
+
+;; In this book, we model circuits or finite state machines. These are
+;; efficient representations of Kripke Structures.
+
+(certify-book "circuits")
+(u)
+
+;; This book verifies the cone of influence reduction implementation in ACL2.
+
+(certify-book "cone-of-influence")
+(u)
+
+;; This book proves the final theorem about compositional reductions.
+
+(certify-book "reductions")
+(u)
+
+;; This does not have any technical material at all. But the book allows us to
+;; rewrite the ltl-semantics function into a function that we can efficiently
+;; execute. In the underlying lisp, we replace calls to this efficient function
+;; ltl-semantics-hack by a sys-call calling the external model checker (SMV).
+
+(certify-book "impl-hack" 0 t :defaxioms-okp t)
+(u)
+
+;; Note: The book concrete-ltl is not used in the rest of the materials any
+;; more. The book is present simply as a demonstration that we could actually
+;; define the semantics of LTL. The proof of the theorem
+;; ltl-ppath-semantics-cannot-distinguish-between-equal-labels used to take a
+;; lot of time with v2-6, and considering the relative slowdown between v2-6
+;; and v2-7, I did not experiment with that proof on v2-7 using
+;; concrete-ltl. The proof has therefore been removed from this book. I do wish
+;; to leave the comment here that the proof is not very trivial (actually I
+;; also simplified the theorem a lot when I changed from concrete-ltl-semantics
+;; to ltl-ppath-semantics which has the property encapsulated.) although very
+;; simple at the high level. The proof simply inducts using the induction
+;; suggested by concrete-ltl-semantics. However, I still find reasoning about
+;; mutually recursive functions difficult in ACL2, and I did not want to
+;; clutter the scripts with those theorems. (After all, if an implementation of
+;; ltl-ppath-semantics does not satisfy that theorem, then we need to change
+;; the definition rather than the theorem...:->)
+
+
+(certify-book "concrete-ltl")
+(u)
+
+(set-inhibit-output-lst '(proof-tree))
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/circuit-bisim.lisp b/books/workshops/2003/ray-matthews-tuttle/support/circuit-bisim.lisp
new file mode 100644
index 0000000..3740910
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/circuit-bisim.lisp
@@ -0,0 +1,726 @@
+(in-package "ACL2")
+
+#|
+
+ circuit-bisim.lisp
+ ~~~~~~~~~~~~~~~~~~
+
+In this book, we define a specific bisimilarity relation
+evaluation-eq. Roughly, two "circuit states" are evaluation-eq if they match on
+a specific collection of variables. We prove that evaluation-eq is a
+bisimilarity relation. In a later book, we will prove that this bisimilarity
+relation holds between the "Kripke Structure of a circuit" and the "Kripke
+Structure of the cone of influence of the circuit". That will enable us to
+prove that the two kripke structures satisfy the same LTL formula when
+restricted by vars.
+
+|#
+
+(include-book "ltl")
+
+(in-theory (disable subset-of-empty-is-empty
+ subset-of-nil-is-nil))
+
+(in-theory (enable subset set-intersect))
+
+(defun evaluation-eq (p q vars)
+ (if (endp vars) T
+ (and (equal (<- p (first vars))
+ (<- q (first vars)))
+ (evaluation-eq p q (rest vars)))))
+
+;; We prove evaluation-eq is symmetric here, but I dont want to deal with loop
+;; stoppers so we prove it only for the purpose of use hints.
+
+(defthm evaluation-eq-is-symmetric
+ (equal (evaluation-eq p q vars)
+ (evaluation-eq q p vars))
+ :rule-classes nil)
+
+(defun evaluation-eq-member-p (st states vars)
+ (if (endp states) nil
+ (if (evaluation-eq st (first states) vars) T
+ (evaluation-eq-member-p st (rest states) vars))))
+
+(defun evaluation-eq-member (st states vars)
+ (if (endp states) nil
+ (if (evaluation-eq st (first states) vars)
+ (first states)
+ (evaluation-eq-member st (rest states) vars))))
+
+(defthm member-is-memberp
+ (implies (evaluation-eq-member-p p states vars)
+ (memberp (evaluation-eq-member p states vars)
+ states)))
+
+(defthm member-is-evaluation-eq
+ (implies (evaluation-eq-member-p p states vars)
+ (evaluation-eq p (evaluation-eq-member p states vars)
+ vars)))
+
+(defun-sk strict-evaluation-p (st vars)
+ (forall v (implies (not (memberp v vars))
+ (not (<- st v)))))
+
+(defthm strict-evaluation-p-expanded
+ (implies (and (strict-evaluation-p st vars)
+ (not (memberp v vars)))
+ (not (<- st v)))
+ :hints (("Goal"
+ :use strict-evaluation-p-necc)))
+
+(defun strict-evaluation-list-p (vars states)
+ (if (endp states) T
+ (and (strict-evaluation-p (first states) vars)
+ (strict-evaluation-list-p vars (rest states)))))
+
+(defun evaluation-p (st vars)
+ (if (endp vars) T
+ (and (booleanp (<- st (first vars)))
+ (evaluation-p st (rest vars)))))
+
+(defun only-evaluations-p (states vars)
+ (if (endp states) T
+ (and (evaluation-p (first states) vars)
+ (only-evaluations-p (rest states) vars))))
+
+;; I think we can remove the all-evaluations-p from defun-sk to
+;; defun. But I am feeling lazy at least now to do it.
+
+(defun-sk all-evaluations-p (states vars)
+ (forall st
+ (implies (evaluation-p st vars)
+ (evaluation-eq-member-p st states vars))))
+
+(defun evaluation-eq-subset-p (m-states n-states vars)
+ (if (endp m-states) T
+ (and (evaluation-eq-member-p (first m-states) n-states vars)
+ (evaluation-eq-subset-p (rest m-states) n-states vars))))
+
+(defthm evaluation-eq-subset-to-member
+ (implies (and (evaluation-eq-subset-p m-states n-states vars)
+ (memberp p m-states))
+ (evaluation-eq-member-p p n-states vars)))
+
+(defun truthp-label (label s)
+ (if (endp label) t
+ (and (equal (<- s (first label)) T)
+ (truthp-label (rest label) s))))
+
+(defun only-truth-p (states m)
+ (if (endp states) T
+ (and (truthp-label (label-of (first states) m) (first states))
+ (only-truth-p (rest states) m))))
+
+(defun all-truthsp-label (label s vars)
+ (if (endp vars) T
+ (and (implies (equal (<- s (car vars)) T)
+ (memberp (car vars) label))
+ (all-truthsp-label label s (rest vars)))))
+
+(defthm all-truthsp-label-expanded
+ (implies (and (all-truthsp-label label s vars)
+ (memberp v vars)
+ (equal (<- s v) T))
+ (memberp v label)))
+
+(defun only-all-truths-p (states m vars)
+ (if (endp states) T
+ (and (all-truthsp-label (label-of (first states) m) (first states) vars)
+ (only-all-truths-p (rest states) m vars))))
+
+(defun label-subset-vars (states m vars)
+ (if (endp states) T
+ (and (subset (label-of (first states) m) vars)
+ (label-subset-vars (rest states) m vars))))
+
+(defthm label-subset-subset-reduction
+ (implies (and (label-subset-vars states m vars)
+ (memberp p states))
+ (subset (label-of p m) vars)))
+
+;; Now for a few properties governing the next state.
+
+(defun-sk well-formed-transition-p (states-m trans-m states-n trans-n vars)
+ (forall (p q)
+ (implies (and (evaluation-eq p q vars)
+ (evaluation-p p vars)
+ (memberp p states-m)
+ (memberp q states-n)
+ (evaluation-p q vars))
+ (evaluation-eq-subset-p (<- trans-m p)
+ (<- trans-n q)
+ vars))))
+
+(defthm well-formed-transition-p-expanded
+ (implies (and (well-formed-transition-p states-m trans-m states-n trans-n vars)
+ (evaluation-eq p q vars)
+ (evaluation-p p vars)
+ (memberp p states-m)
+ (memberp q states-n)
+ (evaluation-p q vars))
+ (evaluation-eq-subset-p (<- trans-m p) (<- trans-n q) vars))
+ :hints (("Goal"
+ :use well-formed-transition-p-necc)))
+
+(in-theory (disable well-formed-transition-p well-formed-transition-p-necc))
+
+
+(defun transition-subset-p (states states-prime trans)
+ (if (endp states) T
+ (and (subset (<- trans (first states)) states-prime)
+ (transition-subset-p (rest states) states-prime trans))))
+
+(defthm transition-subset-p-expanded
+ (implies (and (transition-subset-p states states-prime trans)
+ (memberp p states)
+ (memberp r (<- trans p)))
+ (memberp r states-prime)))
+
+
+(defun circuit-modelp (m)
+ (and (only-evaluations-p (states m) (variables m))
+ (all-evaluations-p (states m) (variables m))
+ (strict-evaluation-list-p (variables m) (states m))
+ (only-all-truths-p (states m) m (variables m))
+ (only-truth-p (states m) m)
+ (label-subset-vars (states m) m (variables m))
+ (transition-subset-p (states m) (states m) (transition m))
+ (subset (initial-states m) (states m))
+ (consp (states m))
+ (next-states-in-states m (states m))))
+
+;; And here is our bisimilarity relation
+
+(defun c-bisim-equiv (m n vars)
+ (and (circuit-modelp m)
+ (circuit-modelp n)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (well-formed-transition-p (states m) (transition m) (states n) (transition n) vars)
+ (well-formed-transition-p (states n) (transition n) (states m) (transition m) vars)
+ (evaluation-eq-subset-p (initial-states m) (initial-states n) vars)
+ (evaluation-eq-subset-p (initial-states n) (initial-states m) vars)))
+
+
+(local
+(defun circuit-bisim (p m q n vars)
+ (and (circuit-modelp m)
+ (circuit-modelp n)
+ (memberp p (states m))
+ (memberp q (states n))
+ (well-formed-transition-p (states m) (transition m) (states n) (transition n) vars)
+ (well-formed-transition-p (states n) (transition n) (states m) (transition m) vars)
+ (evaluation-eq-subset-p (initial-states m) (initial-states n) vars)
+ (evaluation-eq-subset-p (initial-states n) (initial-states m) vars)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (evaluation-eq p q vars)))
+)
+
+;; Now that we have defined a bisimilar relation between circuit models, let us
+;; prove that this is actually a bisimilar relation.
+
+;; So what do we need to have? Given two circuit models m and m', we need to
+;; show that the bisimilarity witness from m to m' and from m' to m.
+
+(local
+(defun c-bisimilar-initial-state-witness-m->n (s m n vars)
+ (declare (ignore m))
+ (evaluation-eq-member s (initial-states n) vars))
+)
+
+(local
+(defun c-bisimilar-initial-state-witness-n->m (m s n vars)
+ (declare (ignore n))
+ (evaluation-eq-member s (initial-states m) vars))
+)
+
+(defthm all-evaluations-considers-an-evaluation-a-member
+ (implies (and (evaluation-p st vars)
+ (all-evaluations-p states vars))
+ (evaluation-eq-member-p st states vars))
+ :hints (("Goal"
+ :use all-evaluations-p-necc)))
+
+(in-theory (disable all-evaluations-p all-evaluations-p-necc))
+
+
+(local
+(defthm c-bisimilar-equiv-implies-init->init-n->m
+ (implies (and (c-bisim-equiv m n vars)
+ (memberp s (initial-states n)))
+ (memberp (c-bisimilar-initial-state-witness-n->m m s n vars)
+ (initial-states m))))
+)
+
+(local
+(defthm c-bisimilar-equiv-implies-init->init-m->n
+ (implies (and (c-bisim-equiv m n vars)
+ (memberp s (initial-states m)))
+ (memberp (c-bisimilar-initial-state-witness-m->n s m n vars)
+ (initial-states n))))
+)
+
+(local
+(defthm subset-transitive-member
+ (implies (and (memberp s init)
+ (subset init states))
+ (memberp s states)))
+)
+
+(local
+(defthm c-bisimilar-equiv-implies-bisimilar-initial-states-m->n
+ (implies (and (c-bisim-equiv m n vars)
+ (memberp s (initial-states m)))
+ (circuit-bisim s m
+ (c-bisimilar-initial-state-witness-m->n s m n vars)
+ n vars))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not '(generalize eliminate-destructors)
+ :do-not-induct t
+ :in-theory (disable member-is-memberp
+ evaluation-eq-subset-to-member)
+ :use ((:instance evaluation-eq-subset-to-member
+ (p s)
+ (m-states (initial-states m))
+ (n-states (initial-states n)))
+ (:instance member-is-memberp
+ (p s)
+ (states (initial-states n)))))))
+)
+
+(local
+(defthm c-bisimilar-equiv-implies-bisimilar-initial-states-n->m
+ (implies (and (c-bisim-equiv m n vars)
+ (memberp s (initial-states n)))
+ (circuit-bisim (c-bisimilar-initial-state-witness-n->m m s n vars)
+ m s n vars))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not '(generalize eliminate-destructors)
+ :do-not-induct t
+ :in-theory (disable member-is-memberp
+ evaluation-eq-subset-to-member)
+ :use ((:instance evaluation-eq-subset-to-member
+ (p s)
+ (m-states (initial-states n))
+ (n-states (initial-states m)))
+ (:instance member-is-memberp
+ (p s)
+ (states (initial-states m)))
+ (:instance
+ evaluation-eq-is-symmetric
+ (p (evaluation-eq-member s (initial-states m) vars))
+ (q s))))))
+)
+
+
+;; Now we go to our first difficult proof, showing that bisimilar
+;; states have equal labels.
+
+;; (label-of s m) are only truths.
+
+(defthm truthp-label-from-only-truthp
+ (implies (and (only-truth-p states m)
+ (memberp s states))
+ (truthp-label (label-of s m) s)))
+
+;; And all truths are present in the label.
+
+(defthm all-truths-p-from-only-all-truths-p
+ (implies (and (only-all-truths-p states m vars)
+ (memberp s states))
+ (all-truthsp-label (label-of s m) s vars)))
+
+;; For every variable in (and vars label) they re members of vars and label.
+
+(defthm memberp-to-intersect-reduction
+ (implies (memberp v (set-intersect x y))
+ (and (memberp v x)
+ (memberp v y)))
+ :rule-classes :forward-chaining)
+
+;; Since they are in vars, they must evaluate the same way in q.
+
+(defthm evaluation-eq-vars-reduction
+ (implies (and (evaluation-eq p q vars)
+ (memberp v vars))
+ (equal (<- p v)
+ (<- q v))))
+
+;; Thus, variables in (label-of p m) and vars will evaluate to T in q.
+
+(defthm variables-in-label-are-T-in-q
+ (implies (and (memberp v (set-intersect label vars))
+ (truthp-label label p)
+ (evaluation-eq p q vars))
+ (equal (<- q v) T)))
+
+(defthm only-truthsp-and-subset-to-subset
+ (implies (and (equal (<- q v) T)
+ (memberp v vars)
+ (subset vars variables)
+ (all-truthsp-label label q variables))
+ (memberp v label)))
+
+(defthm truthp-label-to-subset
+ (implies (and (memberp v (set-intersect lp vars))
+ (truthp-label lp p)
+ (evaluation-eq p q vars)
+ (subset vars variables)
+ (all-truthsp-label lq q variables))
+ (memberp v lq)))
+
+;; And let us do a little trick to get ACL2 from memberp to subset
+
+
+(defthm truthp-label-is-a-subset
+ (implies (and (truthp-label lp p)
+ (evaluation-eq p q vars)
+ (subset vars variables)
+ (all-truthsp-label lq q variables))
+ (subset (set-intersect lp vars)
+ lq)))
+
+(local
+(defthm subset-intersect-reduction
+ (implies (and (subset lp lq)
+ (subset lp vars))
+ (subset lp (set-intersect lq vars))))
+)
+
+(local
+(defthm truthp-label-intersect-is-a-subset
+ (implies (and (truthp-label lp p)
+ (evaluation-eq p q vars)
+ (subset vars variables)
+ (all-truthsp-label lq q variables))
+ (subset (set-intersect lp vars)
+ (set-intersect lq vars))))
+)
+
+(local
+(defthm c-bisimilar-states-have-labels-equal-aux
+ (implies (circuit-bisim p m q n vars)
+ (subset (set-intersect (label-of p m) vars)
+ (set-intersect (label-of q n) vars)))
+ :hints (("Goal"
+ :in-theory (disable truthp-label-intersect-is-a-subset)
+ :use ((:instance truthp-label-intersect-is-a-subset
+ (lp (label-of p m))
+ (lq (label-of q n))
+ (variables (variables n)))))))
+)
+
+(local
+(in-theory (enable set-equal))
+)
+
+(local
+(defthm c-bisimilar-states-have-labels-equal
+ (implies (circuit-bisim p m q n vars)
+ (set-equal (set-intersect (label-of q n) vars)
+ (set-intersect (label-of p m) vars)))
+ :hints (("Goal"
+ :in-theory (disable c-bisimilar-states-have-labels-equal-aux)
+ :use ((:instance c-bisimilar-states-have-labels-equal-aux
+ (p q)
+ (m n)
+ (n m)
+ (q p))
+ (:instance c-bisimilar-states-have-labels-equal-aux)))
+ ("Goal'''"
+ :use evaluation-eq-is-symmetric)))
+)
+
+;; Now we start with the next states.
+
+(local
+(defun c-bisimilar-transition-witness-m->n (p r m q n vars)
+ (declare (ignore p m))
+ (evaluation-eq-member r (<- (transition n) q) vars))
+)
+
+(local
+(defun c-bisimilar-transition-witness-n->m (p m q r n vars)
+ (declare (ignore q n))
+ (evaluation-eq-member r (<- (transition m) p) vars))
+)
+
+(defthm evaluationp-for-subset
+ (implies (and (evaluation-p st variables)
+ (subset vars variables))
+ (evaluation-p st vars)))
+
+(defthm evaluation-p-only-evaluations-reduction
+ (implies (and (only-evaluations-p states vars)
+ (memberp p states))
+ (evaluation-p p vars)))
+
+(defthm r-is-evaluation-eq-member-p
+ (implies (and (evaluation-eq p q vars)
+ (well-formed-transition-p states-m trans-m states-n trans-n vars)
+ (memberp p states-m)
+ (memberp q states-n)
+ (evaluation-p p vars)
+ (evaluation-p q vars)
+ (memberp r (<- trans-m p)))
+ (evaluation-eq-member-p r (<- trans-n q) vars))
+ :hints (("Goal"
+ :in-theory (disable well-formed-transition-p-expanded)
+ :use well-formed-transition-p-expanded)))
+
+(local
+(defthm c-bisimilar-witness-member-of-states-m->n
+ (implies (and (circuit-bisim p m q n vars)
+ (next-statep p r m)
+ (memberp r (states m)))
+ (memberp (c-bisimilar-transition-witness-m->n p r m q n vars)
+ (states n)))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (enable next-statep))
+ ("Goal'"
+ :in-theory (disable evaluationp-for-subset
+ r-is-evaluation-eq-member-p)
+ :use ((:instance r-is-evaluation-eq-member-p
+ (states-m (states m))
+ (states-n (states n))
+ (trans-m (transition m))
+ (trans-n (transition n)))
+ (:instance evaluationp-for-subset
+ (st p)
+ (variables (variables m)))
+ (:instance evaluationp-for-subset
+ (st q)
+ (variables (variables n)))))))
+)
+
+(local
+(defthm c-bisimilar-witness-member-of-states-n->m
+ (implies (and (circuit-bisim p m q n vars)
+ (next-statep q r n)
+ (memberp r (states n)))
+ (memberp (c-bisimilar-transition-witness-n->m p m q r n vars)
+ (states m)))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (enable next-statep))
+ ("Goal'"
+ :in-theory (disable evaluationp-for-subset
+ only-evaluations-p
+ all-evaluations-p
+ evaluation-p
+ subset
+ r-is-evaluation-eq-member-p)
+ :use ((:instance r-is-evaluation-eq-member-p
+ (states-n (states m))
+ (states-m (states n))
+ (q p)
+ (p q)
+ (trans-m (transition n))
+ (trans-n (transition m)))
+ (:instance evaluationp-for-subset
+ (st p)
+ (variables (variables m)))
+ (:instance evaluationp-for-subset
+ (st q)
+ (variables (variables n)))))
+ ("Goal'''"
+ :use evaluation-eq-is-symmetric)))
+)
+
+(local
+(defthm c-bisimilar-witness-matches-transition-m->n
+ (implies (and (circuit-bisim p m q n vars)
+ (next-statep p r m))
+ (next-statep q (c-bisimilar-transition-witness-m->n p r m q n vars)
+ n))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (enable next-statep))
+ ("Goal'"
+ :in-theory (disable evaluationp-for-subset
+ r-is-evaluation-eq-member-p)
+ :use ((:instance r-is-evaluation-eq-member-p
+ (states-m (states m))
+ (states-n (states n))
+ (trans-m (transition m))
+ (trans-n (transition n)))
+ (:instance evaluationp-for-subset
+ (st p)
+ (variables (variables m)))
+ (:instance evaluationp-for-subset
+ (st q)
+ (variables (variables n)))))))
+)
+
+(local
+(defthm c-bisimilar-witness-matches-transition-n->m
+ (implies (and (circuit-bisim p m q n vars)
+ (next-statep q r n))
+ (next-statep p (c-bisimilar-transition-witness-n->m p m q r n vars)
+ m))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (enable next-statep))
+ ("Goal'"
+ :in-theory (disable evaluationp-for-subset
+ only-evaluations-p
+ all-evaluations-p
+ evaluation-p
+ subset
+ r-is-evaluation-eq-member-p)
+ :use ((:instance r-is-evaluation-eq-member-p
+ (q p)
+ (p q)
+ (states-n (states m))
+ (states-m (states n))
+ (trans-m (transition n))
+ (trans-n (transition m)))
+ (:instance evaluationp-for-subset
+ (st p)
+ (variables (variables m)))
+ (:instance evaluationp-for-subset
+ (st q)
+ (variables (variables n)))))
+ ("Goal'''"
+ :use evaluation-eq-is-symmetric)))
+)
+
+(local
+(defthm c-bisimilar-witness-produces-bisimilar-states-m->n
+ (implies (and (circuit-bisim p m q n vars)
+ (next-statep p r m))
+ (circuit-bisim r m
+ (c-bisimilar-transition-witness-m->n p r m q n vars)
+ n vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (enable next-statep))
+ ("Goal'"
+ :in-theory (disable evaluationp-for-subset
+ r-is-evaluation-eq-member-p)
+ :use ((:instance r-is-evaluation-eq-member-p
+ (states-m (states m))
+ (states-n (states n))
+ (trans-m (transition m))
+ (trans-n (transition n)))
+ (:instance evaluationp-for-subset
+ (st p)
+ (variables (variables m)))
+ (:instance evaluationp-for-subset
+ (st q)
+ (variables (variables n)))))))
+)
+
+(local
+(defthm c-bisimilar-witness-produces-bisimilar-states-n->m
+ (implies (and (circuit-bisim p m q n vars)
+ (next-statep q r n))
+ (circuit-bisim
+ (c-bisimilar-transition-witness-n->m p m q r n vars)
+ m r n vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (enable next-statep))
+ ("Goal'"
+ :in-theory (disable evaluationp-for-subset
+ only-evaluations-p
+ all-evaluations-p
+ evaluation-p
+ subset
+ r-is-evaluation-eq-member-p)
+ :use ((:instance r-is-evaluation-eq-member-p
+ (q p)
+ (p q)
+ (states-n (states m))
+ (states-m (states n))
+ (trans-m (transition n))
+ (trans-n (transition m)))
+ (:instance evaluationp-for-subset
+ (st p)
+ (variables (variables m)))
+ (:instance evaluationp-for-subset
+ (st q)
+ (variables (variables n)))))
+ ("Subgoal 3"
+ :use evaluation-eq-is-symmetric)
+ ("Subgoal 2"
+ :use evaluation-eq-is-symmetric)
+ ("Subgoal 1"
+ :use ((:instance evaluation-eq-is-symmetric
+ (p (evaluation-eq-member r (<- (transition m) p)
+ vars))
+ (q r))))))
+)
+
+(local
+(defthm circuit-modelp-is-modelp
+ (implies (circuit-modelp m)
+ (and (subset (initial-states m) (states m))
+ (consp (states m))
+ (next-states-in-states m (states m)))))
+)
+
+(local
+(in-theory (disable circuit-bisim circuit-modelp c-bisim-equiv
+ c-bisimilar-initial-state-witness-m->n
+ set-equal
+ c-bisimilar-transition-witness-m->n
+ c-bisimilar-initial-state-witness-n->m
+ c-bisimilar-transition-witness-n->m))
+)
+
+(local
+(include-book "bisimilarity")
+)
+
+(DEFTHM circuit-bisim-implies-same-ltl-semantics
+ (implies (and (circuit-modelp m)
+ (circuit-modelp n)
+ (c-bisim-equiv m n vars)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (restricted-formulap f vars))
+ (equal (ltl-semantics f m)
+ (ltl-semantics f n)))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :use
+ ((:functional-instance
+ bisimilar-models-have-same-ltl-semantics
+ (bisimilar-equiv (lambda (m n vars)
+ (c-bisim-equiv m n vars)))
+ (modelp (lambda (m) (circuit-modelp m)))
+ (bisimilar (lambda (p m q n vars)
+ (circuit-bisim
+ p m q n vars)))
+ (bisimilar-initial-state-witness-m->n
+ (lambda (s m n vars)
+ (c-bisimilar-initial-state-witness-m->n
+ s m n vars)))
+ (bisimilar-initial-state-witness-n->m
+ (lambda (m s n vars)
+ (c-bisimilar-initial-state-witness-n->m
+ m s n vars)))
+ (bisimilar-transition-witness-m->n
+ (lambda (p r m q n vars)
+ (c-bisimilar-transition-witness-m->n
+ p r m q n vars)))
+ (bisimilar-transition-witness-n->m
+ (lambda (p m q r n vars)
+ (c-bisimilar-transition-witness-n->m
+ p m q r n vars))))))))
+
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/circuits.lisp b/books/workshops/2003/ray-matthews-tuttle/support/circuits.lisp
new file mode 100644
index 0000000..0edb124
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/circuits.lisp
@@ -0,0 +1,1146 @@
+(in-package "ACL2")
+
+#|
+
+ circuits.lisp
+ ~~~~~~~~~~~~~
+
+In this book, we discuss a procedure to construct Kripke Structures from
+"circuit descriptions. A circuit in our world is a collection of variables, a
+collection of equations, and a collection of equations. An equation is a
+boolean evaluator of the current circuit valuaes producing the next state
+function. We show that under certain "well-formed-ness constraints", our
+procedure produces a valid model, in terms of the circuit-modelp predicate
+defined earlier.
+
+|#
+
+
+(include-book "circuit-bisim")
+
+
+;; A circuit is a collection of variables, equations and initial states. We
+;; will add equations to the macros, and tell you what is a good circuit.
+
+(defmacro equations (c) `(<- ,c :equations))
+
+;; Now we define what it means for the equations to be consistent with the
+;; variables of the circuit.
+
+(defun find-variables (equation)
+ (cond ((and (atom equation) (not (booleanp equation)))
+ (list equation))
+ ((and (equal (len equation) 3) (memberp (second equation) '(& +)))
+ (set-union (find-variables (first equation))
+ (find-variables (third equation))))
+ ((and (equal (len equation) 2) (equal (first equation) '~))
+ (find-variables (second equation)))
+ (t nil)))
+
+(defun-sk consistent-equation-record-p (vars equations)
+ (forall (v equation)
+ (implies (and (uniquep vars)
+ (memberp v vars)
+ (memberp equation (<- equations v)))
+ (subset (find-variables equation) vars))))
+
+(defun cons-list-p (vars equations)
+ (if (endp vars) T
+ (and (consp (<- equations (first vars)))
+ (cons-list-p (rest vars) equations))))
+
+;; OK, now let us define the function circuitp.
+
+(defun circuitp (C)
+ (and (only-evaluations-p (initial-states C) (variables C))
+ (strict-evaluation-list-p (variables C) (initial-states C))
+ (uniquep (variables C))
+ (cons-list-p (variables C) (equations C))
+ (consistent-equation-record-p (variables C) (equations C))))
+
+;; Now let us try to create a Kripke Structure from the circuit. We need to
+;; show that under (circuitp C), the kripke structure we produce is a
+;; circuit-model-p.
+
+(defun assign-T (v states)
+ (if (endp states) nil
+ (cons (-> (first states) v T)
+ (assign-T v (rest states)))))
+
+(defun assign-nil (v states)
+ (if (endp states) nil
+ (cons (-> (first states) v nil)
+ (assign-nil v (rest states)))))
+
+;; Now we create all the states of the model.
+
+(defun create-all-evaluations (vars states)
+ (if (endp vars) states
+ (let ((rec-states (create-all-evaluations (cdr vars) states)))
+ (append (assign-t (car vars) rec-states)
+ (assign-nil (car vars) rec-states)))))
+
+;; Now let us create the label function.
+
+(defun label-fn-of-st (st vars)
+ (if (endp vars) nil
+ (if (equal (<- st (first vars)) T)
+ (cons (first vars)
+ (label-fn-of-st st (rest vars)))
+ (label-fn-of-st st (rest vars)))))
+
+(defun create-label-fn (states vars label)
+ (if (endp states) label
+ (create-label-fn (rest states) vars
+ (-> label (first states)
+ (label-fn-of-st (first states) vars)))))
+
+;; And finally the transitions.
+
+(defun apply-equation (equation st)
+ (cond ((atom equation) (if (booleanp equation)
+ equation
+ (<- st equation)))
+ ((equal (len equation) 2)
+ (case (first equation)
+ (~ (not (apply-equation (second equation) st)))
+ (t nil)))
+ ((equal (len equation) 3)
+ (case (second equation)
+ (& (and (apply-equation (first equation) st)
+ (apply-equation (third equation) st)))
+ (+ (or (apply-equation (first equation) st)
+ (apply-equation (third equation) st)))
+ (t nil)))
+ (t nil)))
+
+(defun produce-next-state (vars st equations)
+ (if (endp vars) st
+ (-> (produce-next-state (rest vars) st equations)
+ (first vars)
+ (apply-equation (<- equations (first vars)) st))))
+
+(defun consistent-p-equations (vars eqn equations)
+ (if (endp vars) T
+ (and (memberp (<- eqn (first vars)) (<- equations (first vars)))
+ (consistent-p-equations (rest vars) eqn equations))))
+
+(defun-sk next-state-is-ok (p q vars equations)
+ (exists eqn (and (consistent-p-equations vars eqn equations)
+ (evaluation-eq q (produce-next-state vars p eqn) vars))))
+
+(defun create-next-states-of-p (p states vars equations)
+ (if (endp states) nil
+ (if (next-state-is-ok p (first states) vars equations)
+ (cons (first states) (create-next-states-of-p
+ p (rest states) vars equations))
+ (create-next-states-of-p p (rest states) vars equations))))
+
+(defun create-next-states (states states-prime vars equations)
+ (if (endp states) ()
+ (->
+ (create-next-states (rest states) states-prime vars equations)
+ (first states)
+ (create-next-states-of-p (first states) states-prime vars equations))))
+
+(defun create-kripke (C)
+ (let ((vars (variables C))
+ (equations (equations C))
+ (initial-states (initial-states C)))
+ (let* ((states (create-all-evaluations vars (list ())))
+ (label-fn (create-label-fn (set-union initial-states states) vars ()))
+ (transition (create-next-states (set-union initial-states states)
+ (set-union initial-states states)
+ vars equations)))
+ (>_ :states (set-union initial-states states)
+ :initial-states initial-states
+ :label-fn label-fn
+ :transition transition
+ :variables vars))))
+
+
+;; Since I have defined the Kripke model for a circuit, let us prove that it is
+;; a circuit-model-p.
+
+;; We start with the initial states.
+
+;; The theorem that initial-states are subsets of states is trivial by
+;; union. So there is nothing to prove.
+
+(local
+(defthm initial-states-are-subset-of-states
+ (subset (initial-states (create-kripke C)) (states (create-kripke C))))
+)
+
+;; END of proofs on initial-states.
+
+;; OK, let us prove that create-label-fn is a valid label function.
+
+(local
+(defthm label-fn-is-subset
+ (subset (label-fn-of-st st vars) vars))
+)
+
+(local
+(defthm label-fn-of-st-is-truth-p-label
+ (truthp-label (label-fn-of-st st vars) st))
+)
+
+(local
+(defthm label-fn-of-st-is-all-truths-p-label
+ (all-truthsp-label (label-fn-of-st st vars) st vars))
+)
+
+(local
+(defun abs-only-all-truths-p (states label vars)
+ (if (endp states) T
+ (and (all-truthsp-label (<- label (first states)) (first states) vars)
+ (abs-only-all-truths-p (rest states) label vars))))
+)
+
+(local
+(defthm abs-concrete-only-all-truthsp-reduction
+ (equal (only-all-truths-p states m vars)
+ (abs-only-all-truths-p states (label-fn m) vars))
+ :hints (("Goal"
+ :in-theory (enable label-of))))
+)
+
+;; And now let us just prove abs-all-truthsp-label for the label-fn
+
+
+(local
+(defthm create-label-fn-does-not-mess-with-non-members
+ (implies (not (memberp s states))
+ (equal (<- (create-label-fn states vars label) s)
+ (<- label s))))
+)
+
+(local
+(defthm create-label-fn-creates-an-all-truthsp-label
+ (implies (memberp s states)
+ (equal (<- (create-label-fn states vars label) s)
+ (label-fn-of-st s vars))))
+)
+
+(local
+(defthm label-fn-is-abs-only--all-truthsp
+ (abs-only-all-truths-p states (create-label-fn states vars label) vars)
+ :hints (("Subgoal *1/3"
+ :cases ((memberp (car states) (cdr states)))
+ :do-not-induct t)))
+)
+
+(local
+(defthm label-fn-is-only-all-truthsp
+ (only-all-truths-p (states (create-kripke C)) (create-kripke C)
+ (variables C)))
+)
+
+(local
+(in-theory (disable abs-concrete-only-all-truthsp-reduction))
+)
+
+(local
+(defun abs-label-subset-vars (states label vars)
+ (if (endp states) T
+ (and (subset (<- label (first states)) vars)
+ (abs-label-subset-vars (rest states) label vars))))
+)
+
+(local
+(defthm abs-label-subset-vars-is-same-as-concrete
+ (equal (label-subset-vars states m vars)
+ (abs-label-subset-vars states (label-fn m) vars))
+ :hints (("Goal"
+ :in-theory (enable label-of))))
+)
+
+(local
+(defthm create-label-fn-is-abs-label-subset-vars
+ (abs-label-subset-vars states (create-label-fn states vars label) vars)
+ :hints (("Subgoal *1/3"
+ :cases ((memberp (car states) (cdr states)))
+ :do-not-induct t)))
+)
+
+(local
+(defthm label-fn-is-label-subset-vars
+ (label-subset-vars (states (create-kripke C)) (create-kripke C) (variables
+ C)))
+)
+
+(local
+(in-theory (disable abs-label-subset-vars-is-same-as-concrete))
+)
+
+(local
+(defun abs-only-truth-p (states label)
+ (if (endp states) T
+ (and (truthp-label (<- label (first states)) (first states))
+ (abs-only-truth-p (rest states) label))))
+)
+
+(local
+(defthm only-truth-p-abs-reduction
+ (equal (only-truth-p states m)
+ (abs-only-truth-p states (label-fn m)))
+ :hints (("Goal"
+ :in-theory (enable label-of))))
+)
+
+(local
+(defthm label-fn-is-abs-only-truth-p
+ (abs-only-truth-p states (create-label-fn states vars label))
+ :hints (("Subgoal *1/3"
+ :cases ((memberp (car states) (cdr states))))))
+)
+
+(local
+(defthm label-fn-is-only-truth-p
+ (only-truth-p (states (create-kripke C)) (create-kripke C)))
+)
+
+(local
+(in-theory (disable only-truth-p-abs-reduction))
+)
+
+;; END of proofs for label function.
+
+;; Let us now work with the transition function.
+
+(local
+(defthm create-next-states-is-subset-of-states-aux
+ (implies (memberp q (create-next-states-of-p p states vars equations))
+ (memberp q states)))
+)
+
+(local
+(defthm create-next-states-of-p-subset-helper
+ (implies (subset states-prime (create-next-states-of-p p states vars
+ equations))
+ (subset states-prime states)))
+)
+
+
+(local
+(defthm create-next-states-is-subset-of-states
+ (subset (create-next-states-of-p p states vars equations)
+ states)
+ :hints (("Goal"
+ :use ((:instance create-next-states-of-p-subset-helper
+ (states-prime (create-next-states-of-p p states
+ vars equations)))))))
+)
+
+(local
+(defthm not-memberp-next-states-reduction
+ (implies (not (memberp s states))
+ (equal (<- (create-next-states states states-prime vars equations)
+ s)
+ nil)))
+)
+
+(local
+(defthm memberp-next-state-reduction
+ (implies (memberp s states)
+ (equal (<- (create-next-states states states-prime vars equations)
+ s)
+ (create-next-states-of-p s states-prime vars equations)))
+ :hints (("Subgoal *1/3"
+ :cases ((equal s (car states))))))
+)
+
+(local
+(defthm transition-subset-p-for-next-state
+ (transition-subset-p states states-prime
+ (create-next-states states states-prime vars equations))
+ :hints (("Subgoal *1/2"
+ :cases ((memberp (car states) (cdr states))))))
+)
+
+(local
+(defthm transition-subset-p-holds-for-kripke
+ (transition-subset-p (states (create-kripke C))
+ (states (create-kripke C))
+ (transition (create-kripke C))))
+)
+
+(local
+(defthm next-states-in-states-concretized
+ (equal (next-states-in-states m states)
+ (transition-subset-p states (states m) (transition m)))
+ :hints (("Goal"
+ :in-theory (enable next-states-in-states))))
+)
+
+(local
+(defthm next-states-in-states-holds-for-create-kripke
+ (next-states-in-states (create-kripke C) (states (create-kripke C))))
+)
+
+
+;; END of proofs for transition function.
+
+;; BEGIN proofs for states
+
+;; first states is a consp
+
+(local
+(defthm consp-states-for-consp-vars
+ (implies (consp states)
+ (consp (create-all-evaluations vars states))))
+)
+
+;; The following theorem is a hack. This theorem is known as a
+;; type-prescription rule for append. Unfortunately, we need it as a rewrite
+;; rule.
+
+(local
+(in-theory (enable set-union))
+)
+
+(local
+(defthm consp-union-reduction
+ (implies (consp y)
+ (consp (set-union x y))))
+)
+
+(local
+(defthm create-kripke-is-consp-states
+ (consp (states (create-kripke C))))
+)
+
+;; OK let us prove that everything is boolean with create-all-evaluations
+
+(local
+(defthm only-evaluations-p-union-reduction
+ (implies (and (only-evaluations-p init vars)
+ (only-evaluations-p states vars))
+ (only-evaluations-p (set-union init states) vars)))
+)
+
+;; OK that takes care of the set-union part. Now we only need to show the
+;; create-all-evaluations produces only-evaluations-p
+
+(local
+(defun boolean-p-states (v states)
+ (if (endp states) T
+ (and (booleanp (<- (first states) v))
+ (boolean-p-states v (rest states)))))
+)
+
+(local
+(defun boolean-list-p-states (vars states)
+ (if (endp vars) T
+ (and (boolean-p-states (first vars) states)
+ (boolean-list-p-states (rest vars) states))))
+)
+
+;; Now can we prove that boolean-p-states holds for create-all-evaluations?
+
+(local
+(defthm assign-t-produces-boolean-p
+ (boolean-p-states v (assign-T v states)))
+)
+
+(local
+(defthm assign-nil-produces-boolean-p
+ (boolean-p-states v (assign-nil v states)))
+)
+
+(local
+(defthm assign-T-remains-same-for-not-v
+ (implies (not (equal v v-prime))
+ (equal (boolean-p-states v (assign-T v-prime states))
+ (boolean-p-states v states))))
+)
+
+(local
+(defthm assign-nil-remains-same-for-not-v
+ (implies (not (equal v v-prime))
+ (equal (boolean-p-states v (assign-nil v-prime states))
+ (boolean-p-states v states))))
+)
+
+(local
+(defthm boolean-p-append-reduction
+ (equal (boolean-p-states v (append states states-prime))
+ (and (boolean-p-states v states)
+ (boolean-p-states v states-prime))))
+)
+
+(local
+(defthm boolean-p-create-non-member-reduction
+ (implies (not (memberp v vars))
+ (equal (boolean-p-states v (create-all-evaluations vars states))
+ (boolean-p-states v states)))
+ :hints (("Goal"
+ :induct (create-all-evaluations vars states)
+ :do-not-induct t)))
+)
+
+(local
+(defthm create-all-evaluations-for-member-is-boolean
+ (implies (memberp v vars)
+ (boolean-p-states v (create-all-evaluations vars states)))
+ :hints (("Goal"
+ :induct (create-all-evaluations vars states)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :cases ((equal v (car vars))))))
+)
+
+(local
+(defthm create-all-evaluations-is-boolean-list-p-aux
+ (implies (subset vars vars-prime)
+ (boolean-list-p-states vars
+ (create-all-evaluations vars-prime states))))
+)
+
+(local
+(defthm create-all-evaluations-is-boolean-list-p
+ (boolean-list-p-states vars (create-all-evaluations vars states)))
+)
+
+;; Can we prove that if we produce a boolean list then it is an evaluation?
+
+(local
+(defun evaluation-witness-variable (vars st)
+ (if (endp vars) nil
+ (if (not (booleanp (<- st (first vars))))
+ (first vars)
+ (evaluation-witness-variable (rest vars) st))))
+)
+
+(local
+(defthm evaluation-p-from-witness
+ (implies (booleanp (<- st (evaluation-witness-variable vars st)))
+ (evaluation-p st vars)))
+)
+
+(local
+(defthm boolean-list-p-to-boolean-vars
+ (implies (and (boolean-list-p-states vars states)
+ (memberp v vars))
+ (boolean-p-states v states)))
+)
+
+(local
+(defthm boolean-p-states-implies-boolean-v
+ (implies (and (boolean-p-states v states)
+ (memberp st states))
+ (booleanp (<- st v))))
+)
+
+(local
+(defthm boolean-p-states-to-evaluation-p
+ (implies (and (boolean-list-p-states vars states)
+ (memberp st states))
+ (evaluation-p st vars)))
+)
+
+(local
+(defthm boolean-p-states-to-only-evaluation-p-aux
+ (implies (and (boolean-list-p-states vars states)
+ (subset states-prime states))
+ (only-evaluations-p states-prime vars)))
+)
+
+(local
+(defthm boolean-p-states-to-only-evaluations-p
+ (implies (boolean-list-p-states vars states)
+ (only-evaluations-p states vars)))
+)
+
+(local
+(defthm create-all-evaluations-is-only-evaluations-p
+ (only-evaluations-p (create-all-evaluations vars states) vars))
+)
+
+(local
+(defthm create-kripke-is-only-evaluations-p
+ (implies (circuitp C)
+ (only-evaluations-p (states (create-kripke C)) (variables C))))
+)
+
+;; The final predicate is all-evaluations-p. This is tricky, since it is
+;; defined using defun-sk. We try to create a witness for all-evaluations-p.
+
+(local
+(defun find-matching-states (st vars states)
+ (cond ((endp vars) states)
+ ((equal (<- st (first vars)) T)
+ (assign-t (first vars)
+ (find-matching-states st (rest vars) states)))
+ (t (assign-nil (first vars)
+ (find-matching-states st (rest vars) states)))))
+)
+
+;; Let us first prove find-matching-states is a consp
+
+(local
+(defthm find-matching-states-is-consp
+ (implies (consp states)
+ (consp (find-matching-states st vars states))))
+)
+
+;; Now let us prove that for every member of find-matching-states it is
+;; evaluation-eq to st.
+
+(local
+(defthm nth-member-reduction
+ (implies (and (< i (len x))
+ (consp x))
+ (memberp (nth i x) x)))
+)
+
+(local
+(defthm nth-member-reduction-2
+ (implies (and (>= i (len x))
+ (integerp i))
+ (equal (nth i x) nil))
+ :hints (("Goal"
+ :in-theory (enable zp))))
+)
+
+(local
+(defthm assign-nil-produces-nil-member
+ (implies (memberp q (assign-nil v states))
+ (equal (<- q v) nil)))
+)
+
+(local
+(defthm assign-t-produces-t-member
+ (implies (memberp q (assign-t v states))
+ (equal (<- q v) t)))
+)
+
+(local
+(defthm assign-nil-produces-nil
+ (implies (and (consp states)
+ (integerp i))
+ (not (<- (nth i (assign-nil v states)) v)))
+ :otf-flg t
+ :hints (("Goal"
+ :cases ((>= i (len (assign-nil v states))))
+ :do-not-induct t)
+ ("Subgoal 2"
+ :in-theory (disable nth-member-reduction)
+ :use ((:instance nth-member-reduction
+ (x (assign-nil v states)))))))
+)
+
+(local
+(defthm assign-t-has-same-len
+ (equal (len (assign-t v states))
+ (len states)))
+)
+
+(local
+(defthm assign-nil-has-same-len
+ (equal (len (assign-nil v states))
+ (len states)))
+)
+
+(local
+(defthm len-consp-reduction
+ (implies (and (equal (len x) (len y))
+ (consp x))
+ (consp y)))
+)
+
+(local
+(defthm assign-t-produces-t
+ (implies (and (consp states)
+ (< i (len states))
+ (integerp i))
+ (equal (<- (nth i (assign-t v states)) v) t))
+ :otf-flg t
+ :hints (("Goal"
+ :in-theory (disable nth-member-reduction)
+ :use ((:instance nth-member-reduction
+ (x (assign-t v states)))))))
+)
+
+(local
+(defthm assign-t-does-not-fuss
+ (implies (and (consp states)
+ (< i (len states))
+ (integerp i)
+ (not (equal v v-prime)))
+ (equal (<- (nth i (assign-t v states)) v-prime)
+ (<- (nth i states) v-prime))))
+)
+
+(local
+(defthm assign-nil-does-not-fuss
+ (implies (and (consp states)
+ (< i (len states))
+ (integerp i)
+ (not (equal v v-prime)))
+ (equal (<- (nth i (assign-nil v states)) v-prime)
+ (<- (nth i states) v-prime))))
+)
+
+(local
+(defthm len-of-find-matching-states-is-same
+ (equal (len (find-matching-states st vars states))
+ (len states)))
+)
+
+(local
+(defthm find-matching-state-produces-equivalent-assignment
+ (implies (and (memberp v vars)
+ (consp states)
+ (integerp i)
+ (< i (len states))
+ (evaluation-p st vars))
+ (equal (<- (nth i (find-matching-states st vars states)) v)
+ (<- st v)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (find-matching-states st vars states)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/3.1"
+ :cases ((equal v (car vars))))
+ ("Subgoal *1/2.1"
+ :cases ((equal v (car vars))))))
+)
+
+(local
+(defun falsifier-evaluation-eq (p q vars)
+ (if (endp vars) nil
+ (if (not (equal (<- p (first vars))
+ (<- q (first vars))))
+ (first vars)
+ (falsifier-evaluation-eq p q (rest vars)))))
+)
+
+(local
+(defthm falsifier-means-evaluation-eq
+ (implies (equal (<- p (falsifier-evaluation-eq p q vars))
+ (<- q (falsifier-evaluation-eq p q vars)))
+ (evaluation-eq p q vars)))
+)
+
+(local
+(defthm falsifier-not-member-to-evaluation-eq
+ (implies (not (memberp (falsifier-evaluation-eq p q vars) vars))
+ (evaluation-eq p q vars)))
+)
+
+(local
+(defthm find-matching-states-evaluation-eq
+ (implies (and (consp states)
+ (integerp i)
+ (< i (len states))
+ (evaluation-p st vars))
+ (evaluation-eq (nth i (find-matching-states st vars states))
+ st vars))
+ :hints (("Goal"
+ :cases ((not (memberp
+ (falsifier-evaluation-eq
+ (nth i (find-matching-states st vars states))
+ st vars)
+ vars))))))
+)
+
+(local
+(defthm find-matching-is-evaluation-eq-concretized
+ (implies (and (consp states)
+ (evaluation-p st vars))
+ (evaluation-eq (car (find-matching-states st vars states))
+ st vars))
+ :hints (("Goal"
+ :in-theory (disable find-matching-states-evaluation-eq)
+ :use ((:instance find-matching-states-evaluation-eq
+ (i 0))))))
+)
+
+(local
+(defthm memberp-append-reduction
+ (equal (memberp a (append x y))
+ (or (memberp a x)
+ (memberp a y))))
+)
+
+(local
+(defthm member-assign-t-reduction
+ (implies (memberp e x)
+ (memberp (-> e v t)
+ (assign-t v x))))
+)
+
+(local
+(defthm assign-t-subset-reduction
+ (implies (subset x y)
+ (subset (assign-t v x)
+ (assign-t v y))))
+)
+
+(local
+(defthm member-assign-nil-reduction
+ (implies (memberp e x)
+ (memberp (-> e v nil)
+ (assign-nil v x))))
+)
+
+(local
+(defthm assign-nil-subset-reduction
+ (implies (subset x y)
+ (subset (assign-nil v x)
+ (assign-nil v y))))
+)
+
+(local
+(defthm append-subset-reduction-1
+ (implies (subset x y)
+ (subset x (append y z))))
+)
+
+(local
+(defthm append-subset-reduction-2
+ (implies (subset x y)
+ (subset x (append z y))))
+)
+
+(local
+(defthm find-matching-subset-reduction
+ (subset (find-matching-states st vars states)
+ (create-all-evaluations vars states)))
+)
+
+(local
+(defthm car-of-find-matching-is-member-of-all-evaluations
+ (implies (consp states)
+ (memberp (car (find-matching-states st vars states))
+ (create-all-evaluations vars states))))
+)
+
+(local
+(defthm evaluation-eq-memberp-from-memberp
+ (implies (and (evaluation-eq p q vars)
+ (memberp q states))
+ (evaluation-eq-member-p p states vars)))
+)
+
+(local
+(defthm evalaution-eq-symmetry-hack
+ (implies (and (evaluation-eq p q vars)
+ (memberp p states))
+ (evaluation-eq-member-p q states vars))
+ :hints (("Goal"
+ :in-theory (disable evaluation-eq evaluation-eq-member-p
+ evaluation-eq-memberp-from-memberp)
+ :use ((:instance evaluation-eq-memberp-from-memberp
+ (p q)
+ (q p))
+ (:instance evaluation-eq-is-symmetric)))))
+)
+
+(local
+(in-theory (disable evaluation-eq-memberp-from-memberp))
+)
+
+(local
+(defthm create-all-evaluations-is-evaluation-eq-memberp
+ (implies (and (evaluation-p st vars)
+ (consp states))
+ (evaluation-eq-member-p st (create-all-evaluations vars states)
+ vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable evalaution-eq-symmetry-hack)
+ :use ((:instance evalaution-eq-symmetry-hack
+ (q st)
+ (states (create-all-evaluations vars states))
+ (p (car (find-matching-states st vars
+ states))))))))
+)
+
+(local
+(defthm consp-states-to-all-evaluations-p
+ (implies (consp states)
+ (all-evaluations-p (create-all-evaluations vars states) vars))
+ :hints (("Goal"
+ :use ((:instance (:definition all-evaluations-p)
+ (states (create-all-evaluations vars states)))))))
+)
+
+(local
+(defthm append-evaluation-eq-member-reduction
+ (implies (evaluation-eq-member-p st states vars)
+ (evaluation-eq-member-p st (set-union init states) vars)))
+)
+
+(local
+(defthm all-evaluations-p-union-reduction
+ (implies (all-evaluations-p states vars)
+ (all-evaluations-p (set-union init states) vars))
+ :hints (("Goal"
+ :use ((:instance all-evaluations-p-necc)
+ (:instance (:definition all-evaluations-p)
+ (states (set-union init states)))))))
+)
+
+(local
+(defthm create-kripke-is-all-evaluations-p
+ (all-evaluations-p (states (create-kripke C))
+ (variables c)))
+)
+
+(local
+(defthm variables-of-create-kripke-are-original-vars
+ (equal (variables (create-kripke C))
+ (variables C)))
+)
+
+(local
+(defthm strict-evaluations-list-to-evaluation
+ (implies (and (strict-evaluation-list-p vars states)
+ (memberp st states))
+ (strict-evaluation-p st vars)))
+)
+
+(local
+(defthm strict-evaluations-append-reduction
+ (implies (and (strict-evaluation-list-p vars states)
+ (strict-evaluation-list-p vars states-prime))
+ (strict-evaluation-list-p vars (append states states-prime))))
+)
+
+(local
+(defthm strict-evaluation-list-p-nth-reduction
+ (implies (and (strict-evaluation-list-p vars states)
+ (integerp i)
+ (< i (len states))
+ (consp states))
+ (strict-evaluation-p (nth i states) vars)))
+)
+
+(local
+(defthm assign-t-strict-evaluations-reduction
+ (implies (and (strict-evaluation-list-p vars states)
+ (memberp v vars)
+ (consp states)
+ (integerp i)
+ (< i (len states))
+ (not (memberp v-prime vars)))
+ (not (<- (nth i (assign-t v states)) v-prime)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable assign-t-does-not-fuss)
+ :use ((:instance assign-t-does-not-fuss)
+ (:instance strict-evaluation-p-necc
+ (v v-prime)
+ (st (nth i states)))))))
+)
+
+(local
+(defthm assign-nil-strict-evaluations-reduction
+ (implies (and (strict-evaluation-list-p vars states)
+ (memberp v vars)
+ (consp states)
+ (integerp i)
+ (< i (len states))
+ (not (memberp v-prime vars)))
+ (not (<- (nth i (assign-nil v states)) v-prime)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable assign-nil-does-not-fuss)
+ :use ((:instance assign-nil-does-not-fuss)
+ (:instance strict-evaluation-p-necc
+ (v v-prime)
+ (st (nth i states)))))))
+)
+
+(local
+(defthm strict-evaluations-assign-t-reduction
+ (implies (and (integerp i)
+ (consp states)
+ (strict-evaluation-list-p vars states)
+ (memberp v vars)
+ (< i (len states)))
+ (strict-evaluation-p (nth i (assign-t v states)) vars)))
+)
+
+(local
+(defthm strict-evaluations-assign-nil-reduction
+ (implies (and (integerp i)
+ (consp states)
+ (strict-evaluation-list-p vars states)
+ (memberp v vars)
+ (< i (len states)))
+ (strict-evaluation-p (nth i (assign-nil v states)) vars)))
+)
+
+(local
+(defun find-index (st states)
+ (if (endp states) 0
+ (if (equal st (first states)) 0
+ (1+ (find-index st (rest states))))))
+)
+
+(local
+(defthm find-index-is-memberp
+ (implies (memberp st states)
+ (equal (nth (find-index st states) states)
+ st)))
+)
+
+(local
+(defthm find-index-returns-<-len
+ (implies (memberp st states)
+ (< (find-index st states) (len states)))
+ :rule-classes :linear)
+)
+
+(local
+(defthm strict-evaluation-for-memberp-assign-t
+ (implies (and (consp states)
+ (strict-evaluation-list-p vars states)
+ (memberp v vars)
+ (memberp st (assign-t v states)))
+ (strict-evaluation-p st vars))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable assign-t-strict-evaluations-reduction
+ strict-evaluation-p)
+ :use ((:instance strict-evaluations-assign-t-reduction
+ (i (find-index st (assign-t v states))))))))
+)
+
+(local
+(defthm strict-evaluation-for-memberp-assign-nil
+ (implies (and (consp states)
+ (strict-evaluation-list-p vars states)
+ (memberp v vars)
+ (memberp st (assign-nil v states)))
+ (strict-evaluation-p st vars))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable assign-nil-strict-evaluations-reduction
+ strict-evaluation-p)
+ :use ((:instance strict-evaluations-assign-nil-reduction
+ (i (find-index st (assign-nil v states))))))))
+)
+
+(local
+(in-theory (disable strict-evaluation-p))
+)
+
+(local
+(defthm strict-evaluations-for-assign-t
+ (implies (and (consp states)
+ (strict-evaluation-list-p vars states)
+ (memberp v vars))
+ (strict-evaluation-list-p vars (assign-t v states))))
+)
+
+(local
+(defthm strict-evaluations-for-assign-nil
+ (implies (and (consp states)
+ (strict-evaluation-list-p vars states)
+ (memberp v vars))
+ (strict-evaluation-list-p vars (assign-nil v states))))
+)
+
+(local
+(defun null-list-p (states)
+ (if (endp states) T
+ (and (null (first states))
+ (null-list-p (rest states)))))
+)
+
+(local
+(defthm strict-evaluation-p-cons-reduction
+ (implies (strict-evaluation-p st vars)
+ (strict-evaluation-p (-> st v t) (cons v vars)))
+ :hints (("Goal"
+ :expand (strict-evaluation-p (-> st v t) (cons v vars)))))
+)
+
+(local
+(defthm strict-evaluation-p-cons-reduction-2
+ (implies (strict-evaluation-p st vars)
+ (strict-evaluation-p (-> st v nil) (cons v vars)))
+ :hints (("Goal"
+ :expand (strict-evaluation-p (-> st v nil) (cons v vars)))))
+)
+
+(local
+(defthm strict-evaluation-p-assign-reduction-t
+ (implies (strict-evaluation-list-p vars states)
+ (strict-evaluation-list-p (cons v vars) (assign-t v states))))
+)
+
+(local
+(defthm strict-evaluation-p-assign-reduction-nil
+ (implies (strict-evaluation-list-p vars states)
+ (strict-evaluation-list-p (cons v vars) (assign-nil v states))))
+)
+
+(local
+(defthm nil-is-strict-evaluation-p
+ (strict-evaluation-p nil vars)
+ :hints (("Goal"
+ :in-theory (enable strict-evaluation-p))))
+)
+
+(local
+(defthm null-list-p-is-strict-evaluation-p
+ (implies (null-list-p states)
+ (strict-evaluation-list-p vars states)))
+)
+
+(local
+(defthm create-evaluations-is-strict-evaluation-list-p
+ (implies (and (consp states)
+ (null-list-p states)
+ (uniquep vars))
+ (strict-evaluation-list-p
+ vars (create-all-evaluations vars states)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (create-all-evaluations vars states)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :in-theory (disable strict-evaluation-p-assign-reduction-t
+ strict-evaluation-p-assign-reduction-nil)
+ :use ((:instance strict-evaluation-p-assign-reduction-t
+ (states (create-all-evaluations (cdr vars) states))
+ (vars (cdr vars))
+ (v (car vars)))
+ (:instance strict-evaluation-p-assign-reduction-nil
+ (states (create-all-evaluations (cdr vars) states))
+ (vars (cdr vars))
+ (v (car vars)))))))
+)
+
+(local
+(defthm strict-evaluation-set-union-reduction
+ (implies (and (strict-evaluation-list-p vars init)
+ (strict-evaluation-list-p vars states))
+ (strict-evaluation-list-p vars (set-union init states)))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+)
+
+(local
+(defthm strict-evaluation-list-p-holds
+ (implies (circuitp C)
+ (strict-evaluation-list-p (variables C) (states (create-kripke C)))))
+)
+
+(local
+(in-theory (disable create-kripke))
+)
+
+(DEFTHM create-kripke-produces-circuit-model
+ (implies (circuitp C)
+ (circuit-modelp (create-kripke C))))
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/concrete-ltl.lisp b/books/workshops/2003/ray-matthews-tuttle/support/concrete-ltl.lisp
new file mode 100644
index 0000000..c4da3ba
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/concrete-ltl.lisp
@@ -0,0 +1,308 @@
+(in-package "ACL2")
+
+#|
+
+ concrete-ltl.lisp
+ ~~~~~~~~~~~~~~~~~
+
+In this book, we define functions to reason about concrete semantics of
+LTL. This book is shipped with the certification of our compositional reduction
+paper for the purpose of demonstration. We first define a mutually recusrive
+clique that defines the semantics of LTL and then we define a single recursive
+function to justify that definition. We then go ahead and prove some properties
+about the functions. Our goal is to prove the properties that are necessary
+about the mutually recursive4 clique as the properties we wish to export about
+semantics of LTL. For conjunctive and cone of influence reductions, we need
+basically two properties.
+
+(1) That the ltl semantics can be decomposed over conjunction. (Obvious from
+definition)
+
+(2) That it is oblivious to paths that are bisimilar.
+
+We have removed the second part of the theorems from this book, primarily
+because it was taking a humongous amount of time in v2-6, and I did not have
+the guts to see how much time it takes to prove in v2-7. And further, we
+contend that if we have defined the semantics of ltl such that the theorem
+cannot be proved, then we need to consider redefining the semantics of
+LTL. (This book, I hope will provide enough evidence that the semantics can be
+defined.) Hence we reasoned completely using a function that is encapsulated
+and known to satisfy this property. If the reader feels unsatisfied with this,
+we can provide the actual theorems about ltl-periodic-path-emantics, (which are
+actually slightly more general than those I exported from the constrained
+functions).
+
+|#
+
+(include-book "ltl")
+
+;; Added for compatibility with previous versions of ACL2.
+
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+(mutual-recursion
+
+(defun ltl-periodic-path-semantics (f init prefix cycle label)
+ (declare (xargs :measure (cons (1+ (acl2-count f)) 0)))
+ (cond ((atom f)
+ (if (ltl-constantp f)
+ (equal f 'true)
+ (memberp f (<- label init))))
+ ((equal (len f) 3)
+ (case (second f)
+ (& (and (ltl-periodic-path-semantics (first f) init prefix cycle
+ label)
+ (ltl-periodic-path-semantics (third f) init prefix cycle
+ label)))
+ (+ (or (ltl-periodic-path-semantics (first f) init prefix cycle
+ label)
+ (ltl-periodic-path-semantics (third f) init prefix cycle
+ label)))
+ (U (let* ((found-and-index
+ (find-state-satisfying-formula
+ (third f) init prefix cycle label
+ (+ 1 (len prefix) (len cycle))))
+ (found (first found-and-index))
+ (index (second found-and-index)))
+ (if (not found)
+ nil
+ (ltl-periodic-path-semantics* (first f) init prefix
+ cycle label index))))
+ (W (let* ((found-and-index
+ (find-state-satisfying-formula
+ (third f) init prefix cycle label
+ (+ 1 (len prefix) (len cycle))))
+ (found (first found-and-index))
+ (index (second found-and-index)))
+ (if (not found)
+ (ltl-periodic-path-semantics* (first f) init prefix
+ cycle label
+ (+ 1 (len prefix) (len cycle)))
+ (ltl-periodic-path-semantics* (first f) init prefix
+ cycle label index))))
+ (t nil)))
+ ((equal (len f) 2)
+ (case (first f)
+ (~ (not (ltl-periodic-path-semantics (second f) init prefix cycle
+ label)))
+ (G (ltl-periodic-path-semantics* (second f) init prefix
+ cycle label
+ (+ 1 (len prefix) (len cycle))))
+ (F (let* ((found-and-index
+ (find-state-satisfying-formula
+ (second f) init prefix cycle label
+ (+ 1 (len prefix) (len cycle))))
+ (found (first found-and-index)))
+ (if found t nil)))
+ (X (ltl-periodic-path-semantics (second f) (first prefix)
+ (if (endp (rest prefix))
+ cycle
+ (rest prefix))
+ cycle
+ label))
+ (t nil)))
+ (t nil)))
+
+(defun ltl-periodic-path-semantics* (f init prefix cycle label dist)
+ (declare (xargs :measure (cons (1+ (acl2-count f)) (nfix dist))))
+ (if (zp dist) t
+ (and (ltl-periodic-path-semantics f init prefix cycle label)
+ (ltl-periodic-path-semantics* f (first prefix)
+ (if (endp (rest prefix))
+ cycle
+ (rest prefix))
+ cycle label (1- dist)))))
+
+(defun find-state-satisfying-formula (f init prefix cycle label dist)
+ (declare (xargs :measure (cons (1+ (acl2-count f)) (nfix dist))))
+ (cond ((zp dist) (list nil 0))
+ ((ltl-periodic-path-semantics f init prefix cycle label)
+ (list t 0))
+ (t (let* ((found-and-index
+ (find-state-satisfying-formula
+ f (first prefix)
+ (if (endp (rest prefix)) cycle (rest prefix))
+ cycle label (1- dist)))
+ (found (first found-and-index))
+ (ndx (second found-and-index)))
+ (list found (1+ ndx))))))
+
+)
+
+;; Now we have ther semantics of LTL that we will call the spec. We now proceed
+;; to define a singly recursive version that is equivalent to the spec. Our
+;; proofs will be using the singly recursive definition critically in order to
+;; get us to what we want.
+
+(defun ltl-semantics-single-recursion (f init prefix cycle label dist index)
+ (declare (xargs :measure (cons (1+ (acl2-count f)) (if (equal index 0) 0 (nfix dist)))
+ :otf-flg nil))
+
+ (if (equal index 0)
+ (cond ((atom f)
+ (if (ltl-constantp f)
+ (equal f 'true)
+ (memberp f (<- label init))))
+ ((equal (len f) 3)
+ (case (second f)
+ (& (and (ltl-semantics-single-recursion (first f) init prefix cycle
+ label dist 0)
+ (ltl-semantics-single-recursion (third f) init prefix cycle
+ label dist 0)))
+ (+ (or (ltl-semantics-single-recursion (first f) init prefix cycle
+ label dist 0)
+ (ltl-semantics-single-recursion (third f) init prefix cycle
+ label dist 0)))
+ (U (let* ((found-and-index
+ (ltl-semantics-single-recursion
+ (third f) init prefix cycle label
+ (+ 1 (len prefix) (len cycle))
+ 2))
+ (found (first found-and-index))
+ (ndx (second found-and-index)))
+ (if (not found)
+ nil
+ (ltl-semantics-single-recursion (first f) init prefix
+ cycle label ndx 1))))
+ (W (let* ((found-and-index
+ (ltl-semantics-single-recursion
+ (third f) init prefix cycle label
+ (+ 1 (len prefix) (len cycle))
+ 2))
+ (found (first found-and-index))
+ (ndx (second found-and-index)))
+ (if (not found)
+ (ltl-semantics-single-recursion (first f) init prefix
+ cycle label
+ (+ 1 (len prefix) (len
+ cycle))
+ 1)
+ (ltl-semantics-single-recursion (first f) init prefix
+ cycle label ndx 1))))
+ (t nil)))
+ ((equal (len f) 2)
+ (case (first f)
+ (~ (not (ltl-semantics-single-recursion (second f) init prefix cycle
+ label dist 0)))
+ (G (ltl-semantics-single-recursion (second f) init prefix
+ cycle label
+ (+ 1 (len prefix) (len cycle)) 1))
+ (F (let* ((found-and-index
+ (ltl-semantics-single-recursion
+ (second f) init prefix cycle label
+ (+ 1 (len prefix) (len cycle))
+ 2))
+ (found (first found-and-index)))
+ (if found T nil)))
+ (X (ltl-semantics-single-recursion (second f) (first prefix)
+ (if (endp (rest prefix))
+ cycle
+ (rest prefix))
+ cycle
+ label dist 0))
+ (t nil)))
+ (t nil))
+ (if (equal index 1)
+ (if (zp dist) t
+ (and (ltl-semantics-single-recursion f init prefix cycle label dist 0)
+ (ltl-semantics-single-recursion f (first prefix)
+ (if (endp (rest prefix))
+ cycle
+ (rest prefix))
+ cycle label (1- dist)
+ 1)))
+ (if (equal index 2)
+ (cond ((zp dist) (list nil 0))
+ ((ltl-semantics-single-recursion f init prefix cycle label dist 0)
+ (list t 0))
+ (t (let* ((found-and-index
+ (ltl-semantics-single-recursion
+ f (first prefix)
+ (if (endp (rest prefix)) cycle (rest prefix))
+ cycle label (1- dist) 2))
+ (found (first found-and-index))
+ (ndx (second found-and-index)))
+ (list found (1+ ndx)))))
+ nil))))
+
+
+;; So do we believe that this big hodge-podge is same as the mutually recursive
+;; code? Well, let us prove it.
+
+(local
+ ;; [Jared] added this because the following proof broke when I built it into ACL2.
+ (in-theory (disable FOLD-CONSTS-IN-+)))
+
+(defthm single-and-mutually-recursive-code-same
+ (equal (ltl-semantics-single-recursion f init prefix cycle label dist index)
+ (if (equal index 0)
+ (ltl-periodic-path-semantics f init prefix cycle label)
+ (if (equal index 1)
+ (ltl-periodic-path-semantics* f init prefix cycle label dist)
+ (if (equal index 2)
+ (find-state-satisfying-formula f init prefix cycle
+ label dist)
+ nil))))
+ :rule-classes nil)
+
+(defthm ltl-semantics-is-boolean
+ (if (not (equal i 2))
+ (booleanp (ltl-semantics-single-recursion f init prefix cycle label
+ dist i))
+ (and (booleanp (first (ltl-semantics-single-recursion f init prefix
+ cycle label dist
+ i)))
+ (integerp (second (ltl-semantics-single-recursion f init prefix
+ cycle label dist
+ i)))))
+ :rule-classes nil)
+
+(defthm ltl-semantics-0-is-boolean
+ (booleanp (ltl-semantics-single-recursion f init prefix cycle label dist 0))
+ :hints (("Goal"
+ :use ((:instance single-and-mutually-recursive-code-same
+ (index 0)))))
+ :rule-classes :type-prescription)
+
+(defthm ltl-semantics-1-boolean
+ (booleanp (ltl-semantics-single-recursion f init prefix cycle label dist 1))
+ :hints (("Goal"
+ :use ((:instance single-and-mutually-recursive-code-same
+ (index 1)))))
+ :rule-classes :type-prescription)
+
+(defthm ltl-semantics->2-boolean
+ (implies (and (not (equal i 0))
+ (not (equal i 1))
+ (not (equal i 2)))
+ (not (ltl-semantics-single-recursion f init prefix cycle label
+ dist i)))
+ :rule-classes :type-prescription)
+
+(defthm ltl-semantics-2-boolean
+ (booleanp (first (ltl-semantics-single-recursion f init prefix cycle label
+ dist 2)))
+ :hints (("Goal"
+ :use ((:instance ltl-semantics-is-boolean
+ (i 2)))))
+ :rule-classes :type-prescription)
+
+(defthm ltl-semantics-2-integer
+ (integerp (second (ltl-semantics-single-recursion f init prefix cycle label
+ dist 2)))
+ :hints (("Goal"
+ :use ((:instance ltl-semantics-is-boolean
+ (i 2)))))
+ :rule-classes :type-prescription)
+
+(defthm ltl-periodic-path-semantics-decomposed-for-conjunction
+ (implies (and ;; (ltl-formulap f)
+ (equal (len f) 3)
+ (equal (second f) '&))
+ (equal (ltl-periodic-path-semantics f init prefix cycle label)
+ (and (ltl-periodic-path-semantics (first f) init prefix cycle
+ label)
+ (ltl-periodic-path-semantics (third f) init prefix cycle
+ label))))
+ :rule-classes nil)
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/cone-of-influence.lisp b/books/workshops/2003/ray-matthews-tuttle/support/cone-of-influence.lisp
new file mode 100644
index 0000000..890141b
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/cone-of-influence.lisp
@@ -0,0 +1,1976 @@
+(in-package "ACL2")
+
+;; The following two lines are added for portability to v2-7....
+
+
+#|
+
+ cone-of-influence.lisp
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+We implement a cone of influence reduction algorithm. Cone of influence is
+(roughly) elimination of redundant variables. Given a collection of V variables,
+we determine the closure V*, V =< V* =< (variables C) and a collection
+E =< (equations C), such that for every variable in V*, the equation in E for
+that variable corresponds to the equation in (equations C). We then claim that
+the Kripke structure created from the cone-of-influence reduced circuit is
+bisimilar with respect to V* to the Kripke Structure created from the original
+circuit.
+
+|#
+
+
+(include-book "circuits")
+
+;; Here are the two culprit rules that I need to disable to get the proof
+;; faster. Just shows how naive a user I was when I did this proof.
+
+(in-theory (disable subset-of-nil-is-nil
+ subset-of-empty-is-empty))
+
+(defun find-variables* (equation-list)
+ (if (endp equation-list) nil
+ (set-union (find-variables (first equation-list))
+ (find-variables* (rest equation-list)))))
+
+(defun find-all-variables-1-pass (vars equations)
+ (if (endp vars) nil
+ (set-union (find-variables* (<- equations (first vars)))
+ (find-all-variables-1-pass (rest vars) equations))))
+
+;; The following function find-all-variables is a difficult function to
+;; admit. It computes the closure of a given set of variables (vars) with
+;; respect to a collection of variables (variables) and a collection of
+;; equations.
+
+(local
+(in-theory (enable set-union))
+)
+
+(local
+(defthm len-set-union-more-than-y
+ (<= (len y)
+ (len (set-union x y)))
+ :rule-classes :linear)
+)
+
+(local
+(defthm uniquep-member-reduction
+ (equal (memberp e (set-union x y))
+ (or (memberp e x)
+ (memberp e y))))
+)
+
+(local
+(defthm uniquep-union-reduction
+ (implies (and (uniquep x)
+ (uniquep y))
+ (uniquep (set-union x y))))
+)
+
+(local
+(defthm find-variables-is-unique
+ (uniquep (find-variables equations)))
+)
+
+(local
+(defthm find-variables*-is-unique
+ (uniquep (find-variables* equations)))
+)
+
+(local
+(defthm find-all-variables-1-pass-is-unique
+ (uniquep (find-all-variables-1-pass vars equations)))
+)
+
+(defun del (e x)
+ (if (endp x) x
+ (if (equal e (first x))
+ (rest x)
+ (cons (first x) (del e (rest x))))))
+
+(local
+(defthm len-del-reduction-1
+ (implies (memberp e x)
+ (equal (len (del e x))
+ (1- (len x))))
+ :hints (("Goal"
+ :in-theory (enable len))))
+)
+
+(defun induction-hint-for-len-<= (x y)
+ (if (endp x) (list x y)
+ (induction-hint-for-len-<= (cdr x) (del (car x) y))))
+
+(local
+(defthm del-not-member-reduction
+ (implies (not (memberp e x))
+ (equal (del e x) x)))
+)
+
+(local
+(defthm member-del-reduction
+ (implies (not (equal v e))
+ (equal (memberp v (del e y))
+ (memberp v y))))
+)
+
+(local
+(defthm subset-del-member
+ (implies (and (not (memberp e x))
+ (subset x y))
+ (subset x (del e y))))
+)
+
+(local
+(defthm uniquep-del-reduction
+ (implies (uniquep x)
+ (uniquep (del e x))))
+)
+
+(local
+(defthm uniquep-and-subset-implies-len-<=
+ (implies (and (uniquep x)
+ (uniquep y)
+ (subset x y))
+ (<= (len x)
+ (len y)))
+ :hints (("Goal"
+ :induct (induction-hint-for-len-<= x y)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm subset-from-union
+ (implies (and (subset x z)
+ (subset y z))
+ (subset (set-union x y) z)))
+)
+
+(local
+(defthm subset-from-union-2
+ (implies (and (subset (set-union x y) z)
+ (uniquep x)
+ (uniquep y))
+ (and (subset x z)
+ (subset y z))))
+)
+
+(local
+(include-book "../../../../arithmetic-2/meta/top")
+)
+
+(local
+(defthm del-e-to-cons-subset
+ (implies (subset (del e y) x)
+ (subset y (cons e x))))
+)
+
+(local
+(defthm len-equal-to-set-equal
+ (implies (and (equal (len x) (len y))
+ (uniquep x)
+ (uniquep y)
+ (subset x y))
+ (subset y x))
+ :hints (("Goal"
+ :induct (induction-hint-for-len-<= x y)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/2.1"
+ :in-theory (disable del-e-to-cons-subset)
+ :use ((:instance del-e-to-cons-subset
+ (e (car x))
+ (x (cdr x)))))))
+)
+
+(defun find-all-variables (vars variables equations)
+ (declare (xargs :measure (nfix (- (len variables) (len vars)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (enable set-equal)
+ :do-not '(eliminate-destructors generalize)))))
+ (if (or (not (uniquep variables))
+ (not (uniquep vars))
+ (not (subset vars variables)))
+ vars
+ (let ((new-vars (set-union (find-all-variables-1-pass vars equations)
+ vars)))
+ (if (not (subset new-vars variables)) nil
+ (if (set-equal vars new-vars) vars
+ (find-all-variables new-vars variables equations))))))
+
+(defun find-all-equations (vars equations eq-rec)
+ (if (endp vars) eq-rec
+ (find-all-equations (rest vars) equations
+ (-> eq-rec
+ (first vars)
+ (<- equations (first vars))))))
+
+(defun remove-duplicate-occurrences (x)
+ (cond ((endp x) x)
+ ((memberp (first x) (rest x)) (remove-duplicate-occurrences (rest x)))
+ (t (cons (first x) (remove-duplicate-occurrences (rest x))))))
+
+(defun corresponding-state (init vars)
+ (if (endp vars) nil
+ (-> (corresponding-state init (rest vars))
+ (first vars)
+ (<- init (first vars)))))
+
+(defun corresponding-states (inits vars)
+ (if (endp inits) nil
+ (cons (corresponding-state (first inits) vars)
+ (corresponding-states (rest inits) vars))))
+
+(defun cone-variables (vars C)
+ (find-all-variables
+ (set-intersect (remove-duplicate-occurrences vars)
+ (variables C))
+ (variables C)
+ (equations C)))
+
+(defun cone-of-influence-reduction (C vars)
+ (let ((variables (cone-variables vars C)))
+ (>_ :variables variables
+ :initial-states (corresponding-states (initial-states C) variables)
+ :equations (find-all-equations variables (equations C) ()))))
+
+;; OK, so we have implemented the cone of influence reduction. Let us prove
+;;that create-kripke of this reduced model is bisim-equiv to create-Kripke of
+;; C.
+
+;; Notice that for the bisimilarity proof to go through, the variables that we
+;; choose are the variables in the cone. So proving that the variables are subset
+;; of the variables of cone is trivial. On the other hand, we need to prove that
+;; the variables are subset of the original collection of variables.
+
+(local
+(defthm find-all-variables-subset-of-variables
+ (implies (and (uniquep vars)
+ (uniquep variables)
+ (subset vars variables))
+ (subset (find-all-variables vars variables equations) variables))
+ :hints (("Goal"
+ :in-theory (disable subset-of-nil-is-nil
+ subset-of-empty-is-empty))))
+)
+
+;; OK, so we know find-all-variables-is-a-subset. We need to prove that vars is
+;; a subset and uniquep, though. Now, vars is really remove-duplicates of
+;; (set-intersect (remove-duplicates vars) (variables C))
+
+(local
+(defthm member-remove-duplicate-reduction
+ (equal (memberp e (remove-duplicate-occurrences x))
+ (memberp e x)))
+)
+
+(local
+(defthm unique-duplicate-reduction
+ (uniquep (remove-duplicate-occurrences x)))
+)
+
+(local
+(defthm uniquep-intersect-reduction
+ (implies (and (uniquep x)
+ (uniquep y))
+ (uniquep (set-intersect x y))))
+)
+
+(local
+(defthm find-all-variables-is-unique
+ (implies (uniquep vars)
+ (uniquep (find-all-variables vars variables equations)))
+ :hints (("Goal"
+ :in-theory (disable subset-of-empty-is-empty))))
+)
+
+(local
+(defthm subset-remove-reduction
+ (equal (subset (remove-duplicate-occurrences x) y)
+ (subset x y)))
+)
+
+(local
+(defthm subset-set-intersect-reduction
+ (equal (subset (set-intersect (remove-duplicate-occurrences x) y) z)
+ (subset (set-intersect x y) z))
+ :hints (("Goal"
+ :in-theory (disable subset-of-empty-is-empty))))
+)
+
+;; And now check that we have done the trick.
+
+(local
+(defthm variables-are-subset-of-original
+ (implies (circuitp C)
+ (subset (cone-variables vars C)
+ (variables (create-kripke C))))
+ :hints (("Goal"
+ :in-theory (disable subset-of-nil-is-nil
+ subset-of-empty-is-empty)
+ :do-not-induct t)))
+)
+
+(local
+(defthm variables-are-subset-of-cone
+ (subset (cone-variables vars C)
+ (variables (create-kripke
+ (cone-of-influence-reduction C vars))))
+ :hints (("Goal"
+ :in-theory (disable cone-variables))))
+)
+
+;; OK, so we have proved that the vars are subset of variables. Let us now work
+;; on the initial states.
+
+(local
+(defthm evaluation-eq-subset-reduction
+ (implies (and (subset vars-prime vars)
+ (evaluation-eq p q vars))
+ (evaluation-eq p q vars-prime)))
+)
+
+(local
+(defthm evaluation-eq-member-subset-reduction
+ (implies (and (evaluation-eq-member-p init inits vars)
+ (subset vars-prime vars))
+ (evaluation-eq-member-p init inits vars-prime)))
+)
+
+(local
+(defthm evaluation-eq-subset-subset-reduction
+ (implies (and (evaluation-eq-subset-p inits states vars)
+ (subset vars-prime vars))
+ (evaluation-eq-subset-p inits states vars-prime)))
+)
+
+(local
+(defthm corresponding-states-are-evaluation-eq
+ (implies (uniquep vars)
+ (evaluation-eq init (corresponding-state init vars) vars)))
+)
+
+(local
+(defthm corresponding-state-is-member-of-corresponding-states
+ (implies (memberp init inits)
+ (memberp (corresponding-state init vars)
+ (corresponding-states inits vars))))
+)
+
+(local
+(defthm evaluation-eq-memberp-of-corresponding-states
+ (implies (and (uniquep vars)
+ (memberp init inits))
+ (evaluation-eq-member-p init (corresponding-states inits vars)
+ vars)))
+)
+
+(local
+(defthm evaluation-eq-subsets-reduction
+ (implies (uniquep vars)
+ (evaluation-eq-subset-p inits (corresponding-states inits vars)
+ vars)))
+)
+
+
+(local
+(defthm initial-states-are-evaluation-eq
+ (implies (circuitp C)
+ (evaluation-eq-subset-p
+ (initial-states (create-kripke C))
+ (initial-states
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (cone-variables vars C)))
+ :hints (("Goal"
+ :in-theory (disable subset-of-nil-is-nil
+ subset-of-empty-is-empty))))
+)
+
+(local
+(defthm corresponding-states-are-evaluation-eq-2
+ (implies (uniquep vars)
+ (evaluation-eq (corresponding-state init vars) init vars)))
+)
+
+(local
+(defthm evaluation-eq-memberp-of-corresponding-states-2
+ (implies (and (uniquep vars)
+ (memberp init (corresponding-states inits vars)))
+ (evaluation-eq-member-p init inits
+ vars)))
+)
+
+(local
+(defthm evaluation-eq-subsets-reduction-2
+ (implies (uniquep vars)
+ (evaluation-eq-subset-p (corresponding-states inits vars) inits
+ vars)))
+)
+
+(local
+(defthm initial-states-are-evaluation-eq-2
+ (implies (circuitp C)
+ (evaluation-eq-subset-p
+ (initial-states
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (initial-states (create-kripke C))
+ (cone-variables vars C))))
+)
+
+;; END of work on initial states.
+
+;; OK, now let us work on showing that cone-of-influence-reduction produces a
+;; circuit model. This will follow if the cone of influence reduction actually
+;; produces a circuit. We prove that in the lemmas below.
+
+;; We first prove that the initial states are only evaluations of the variables.
+
+(local
+(defthm initial-states-are-evaluations-p
+ (implies (and (evaluation-p p variables)
+ (subset vars variables)
+ (uniquep variables))
+ (evaluation-p (corresponding-state p vars) vars)))
+)
+
+(local
+(defthm corresponding-states-only-evaluations-p
+ (implies (and (only-evaluations-p init variables)
+ (subset vars variables)
+ (uniquep variables))
+ (only-evaluations-p (corresponding-states init vars) vars)))
+)
+
+(local
+(defthm initial-states-of-cone-of-influence-are-only-evaluations-p
+ (implies (circuitp C)
+ (only-evaluations-p
+ (initial-states
+ (cone-of-influence-reduction C vars))
+ (variables
+ (cone-of-influence-reduction C vars)))))
+)
+
+;; Next we work on strict-evaluation-list-p.
+
+(local
+(defthm not-memberp-to-corresponding-state
+ (implies (not (memberp v vars))
+ (not (<- (corresponding-state init vars) v))))
+)
+
+(local
+(defthm corresponding-state-strict-evaluation-p
+ (strict-evaluation-p (corresponding-state init vars) vars))
+)
+
+(local
+(in-theory (disable strict-evaluation-p))
+)
+
+(local
+(defthm initial-states-strict-evaluation-list-p
+ (strict-evaluation-list-p vars (corresponding-states inits vars)))
+)
+
+(local
+(defthm initial-cone-of-influence-states-are-strict-evaluation-list-p
+ (strict-evaluation-list-p
+ (variables
+ (cone-of-influence-reduction C vars))
+ (initial-states
+ (cone-of-influence-reduction C vars)))
+ :hints (("Goal"
+ :in-theory (disable cone-variables))))
+)
+
+(local
+(defthm variables-of-cone-are-unique-p
+ (implies (circuitp C)
+ (uniquep
+ (variables
+ (cone-of-influence-reduction C vars)))))
+)
+
+
+;; We come here to cons-list-p.
+
+
+(local
+(defun equation-equal-p (eqn-orig eqn-cone vars)
+ (if (endp vars) T
+ (and (equal (<- eqn-orig (first vars))
+ (<- eqn-cone (first vars)))
+ (equation-equal-p eqn-orig eqn-cone (rest vars)))))
+)
+
+(local
+(defthm cons-list-p-equation-equal-reduction
+ (implies (equation-equal-p eqn-orig eqn-cone vars)
+ (equal (cons-list-p vars eqn-cone)
+ (cons-list-p vars eqn-orig))))
+)
+
+(local
+(defthm find-equations-for-not-member-p
+ (implies (not (memberp v vars))
+ (equal (<- (find-all-equations vars equations eqn-rec) v)
+ (<- eqn-rec v))))
+)
+
+(local
+(defthm cons-list-p-subset-reduction
+ (implies (and (cons-list-p vars equations)
+ (subset vars-prime vars))
+ (cons-list-p vars-prime equations)))
+)
+
+(local
+(defthm equations-of-cone-and-orig-are-equal
+ (implies (uniquep vars)
+ (equation-equal-p equations
+ (find-all-equations
+ vars equations eqn-rec)
+ vars))
+ :hints (("Goal"
+ :induct (find-all-equations vars equations eqn-rec)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm equations-of-cone-are-cons-list-p
+ (implies (circuitp C)
+ (cons-list-p (variables
+ (cone-of-influence-reduction C vars))
+ (equations
+ (cone-of-influence-reduction C vars))))
+ :hints (("Goal"
+ :in-theory (disable find-all-equations find-all-variables
+ cons-list-p-equation-equal-reduction)
+ :use ((:instance cons-list-p-equation-equal-reduction
+ (eqn-orig (equations C))
+ (eqn-cone
+ (equations
+ (cone-of-influence-reduction C vars)))
+ (vars (variables
+ (cone-of-influence-reduction C vars))))))))
+)
+
+(local
+(defthm find-variables-variables*-reduction
+ (implies (memberp equation equations)
+ (subset (find-variables equation)
+ (find-variables* equations))))
+)
+
+(local
+(defthm find-variables-1-pass-reduction
+ (implies (and (memberp v vars)
+ (memberp equation (<- equations v)))
+ (subset (find-variables equation)
+ (find-all-variables-1-pass vars equations)))
+ :hints (("Subgoal *1/2"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :cases ((equal v (car vars))))
+ ("Subgoal *1/2.1"
+ :in-theory (disable find-variables-variables*-reduction)
+ :use ((:instance find-variables-variables*-reduction
+ (equations (<- equations (first vars)))))))
+ :rule-classes nil)
+)
+
+(local
+(defthm find-all-variables-computes-closure
+ (implies (and (memberp v (find-all-variables vars variables equations))
+ (uniquep variables)
+ (subset vars variables)
+ (uniquep vars)
+ (memberp equation (<- equations v)))
+ (subset (find-variables equation)
+ (find-all-variables vars variables equations)))
+ :hints (("Goal"
+ :induct (find-all-variables vars variables equations)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :in-theory (enable set-equal)
+ :use find-variables-1-pass-reduction)))
+)
+
+(local
+(in-theory (disable find-all-variables))
+)
+
+(local
+(defthm find-all-variables-is-equation-record-p
+ (implies (and (subset vars variables)
+ (uniquep vars)
+ (uniquep variables))
+ (consistent-equation-record-p
+ (find-all-variables vars variables equations)
+ equations))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable find-all-variables-computes-closure)
+ :use ((:instance (:definition consistent-equation-record-p)
+ (vars (find-all-variables vars variables
+ equations)))
+ (:instance find-all-variables-computes-closure
+ (v (mv-nth 0
+ (consistent-equation-record-p-witness
+ (find-all-variables vars variables
+ equations)
+ equations)))
+ (equation
+ (mv-nth 1
+ (consistent-equation-record-p-witness
+ (find-all-variables vars variables
+ equations)
+ equations))))))))
+)
+
+;; So we have proved that find-all-variables produces a consistent record for
+;; the original equations. Now we have to prove that if two equations are
+;; equation-equal-p, then they are consistent-equation-record-p at the same
+;; time.
+
+(local
+(in-theory (disable consistent-equation-record-p))
+)
+
+(local
+(defthm equation-equal-p-member-reduction
+ (implies (and (equation-equal-p eqn-orig eqn-cone vars)
+ (memberp v vars))
+ (equal (<- eqn-cone v)
+ (<- eqn-orig v))))
+)
+
+(local
+(defthm consistent-eqn-record-p-expanded
+ (implies (and (consistent-equation-record-p vars eqn-orig)
+ (uniquep vars)
+ (memberp v vars)
+ (memberp equation (<- eqn-orig v)))
+ (subset (find-variables equation)
+ vars))
+ :hints (("Goal"
+ :use ((:instance consistent-equation-record-p-necc
+ (equations eqn-orig))))))
+)
+
+(local
+(defthm equation-equal-p-to-consistent
+ (implies (and (equation-equal-p eqn-orig eqn-cone vars)
+ (uniquep vars)
+ (consistent-equation-record-p vars eqn-orig))
+ (consistent-equation-record-p vars eqn-cone))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable consistent-equation-record-p
+ consistent-equation-record-p-necc
+ mv-nth)
+ :expand (consistent-equation-record-p vars eqn-cone)
+ :use ((:instance consistent-equation-record-p-necc
+ (equation eqn-orig))))))
+)
+
+(local
+(in-theory (disable consistent-equation-record-p
+ consistent-equation-record-p-necc))
+)
+
+(local
+(defthm cone-of-influence-reduction-is-consistent
+ (implies (circuitp C)
+ (consistent-equation-record-p
+ (variables (cone-of-influence-reduction C vars))
+ (equations (cone-of-influence-reduction C vars))))
+ :hints (("Goal"
+ :use ((:instance equation-equal-p-to-consistent
+ (eqn-orig (equations C))
+ (eqn-cone
+ (equations (cone-of-influence-reduction C vars)))
+ (vars (variables (cone-of-influence-reduction C vars))))))))
+
+)
+
+(local
+(defthm cone-of-influence-reduction-is-circuit-p
+ (implies (circuitp C)
+ (circuitp (cone-of-influence-reduction C vars)))
+ :hints (("Goal"
+ :in-theory (disable circuitp cone-of-influence-reduction)
+ :expand (circuitp (cone-of-influence-reduction C vars)))))
+)
+
+(local
+(defthm cone-of-influence-reduction-produces-circuit-model
+ (implies (circuitp C)
+ (circuit-modelp (create-kripke (cone-of-influence-reduction C vars))))
+ :hints (("Goal"
+ :in-theory (disable circuitp circuit-modelp
+ create-kripke
+ cone-of-influence-reduction))))
+)
+
+;; OK, so the last thing we need to prove is that the transitions of m and n
+;; are well-formed-transition-p. That means that we have to prove that if two
+;; states are evaluation-eq with respect to vars, then the next states are
+;; evaluation-eq with respect to vars.
+
+;; For simplifying the project let us first start with original circuit and get
+;; to the cone of influence reduction.
+
+;; OK, so what do we need? Let us first prove that if r is in next-states of p,
+;; then there exists an equation consistent with equations that takes from p to
+;; r.
+
+;; We start with a couple of theorems about evaluation-eq
+
+(local
+(defthm evaluation-eq-is-reflexive
+ (evaluation-eq x x vars))
+)
+
+(local
+(defthm evaluation-eq-is-transitive
+ (implies (and (evaluation-eq p q vars)
+ (evaluation-eq q r vars))
+ (evaluation-eq p r vars)))
+)
+
+;; Now to the argument. If r is in next states of p, then there is an equation
+;; taking p to r.
+
+;; We first prove that r is a valid next state of p.
+
+(local
+(defthm next-state-member-implies-consistent-equation
+ (implies (memberp r (create-next-states-of-p p states vars equations))
+ (next-state-is-ok p r vars equations)))
+)
+
+;; Now if next-state-is-ok, then we know that there is a consistent equation
+;; that takes p to r.
+
+(local
+(defthm next-state-is-ok-to-consistent-p-equation
+ (implies (next-state-is-ok p r vars equations)
+ (consistent-p-equations
+ vars
+ (next-state-is-ok-witness p r vars equations)
+ equations)))
+)
+
+(local
+(defthm next-state-is-ok-p-to-actual
+ (implies (next-state-is-ok p r vars equations)
+ (evaluation-eq r (produce-next-state vars p
+ (next-state-is-ok-witness
+ p r vars equations))
+ vars)))
+)
+
+(local
+(defthm thus-r-is-evaluation-eq-to-s
+ (implies (and (next-state-is-ok p r vars-orig equations-orig)
+ (evaluation-eq (produce-next-state vars-orig p
+ (next-state-is-ok-witness p r vars-orig
+ equations-orig))
+ s
+ vars-cone)
+ (subset vars-cone vars-orig))
+ (evaluation-eq r s vars-cone))
+ :hints (("Goal"
+ :in-theory (disable next-state-is-ok-p-to-actual
+ evaluation-eq-subset-reduction
+ next-state-is-ok)
+ :do-not-induct t
+ :use ((:instance next-state-is-ok-p-to-actual
+ (vars vars-orig)
+ (equations equations-orig))
+ (:instance evaluation-eq-subset-reduction
+ (p r)
+ (q (PRODUCE-NEXT-STATE
+ VARS-ORIG P
+ (NEXT-STATE-IS-OK-WITNESS P R VARS-ORIG
+ EQUATIONS-ORIG)))
+ (vars vars-orig)
+ (vars-prime vars-cone))))))
+)
+
+;; Thus r is evaluation-eq with respect to s if we can show that
+;; produce-next-state produces something evaluation-eq to s. Now to show that
+;; this implies r is evaluation-eq-member-p of transition of q, we need to show
+;; that s is a member of states-cone and that there is a consistent equation
+;; with respect to cone that takes q to s. Let us see that this analysis is
+;; accurate.
+
+
+(local
+(defthm next-state-is-ok-from-consistent-eqn
+ (implies (and (consistent-p-equations vars eqn equations)
+ (evaluation-eq q (produce-next-state vars p eqn) vars))
+ (next-state-is-ok p q vars equations)))
+)
+
+(local
+(in-theory (disable next-state-is-ok))
+)
+
+(local
+(defthm memberp-of-next-state-from-consistent-equation
+ (implies (and (memberp s states-cone)
+ (next-state-is-ok q s vars-cone equations-cone))
+ (memberp s (create-next-states-of-p q states-cone vars-cone
+ equations-cone))))
+)
+
+(local
+(defthm memberp-not-using-next-states
+ (implies (and (memberp s states-cone)
+ (consistent-p-equations vars-cone eqn equations-cone)
+ (evaluation-eq s (produce-next-state vars-cone q eqn) vars-cone))
+ (memberp s (create-next-states-of-p q states-cone vars-cone equations-cone))))
+)
+
+;; OK, so now, how do we show that s is a member of states? This is because
+;; states are all-evaluations-p, and s is an evaluation-p as we will see.
+
+
+(local
+(defthm member-of-next-states-from-all-evaluations-p
+ (implies (and (all-evaluations-p states-cone vars-cone)
+ (evaluation-p s vars-cone)
+ (consistent-p-equations vars-cone eqn equations-cone)
+ (evaluation-eq s (produce-next-state vars-cone q eqn) vars-cone))
+ (memberp
+ (evaluation-eq-member s states-cone vars-cone)
+ (create-next-states-of-p q states-cone vars-cone equations-cone)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable memberp-not-using-next-states)
+ :use ((:instance memberp-not-using-next-states
+ (s (evaluation-eq-member s states-cone vars-cone)))
+ (:instance evaluation-eq-is-symmetric
+ (p s)
+ (q (evaluation-eq-member s states-cone vars-cone))
+ (vars vars-cone))))))
+)
+
+(local
+(defthm evaluation-eq-and-memberp-to-evaluation-eq-memberp
+ (implies (and (memberp q states)
+ (evaluation-eq p q vars))
+ (evaluation-eq-member-p p states vars)))
+)
+
+(defthm evaluation-eq-memberp-from-all-evaluations-p
+ (implies (and (all-evaluations-p states-cone vars-cone)
+ (evaluation-p s vars-cone)
+ (consistent-p-equations vars-cone eqn equations-cone)
+ (evaluation-eq s (produce-next-state vars-cone q eqn)
+ vars-cone))
+ (evaluation-eq-member-p
+ s (create-next-states-of-p q states-cone vars-cone equations-cone)
+ vars-cone))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable
+ evaluation-eq-and-memberp-to-evaluation-eq-memberp)
+ :use ((:instance evaluation-eq-and-memberp-to-evaluation-eq-memberp
+ (q (evaluation-eq-member s states-cone vars-cone))
+ (p s)
+ (vars vars-cone)
+ (states (create-next-states-of-p
+ q states-cone vars-cone
+ equations-cone)))))))
+
+(local
+(defthm evaluation-eq-and-memberp-to-memberp
+ (implies (and (evaluation-eq p q vars)
+ (evaluation-eq-member-p q states vars))
+ (evaluation-eq-member-p p states vars)))
+)
+
+(local
+(defthm next-state-of-orig-to-evaluation-eq-member-p
+ (implies (and (memberp r (create-next-states-of-p p states-orig vars-orig
+ equations-orig))
+ (evaluation-eq (produce-next-state vars-orig p
+ (next-state-is-ok-witness p r vars-orig
+ equations-orig))
+ s
+ vars-cone)
+ (subset vars-cone vars-orig)
+ (all-evaluations-p states-cone vars-cone)
+ (evaluation-p s vars-cone)
+ (consistent-p-equations vars-cone eqn equations-cone)
+ (evaluation-eq s (produce-next-state vars-cone q eqn)
+ vars-cone))
+ (evaluation-eq-member-p
+ r (create-next-states-of-p q states-cone vars-cone equations-cone)
+ vars-cone))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable thus-r-is-evaluation-eq-to-s)
+ :use thus-r-is-evaluation-eq-to-s)))
+)
+
+;; The theorem above guarantees that if we can get an s and an eqn with the
+;; properties mentioned then we will be done. Our choice of s is
+;; (produce-next-state vars-cone q eqn). Hence the only thing to prove is that
+;; we can get a corresponding equation for s.
+
+(local
+(defun create-corresponding-equation (vars equation-record vars-prime eqn eq-rec)
+ (if (endp vars) eq-rec
+ (-> (create-corresponding-equation (rest vars) equation-record vars-prime
+ eqn eq-rec)
+ (first vars)
+ (if (memberp (first vars) vars-prime)
+ (<- eqn (first vars))
+ (first (<- equation-record (first vars)))))))
+)
+
+;; OK, so why is this equation consistent with the cone? The argument is that
+;; the cone of influence is well-formed-equation-record-p, and equation-equal-p
+;; with respect to the variables of the cone.
+
+(local
+(defthm equation-equal-to-set-reduction
+ (implies (not (memberp v vars))
+ (equal (equation-equal-p eqn-orig (-> eqn-cone v a) vars)
+ (equation-equal-p eqn-orig eqn-cone vars))))
+)
+
+(local
+(defthm create-corresponding-equation-is-equation-equal
+ (implies (and (subset vars-cone vars-orig)
+ (uniquep vars-cone))
+ (equation-equal-p eqn-orig (create-corresponding-equation
+ vars-cone eqn-cone
+ vars-orig eqn-orig eq-rec)
+
+ vars-cone)))
+)
+
+(local
+(defthm cons-consistent-eqn
+ (implies (and (consistent-p-equations vars eqn equation-record)
+ (memberp equation (<- equation-record v)))
+ (consistent-p-equations (cons v vars) (-> eqn v equation)
+ equation-record))
+ :hints (("Subgoal *1/4"
+ :cases ((equal v (car vars))))))
+)
+
+(local
+(defthm consistent-p-equation-memberp-reduction
+ (implies (and (consistent-p-equations vars eqn equations)
+ (memberp v vars))
+ (memberp (<- eqn v) (<- equations v))))
+)
+
+(local
+(defthm consistent-set-not-member
+ (implies (not (memberp v vars))
+ (equal (consistent-p-equations vars (-> eqn v a) equations)
+ (consistent-p-equations vars eqn equations))))
+)
+
+(local
+(defthm equation-equal-p-to-consistent-equation
+ (implies (and (equation-equal-p eqn-orig eqn-cone vars)
+ (consistent-p-equations vars eqn eqn-orig))
+ (consistent-p-equations vars eqn eqn-cone)))
+)
+
+(local
+(defthm consistent-p-equations-to-consistent-p-equations
+ (implies (and (consistent-p-equations vars-orig eqn eqn-orig)
+ (cons-list-p vars-cone eqn-cone)
+ (equation-equal-p eqn-orig eqn-cone vars-cone)
+ (uniquep vars-orig)
+ (uniquep vars-cone))
+ (consistent-p-equations
+ vars-cone
+ (create-corresponding-equation vars-cone eqn-cone vars-orig eqn
+ eq-rec)
+ eqn-cone))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (create-corresponding-equation vars-cone eqn-cone
+ vars-orig eqn eq-rec)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+;; OK so now we have created an equation eqn that is consistent with respect to
+;; the cone. So the final proof requirement is that s is evaluation-eq to the
+;; application of this equation.
+
+(local
+(defun closed-eqn-record-p (eqn vars vars-prime)
+ (if (endp vars) T
+ (and (subset (find-variables (<- eqn (first vars))) vars-prime)
+ (closed-eqn-record-p eqn (rest vars) vars-prime))))
+)
+
+;; This predicate ensures that the variables of eqn are subsets of
+;; vars-prime. Now let us show that this notion follows from equation-record-p.
+
+(local
+(defthm closed-eqn-record-p-from-consistent-equation-record-p
+ (implies (and (consistent-equation-record-p vars-prime equations)
+ (uniquep vars-prime)
+ (subset vars vars-prime)
+ (consistent-p-equations vars eqn equations))
+ (closed-eqn-record-p eqn vars vars-prime))
+ :hints (("Subgoal *1/5"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+;; And thus, by concretizing it, we have the following theorem:
+
+(local
+(defthm closed-eqn-record-p-true-concretized
+ (implies (and (consistent-equation-record-p vars equations)
+ (uniquep vars)
+ (consistent-p-equations vars eqn equations))
+ (closed-eqn-record-p eqn vars vars)))
+)
+
+(local
+(defthm apply-equation-produces-equal
+ (implies (and (evaluation-p p vars)
+ (evaluation-p q vars)
+ (subset (find-variables equation) vars)
+ (evaluation-eq p q vars))
+ (equal (apply-equation equation p)
+ (apply-equation equation q)))
+ :hints (("Goal"
+ :induct (apply-equation equation p))))
+)
+
+(local
+(defthm produce-next-state-not-memberp-vars-reduction
+ (implies (not (memberp v vars))
+ (equal (<- (produce-next-state vars p equations) v)
+ (<- p v))))
+)
+
+(local
+(defthm produce-next-state-vars-reduction
+ (implies (and (memberp v vars)
+ (uniquep vars))
+ (equal (<- (produce-next-state vars p equations) v)
+ (apply-equation (<- equations v) p))))
+)
+
+(local
+(defthm evaluation-eq-set-reduction
+ (implies (and (evaluation-eq p q vars)
+ (not (memberp v vars)))
+ (evaluation-eq (-> p v a) (-> q v b) vars)))
+)
+
+(local
+(defthm produce-next-state-is-evaluation-eq
+ (implies (and (evaluation-p p vars-prime)
+ (uniquep vars-prime)
+ (evaluation-p q vars-prime)
+ (uniquep vars-prime)
+ (uniquep vars)
+ (subset vars vars-prime)
+ (evaluation-eq p q vars-prime)
+ (closed-eqn-record-p eqn-cone vars vars-prime)
+ (equation-equal-p eqn-orig eqn-cone vars))
+ (evaluation-eq
+ (produce-next-state vars p eqn-orig)
+ (produce-next-state vars q eqn-cone)
+ vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable apply-equation-produces-equal))
+ ("Subgoal *1/6"
+ :use ((:instance apply-equation-produces-equal
+ (vars vars-prime)
+ (equation (<- eqn-cone (first vars))))))))
+)
+
+(local
+(defthm produce-next-state-is-evaluation-eq-concretized
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (uniquep vars-cone)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (consistent-p-equations vars-cone eqn-cone equations-cone)
+ (equation-equal-p eqn-orig eqn-cone vars-cone))
+ (evaluation-eq
+ (produce-next-state vars-cone p eqn-orig)
+ (produce-next-state vars-cone q eqn-cone)
+ vars-cone)))
+)
+
+(local
+(defthm produce-next-state-evaluation-eq-reduction
+ (implies (and (uniquep vars-orig)
+ (uniquep vars-cone)
+ (subset vars-cone vars-orig))
+ (evaluation-eq (produce-next-state vars-orig p eqn-orig)
+ (produce-next-state vars-cone p eqn-orig)
+ vars-cone)))
+)
+
+(local
+(defthm produce-next-state-fully-concretized
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (subset vars-cone vars-orig)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (consistent-p-equations vars-cone eqn-cone equations-cone)
+ (equation-equal-p eqn-orig eqn-cone vars-cone))
+ (evaluation-eq (produce-next-state vars-orig p eqn-orig)
+ (produce-next-state vars-cone q eqn-cone)
+ vars-cone))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable evaluation-eq-is-transitive
+ produce-next-state-is-evaluation-eq-concretized)
+ :use ((:instance produce-next-state-is-evaluation-eq-concretized)
+ (:instance evaluation-eq-is-transitive
+ (p (produce-next-state vars-orig p eqn-orig))
+ (q (produce-next-state vars-cone p eqn-orig))
+ (r (produce-next-state vars-cone q eqn-cone))
+ (vars vars-cone))))))
+)
+
+(local
+(defthm produce-next-state-for-equation-of-choice
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (cons-list-p vars-cone equations-cone)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-p-equations vars-orig eqn-orig equations-orig)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (subset vars-cone vars-orig))
+ (evaluation-eq
+ (produce-next-state vars-orig p eqn-orig)
+ (produce-next-state
+ vars-cone q
+ (create-corresponding-equation
+ vars-cone equations-cone vars-orig eqn-orig eq-rec))
+ vars-cone)))
+)
+
+(local
+(in-theory (disable apply-equation-produces-equal))
+)
+
+(local
+(defthm boolean-p-apply-equation
+ (implies (and (evaluation-p p vars)
+ (subset (find-variables equation) vars))
+ (booleanp (apply-equation equation p)))
+ :hints (("Goal"
+ :induct (apply-equation equation p))))
+)
+
+(local
+(defthm evaluation-p-set-reduction
+ (implies (and (booleanp a)
+ (evaluation-p p vars))
+ (evaluation-p (-> p v a) vars))
+ :hints (("Subgoal *1/4"
+ :cases ((equal v (car vars))))))
+)
+
+(local
+(defthm produce-next-state-is-evaluation-p
+ (implies (and (evaluation-p p vars-prime)
+ (subset vars vars-prime)
+ (uniquep vars)
+ (uniquep vars-prime)
+ (closed-eqn-record-p eqn vars vars-prime))
+ (evaluation-p (produce-next-state vars p eqn) vars-prime)))
+)
+
+(local
+(defthm next-state-is-evaluation-p-concretized
+ (implies (and (evaluation-p p vars)
+ (uniquep vars)
+ (consistent-equation-record-p vars equations)
+ (consistent-p-equations vars eqn equations))
+ (evaluation-p (produce-next-state vars p eqn) vars)))
+)
+
+(local
+(defthm r-is-evaluation-eq-member-p-with-respect-to-states
+ (implies (and (memberp r (create-next-states-of-p p states-orig vars-orig
+ equations-orig))
+ (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (evaluation-p p vars-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-cone equations-cone)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-member-p
+ r (create-next-states-of-p q states-cone vars-cone equations-cone)
+ vars-cone))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable next-state-of-orig-to-evaluation-eq-member-p)
+ :use ((:instance next-state-of-orig-to-evaluation-eq-member-p
+ (s (produce-next-state vars-orig p
+ (next-state-is-ok-witness p r vars-orig
+ equations-orig)))
+ (eqn (create-corresponding-equation
+ vars-cone equations-cone vars-orig
+ (next-state-is-ok-witness p r vars-orig
+ equations-orig)
+ eq-rec)))))
+ ("Subgoal 2"
+ :in-theory (disable evaluationp-for-subset
+ next-state-is-evaluation-p-concretized)
+ :use ((:instance next-state-is-evaluation-p-concretized
+ (eqn (next-state-is-ok-witness
+ p r vars-orig equations-orig))
+ (equations equations-orig)
+ (vars vars-orig))
+ (:instance evaluationp-for-subset
+ (st (PRODUCE-NEXT-STATE
+ VARS-ORIG P
+ (NEXT-STATE-IS-OK-WITNESS P R VARS-ORIG
+ EQUATIONS-ORIG)))
+ (variables vars-orig)
+ (vars vars-cone))))
+ ("Subgoal 1"
+ :in-theory (disable
+ consistent-p-equations-to-consistent-p-equations)
+ :use ((:instance consistent-p-equations-to-consistent-p-equations
+ (eqn-orig equations-orig)
+ (eqn-cone equations-cone)
+ (eqn (next-state-is-ok-witness p r vars-orig
+ equations-orig)))))))
+
+)
+
+(local
+(defthm evaluation-eq-subset-p-orig->cone
+ (implies (and (subset l (create-next-states-of-p p states-orig vars-orig
+ equations-orig))
+ (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (evaluation-p p vars-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-cone equations-cone)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-subset-p
+ l (create-next-states-of-p q states-cone vars-cone equations-cone)
+ vars-cone)))
+)
+
+(local
+(defthm evaluation-eq-subset-orig->cone-concretized
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (only-evaluations-p states-orig vars-orig)
+ (memberp p states-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-cone equations-cone)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-subset-p
+ (create-next-states-of-p p states-orig vars-orig
+ equations-orig)
+ (create-next-states-of-p q states-cone vars-cone equations-cone)
+ vars-cone))
+ :hints (("Goal"
+ :in-theory (disable evaluation-eq-subset-p-orig->cone)
+ :use ((:instance evaluation-eq-subset-p-orig->cone
+ (l (create-next-states-of-p p states-orig vars-orig
+ equations-orig)))))))
+)
+
+(local
+(defthm equation-equal-is-symmetric
+ (equal (equation-equal-p eqn-orig eqn-cone vars)
+ (equation-equal-p eqn-cone eqn-orig vars))
+ :rule-classes nil)
+)
+
+(local
+(defthm equation-equal-to-set-reduction-2
+ (implies (not (memberp v vars))
+ (equal (equation-equal-p (-> eqn-orig v a) eqn-cone vars)
+ (equation-equal-p eqn-orig eqn-cone vars))))
+)
+
+(local
+(defthm memberp-to-create-equation-reduction
+ (implies (and (memberp v vars-cone)
+ (memberp v vars-orig))
+ (equal (<- (create-corresponding-equation vars-orig eqn-orig
+ vars-cone eqn-cone
+ eq-rec)
+ v)
+ (<- eqn-cone v)))
+ :hints (("Subgoal *1/3.2"
+ :cases ((equal v (car vars-orig))))))
+)
+
+(local
+(defthm not-memberp-to-create-equation
+ (implies (not (memberp v vars-orig))
+ (equal (<- (create-corresponding-equation vars-orig eqn-orig
+ vars-cone eqn-cone eq-rec)
+ v)
+ (<- eq-rec v))))
+)
+
+(local
+(defthm memberp-equation-reduction-2
+ (implies (and (not (memberp v vars-cone))
+ (memberp v vars-orig))
+ (equal (<- (create-corresponding-equation vars-orig eqn-orig
+ vars-cone eqn-cone eq-rec)
+ v)
+ (first (<- eqn-orig v))))
+ :hints (("Subgoal *1/3"
+ :cases ((equal v (car vars-orig))))))
+)
+
+(local
+(defthm create-corresponding-equation-is-equation-equal-2
+ (implies (and (subset vars-cone vars-orig)
+ (subset vars vars-cone)
+ (uniquep vars-orig)
+ (uniquep vars-cone))
+ (equation-equal-p (create-corresponding-equation
+ vars-orig eqn-orig
+ vars-cone eqn-cone eq-rec)
+ eqn-cone vars))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize))))
+)
+
+(local
+(defthm produce-next-state-for-equation-of-choice-2
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (cons-list-p vars-orig equations-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-p-equations vars-cone eqn-cone equations-cone)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig))
+ (evaluation-eq
+ (produce-next-state
+ vars-orig p
+ (create-corresponding-equation
+ vars-orig equations-orig vars-cone eqn-cone eq-rec))
+ (produce-next-state vars-cone q eqn-cone)
+ vars-cone)))
+)
+
+(local
+(defthm and-thus-for-vars-cone
+ (implies (and (all-evaluations-p states-orig vars-orig)
+ (evaluation-p r vars-orig)
+ (subset vars-cone vars-orig)
+ (consistent-p-equations vars-orig eqn equations-orig)
+ (evaluation-eq r (produce-next-state vars-orig p eqn)
+ vars-orig))
+ (evaluation-eq-member-p
+ r (create-next-states-of-p p states-orig vars-orig equations-orig)
+ vars-cone))
+ :hints (("Goal"
+ :in-theory (disable evaluation-eq-member-subset-reduction)
+ :use ((:instance evaluation-eq-member-subset-reduction
+ (init r)
+ (vars vars-orig)
+ (vars-prime vars-cone)
+ (inits (create-next-states-of-p
+ p states-orig vars-orig
+ equations-orig)))))))
+)
+
+(local
+(defthm thus-r-is-evaluation-eq-to-s-2
+ (implies (and (next-state-is-ok q s vars-cone equations-cone)
+ (evaluation-eq (produce-next-state
+ vars-cone q
+ (next-state-is-ok-witness q s vars-cone
+ equations-cone))
+ r
+
+ vars-cone))
+ (evaluation-eq s r vars-cone))
+ :rule-classes nil)
+)
+
+;; and then suitably polish it
+
+
+(local
+(defthm thus-polished-r-is-evaluation-eq-to-s-2
+ (implies (and (memberp s (create-next-states-of-p q states-cone vars-cone
+ equations-cone))
+ (evaluation-eq r (produce-next-state
+ vars-cone q
+ (next-state-is-ok-witness
+ q s vars-cone equations-cone))
+ vars-cone))
+ (evaluation-eq r s vars-cone))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable next-state-is-ok
+ next-state-member-implies-consistent-equation)
+ :use ((:instance next-state-member-implies-consistent-equation
+ (p q)
+ (r s)
+ (vars vars-cone)
+ (states states-cone)
+ (equations equations-cone))
+ (:instance thus-r-is-evaluation-eq-to-s-2)
+ (:instance evaluation-eq-is-symmetric
+ (p r)
+ (q s)
+ (vars vars-cone))
+ (:instance evaluation-eq-is-symmetric
+ (p r)
+ (vars vars-cone)
+ (q (produce-next-state
+ vars-cone q
+ (next-state-is-ok-witness
+ q s vars-cone equations-cone))))))))
+)
+
+(local
+(defthm evaluation-eq-member-p-from-memberp
+ (implies (and (evaluation-eq s r vars)
+ (evaluation-eq-member-p r states vars))
+ (evaluation-eq-member-p s states vars)))
+)
+
+(local
+(defthm next-state-of-orig-to-evaluation-eq-member-p-2
+ (implies (and (memberp s (create-next-states-of-p q states-cone vars-cone
+ equations-cone))
+ (evaluation-eq r (produce-next-state
+ vars-cone q
+ (next-state-is-ok-witness q s vars-cone
+ equations-cone))
+ vars-cone)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (subset vars-cone vars-orig)
+ (all-evaluations-p states-orig vars-orig)
+ (evaluation-p r vars-orig)
+ (consistent-p-equations vars-orig eqn equations-orig)
+ (evaluation-eq r (produce-next-state vars-orig p eqn)
+ vars-orig))
+ (evaluation-eq-member-p
+ s (create-next-states-of-p p states-orig vars-orig equations-orig)
+ vars-cone))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable ;; produce-next-state-evaluation-eq-reduction
+ and-thus-for-vars-cone
+ thus-polished-r-is-evaluation-eq-to-s-2)
+ :use ((:instance thus-polished-r-is-evaluation-eq-to-s-2)
+ (:instance and-thus-for-vars-cone)
+ (:instance evaluation-eq-is-symmetric
+ (p r)
+ (q s)
+ (vars vars-cone))))))
+)
+
+(local
+(defthm consistent-p-equations-to-consistent-p-equations-2
+ (implies (and (consistent-p-equations vars-cone eqn equations-cone)
+ (cons-list-p vars-orig equations-orig)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (uniquep vars-orig)
+ (uniquep vars-cone))
+ (consistent-p-equations
+ vars-orig
+ (create-corresponding-equation
+ vars-orig equations-orig vars-cone eqn eqn-rec)
+ equations-orig))
+ :hints (("Goal"
+ :induct (create-corresponding-equation
+ vars-orig equations-orig vars-cone eqn eqn-rec)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :use ((:instance consistent-p-equation-memberp-reduction
+ (vars vars-cone)
+ (v (car vars-orig))
+ (equations equations-cone))))))
+)
+
+(local
+(defthm next-state-cone->orig-thus-settled
+ (implies (and (memberp s (create-next-states-of-p q states-cone vars-cone
+ equations-cone))
+ (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (evaluation-p p vars-orig)
+ (evaluation-p q vars-cone)
+ (all-evaluations-p states-orig vars-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-orig equations-orig)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-member-p
+ s (create-next-states-of-p p states-orig vars-orig equations-orig)
+ vars-cone))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable
+ consistent-p-equations-to-consistent-p-equations-2
+ next-state-of-orig-to-evaluation-eq-member-p-2)
+ :use ((:instance next-state-of-orig-to-evaluation-eq-member-p-2
+ (r (produce-next-state
+ vars-orig p
+ (create-corresponding-equation
+ vars-orig equations-orig vars-cone
+ (next-state-is-ok-witness q s vars-cone
+ equations-cone)
+ eq-rec)))
+ (eqn (create-corresponding-equation
+ vars-orig equations-orig vars-cone
+ (next-state-is-ok-witness q s vars-cone
+ equations-cone)
+ eq-rec)))
+ (:instance next-state-is-evaluation-p-concretized
+ (vars vars-orig)
+ (equations equations-orig)
+ (eqn (create-corresponding-equation
+ vars-orig equations-orig vars-cone
+ (next-state-is-ok-witness q s vars-cone
+ equations-cone)
+ eq-rec)))
+ (:instance consistent-p-equations-to-consistent-p-equations-2
+ (eqn-rec eq-rec)
+ (eqn (next-state-is-ok-witness q s vars-cone
+ equations-cone)))))))
+
+)
+
+(local
+(defthm next-state-cone->orig-concretized
+ (implies (and (subset l (create-next-states-of-p q states-cone vars-cone
+ equations-cone))
+ (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (evaluation-p p vars-orig)
+ (evaluation-p q vars-cone)
+ (all-evaluations-p states-orig vars-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-orig equations-orig)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-subset-p
+ l (create-next-states-of-p p states-orig vars-orig equations-orig)
+ vars-cone)))
+)
+
+(local
+(defthm and-fully-concretized-cone->orig
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (only-evaluations-p states-orig vars-orig)
+ (only-evaluations-p states-cone vars-cone)
+ (memberp p states-orig)
+ (memberp q states-cone)
+ (evaluation-p q vars-cone)
+ (all-evaluations-p states-orig vars-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-orig equations-orig)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-subset-p
+ (create-next-states-of-p q states-cone vars-cone
+ equations-cone)
+ (create-next-states-of-p p states-orig vars-orig equations-orig)
+ vars-cone))
+ :hints (("Goal"
+ :in-theory (disable next-state-cone->orig-concretized)
+ :use ((:instance next-state-cone->orig-concretized
+ (l (create-next-states-of-p q states-cone vars-cone
+ equations-cone)))))))
+)
+
+(local
+(in-theory (disable create-next-states-of-p))
+)
+
+(local
+(defthm not-member-p-to-next-states
+ (implies (not (memberp p states))
+ (equal (<- (create-next-states states states-prime vars equations)
+ p)
+ nil)))
+)
+
+(local
+(defthm create-next-states-to-next-state-of-p
+ (implies (memberp p states)
+ (equal (<- (create-next-states states states-prime vars equations)
+ p)
+ (create-next-states-of-p p states-prime vars equations)))
+ :hints (("Subgoal *1/3"
+ :cases ((equal p (car states))))))
+)
+
+(local
+(defthm well-formed-transition-p-aux-orig->cone
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (only-evaluations-p states-orig vars-orig)
+ (memberp p states-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-cone equations-cone)
+ (memberp q states-cone)
+ (only-evaluations-p states-cone vars-cone)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-subset-p
+ (<- (create-next-states states-orig states-orig vars-orig
+ equations-orig)
+ P)
+ (<- (create-next-states states-cone states-cone vars-cone
+ equations-cone)
+ Q)
+ vars-cone)))
+)
+
+(local
+(defthm well-formed-transition-p-aux-cone->orig
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq p q vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (only-evaluations-p states-orig vars-orig)
+ (only-evaluations-p states-cone vars-cone)
+ (memberp p states-orig)
+ (memberp q states-cone)
+ (evaluation-p q vars-cone)
+ (all-evaluations-p states-orig vars-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-orig equations-orig)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-subset-p
+ (<- (create-next-states states-cone states-cone vars-cone
+ equations-cone)
+ q)
+ (<- (create-next-states states-orig states-orig vars-orig
+ equations-orig)
+ p)
+ vars-cone)))
+)
+
+(local
+(defthm well-formed-transition-p-aux-cone->orig-concretized
+ (implies (and (evaluation-p p vars-cone)
+ (evaluation-p q vars-cone)
+ (evaluation-eq q p vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (subset vars-cone vars-orig)
+ (only-evaluations-p states-orig vars-orig)
+ (only-evaluations-p states-cone vars-cone)
+ (memberp p states-orig)
+ (memberp q states-cone)
+ (evaluation-p q vars-cone)
+ (all-evaluations-p states-orig vars-orig)
+ (uniquep vars-orig)
+ (uniquep vars-cone)
+ (cons-list-p vars-orig equations-orig)
+ (equation-equal-p equations-orig equations-cone vars-cone)
+ (consistent-equation-record-p vars-orig equations-orig)
+ (consistent-equation-record-p vars-cone equations-cone)
+ (all-evaluations-p states-cone vars-cone))
+ (evaluation-eq-subset-p
+ (<- (create-next-states states-cone states-cone vars-cone
+ equations-cone)
+ q)
+ (<- (create-next-states states-orig states-orig vars-orig
+ equations-orig)
+ p)
+ vars-cone))
+ :hints (("Goal"
+ :in-theory (disable and-fully-concretized-cone->orig
+ evaluation-eq-subset-p
+ evaluation-eq-member-p
+ next-state-cone->orig-concretized
+ well-formed-transition-p-aux-cone->orig)
+ :use ((:instance well-formed-transition-p-aux-cone->orig)
+ (:instance evaluation-eq-is-symmetric
+ (vars vars-cone))))))
+)
+
+(local
+(in-theory (disable create-all-evaluations find-all-variables
+ only-evaluations-p
+ all-evaluations-p
+ strict-evaluation-p
+ only-all-truths-p
+ label-subset-vars
+ transition-subset-p
+ next-states-in-states
+ cons-list-p
+ consistent-equation-record-p
+ uniquep
+ subset
+ find-all-equations create-label-fn))
+)
+
+(local
+(in-theory (enable well-formed-transition-p))
+)
+
+(local
+(defthm orig-cone-cone-is-well-formed-transition-p
+ (implies (circuitp C)
+ (well-formed-transition-p
+ (states (create-kripke C))
+ (transition (create-kripke C))
+ (states
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (transition
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (cone-variables vars C)))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize fertilize)
+ :do-not-induct t
+ :in-theory (disable well-formed-transition-p-aux-orig->cone
+ create-kripke-produces-circuit-model)
+ :use ((:instance well-formed-transition-p-aux-orig->cone
+ (states-orig (states (create-kripke C)))
+ (states-cone (states
+ (create-kripke
+ (cone-of-influence-reduction
+ C vars))))
+ (vars-orig (variables C))
+ (vars-cone (variables
+ (cone-of-influence-reduction C vars)))
+ (equations-orig (equations C))
+ (equations-cone (equations
+ (cone-of-influence-reduction C
+ vars)))
+ (p (car (well-formed-transition-p-witness
+ (states (create-kripke C))
+ (transition (create-kripke C))
+ (states (create-kripke
+ (cone-of-influence-reduction C
+ vars)))
+ (transition
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (variables (cone-of-influence-reduction C
+ vars)))))
+ (q (mv-nth 1
+ (well-formed-transition-p-witness
+ (states (create-kripke C))
+ (transition (create-kripke C))
+ (states (create-kripke
+ (cone-of-influence-reduction C
+ vars)))
+ (transition
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (variables (cone-of-influence-reduction C
+ vars))))))
+ (:instance create-kripke-produces-circuit-model)
+ (:instance create-kripke-produces-circuit-model
+ (C (cone-of-influence-reduction C vars)))
+ (:instance cone-of-influence-reduction-is-circuit-p)))))
+)
+
+(local
+(defthm cone-orig-is-well-formed-transition-p
+ (implies (circuitp C)
+ (well-formed-transition-p
+ (states
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (transition
+ (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (states (create-kripke C))
+ (transition (create-kripke C))
+ (cone-variables vars C)))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize fertilize)
+ :do-not-induct t
+ :in-theory (disable well-formed-transition-p-aux-orig->cone
+ create-kripke-produces-circuit-model)
+ :use ((:instance well-formed-transition-p-aux-cone->orig-concretized
+ (states-orig (states (create-kripke C)))
+ (states-cone (states
+ (create-kripke
+ (cone-of-influence-reduction
+ C vars))))
+ (vars-orig (variables C))
+ (vars-cone (variables
+ (cone-of-influence-reduction C vars)))
+ (equations-orig (equations C))
+ (equations-cone (equations
+ (cone-of-influence-reduction C
+ vars)))
+ (q (car (well-formed-transition-p-witness
+ (states (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (transition (create-kripke
+ (cone-of-influence-reduction
+ C vars)))
+ (states (create-kripke C))
+ (transition (create-kripke C))
+
+ (variables (cone-of-influence-reduction C
+ vars)))))
+ (p (mv-nth 1
+ (well-formed-transition-p-witness
+ (states (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (transition (create-kripke
+ (cone-of-influence-reduction
+ C vars)))
+ (states (create-kripke C))
+ (transition (create-kripke C))
+ (variables (cone-of-influence-reduction C
+ vars))))))
+
+ (:instance create-kripke-produces-circuit-model)
+ (:instance create-kripke-produces-circuit-model
+ (C (cone-of-influence-reduction C vars)))
+ (:instance cone-of-influence-reduction-is-circuit-p)))))
+)
+
+(local
+(in-theory (disable well-formed-transition-p create-kripke
+ cone-of-influence-reduction
+ ltl-semantics
+ cone-variables
+ circuit-modelp circuitp))
+)
+
+(local
+(defthm cone-of-influence-is-c-bisimi-equiv
+ (implies (circuitp C)
+ (c-bisim-equiv (create-kripke C)
+ (create-kripke (cone-of-influence-reduction C vars))
+ (cone-variables vars C))))
+)
+
+(local
+(in-theory (disable c-bisim-equiv))
+)
+
+(local
+(defthm restricted-formula-of-vars-is-also-true-for-subset
+ (implies (and (restricted-formulap f vars)
+ (subset vars vars-prime))
+ (restricted-formulap f vars-prime)))
+)
+
+(DEFTHM cone-of-influence-reduction-is-sound
+ (implies (and (restricted-formulap f (cone-variables vars C))
+ (circuitp C))
+ (equal (ltl-semantics f
+ (create-kripke (cone-of-influence-reduction C
+ vars)))
+ (ltl-semantics f (create-kripke C))))
+ :hints (("Goal"
+ :in-theory (disable restricted-formulap
+ circuit-bisim-implies-same-ltl-semantics)
+ :use ((:instance circuit-bisim-implies-same-ltl-semantics
+ (n (create-kripke (cone-of-influence-reduction C
+ vars)))
+ (m (create-kripke C))
+ (vars (cone-variables vars C)))))))
+
+;; So we are done. Let us prove a couple of handy theorems.
+
+(DEFTHM cone-of-influence-reduction-is-sound-generalized
+ (implies (and (subset interesting-vars (cone-variables vars C))
+ (circuitp C)
+ (restricted-formulap f interesting-vars))
+ (equal (ltl-semantics f (create-kripke
+ (cone-of-influence-reduction C vars)))
+ (ltl-semantics f (create-kripke C)))))
+
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/conjunction.lisp b/books/workshops/2003/ray-matthews-tuttle/support/conjunction.lisp
new file mode 100644
index 0000000..b349a0d
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/conjunction.lisp
@@ -0,0 +1,99 @@
+(in-package "ACL2")
+
+#|
+
+ conjunction.lisp
+ ~~~~~~~~~~~~~~~~
+
+In this book, we prove the theorems on conjunctive reductions of LTL
+formula. In particular, we prove that if an ltl-formula f is the conjunction of
+formuals f1 and f2, then the semantics of f with respect to a model m will be
+the conjunction of semantics of f1 and f2 wrt m.
+
+|#
+
+
+(include-book "ltl")
+
+(local
+(defthm ltl-conjunction-reduction-1
+ (implies (and (ltl-formulap f)
+ (equal (len f) 3)
+ (equal (second f) '&)
+ (ltl-semantics (first f) m)
+ (ltl-semantics (third f) m))
+ (ltl-semantics f m))
+ :hints (("Goal"
+ :in-theory (disable compatible-ppath-p)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :cases ((compatible-ppath-p (ltl-semantics-witness
+ f m) m)))))
+
+)
+
+(local
+(defthm ltl-conjunction-reduction-2
+ (implies (and (ltl-formulap f)
+ (equal (len f) 3)
+ (equal (second f) '&)
+ (ltl-semantics f m))
+ (ltl-semantics (first f) m))
+ :hints (("Goal"
+ :in-theory (disable compatible-ppath-p)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :cases ((compatible-ppath-p (ltl-semantics-witness (first f) m) m)))
+ ("Subgoal 1"
+ :in-theory (disable compatible-ppath-p ltl-semantics-necc
+ ltl-ppath-semantics-can-be-decomposed-over-conjunctions
+ ltl-semantics)
+ :expand (ltl-semantics (first f) m)
+ :use ((:instance ltl-semantics-necc
+ (ppath (ltl-semantics-witness (first f) m)))
+ (:instance
+ ltl-ppath-semantics-can-be-decomposed-over-conjunctions
+ (p (ltl-semantics-witness (first f) m)))))))
+)
+
+(local
+(defthm ltl-conjunction-reduction-3
+ (implies (and (ltl-formulap f)
+ (equal (len f) 3)
+ (equal (second f) '&)
+ (ltl-semantics f m))
+ (ltl-semantics (third f) m))
+ :hints (("Goal"
+ :in-theory (disable compatible-ppath-p)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :cases ((compatible-ppath-p (ltl-semantics-witness (third f) m) m)))
+ ("Subgoal 1"
+ :in-theory (disable compatible-ppath-p
+ ltl-semantics-necc
+ ltl-ppath-semantics-can-be-decomposed-over-conjunctions
+ ltl-semantics)
+ :expand (ltl-semantics (third f) m)
+ :use ((:instance ltl-semantics-necc
+ (ppath (ltl-semantics-witness (third f) m)))
+ (:instance
+ ltl-ppath-semantics-can-be-decomposed-over-conjunctions
+ (p (ltl-semantics-witness (third f) m)))))))
+)
+
+(local
+(in-theory (disable ltl-semantics ltl-formulap
+ ltl-semantics-necc))
+)
+
+(DEFTHM ltl-semantics-is-decomposed-over-conjunction
+ (implies (and (ltl-formulap f)
+ (equal (len f) 3)
+ (equal (second f) '&))
+ (equal (ltl-semantics f m)
+ (and (ltl-semantics (first f) m)
+ (ltl-semantics (third f) m))))
+ :hints (("Goal"
+ :use ((:instance ltl-conjunction-reduction-1)
+ (:instance ltl-conjunction-reduction-2)
+ (:instance ltl-conjunction-reduction-3)))))
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/impl-hack.acl2 b/books/workshops/2003/ray-matthews-tuttle/support/impl-hack.acl2
new file mode 100644
index 0000000..1f73a72
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/impl-hack.acl2
@@ -0,0 +1,3 @@
+(in-package "ACL2")
+; cert-flags: ? t :defaxioms-okp t
+(certify-book "impl-hack" ? t :defaxioms-okp t)
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/impl-hack.lisp b/books/workshops/2003/ray-matthews-tuttle/support/impl-hack.lisp
new file mode 100644
index 0000000..6104fae
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/impl-hack.lisp
@@ -0,0 +1,81 @@
+(in-package "ACL2")
+
+#|
+
+ impl-hack.lisp
+ ~~~~~~~~~~~~~~
+
+This book is an implementation hack. The whole state of affairs is extremely
+stupid here. What I want to do is the following. When we are asked whether a
+(constant) formula is true of a (constant) circuit or not, we will apply the
+compositional reduction (by evaluating that function) and then do
+a series of model-checking on the reduced circuit. Since we are willing to rely
+on an external model-checker, we want a hack function to be evaluated in common
+lisp, where it will be redefined as an external system call. In order for that
+to occur, we define the function with a guard of T and then set it up so that
+the rewriter just makes multiple calls to this function for the model-checking
+purpose.
+
+|#
+
+(include-book "reductions")
+
+;; The following function is the hack. It does not matter what it returns,
+;;since we will disable it, and use the defining axiom for our work. But it is
+;;important to have the function defined with a guard of T so that ACL2 dares
+;; to look into the common lisp for its implementation.
+
+(defun ltl-semantics-hack (C f)
+ (declare (xargs :guard t
+ :verify-guards t))
+ (list C f))
+
+(defun ltl-semantics-hack* (list)
+ (if (endp list) T
+ (and (ltl-semantics-hack (second (first list))
+ (first (first list)))
+ (ltl-semantics-hack* (rest list)))))
+
+(in-theory (disable ltl-semantics-hack (:definition ltl-semantics-hack)))
+
+(defaxiom ltl-semantics-hack-revealed
+ (equal (ltl-semantics-for-circuit C f)
+ (ltl-semantics-hack C f)))
+
+(local
+(defthm ltl-semantocs-hack*-revealed
+ (equal (ltl-semantics-hack* list)
+ (ltl-semantics-for-circuits* list))
+ :hints (("Goal"
+ :induct (ltl-semantics-for-circuits* list))))
+)
+
+;; The following theorem rewrites the ltl-semantics-for-circuit into this hack*
+;; function.
+
+(DEFTHM ltl-semantics-hack-*-from-ltl-semantics-*
+ (implies (syntaxp (and (quotep C)
+ (quotep f)))
+ (implies (and (circuitp C)
+ (ltl-formulap f)
+ (subset (create-restricted-var-set f) (variables C)))
+ (equal (ltl-semantics-for-circuit C f)
+ (ltl-semantics-hack* (compositional-reduction C
+ f)))))
+ :hints (("Goal"
+ :in-theory (disable circuitp ltl-semantics-for-circuit
+ compositional-reduction))))
+
+;; Which then is opened up for a series of evaluations of the hack function.
+
+(DEFTHM ltl-semantics-hack-revealed-for-rewriting
+ (implies (syntaxp (quotep list))
+ (equal (ltl-semantics-hack* list)
+ (if (endp list) T
+ (and (ltl-semantics-hack (second (first list))
+ (first (first list)))
+ (ltl-semantics-hack* (rest list)))))))
+
+(in-theory (disable ltl-semantics-hack* (:definition ltl-semantics-hack*)
+ (:type-prescription ltl-semantics-hack*)))
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/ltl.lisp b/books/workshops/2003/ray-matthews-tuttle/support/ltl.lisp
new file mode 100644
index 0000000..279234f
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/ltl.lisp
@@ -0,0 +1,479 @@
+(in-package "ACL2")
+
+;; The following two lines are added for portability to v2-7....
+
+
+#|
+
+ ltl.lisp
+ ~~~~~~~~
+
+In this book, we discuss the syntax of LTL formula and its semantics with
+respect to a Kripke Structure. The standard semantics of LTL involve operations
+with respect to an inifinitary object, namely the path. However, ACL2 does not
+allow such objects. Thus, we need to define the semantics of LTL with respect
+to a Kripke Structure directly. However, this requires a tableau construction
+which is easy to get wrong and harder to prove theorems about, even if
+specified correctly.
+
+We have chosen to take a middle ground based on (John Matthews's)
+discussions with Ernie Cohen. The idea is to define the semantics of LTL with
+respect to eventually periodic paths. (We defer the proof now that any
+verification of semantics over eventually periodic paths corresponds to a
+verification over infinite paths and this might not be possible to do in
+ACL2.) However, for the moment the semantics are with respect to eventually
+periodic paths and the semantics for a Kripke Structure are given by
+quantifying over all compatible paths.
+
+The current book is produced to prove compositional reductions for
+model-checking. The goal is to verify that the composition reductions are
+correct given that the underlying model-checking routines are correct. Given
+this assumption, we take further liberties and encapsulate the ltl semantics
+over periodic paths as an underlying model-checking routine, exporting theorems
+that are required to verify the reductions. The point in the case is that if
+for a real LTL semantics function these constraints are not satisfied for
+periodic paths, then the functions (and not the theorems) need to be changed,
+making encapsulate a viable option in order to not get bogged down in
+implementation of a model-checking routine for ltl.
+
+Questions and comments are welcome. -- Sandip.
+
+|#
+
+(set-match-free-default :once)
+
+(include-book "sets")
+
+
+
+
+;; We now define the syntax of an LTL formula. For purpose of reductions, we
+;; also define a restricted formula over a subset of variables.
+
+(defun ltl-constantp (f)
+ (or (equal f 'true)
+ (equal f 'false)))
+
+(defun ltl-variablep (f)
+ (and (symbolp f)
+ (not (memberp f '(+ & U W X F G)))))
+
+;; So an LTL formula is either (i) a constant 'True or 'False, (ii) a variable
+;; which is a quote or a symbol other than the LTL operator symbol, or of the
+;; form (P + Q), (P & Q), (P U Q), (P W Q), (~ P), (F P), (G P), (X P), where P
+;; and Q are LTL formulas.
+
+
+(defun ltl-formulap (f)
+ (cond ((atom f) (or (ltl-constantp f)
+ (ltl-variablep f)))
+ ((equal (len f) 3)
+ (and (memberp (second f) '(+ & U W))
+ (ltl-formulap (first f))
+ (ltl-formulap (third f))))
+ ((equal (len f) 2)
+ (and (memberp (first f) '(~ X F G))
+ (ltl-formulap (second f))))
+ (t nil)))
+
+;; A formula is called resctricted with respect to a collection vars of
+;; variables if it mentions no variable other than those in vars. Here is the
+;; recursive definition.
+
+(defun restricted-formulap (f v-list)
+ (cond ((atom f) (or (ltl-constantp f)
+ (and (ltl-variablep f)
+ (memberp f v-list))))
+ ((equal (len f) 3) (and (memberp (second f) '(& + U W))
+ (restricted-formulap (first f) v-list)
+ (restricted-formulap (third f) v-list)))
+ ((equal (len f) 2) (and (memberp (first f) '(~ X F G))
+ (restricted-formulap (second f) v-list)))
+ (t nil)))
+
+;; Now we show the obvious thing that a restricted formula is also an ltl
+;; formula.
+
+(defthm restricted-formula-is-an-ltl-formula
+ (implies (restricted-formulap f v-list)
+ (ltl-formulap f))
+ :rule-classes :forward-chaining)
+
+;; Given an LTL formula, can we create a v-list such that the LTL-formula is a
+;; restricted formula over the variables in v-list? The function
+;; create-restricted-var-set attempts that.
+
+(defun create-restricted-var-set (f)
+ (cond ((atom f) (if (ltl-constantp f) nil (list f)))
+ ((equal (len f) 3) (set-union (create-restricted-var-set (first f))
+ (create-restricted-var-set (third f))))
+ ((equal (len f) 2) (create-restricted-var-set (second f)))
+ (t nil)))
+
+;; And show that we have been successful
+
+(local
+(defthm restricted-formulap-append-reduction
+ (implies (restricted-formulap f vars)
+ (restricted-formulap f (set-union vars vars-prime)))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+)
+
+(local
+(defthm restricted-formulap-append-reduction-2
+ (implies (restricted-formulap f vars)
+ (restricted-formulap f (set-union vars-prime vars)))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+)
+
+(defthm ltl-formula-is-a-restricted-formula
+ (implies (ltl-formulap f)
+ (restricted-formulap f (create-restricted-var-set f)))
+ :rule-classes :forward-chaining)
+
+;; OK, so we are done with syntax of LTL for mow. We will revisit this section
+;; and add different restricted models when we do proofs of different
+;; reductions.
+
+;; We turn our attention to models.
+
+;; First this handy collection of functions that might help us.
+;; NOTE TO MYSELF: I should write some utilities in ACL2 that will allow me to
+;; load the accessor and updater macros easily. I will have to think about it
+;; at aome point.
+
+;; Here are the accessors and updaters as macros. A Kripke structure is a
+;; record of states, initial-states, transition and label-fn.
+
+(defmacro initial-states (m) `(<- ,m :initial-states))
+(defmacro transition (m) `(<- ,m :transition))
+(defmacro label-fn (m) `(<- ,m :label-fn))
+(defmacro states (m) `(<- ,m :states))
+(defmacro variables (m) `(<- ,m :variables))
+
+;; A periodic path is a record of initial-state, (finite) prefix, and (finite)
+;; cycle.
+
+;; NOTE TO MYSELF: The initial state might not be required. It is difficult to
+;; estimate what is considered standard for Kripke structures. I have heard
+;; Professor Emerson talk about Kripke Structures with initial states and
+;; Kripke Structures without initial states (and so in Dr. Clarke's Book). I
+;; follow the "with initial states" in that jargon, though I do believe that we
+;; can modify the theorems for Kripke Structures "without initial states". The
+;; reason for this choice is that I think the stronger requirements of "without
+;; initial states" should not bother us at this time.
+
+(defmacro initial-state (p) `(<- ,p :initial-state))
+(defmacro cycle (p) `(<- ,p :cycle))
+(defmacro prefix (p) `(<- ,p :prefix))
+
+(defmacro >_ (&rest upds) `(update nil ,@upds))
+
+(defun next-statep (p q m)
+ (memberp q (<- (transition m) p)))
+
+(defun initial-statep (p m)
+ (memberp p (initial-states m)))
+
+(defun label-of (s m)
+ (<- (label-fn m) s))
+
+(in-theory (disable next-statep initial-statep label-of))
+
+;; The predicate modelp here precisely describes what we expect a Kripke
+;; Structure to look like.
+
+(defun next-states-in-states (m states)
+ (if (endp states) T
+ (and (subset (<- (transition m) (first states))
+ (states m))
+ (next-states-in-states m (rest states)))))
+
+(defthm next-states-in-states-clarified-aux
+ (implies (and (memberp p states)
+ (next-states-in-states m states)
+ (next-statep p q m))
+ (memberp q (states m)))
+ :hints (("Goal"
+ :in-theory (enable next-statep))))
+
+(defthm next-states-in-states-clarified
+ (implies (and (next-states-in-states m (states m))
+ (memberp p (states m))
+ (next-statep p q m))
+ (memberp q (states m))))
+
+(in-theory (disable next-states-in-states-clarified-aux
+ next-states-in-states))
+
+(encapsulate
+ (((modelp *) => *))
+
+ (local
+ (defun modelp (m)
+ (and (subset (initial-states m) (states m))
+ (consp (states m))
+ (next-states-in-states m (states m)))))
+
+ (defthm modelp-characterization
+ (implies (modelp m)
+ (and (subset (initial-states m) (states m))
+ (consp (states m))
+ (next-states-in-states m (states m)))))
+)
+
+
+;; We define a periodic path to be compatible with a model if (a) its initial
+;; state is in the initial states of the model, (b) its prefix is a compatible
+;; path wrt the model, and (c) its cycle is a compatible cycle with respect to
+;; the prefix.
+
+(defun last-val (x)
+ (cond ((endp x) nil)
+ ((endp (rest x)) (first x))
+ (t (last-val (rest x)))))
+
+(defun compatible-path-p (path model)
+ (cond ((endp path) (null path))
+ ((endp (rest path)) (and (memberp (first path) (states model))
+ (null (rest path))))
+ (t (and (next-statep (first path) (second path) model)
+ (memberp (first path) (states model))
+ (compatible-path-p (rest path) model)))))
+
+(defthm compatible-path-is-true-listp
+ (implies (compatible-path-p path model)
+ (true-listp path)))
+
+(defthm compatible-paths-have-only-states
+ (implies (and (compatible-path-p path m)
+ (memberp s path))
+ (memberp s (states m))))
+
+(defun compatible-ppath-p (ppath model)
+ (let ((init (initial-state ppath))
+ (prefix (prefix ppath))
+ (cycle (cycle ppath)))
+ (and (memberp init (initial-states model))
+ (consp prefix)
+ (next-statep init (first prefix) model)
+ (consp cycle)
+ (next-statep (last-val prefix) (first cycle) model)
+ (compatible-path-p prefix model)
+ (compatible-path-p cycle model)
+ (next-statep (last-val cycle) (first cycle) model))))
+
+(defun labels-equal-along-paths (p m q n vars)
+ (if (endp p) T
+ (and (set-equal (set-intersect (label-of (first p) m) vars)
+ (set-intersect (label-of (first q) n) vars))
+ (labels-equal-along-paths (rest p) m (rest q) n vars))))
+
+(defun state-at-aux (n cycle)
+ (declare (xargs :measure (nfix n)))
+ (cond ((endp cycle) nil) ;; for termination
+ ((< (nfix n) (len cycle)) (nth n cycle))
+ (t (state-at-aux (- n (len cycle)) cycle))))
+
+(defun state-at (n ppath)
+ (let ((init (initial-state ppath))
+ (prefix (prefix ppath))
+ (cycle (cycle ppath)))
+ (cond ((zp n) init)
+ ((< (1- n) (len prefix)) (nth (1- n) prefix))
+ (t (state-at-aux (- n (1+ (len prefix))) cycle)))))
+
+
+;; Now we are ready to define ltl semantics. We will define LTL semantics as an
+;; encapsulated function with the properties we need exported out.
+
+
+(defun labels-equal-for-paths (p m q n vars)
+ (if (endp p) (endp q)
+ (and (equal (set-intersect (label-of (first p) m) vars)
+ (set-intersect (label-of (first q) n) vars))
+ (labels-equal-for-paths (rest p) m (rest q) n vars))))
+
+
+(defun first-n (n lst)
+ (if (zp n) nil
+ (cons (first lst) (first-n (1- n) (rest lst)))))
+
+(defun last-n (n lst)
+ (if (zp n) lst
+ (last-n (1- n) (rest lst))))
+
+(defthm first-last-append-reduction
+ (implies (<= n (len x))
+ (equal (append (first-n n x)
+ (last-n n x))
+ x)))
+
+(defthm len-of-last-n-is-len-minus-n
+ (implies (and (not (zp n))
+ (<= n (len x)))
+ (equal (len (last-n n x)) (- (len x) n))))
+
+(defthm append-of-nil-is-x
+ (implies (true-listp x)
+ (equal (append x nil) x)))
+
+
+(local
+(include-book "../../../../arithmetic-2/meta/top")
+)
+
+(defthm first-n-append-reduction
+ (implies (and (equal i (len y))
+ (true-listp y))
+ (equal (first-n i (append y z))
+ y)))
+
+
+(defthm last-n-append-reduction
+ (implies (equal i (len x))
+ (equal (last-n i (append x y))
+ y)))
+
+(defun equal-label-segments-p (p m q n vars)
+ (if (endp p) (endp q)
+ (and (consp q)
+ (set-equal (set-intersect (label-of (first p) m) vars)
+ (set-intersect (label-of (first q) n) vars))
+ (equal-label-segments-p (rest p) m (rest q) n vars))))
+
+(defthm len-of-last-n-expanded
+ (implies (and (integerp i)
+ (< 0 i)
+ (<= i (len x)))
+ (< (len (last-n i x))
+ (len x)))
+ :rule-classes :linear)
+
+(defthm consp-to-len-expanded
+ (implies (consp x)
+ (< 0 (len x)))
+ :rule-classes :linear)
+
+(defun equal-label-segments-sequence-p-small-p (p m q n vars)
+ (declare (xargs :measure (len q)))
+ (if (endp q) T
+ (if (or (endp p) (< (len q) (len p))) nil
+ (and (equal-label-segments-p p m (first-n (len p) q) n vars)
+ (equal-label-segments-sequence-p-small-p
+ p m
+ (last-n (len p) q) n vars)))))
+
+(defun equal-label-segments-sequence-p-large-p (p m q n vars)
+ (declare (xargs :measure (len p)))
+ (if (endp p) T
+ (if (or (endp q) (< (len p) (len q))) nil
+ (and (equal-label-segments-p (first-n (len q) p) m q n vars)
+ (equal-label-segments-sequence-p-large-p
+ (last-n (len q) p) m q n vars)))))
+
+(defun equal-labels-periodic-path-p (p m q n vars)
+ (and (set-equal (set-intersect (label-of (initial-state p) m) vars)
+ (set-intersect (label-of (initial-state q) n) vars))
+ (or (and (equal-label-segments-p (prefix p) m
+ (first-n (len (prefix p)) (prefix q))
+ n vars)
+ (equal-label-segments-sequence-p-small-p
+ (cycle p) m
+ (last-n (len (prefix p)) (prefix q))
+ n vars)
+ (equal-label-segments-sequence-p-small-p
+ (cycle p) m (cycle q)
+ n vars))
+ (and (equal-label-segments-p
+ (first-n (len (prefix q)) (prefix p))
+ m (prefix q) n vars)
+ (equal-label-segments-sequence-p-large-p
+ (last-n
+ (len (prefix q))
+ (prefix p)) m
+ (cycle q) n vars)
+ (equal-label-segments-sequence-p-large-p
+ (cycle p) m (cycle q) n vars)))))
+
+
+;; Now we define the semantics of ltl. The semantics function is the
+;; concrete-ltl-semantics provided below. And I need not emphasize that the
+;; function is a mess.
+
+;; We have decided to snip out part of this book from here. I have actually
+;; proved that concrete-ltl-semantics satisfies the theorem
+;; ltl-ppath-semantics-cannot-distinguish-between-equal-labels. Actually we
+;; proved a more general version of the theorem, and equal-labels-periodic-path-p
+;; is too restrictive. However, as we will see in the sequel, that is all that we
+;; would need. The proof simply is to induct with the structure of the formula
+;; f. However, it turned out that the proof in this case became extremely
+;; cluttered, mainly because to prove a theorem about mutually recursive
+;; function, we need to prove a theorem about all the functions in the
+;; clique. (The corresponding statements for the different other functions are not
+;; very elegant in our case.) To see how bad theorems can become look at the
+;; file bisimilarity.lisp. Further, we note that we will never actually
+;; execute the function ltl-ppath-semantics. (Indeed the function we would have
+;; hoped to execute would be the model checking function ltl-semantics, but
+;; that is defined using defun-sk and hence we have lost all hopes of executing
+;; it. The reason for our going to such lengths to define
+;; concrete-ltl-semantics is to justify that we can indeed do what we want with
+;; eventually periodic paths. Henceforth, however, we will simply use the
+;; following encapsulated function ltl-ppath-semantcs, where we assume the
+;; version of ltl-ppath-semantics-cannot-distinguish-between-equal-labels, that
+;; we export from the encapsulate. If a reader of the script feels unsatisfied,
+;; we can provide the actual theorems about concrete-ltl-semantics.
+
+
+(encapsulate
+ (((ltl-ppath-semantics * * *) => *))
+
+ (local
+ (defun ltl-ppath-semantics (f ppath m)
+ (declare (ignore f ppath m))
+ T)
+ )
+
+ (defthm ltl-ppath-semantics-returns-boolean
+ (or (equal (ltl-ppath-semantics f ppath m) T)
+ (equal (ltl-ppath-semantics f ppath m) nil))
+ :rule-classes :type-prescription)
+
+ (defthm ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ (implies (and (equal-labels-periodic-path-p p m q n vars)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (compatible-ppath-p p m)
+ (compatible-ppath-p q n)
+ (restricted-formulap f vars))
+ (equal (ltl-ppath-semantics f p m)
+ (ltl-ppath-semantics f q n))))
+
+ (defthm ltl-ppath-semantics-can-be-decomposed-over-conjunctions
+ (implies (and (ltl-formulap f)
+ (equal (len f) 3)
+ (equal (second f) '&)
+ (compatible-ppath-p p m))
+ (equal (ltl-ppath-semantics f p m)
+ (and (ltl-ppath-semantics (first f) p m)
+ (ltl-ppath-semantics (third f) p m)))))
+
+
+)
+
+(defun-sk ltl-semantics (f m)
+ (forall ppath
+ (implies (compatible-ppath-p ppath m)
+ (ltl-ppath-semantics f ppath m))))
+
+(defthm ltl-semantics-necc-expanded
+ (implies (and (ltl-semantics f m)
+ (compatible-ppath-p ppath m))
+ (ltl-ppath-semantics f ppath m))
+ :hints (("Goal"
+ :use ltl-semantics-necc)))
+
+(in-theory (disable ltl-semantics-necc))
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/records.lisp b/books/workshops/2003/ray-matthews-tuttle/support/records.lisp
new file mode 100644
index 0000000..7705c11
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/records.lisp
@@ -0,0 +1,299 @@
+(in-package "ACL2")
+
+
+#|
+
+ records.lisp
+ ~~~~~~~~~~~~
+
+We define properties of a generic record accessor function and updater
+function. The basic functions are (g a r) and (s a v r) where a is an
+address/key, v is a value, r is a record, and (g a r) returns the
+value set to address a in record r, and (s a v r) returns a new record
+with address a set to value v in record r.
+
+We normalize the record structures (which allows the 'equal-ity based
+rewrite rules) as alists where the keys (cars) are ordered using
+Pete's total-order added to ACL2. We define a set of -aux functions
+which assume well-formed records -- defined by rcdp -- and then prove
+the desired properties using hypothesis assuming well-formed objects.
+
+We then remove these well-formed object hypothesis by defining a invertible
+mapping (acl2->rcd) from any ACL2 object to a well-formed records. We then
+prove the desired properties using the proper translations of the -aux
+functions to the acl2 objects, and subsequently remove the well-founded
+hypothesis.
+
+|#
+
+(include-book "apply-total-order")
+
+;; BEGIN records definitions.
+
+(defun rcdp (x)
+ (or (null x)
+ (and (consp x)
+ (consp (car x))
+ (rcdp (cdr x))
+ (cdar x)
+ (or (null (cdr x))
+ (<< (caar x) (caadr x))))))
+
+(defun ifrp (x) ;; ill-formed rcdp
+ (or (not (rcdp x))
+ (and (consp x)
+ (null (cdr x))
+ (consp (car x))
+ (null (caar x))
+ (ifrp (cdar x)))))
+
+(defun acl2->rcd (x)
+ (if (ifrp x) (list (cons nil x)) x))
+
+(defun rcd->acl2 (x)
+ (if (ifrp x) (cdar x) x))
+
+(defun g-aux (a x)
+ (cond ((or (endp x)
+ (<< a (caar x)))
+ nil)
+ ((equal a (caar x))
+ (cdar x))
+ (t
+ (g-aux a (cdr x)))))
+
+(defun g (a x)
+ (g-aux a (acl2->rcd x)))
+
+(defun s-aux (a v r)
+ (cond ((or (endp r)
+ (<< a (caar r)))
+ (if v (cons (cons a v) r) r))
+ ((equal a (caar r))
+ (if v (cons (cons a v) (cdr r)) (cdr r)))
+ (t
+ (cons (car r) (s-aux a v (cdr r))))))
+
+(defun s (a v x)
+ (rcd->acl2 (s-aux a v (acl2->rcd x))))
+
+(defun keys-aux (x)
+ (cond ((endp x)
+ ())
+ (t (cons (caar x)
+ (keys-aux (cdr x))))))
+
+(defun keys (x)
+ (keys-aux (acl2->rcd x)))
+
+
+
+;;;; basic property of records ;;;;
+
+(local
+(defthm rcdp-implies-true-listp
+ (implies (rcdp x)
+ (true-listp x))
+ :rule-classes (:forward-chaining
+ :rewrite)))
+
+
+;;;; initial properties of s-aux and g-aux ;;;;
+
+(local
+(defthm s-aux-is-bounded
+ (implies (and (rcdp r)
+ (s-aux a v r)
+ (<< e a)
+ (<< e (caar r)))
+ (<< e (caar (s-aux a v r))))))
+
+(local
+(defthm s-aux-preserves-rcdp
+ (implies (rcdp r)
+ (rcdp (s-aux a v r)))))
+
+(local
+(defthm g-aux-same-s-aux
+ (implies (rcdp r)
+ (equal (g-aux a (s-aux a v r))
+ v))))
+
+(local
+(defthm g-aux-diff-s-aux
+ (implies (and (rcdp r)
+ (not (equal a b)))
+ (equal (g-aux a (s-aux b v r))
+ (g-aux a r)))))
+
+(local
+(defthm s-aux-same-g-aux
+ (implies (rcdp r)
+ (equal (s-aux a (g-aux a r) r)
+ r))))
+
+(local
+(defthm s-aux-same-s-aux
+ (implies (rcdp r)
+ (equal (s-aux a y (s-aux a x r))
+ (s-aux a y r)))))
+
+(local
+(defthm s-aux-diff-s-aux
+ (implies (and (rcdp r)
+ (not (equal a b)))
+ (equal (s-aux b y (s-aux a x r))
+ (s-aux a x (s-aux b y r))))
+ :rule-classes ((:rewrite :loop-stopper ((b a s))))))
+
+(local
+(defthm s-aux-non-nil-cannot-be-nil
+ (implies (and v (rcdp r))
+ (s-aux a v r))))
+
+(local
+(defthm g-aux-is-nil-for-<<
+ (implies (and (rcdp r)
+ (<< a (caar r)))
+ (equal (g-aux a r) nil))))
+
+(local
+(defthm g-keys-aux-relationship
+ (implies (rcdp r)
+ (iff (memberp a (keys-aux r))
+ (g-aux a r)))))
+
+(local
+(defthm s-keys-aux-reduction
+ (implies (rcdp r)
+ (equal (keys-aux (s-aux a v r))
+ (if v
+ (insert a (keys-aux r))
+ (drop a (keys-aux r)))))))
+
+(local
+(defthm keys-aux-are-ordered
+ (implies (rcdp r)
+ (orderedp (keys-aux r)))))
+
+
+;;;; properties of acl2->rcd and rcd->acl2 ;;;;
+
+(local
+(defthm acl2->rcd-rcd->acl2-of-rcdp
+ (implies (rcdp x)
+ (equal (acl2->rcd (rcd->acl2 x))
+ x))))
+
+(local
+(defthm acl2->rcd-returns-rcdp
+ (rcdp (acl2->rcd x))))
+
+(local
+(defthm acl2->rcd-preserves-equality
+ (iff (equal (acl2->rcd x) (acl2->rcd y))
+ (equal x y))))
+
+(local
+(defthm rcd->acl2-acl2->rcd-inverse
+ (equal (rcd->acl2 (acl2->rcd x)) x)))
+
+(local
+(defthm rcd->acl2-of-record-non-nil
+ (implies (and r (rcdp r))
+ (rcd->acl2 r))))
+
+(in-theory (disable acl2->rcd rcd->acl2))
+
+
+;;;; final properties of record g(et) and s(et) ;;;;
+
+(defthm g-same-s
+ (equal (g a (s a v r))
+ v))
+
+(defthm g-diff-s
+ (implies (not (equal a b))
+ (equal (g a (s b v r))
+ (g a r))))
+
+;;;; NOTE: I often use the following instead of the above rules
+;;;; to force ACL2 to do a case-split. In some cases, I will
+;;;; disable this rule ACL2 is sluggish or if the number of cases
+;;;; is unreasonable
+
+(defthm g-of-s-redux
+ (equal (g a (s b v r))
+ (if (equal a b) v (g a r))))
+
+(in-theory (disable g-of-s-redux))
+
+(defthm s-same-g
+ (equal (s a (g a r) r)
+ r))
+
+(defthm s-same-s
+ (equal (s a y (s a x r))
+ (s a y r)))
+
+(defthm s-diff-s
+ (implies (not (equal a b))
+ (equal (s b y (s a x r))
+ (s a x (s b y r))))
+ :rule-classes ((:rewrite :loop-stopper ((b a s)))))
+
+(defthm g-keys-relationship
+ (iff (memberp a (keys r))
+ (g a r)))
+
+(defthm s-keys-reduction
+ (equal (keys (s a v r))
+ (if v
+ (insert a (keys r))
+ (drop a (keys r)))))
+
+(defthm keys-are-ordered
+ (orderedp (keys r)))
+
+(defthm g-of-nil-is-nil
+ (not (g a nil)))
+
+(defthm s-non-nil-cannot-be-nil
+ (implies v (s a v r))
+ :hints (("Goal"
+ :in-theory (disable rcd->acl2-of-record-non-nil)
+ :use (:instance rcd->acl2-of-record-non-nil
+ (r (s-aux a v (acl2->rcd r)))))))
+
+(defthm non-nil-if-g-non-nil
+ (implies (g a r) r)
+ :rule-classes :forward-chaining)
+
+
+(defthm s-same-g-back-chaining
+ (implies (equal v (g a r))
+ (equal (s a v r) r)))
+
+
+;; We disable s and g, assuming the rules proven in this book are sufficient to
+;; manipulate record terms which are encountered
+
+(in-theory (disable s g keys))
+
+(defmacro <- (x a) `(g ,a ,x))
+
+(defmacro -> (x a v) `(s ,a ,v ,x))
+
+(defun update-macro (upds result)
+ (declare (xargs :guard (keyword-value-listp upds)))
+ (if (endp upds) result
+ (update-macro (cddr upds)
+ (list 's (car upds) (cadr upds) result))))
+
+(defmacro update (old &rest updates)
+ (declare (xargs :guard (keyword-value-listp updates)))
+ (update-macro updates old))
+
+
+
+
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/reductions.lisp b/books/workshops/2003/ray-matthews-tuttle/support/reductions.lisp
new file mode 100644
index 0000000..fe4382e
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/reductions.lisp
@@ -0,0 +1,392 @@
+(in-package "ACL2")
+
+#|
+
+ reductions.lisp
+ ~~~~~~~~~~~~~~~
+
+In this book, we use the conjunctive reduction and cone of influence reduction
+compositionally to provide reduction algorithms for circuits.
+
+|#
+
+(local
+(include-book "conjunction")
+)
+
+(include-book "cone-of-influence")
+
+
+(defun ltl-semantics-for-circuit (C f)
+ (ltl-semantics f (create-kripke C)))
+
+(defun ltl-semantics-for-circuits* (list)
+ (if (endp list) T
+ (and (ltl-semantics-for-circuit (second (first list))
+ (first (first list)))
+ (ltl-semantics-for-circuits* (rest list)))))
+
+
+(defun reduce-problem-conjunction (f C)
+ (if (and (equal (len f) 3)
+ (equal (second f) '&))
+ (append (reduce-problem-conjunction (first f) C)
+ (reduce-problem-conjunction (third f) C))
+ (list (list f C))))
+
+(defun reduce-problem-cone (f C)
+ (let ((vars (create-restricted-var-set f)))
+ (cone-of-influence-reduction C vars)))
+
+(defun reduce-problem-cone* (list)
+ (if (endp list) nil
+ (cons (list (first (first list))
+ (reduce-problem-cone (first (first list)) (second (first list))))
+ (reduce-problem-cone* (rest list)))))
+
+
+(defun compositional-reduction (C f)
+ (let ((list (reduce-problem-conjunction f C)))
+ (reduce-problem-cone* list)))
+
+;; OK, so let us dispatch the obligations for conjunction first.
+
+(local
+(in-theory (disable ltl-semantics create-kripke ltl-formulap))
+)
+
+(local
+(defthm ltl-semantics*-append-reduction
+ (equal (ltl-semantics-for-circuits* (append x y))
+ (and (ltl-semantics-for-circuits* x)
+ (ltl-semantics-for-circuits* y))))
+)
+
+(local
+(defthm conjunction-produces-correct-list
+ (implies (ltl-formulap f)
+ (equal (ltl-semantics-for-circuits*
+ (reduce-problem-conjunction f C))
+ (ltl-semantics-for-circuit C f)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (reduce-problem-conjunction f C)
+ :do-not-induct t
+ :in-theory (enable ltl-formulap)
+ :do-not '(eliminate-destructors generalize))))
+)
+
+;; To work with reduce-problems-cone, we need to assume that the variables in f
+;; are subsets of the variables in cone of influence reduction. We show that
+;; assuming that the variables are subsets of variables of the circuit. We need
+;; to show though that the variables of cone will be a superset of vars if we
+;; start with a collection of vars that are subset of the variables of the
+;; circuit.
+
+(local
+(encapsulate
+ ()
+ (defthm not-memberp-union-reduction
+ (implies (and (not (memberp e x))
+ (not (memberp e y)))
+ (not (memberp e (set-union x y))))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+
+ (local
+ (defthm uniquep-set-union-reduction
+ (implies (and (uniquep x)
+ (uniquep y))
+ (uniquep (set-union x y)))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+ )
+
+ (local
+ (in-theory (disable consistent-equation-record-p))
+ )
+
+ (local
+ (defthm consistent-equation-record-p-expanded
+ (implies (and (consistent-equation-record-p vars equations)
+ (uniquep vars)
+ (memberp v vars)
+ (memberp equation (<- equations v)))
+ (subset (find-variables equation)
+ vars))
+ :hints (("Goal"
+ :use consistent-equation-record-p-necc)))
+ )
+
+ (local
+ (in-theory (disable consistent-equation-record-p-necc))
+ )
+
+ (local
+ (defthm set-union-subset-reduction
+ (implies (and (subset x z)
+ (subset y z))
+ (subset (set-union x y) z))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+ )
+
+ (local
+ (defthm find-variables*-subset-of-variables
+ (implies (and (consistent-equation-record-p variables equations)
+ (uniquep variables)
+ (memberp v variables)
+ (subset equation-list (<- equations v)))
+ (subset (find-variables* equation-list)
+ variables))
+ :hints (("Goal"
+ :in-theory (disable find-variables)
+ :induct (find-variables* equation-list)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+ )
+
+ (local
+ (defthm find-variables*-is-subset-concretized
+ (implies (and (consistent-equation-record-p variables equations)
+ (memberp v variables)
+ (uniquep variables))
+ (subset (find-variables* (<- equations v)) variables)))
+ )
+
+ (local
+ (in-theory (disable find-variables*-subset-of-variables))
+ )
+
+ (local
+ (defthm find-variables-1-pass-is-subset
+ (implies (and (consistent-equation-record-p variables equations)
+ (subset vars variables)
+ (uniquep variables))
+ (subset (find-all-variables-1-pass vars equations)
+ variables)))
+ )
+
+ (local
+ (defthm memberp-union-reduction-1
+ (implies (memberp e x)
+ (memberp e (set-union y x)))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+ )
+
+ (local
+ (defthm memberp-find-all-variables-reduction
+ (implies (and (consistent-equation-record-p variables equations)
+ (subset vars variables)
+ (memberp v vars))
+ (memberp v (find-all-variables vars variables equations)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (find-all-variables vars variables equations)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+ )
+
+ (local
+ (defthm find-all-variables-produces-subset
+ (implies (and (consistent-equation-record-p variables equations)
+ (subset vars variables)
+ (subset vars-prime vars))
+ (subset vars-prime (find-all-variables vars variables equations))))
+ )
+
+ (local
+ (defthm set-intersect-is-subset
+ (implies (and (subset vars variables)
+ (subset vars vars-prime))
+ (subset vars (set-intersect vars-prime variables))))
+ )
+
+ (local
+ (defthm memberp-remove-reduction
+ (equal (memberp e (remove-duplicate-occurrences variables))
+ (memberp e variables)))
+ )
+
+ (local
+ (defthm remove-duplicates-is-subset
+ (implies (subset vars variables)
+ (subset vars (remove-duplicate-occurrences variables))))
+ )
+
+ (local
+ (defthm cone-variables-are-subset
+ (implies (and (consistent-equation-record-p variables equations)
+ (subset vars variables))
+ (subset vars (find-all-variables
+ (set-intersect
+ (remove-duplicate-occurrences vars)
+ variables)
+ variables equations)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable find-all-variables-produces-subset)
+ :use ((:instance find-all-variables-produces-subset
+ (vars-prime vars)
+ (vars (set-intersect
+ (remove-duplicate-occurrences vars)
+ variables)))))))
+ )
+
+ (local
+ (defthm circuitp-to-cone-variables
+ (implies (and (circuitp C)
+ (subset vars (variables C)))
+ (subset vars (cone-variables vars C))))
+ )
+
+ (local
+ (in-theory (disable circuitp cone-variables cone-of-influence-reduction))
+ )
+
+ (defthm cone-of-influence-reduction-for-specific
+ (implies (and (circuitp C)
+ (ltl-formulap f)
+ (subset (create-restricted-var-set f)
+ (variables C)))
+ (equal (ltl-semantics-for-circuit (cone-of-influence-reduction
+ C (create-restricted-var-set
+ f))
+ f)
+ (ltl-semantics-for-circuit C f)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable cone-of-influence-reduction-is-sound-generalized)
+ :use ((:instance cone-of-influence-reduction-is-sound-generalized
+ (interesting-vars (create-restricted-var-set f))
+ (vars (create-restricted-var-set f)))))))
+
+ )
+)
+
+(local
+(in-theory (disable ltl-semantics-for-circuit create-restricted-var-set
+ cone-of-influence-reduction
+ circuitp ltl-formulap))
+)
+
+(local
+(defthm reduce-problem-cone-reduction
+ (implies (and (circuitp C)
+ (ltl-formulap f)
+ (subset (create-restricted-var-set f) (variables C)))
+ (equal (ltl-semantics-for-circuit (reduce-problem-cone f C)
+ f)
+ (ltl-semantics-for-circuit C f))))
+)
+
+(local
+(in-theory (disable reduce-problem-cone))
+)
+
+(local
+(defun well-formed-problems-p (list)
+ (if (endp list) T
+ (and (ltl-formulap (first (first list)))
+ (circuitp (second (first list)))
+ (subset (create-restricted-var-set (first (first list)))
+ (variables (second (first list))))
+ (well-formed-problems-p (rest list)))))
+)
+
+(local
+(defthm reduce-problem-cone*-reduction
+ (implies (well-formed-problems-p list)
+ (equal (ltl-semantics-for-circuits* (reduce-problem-cone* list))
+ (ltl-semantics-for-circuits* list)))
+ :otf-flg t
+ :hints (("Goal"
+ :in-theory (enable reduce-problem-cone*)
+ :do-not '(eliminate-destructors generalize))))
+)
+
+(local
+(defthm subset-member-reduction
+ (implies (and (subset (set-union x y) z)
+ (memberp e x))
+ (memberp e z))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+)
+
+(local
+(defthm subset-member-reduction-2
+ (implies (and (subset (set-union x y) z)
+ (memberp e y))
+ (memberp e z))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+)
+
+(local
+(defthm set-union-subset-reduction
+ (implies (subset (set-union x y) z)
+ (subset x z))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+)
+
+(local
+(defthm set-union-subset-reduction-2
+ (implies (subset (set-union x y) z)
+ (subset y z))
+ :hints (("Goal"
+ :in-theory (enable set-union))))
+)
+
+(local
+(defthm conjunction-has-variables-subset-1
+ (implies (and (ltl-formulap f)
+ (equal (len f) 3)
+ (subset (create-restricted-var-set f) vars))
+ (subset (create-restricted-var-set (first f)) vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (enable create-restricted-var-set ltl-formulap)
+ :expand (create-restricted-var-set f))))
+)
+(local
+(defthm conjunction-has-variables-subset-2
+ (implies (and (ltl-formulap f)
+ (equal (len f) 3)
+ (subset (create-restricted-var-set f) vars))
+ (subset (create-restricted-var-set (third f)) vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (enable create-restricted-var-set ltl-formulap)
+ :expand (create-restricted-var-set f))))
+)
+
+(local
+(defthm well-formed-append-reduction
+ (implies (and (force (well-formed-problems-p first))
+ (force (well-formed-problems-p second)))
+ (well-formed-problems-p (append first second))))
+)
+
+(local
+(defthm conjunction-produces-well-formed-problems
+ (implies (and (circuitp C)
+ (ltl-formulap f)
+ (subset (create-restricted-var-set f) (variables C)))
+ (well-formed-problems-p (reduce-problem-conjunction f C)))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :induct (reduce-problem-conjunction f C))))
+)
+
+(DEFTHM compositional-reduction-is-sound
+ (implies (and (circuitp C)
+ (ltl-formulap f)
+ (subset (create-restricted-var-set f) (variables C)))
+ (equal (ltl-semantics-for-circuits* (compositional-reduction C f))
+ (ltl-semantics-for-circuit C f))))
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/sets.lisp b/books/workshops/2003/ray-matthews-tuttle/support/sets.lisp
new file mode 100644
index 0000000..2e3a4ff
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/sets.lisp
@@ -0,0 +1,137 @@
+(in-package "ACL2")
+
+#|
+
+ sets.lisp
+ ~~~~~~~~~
+
+In this book, we discuss the basic theory of flat sets. We define the functions
+subset, set-intersect, set-union and set-equal, and prove properties of these
+functions. I include the records book here, just so that I dont have two
+set-memberp functions. I do not know if this is going to be useful, but now I
+am not feeling like I want to do much (what with feeling drowsy and depressed
+and all) and so I thought this would just be an interesting exercise and be
+useful later, since anyway I would need to reason about sets in model-checking.
+
+|#
+
+(include-book "records")
+
+(defun subset (x y)
+ (if (endp x) T
+ (and (memberp (first x) y)
+ (subset (rest x) y))))
+
+(defun set-intersect (x y)
+ (cond ((endp x) nil)
+ ((memberp (first x) y)
+ (cons (first x) (set-intersect (rest x) y)))
+ (t (set-intersect (rest x) y))))
+
+(defun set-union (x y)
+ (cond ((endp x) y)
+ ((memberp (first x) y)
+ (set-union (rest x) y))
+ (t (cons (first x) (set-union (rest x) y)))))
+
+(defun set-equal (x y)
+ (and (subset x y)
+ (subset y x)))
+
+;; We prove that set-equal is an equivalence relation.
+
+(local
+(defthm proper-subset-is-a-subset
+ (implies (subset x y)
+ (subset x (cons a y))))
+)
+
+(defthm subset-is-reflexive
+ (subset x x))
+
+(defthm subset-is-transitive
+ (implies (and (subset x y)
+ (subset y z))
+ (subset x z)))
+
+(defthm subset-of-empty-is-empty
+ (implies (and (not (consp x))
+ (subset y X))
+ (not (consp y))))
+
+
+;; Just prove that set-equal is an equivalence now, should be trivial.
+
+(defequiv set-equal)
+
+;; We have got reflexivity, and transitivity so far for subset, show that it is
+;; anti-symmetric.
+
+(defthm subset-is-antisymmetric
+ (implies (and (subset x y)
+ (subset y x))
+ (set-equal x y))
+ :rule-classes :forward-chaining)
+
+;; This completes the properties of subset relation.
+
+
+;; Now show how union and intersection work with subset.
+
+(defthm intersect-is-a-subset-1
+ (subset (set-intersect x y) x))
+
+(defthm intersect-is-a-subset-2
+ (subset (set-intersect x y) y))
+
+(defthm union-is-a-subset-1
+ (subset x (set-union x y)))
+
+(defthm union-is-a-subset-2
+ (subset y (set-union x y)))
+
+;; This completes interaction of union and intersection with subset.
+
+;; Now show interaction between subset and memberp functions
+
+(defthm superset-contains-everything
+ (implies (and (memberp e x)
+ (subset x y))
+ (memberp e y))
+ :rule-classes :forward-chaining)
+
+;; And let us do the consp of subset reduction
+
+(defthm subset-of-nil-is-nil
+ (implies (and (not (consp y))
+ (subset x y))
+ (not (consp x))))
+
+;; This completes interaction between subset and memberp.
+
+;; Now we define a proper subset and show it is irreflexive.
+
+(defun proper-subset (x y)
+ (and (subset x y)
+ (not (subset y x))))
+
+(defthm proper-subset-is-irreflexive
+ (not (proper-subset x x)))
+
+(defthm proper-subset-is-transitive
+ (implies (and (proper-subset x y)
+ (proper-subset y z))
+ (proper-subset x z)))
+
+(defthm proper-subset-is-stronger-than-subset
+ (implies (proper-subset x y)
+ (subset x y)))
+
+;; So I think we have proved enough theorems about sets for now, and we disable
+;; all the functions.
+
+(in-theory (disable proper-subset set-union set-equal set-intersect))
+
+;; Note: Unfortunately we cannot disable subset, since it is used everywhere
+;; else. It might be worthwhile to do a more thorough job of the rewrite rules
+;; and at least try doing it. But I am not sure.
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/total-order.lisp b/books/workshops/2003/ray-matthews-tuttle/support/total-order.lisp
new file mode 100644
index 0000000..b0887c6
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/total-order.lisp
@@ -0,0 +1,33 @@
+; This total order book, put together by Matt Kaufmann, is culled from events
+; contributed by Pete Manolios and also benefits from contributions by Rob
+; Sumners.
+
+(in-package "ACL2")
+
+(defun << (x y)
+ (declare (xargs :guard t))
+ (and (lexorder x y)
+ (not (equal x y))))
+
+(defthm <<-irreflexive
+ (not (<< x x)))
+
+(defthm <<-transitive
+ (implies (and (<< x y)
+ (<< y z))
+ (<< x z)))
+
+(defthm <<-asymmetric
+ (implies (<< x y)
+ (not (<< y x))))
+
+(defthm <<-trichotomy
+ (implies (and (not (<< y x))
+ (not (equal x y)))
+ (<< x y)))
+
+(defthm <<-implies-lexorder
+ (implies (<< x y)
+ (lexorder x y)))
+
+(in-theory (disable <<))
diff --git a/books/workshops/2003/schmaltz-al-sammane-et-al/combining.pdf.gz b/books/workshops/2003/schmaltz-al-sammane-et-al/combining.pdf.gz
new file mode 100644
index 0000000..848b0d3
--- /dev/null
+++ b/books/workshops/2003/schmaltz-al-sammane-et-al/combining.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-al-sammane-et-al/combining.ps.gz b/books/workshops/2003/schmaltz-al-sammane-et-al/combining.ps.gz
new file mode 100644
index 0000000..41d09b4
--- /dev/null
+++ b/books/workshops/2003/schmaltz-al-sammane-et-al/combining.ps.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.pdf.gz b/books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.pdf.gz
new file mode 100644
index 0000000..7027167
--- /dev/null
+++ b/books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.ps.gz b/books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.ps.gz
new file mode 100644
index 0000000..ce3fa91
--- /dev/null
+++ b/books/workshops/2003/schmaltz-al-sammane-et-al/math-slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-al-sammane-et-al/support/acl2link.txt b/books/workshops/2003/schmaltz-al-sammane-et-al/support/acl2link.txt
new file mode 100644
index 0000000..33076a9
--- /dev/null
+++ b/books/workshops/2003/schmaltz-al-sammane-et-al/support/acl2link.txt
@@ -0,0 +1,56 @@
+******************************************************************************
+
+ ACL2-MATHEMATICA LINK
+
+ TIMA - VDS, Grenoble, France
+
+ Al Sammane Ghiath, Borrione Dominique, Ostier Pierre
+
+ Schmaltz Julien and Toma Diana
+
+*****************************************************************************
+
+acl2link is an executable that links Mathematica and ACL2 through a pipe.
+
+-----------------------------------------------------------
+INSTALL
+
+To install the link, just execute:
+
+
+In[1]:= Install["acl2link"]
+
+
+in Mathematica. You will get:
+
+
+Out[1]= LinkObject[./acl2link, 1, 1]
+
+In[2]:=
+
+Now, you can call ACL2 in Mathematica through the functions
+
+callAcl2["string"],
+
+where string is send to ACL2 and the last line of the ACL2 message is returned.
+For instance:
+
+In[2]:= callAcl2["(defthm foo (equal x x) :rule-classes nil)"]
+
+Out[2]= FOO
+
+In[3]:=
+
+------------------------------------------------------------
+UNINSTALL
+
+To uninstall acl2link (before exiting mathematica), execute :
+
+closeAcl2[]
+
+
+In[4]:= closeAcl2[]
+
+Out[4]= 0
+
+
diff --git a/books/workshops/2003/schmaltz-al-sammane-et-al/support/consistency.lisp b/books/workshops/2003/schmaltz-al-sammane-et-al/support/consistency.lisp
new file mode 100644
index 0000000..c17a9c5
--- /dev/null
+++ b/books/workshops/2003/schmaltz-al-sammane-et-al/support/consistency.lisp
@@ -0,0 +1,85 @@
+;------------------------------------------------------------------------------------
+;
+; File: consistency.lisp
+; April 2003
+; Authors: Toma Diana and Schmaltz Julien
+; TIMA - VDS, Grenoble, France
+; Functions checking the consistency of hypotheses
+;
+;------------------------------------------------------------------------------------
+
+
+(in-package "ACL2")
+
+
+; we use the expander book
+(include-book "../../../../misc/expander")
+
+(set-state-ok t)
+
+(program)
+
+
+; consistency returns nil in case of errors when calling tool1-fn
+; normally returns the list of contradictory constraints of L
+; Note that at call, L contains a contradiction
+
+(defun consistency (L Ih i state)
+ (if (and (true-listp L)
+ (true-listp Ih)
+ (integerp i)
+ (< 0 i))
+ (cond ((endp L) ; last step of the algorithm
+ (value Ih)); L empty means that L is the minal set and now Ih = L
+ ((< (length L) i) (value nil)) ;error: i out of L range
+ ((endp Ih) ; first step(s) of the algorithm (at call Ih is empty)
+ (mv-let (erp val state)
+ (tool1-fn (subseq L 0 i) state nil t nil t t)
+ (if erp
+ (value nil) ; tool1-fn error case
+ (if (nth 1 val) ; is either a list of consistent constraints or nil
+ (consistency L Ih (+ i 1) state)
+ ; if no contradictions in L[0 .. i], proceed with L[0 .. i+1]
+ ; else the added constraint is removed from L and added to Ih
+ (consistency (remove (nth (- i 1) L) L)
+ (cons (nth (- i 1) L) Ih) 1 state)))))
+ (t (mv-let (erp val state) ; one step of the algorithm
+ (tool1-fn Ih state nil t nil t t)
+ (if erp
+ (value nil) ; tool1-fn error case
+ (if (nth 1 val)
+ (mv-let (erp1 val1 state)
+ (tool1-fn (append Ih (subseq L 0 i))
+ state nil t nil t t)
+ ; check of the consistency of the union of Ih and L[0 .. i]
+ (if erp1
+ (value nil) ; tool1-fn error case
+ (if (nth 1 val1)
+ (consistency L Ih (+ i 1) state)
+ (consistency (remove (nth (- i 1) L) L)
+ (cons (nth (- i 1) L) Ih) 1 state))))
+ (value Ih))))))
+ (value nil)))
+
+
+
+; check-consistency returns t if l is consistent
+; else it calls consistency
+
+(defun check-consistency (l state)
+ (if (true-listp l)
+ (cond ((endp l) (value nil))
+ (t (mv-let (erp val state)
+ (tool1-fn l state nil t nil t t)
+ (if erp
+ (value nil) ; tool1-fn error case
+ (if (nth 1 val)
+ (value t) ; l contains no contradictions
+ (consistency l nil 1 state))))))
+ ; l is not consistent and
+ ; we call consistency to extract the set of contradictory hyps
+ (value nil)))
+
+(logic)
+
+
diff --git a/books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.pdf.gz b/books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.pdf.gz
new file mode 100644
index 0000000..0840da6
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.ps.gz b/books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.ps.gz
new file mode 100644
index 0000000..b156b14
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/schmaltz-borrione-final.ps.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-borrione/schmaltz-presentation.pdf.gz b/books/workshops/2003/schmaltz-borrione/schmaltz-presentation.pdf.gz
new file mode 100644
index 0000000..386c66d
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/schmaltz-presentation.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-borrione/schmaltz-presentation.ps.gz b/books/workshops/2003/schmaltz-borrione/schmaltz-presentation.ps.gz
new file mode 100644
index 0000000..bf22e6c
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/schmaltz-presentation.ps.gz
Binary files differ
diff --git a/books/workshops/2003/schmaltz-borrione/support/arbiter.lisp b/books/workshops/2003/schmaltz-borrione/support/arbiter.lisp
new file mode 100644
index 0000000..ade2277
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/support/arbiter.lisp
@@ -0,0 +1,505 @@
+;------------------------------------------------------------------------
+;
+; File : arbiter.lisp
+; Author : Julien Schmaltz
+; April 2003
+; TIMA-VDS
+; Grenoble, France
+;
+;------------------------------------------------------------------------
+
+
+(in-package "ACL2")
+
+; my little book on inequalities
+(include-book "inequalities")
+
+; the book on decoder and select
+(include-book "decoder")
+
+; my book with the needed predicates
+(include-book "predicates")
+
+;--------------------------------------------------------------------------
+
+; Bus Arbitration Modeling
+
+
+;------------------------------------------------------------------------------
+;
+; first step of the algorithm
+;
+;-----------------------------------------------------------------------------
+
+; function that returns the number of the first line containing at least one
+; request or 0
+
+(defun stage_P (L)
+ (cond ((endp L) 0)
+ ((no_requestp_matrix L) 0)
+ ((not (no_requestp (car L))) 0)
+ (t
+ (+ 1 (stage_P (cdr L))))))
+
+; ACL2 finds that the result is a positive integer
+
+;------------------------------------------------------------------------------
+
+; Verification of this step
+
+;------------------------------------------------------------------------------
+
+
+; this step is correct if:
+
+
+; stage_P returns an integer
+
+;(defthm integerp_stage_P
+; (integerp (stage_P L)))
+; proven during definition
+
+; stage_P returns a positive
+
+;(defthm stage_P_>=0
+; (<= 0 (stage_P L)))
+
+; stage number <= master number - 1
+
+(defthm stage_p_<=_len_L-1
+ (implies (and (consp L) (not (no_requestp_matrix L)))
+ (<= (stage_P L) (- (len L) 1))))
+; Prove 0.05
+
+; or stage number < master number
+
+(defthm stage_p_<_len_L
+ (implies (and (consp L) (not (no_requestp_matrix L)))
+ (< (stage_P L) (len L))))
+; Prove 0.03
+
+; any line before the chosen one RLINE contains no pending request
+
+(defthm prior_scheme
+ (implies (and (equal (stage_P L) i)
+ (< j i) (<= 0 j))
+ (no_requestp (nth j L)))
+ :rule-classes ((:rewrite :match-free :all)))
+; Prove 0.08
+
+; A chosen stage contains at least one request
+
+(defthm chosen_stage_not_empty
+ (implies (and (equal (stage_P L) i) (not (no_requestp_matrix L)))
+ (not (no_requestp (nth i L)))))
+; Prove 0.19
+
+(in-theory (disable stage_P))
+
+
+;------------------------------------------------------------------------------
+;
+; Second step of the algorithm
+;
+;-----------------------------------------------------------------------------
+
+; computation of the next requesting master to be granted the bus according to
+; a round robin scheme
+
+(defun round_robin (RLINE Last_Granted)
+ (cond ((no_requestp RLINE) 0)
+ ((no_requestp (lastn (1+ Last_Granted) RLINE))
+ (find_next_1 (firstn (1+ Last_Granted) RLINE)))
+ (t
+ (+ (1+ Last_Granted) (find_next_1 (lastn (1+ Last_Granted) RLINE))))))
+
+; Type-presciption: acl2-numberp
+
+;------------------------------------------------------------------------------
+
+; Verification of this step
+
+;------------------------------------------------------------------------------
+
+; round_robin returns an integer if its inputs are integers
+
+(defthm integerp_round_robin
+ (implies (integerp Last_Granted) ;(<= 0 Last_Granted))
+ (integerp (round_robin RLINE Last_Granted))))
+; Prove 0.01
+
+; if inputs are positive then rounb_robin is positive
+
+(defthm round_robin_>=_0
+ (implies (<= 0 Last_Granted)
+ (<= 0 (round_robin RLINE Last_Granted))))
+; Prove 0.02
+
+; If RLINE has no request then round_robin returns 0
+
+(defthm no_req_=>_round_robin_=_0
+ (implies (no_requestp RLINE)
+ (equal (round_robin RLINE Last_Granted) 0)))
+
+; we prove that round_robin returns an integer less than the length of RLINE
+
+; if the last part of the list L containing at least one request
+; contains no request, then the first part of the list contains at least one
+; request
+
+(defthm lemma_for_round_robin_<_case_2
+ (implies (and (not (no_requestp L)) (no_requestp (lastn n L)))
+ (not (no_requestp (firstn n L))))
+ :hints (("GOAL" :in-theory (enable no_requestp lastn firstn))))
+; Prove 0.32
+
+;(defthm round_robin_<_N_case_1
+; (implies (and (no_requestp RLINE) (equal (len RLINE) N) (consp RLINE))
+; (< (round_robin RLINE Last_Granted) N)))
+
+(defthm lemma1_case_2
+ (implies (and (not (no_requestp (firstn n L)))
+ (list_of_1_and_0 (firstn n L)))
+ (<= (find_next_1 (firstn n L)) (len (firstn n L))))
+ :hints (("GOAL" :use (:instance find_next_1_<_len_L (L (firstn n L)))
+ :in-theory (disable find_next_1_<_len_L)))
+ :rule-classes ((:rewrite :match-free :all)))
+; Prove 0.33
+
+(defthm lemma2_case_2
+ (implies (and (<= a b) (< b c))
+ (< a c))
+ :rule-classes ((:rewrite :match-free :all)))
+
+(defthm lemma3_case_2
+ (implies (and (<= 0 n) (< n (len L)))
+ (< (len (firstn n L)) (len L))))
+; Prove 0.02
+
+(defthm lemma4_case_2
+ (implies (and (not (no_requestp (firstn n L)))
+ (< n (len L)) (<= 0 n)
+ (list_of_1_and_0 (firstn n L)))
+ (< (find_next_1 (firstn n L)) (len L)))
+ :hints (("GOAL" :use (:instance lemma1_case_2)
+ :do-not-induct t
+ :in-theory (disable len-firstn lemma1_case_2))))
+; Prove 0.26
+
+(defthm round_robin_<_N_case_2
+ (implies (and (no_requestp (lastn (1+ Last_Granted) RLINE))
+ (< (1+ Last_Granted) (len RLINE))
+ (not (no_requestp RLINE))
+ (list_of_1_and_0 (firstn (1+ Last_Granted) RLINE))
+ (< 0 (1+ Last_Granted)))
+ (< (round_robin RLINE Last_Granted) (len RLINE)))
+ :hints (("GOAL" :do-not-induct t
+ :in-theory (disable firstn))))
+; Prove 0.05
+
+(defthm lemma1_case_3
+ (implies (and (not (no_requestp (lastn n L)))
+ (list_of_1_and_0 (lastn n L)))
+ (< (find_next_1 (lastn n L)) (len (lastn n L))))
+ :hints (("GOAL" :use (:instance find_next_1_<_len_L (L (lastn n L)))
+ :in-theory (disable find_next_1_<_len_L))))
+; subsume but useful
+; Prove 0.01
+
+;(defthm lemma2_case_3
+; (implies (and (integerp n) (< 0 n) (< n (len L)) (consp L))
+; (<= (len (lastn n L)) (- (len L) n)))) ; USELESS
+
+;(defthm lemma3_case_3
+; (implies (and (< a b) (<= b c))
+; (< a c))
+; :rule-classes ((:rewrite :match-free :all))) ; USELESS
+
+(defthm lemma4_case_3
+ (implies (and (integerp n) (< 0 n) (< n (len L))
+ (list_of_1_and_0 (lastn n L))
+ (not (no_requestp (lastn n L)))
+ (consp L))
+ (< (find_next_1 (lastn n L)) (- (len L) n)))
+ :hints (("GOAL" :use (:instance lemma1_case_3)
+ :do-not-induct t
+ :in-theory (disable lemma1_case_3))))
+; Prove 0.19
+
+(defthm lemma5_case_3
+ (implies (and (integerp n) (< 0 n) (< n (len L))
+ (list_of_1_and_0 (lastn n L))
+ (not (no_requestp (lastn n L)))
+ (consp L))
+ (< (+ n (find_next_1 (lastn n L))) (len L)))
+ :hints (("GOAL" :use (:instance lemma4_case_3)
+ :do-not-induct t
+ :in-theory (disable lemma4_case_3))))
+; Prove 0.06
+
+(defthm round_robin_<_N_case_3
+ (implies (and (not (no_requestp (lastn (1+ Last_Granted) RLINE)))
+ (not (no_requestp RLINE))
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (list_of_1_and_0 (lastn (1+ Last_Granted) RLINE))
+ (consp (lastn (1+ Last_Granted) RLINE))
+ (< (1+ Last_Granted) (len RLINE)))
+ (< (round_robin RLINE Last_Granted) (len RLINE)))
+ :hints (("GOAL" :use (:instance lemma5_case_3 (n (1+ Last_Granted))
+ (L RLINE))
+ :do-not-induct t
+ :in-theory (disable lemma5_case_3))))
+; Prove 0.06
+
+(defthm list_REQ_=>_list_last
+ (implies (and (list_of_1_and_0 L) (consp L)
+ (integerp n) (< 0 n) (< n (len L)))
+ (list_of_1_and_0 (lastn n L)))
+ :hints (("GOAL" :in-theory (enable lastn))))
+; Prove 0.80
+
+(defthm round_robin_<_N
+ (implies (and (integerp Last_Granted) (consp RLINE) (<= 0 Last_Granted)
+ (< (1+ Last_Granted) (len RLINE)) (not (no_requestp RLINE))
+ (<= 0 Last_Granted) (list_of_1_and_0 RLINE))
+ (< (round_robin RLINE Last_Granted) (len RLINE)))
+ :hints (("GOAL" :use (:instance round_robin_<_N_case_3)
+ :do-not-induct t
+ :in-theory (disable firstn round_robin_<_N_case_3))))
+; Prove 0.24
+
+(defthm round_robin_<=N-1
+ (implies (and (integerp Last_Granted) (consp RLINE) (<= 0 Last_Granted)
+ (< (1+ Last_Granted) (len RLINE)) (not (no_requestp RLINE))
+ (<= 0 Last_Granted) (list_of_1_and_0 RLINE))
+ (<= (round_robin RLINE Last_Granted) (1- (len RLINE))))
+ :hints (("GOAL" :use (:instance round_robin_<_N)
+ :in-theory (disable firstn round_robin_<_N))))
+; Prove 0.25
+
+; No_Deadlock
+
+(defthm find_not_equal_last_granted
+ (implies (and (not (equal last_granted i)) (equal (nth i L) 1)
+ (< i last_granted)
+ (integerp last_granted) (integerp i) (<= 0 i))
+ (not (equal (find_next_1 L) last_granted)))
+ :hints (("GOAL" :in-theory (enable find_next_1)))
+ :rule-classes ((:rewrite :match-free :all)))
+; Prove 0.24
+
+(defthm lemma1_no_deadlock
+ (implies (and (integerp last_granted)
+ (integerp i)
+ (equal (nth last_granted RLINE) 1)
+ (equal (nth i RLINE) 1)
+ (list_of_1_and_0 RLINE)
+ (<= 0 i)
+ (< i (1+ last_granted))
+ (not (equal last_granted i)))
+ (not (equal (round_robin RLINE Last_Granted) Last_Granted)))
+ :hints (("GOAL" :use (:instance find_not_equal_last_granted
+ (L (firstn (1+ Last_Granted) RLINE)))
+ :in-theory (disable find_not_equal_last_granted firstn)))
+ :rule-classes ((:rewrite :match-free :all)))
+; prove 0.24
+
+(defthm lemma2_no_deadlock
+ (implies (and (integerp i) (integerp n) (< 0 n))
+ (implies (and (no_requestp (lastn n L)) (equal (nth i L) 1))
+ (< i n)))
+ :hints (("GOAL" :in-theory (enable lastn no_requestp)))
+ :rule-classes ((:rewrite :match-free :all))
+)
+; Prove 0.32
+
+(defthm no_deadlock
+ (implies (and (integerp i) (<= 0 i)
+ (equal (nth Last_Granted RLINE) 1) (list_of_1_and_0 RLINE)
+ (not (equal Last_granted i)))
+ (implies (equal (nth i RLINE) 1)
+ (not (equal (round_robin RLINE Last_Granted) Last_Granted))))
+ :hints (("GOAL" :use lemma1_no_deadlock
+ :in-theory (disable lemma1_no_deadlock firstn)))
+ :rule-classes ((:rewrite :match-free :all))
+)
+
+; Prove 0.90
+
+(in-theory (disable round_robin))
+
+;------------------------------------------------------------------------------
+;
+; Third step of the algorithm
+;
+;-----------------------------------------------------------------------------
+
+
+; computation of the number of the new granted master
+
+(defun master_num (MREQ N Last_Granted)
+ (+ (* (stage_P MREQ) N)
+ (round_robin (nth (stage_P MREQ) MREQ) Last_Granted)))
+
+; type-prescription: acl2-numberp
+
+;------------------------------------------------------------------------------
+
+; Verification of this step
+
+;------------------------------------------------------------------------------
+
+; master_num returns an integer
+
+(defthm int+int=int
+ (implies (and (integerp a) (integerp b))
+ (integerp (+ a b)))) ; not subsume,
+; Prove 0.00
+
+(defthm integerp_master_num
+ (implies (and (integerp N)
+ (integerp last_granted))
+ (integerp (master_num MREQ N last_granted))))
+; Prove 0.04
+
+; master_num >= 0
+
+(defthm pos+pos=pos
+ (implies (and (<= 0 a) (<= 0 b))
+ (<= 0 (+ a b)))); not subsume
+
+(defthm master_num_>=0
+ (implies (and (integerp N) (< 0 N)
+ (integerp Last_Granted) (<= 0 Last_Granted))
+ (<= 0 (master_num MREQ N Last_Granted))))
+; Prove 0.03
+
+;the default_master (number 0) is chosen when necessary
+
+(defthm default_master_master_num
+ (implies (no_requestp_matrix MREQ)
+ (equal (master_num MREQ N Last_Granted) 0))
+ :hints (("GOAL" :in-theory (enable stage_P round_robin))))
+; Prove 0.24
+
+; the computed number is strictly less than the number of masters
+; number of masters = N * P
+
+
+(defthm len_nth_uni_list
+ (implies (and (integerp p) (<= 0 p)
+ (< p (len l))
+ (uniform_listp l)
+ (consp (cdr l)))
+ (equal (len (nth p l))
+ (len (car l)))))
+; Prove 0.35
+
+(defthm master_num_<_P*N
+ (implies (and ;(< 0 (stage_p MREQ))
+ (integerp N) (< 0 N)
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (integerp P) (equal P (len MREQ))
+ (equal (len (car MREQ)) N)
+ (consp MREQ)
+ (not (no_requestp_matrix MREQ))
+ (uniform_listp MREQ)
+ (consp (cdr MREQ))
+ (< (1+ Last_Granted) N)
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ )
+ (< (master_num MREQ N Last_Granted) (* P N)))
+ :hints (("GOAL" :use ((:instance stage_P_<_len_L (L MREQ))
+ (:instance round_robin_<=N-1
+ (RLINE (nth (stage_P MREQ) MREQ))))
+ :in-theory (e/d ()
+ (COMMUTATIVITY-OF-* COMMUTATIVITY-OF-+
+ uniform_listp no_requestp_matrix
+ stage_P_<_len_L
+ firstn nth
+ round_robin_<=N-1)))))
+; the proof require the inequalities book
+; Prove 0.60
+
+(in-theory (disable master_num))
+
+;------------------------------------------------------------------------------
+;
+; Last step of the algorithm
+;
+;-----------------------------------------------------------------------------
+
+; builds the ouptut vector
+
+(defun arbiter (N P MREQ Last_Granted)
+ (select (* N P) (master_num MREQ N Last_Granted)))
+
+;------------------------------------------------------------------------------
+
+; Verification de cette etape
+
+;------------------------------------------------------------------------------
+
+; arbiter returns a true-list
+; found during definition
+;(defthm true-listp_AHB_Arbiter
+; (true-listp (AHB_Arbiter N P MREQ Last_Granted)))
+
+; length of arbiter is the number of masters = N*P
+
+(defthm len_arbiter
+ (implies (and (integerp N) (< 0 N) (integerp P) (<= 0 P))
+ (equal (len (arbiter N P MREQ Last_Granted)) (* N P))))
+; Prove 0.02
+
+; arbiter is a cons-pair
+
+(defthm consp_arbiter
+ (implies (and (integerp N) (< 0 N) (integerp P) (< 0 P))
+ (consp (arbiter N P MREQ Last_Granted))))
+; Prove 0.00
+
+; The bit at 1 is the desired one
+
+(defthm nth_arbiter_=_1
+ (implies (and (integerp N) (< 0 N)
+ (integerp Last_Granted) (<= 0 Last_granted)
+ (integerp P)
+ (equal P (len MREQ))
+ (equal (len (car MREQ)) N)
+ (not (no_requestp_matrix MREQ))
+ (uniform_listp MREQ)
+ (< (1+ Last_granted) N)
+ (consp MREQ)
+ (consp (cdr MREQ))
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ )
+ (equal (nth (master_num MREQ N Last_granted)
+ (arbiter N P MREQ Last_granted)) 1))
+ :hints (("GOAL" :use (:instance master_num_<_P*N)
+ :do-not-induct t
+ :in-theory (disable master_num_<_P*N
+ DISTRIBUTIVITY
+ ))))
+; Prove 1.43
+
+; we prove the mutual exlusion, i.e. all other bits are 0
+
+(defthm nth_arbiter_=_0
+ (implies (and (integerp N)
+ (equal P (len MREQ))
+ (integerp i) (<= 0 i) (< i (* P N))
+ (not (equal i (master_num MREQ N last_Granted)))
+ )
+ (equal (nth i
+ (arbiter N P MREQ Last_granted)) 0)))
+; Prove 0.03
+
+(in-theory (disable arbiter))
+;------------------------------------------------------------------------------
+;Summary
+;Form: (CERTIFY-BOOK "arbiter" ...)
+;Rules: NIL
+;Warnings: Guards, Subsume, Non-rec and Compiled file
+;Time: 13.76 seconds (prove: 5.47, print: 0.55, other: 7.74)
+; "/h3/schmaltz/These/ACL2_Workshop/2003/Support/arbiter.lisp"
diff --git a/books/workshops/2003/schmaltz-borrione/support/decoder.lisp b/books/workshops/2003/schmaltz-borrione/support/decoder.lisp
new file mode 100644
index 0000000..022faac
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/support/decoder.lisp
@@ -0,0 +1,218 @@
+;------------------------------------------------------------------------
+;
+; File : decoder.lisp
+; Author : Julien Schmaltz
+;
+; April 2003
+; TIMA-VDS
+; Grenoble, France
+;
+;------------------------------------------------------------------------
+
+(in-package "ACL2")
+
+; book on arithmetics
+(include-book "../../../../arithmetic/top")
+
+(include-book "../../../../arithmetic-2/floor-mod/floor-mod")
+
+;-------------------------------------------------------------------------
+;
+;
+; SELECT
+;
+;
+;------------------------------------------------------------------------
+
+; function that builds a list of bits where
+; the first element is the least significant bit
+; the bit at position sel is '1' and others are '0'
+
+(defun select (Card_S SEL)
+ (cond ((not (integerp Card_S)) nil)
+ ((<= Card_S 0) nil)
+ ((equal SEL 0)
+ (cons 1 (select (1- Card_S) (1- SEL))))
+ (t
+ (cons 0 (select (1- Card_S) (1- SEL))))))
+
+;----------------------------------------------------------------------------
+;
+;
+; LEMMAS ON SELECT
+;
+;----------------------------------------------------------------------------
+
+
+; 1- select returns a true-list
+; (ACL2 finds that when accepting the definition)
+
+;(defthm true-listp_select
+; (true-listp (select a b)))
+
+; 2- the length of the list is equal to Card_S
+
+(defthm len_select
+ (implies (and (integerp Card_S) (<= 0 Card_S))
+ (equal (len (select Card_S sel)) Card_S)))
+; Prove 0.03
+
+; 3- select returns a cons-pair when Card_S> 0
+
+(defthm consp_select
+ (implies (and (integerp Card_S) (< 0 Card_S))
+ (consp (select Card_S sel)))
+ :hints (("GOAL" :expand (select 1 sel))))
+; Prove 0.03
+
+; 4- if (integerp Card_S) and (< 0 Card_S) then (car (select Card_S0)) is 1
+; this lemma is needed to ease the proof of the next theorem
+
+(defthm car_select_=_1
+ (implies (and (integerp Card_S) (< 0 Card_S))
+ (equal (car (select Card_S 0)) 1)))
+; Prove 0.01
+
+; 5- the i'th bit of (select Card_S i) is 1
+; That proofs that the selection of the slave is correct
+; SLAVE CHOICE CORRECTNESS
+(defthm ith_select_=_1
+ (implies (and (integerp i) (integerp Card_S)
+ (>= i 0) (> Card_S i))
+ (equal (nth i (select Card_S i )) 1)))
+; Prove 0.06
+
+; 6- if p is not equal to i, then (car (select a i)) is 0
+; lemma needed for the proof of the UNICITY theorem
+
+(defthm car_select_=_0
+ (implies (and (integerp Card_S) (< 0 Card_S) (not (equal i 0)))
+ (equal (car (select Card_S i)) 0))
+ :hints (("GOAL"
+ :expand (select 1 I))))
+; Prove 0.06
+
+; 7- The p'th is 0
+
+; function suggesting the induction scheme for the proof of the UNICITY theorem
+
+(local
+ (defun function_hint_th2_select (p Card_S sel)
+ (cond ((zp p) 0)
+ ((and (not (integerp Card_S))
+ (not (integerp sel)))
+ 0)
+ (t (+ 1 (function_hint_th2_select (1- p)
+ (1- Card_S)
+ (1- sel))))))
+)
+
+; UNIQUENESS OF THE SELECTION
+(defthm pth_select_=_0
+ (implies (and (integerp p) (integerp Card_S)
+ (<= 0 p) (< p Card_S)
+ (not (equal p i)))
+ (equal (nth p (select Card_S i)) 0))
+ :hints (("GOAL"
+ :induct (function_hint_th2_select p Card_S i))))
+; Prove 0.10
+
+(in-theory (disable select))
+;-------------------------------------------------------------------------
+;
+;
+; DECODER
+;
+;
+;------------------------------------------------------------------------
+
+
+;--------------------------------------------------------------------------
+;
+; function modeling the address decoder
+; Card_S = number of slaves
+; ADDR = Global address of data
+; MEM_SIZE = memory size of each unit
+
+; the local address UNADDR is equal to ADDR mod MEM_SIZE
+; the slave number i that possed the datum at ADDR is HADDR/MEM_SIZE
+
+(defun decoder (MEM_SIZE Card_S HADDR)
+ (select Card_S (floor HADDR MEM_SIZE)))
+
+; when accepting the function ACL2 finds that this function returns a true-list
+
+;-------------------------------------------------------------------------
+;
+; PREUVE DE AHB_DECODER
+;
+;------------------------------------------------------------------------
+
+
+; lemma stating that (floor ADDR MEM_SIZE) < Card_S
+; if ADDR = Card_S * MEM_SIZE
+; lemma needed for the proof of the next theorem
+
+(defthm floor_<_Card_S
+ (implies (and (< HADDR (* Card_S MEM_SIZE))
+ (integerp HADDR) (integerp MEM_SIZE)
+ (< 0 MEM_SIZE) (< 0 Card_S) (<= 0 ADDR)
+ (integerp Card_S))
+ (< (floor HADDR MEM_SIZE) Card_S))
+ :hints (("GOAL" :in-theory (disable floor COMMUTATIVITY-OF-* FLOOR-MOD-ELIM
+ DISTRIBUTIVITY-OF-/-OVER-*
+ FUNCTIONAL-SELF-INVERSION-OF-/))))
+; Prove 1.70
+
+; decoder returns 1
+
+(defthm decoder_nth_1
+ (implies (and (< HADDR (* Card_S MEM_SIZE))
+ (integerp HADDR) (integerp MEM_SIZE)
+ (< 0 MEM_SIZE) (< 0 Card_S) (<= 0 HADDR)
+ (integerp Card_S))
+ (equal (nth (floor HADDR MEM_SIZE)
+ (decoder MEM_SIZE Card_S HADDR)) 1))
+ :hints (("GOAL"
+ :in-theory (disable floor ))))
+; Prove 0.11
+
+; decoder returns 0
+
+(defthm decoder_nth_0
+ (implies (and (integerp p) (integerp Card_S)
+ (<= 0 p) (< p Card_S)
+ (not (equal p (floor HADDR MEM_SIZE))))
+ (equal (nth p (decoder MEM_SIZE Card_S HADDR)) 0))
+ :hints (("GOAL" :in-theory (disable floor))))
+; Prove 0.02
+
+
+; DECODER returns a true-list
+; (already found by ACL2)
+;(defthm true-listp_DECODER
+; (true-listp (DECODER MEM_SIZE Card_S ADDR)))
+
+; the length of DECODER is its second operand
+
+(defthm len_DECODER
+ (implies (and (integerp Card_S) (<= 0 Card_S))
+ (equal (len (DECODER MEM_SIZE Card_S HADDR)) Card_S)))
+
+; DECODER is a conspair
+
+(defthm consp_DECODER
+ (implies (and (integerp Card_S) (< 0 Card_S))
+ (consp (DECODER MEM_SIZE Card_S HADDR))))
+
+
+(in-theory (disable DECODER))
+
+;------------------------------------------------------------------------
+
+;Summary
+;Form: (CERTIFY-BOOK "decoder" ...)
+;Rules: NIL
+;Warnings: Guards and Non-rec
+;Time: 7.41 seconds (prove: 2.48, print: 0.24, other: 4.69)
+; "/h3/schmaltz/These/ACL2_Workshop/2003/Support/decoder.lisp"
diff --git a/books/workshops/2003/schmaltz-borrione/support/inequalities.lisp b/books/workshops/2003/schmaltz-borrione/support/inequalities.lisp
new file mode 100644
index 0000000..8c883a7
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/support/inequalities.lisp
@@ -0,0 +1,100 @@
+;------------------------------------------------------------------------
+;
+; File : inequalities.lisp
+; Author : Julien Schmaltz
+; April 2003
+; TIMA - VDS
+; Grenoble, France
+;------------------------------------------------------------------------
+
+(in-package "ACL2")
+
+
+(include-book "../../../../arithmetic/top")
+
+
+;-----------------------------------------------------------------------
+;
+;
+; Conclusion to reach: a*b + c < P*b
+;
+; Hypotheses : a, b, c, P are naturals
+; a <= P - 1
+; c <= b - 1
+;
+;
+;
+; Intermediate Theorem: a*b + c <= P*b - 1
+;
+;-------------------------------------------------------------------------
+
+; the "majorant" of the sum is the sum of the majorants
+
+(defthm maj_sum_=_sum_maj
+ (implies (and (integerp a) (integerp b)
+ (integerp alpha) (<= 0 a) (<= a alpha))
+ (<= (+ a b) (+ alpha b))))
+; Prove 0.00
+
+; for positives the majorant of the product is the product of the majorants
+
+(defthm maj_prod_=_prod_maj
+ (implies (and (integerp a) (integerp b) (< 0 b)
+ (integerp alpha) (<= 0 a) (<= a alpha))
+ (<= (* a b) (* alpha b)))
+ :hints (("GOAL" :in-theory (disable COMMUTATIVITY-OF-* DISTRIBUTIVITY))))
+; Prove 0.01
+
+; PROOF OF THE INTERMEDIATE THEOREM
+
+(defthm lemma1
+ (implies (and (integerp a) (integerp b) (integerp c)
+ (<= 0 a) (< 0 b) (integerp alpha) (<= (* a b) (* alpha b)))
+ (<= (+ (* a b) c) (+ (* alpha b) c))))
+; Prove 0.00
+
+(defthm lemma2
+ (implies (and (integerp a) (integerp b) (integerp c)
+ (<= 0 a) (< 0 b) (integerp alpha) (<= a alpha))
+ (<= (+ (* a b) c) (+ (* alpha b) c)))
+ :hints (("GOAL" :use (:instance maj_prod_=_prod_maj)
+ :in-theory (disable maj_prod_=_prod_maj COMMUTATIVITY-OF-+))))
+; Prove 0.13
+
+(defthm lemma3
+ (implies (and (integerp a) (integerp b) (integerp c)
+ (<= 0 a) (< 0 b) (integerp alpha) (<= a alpha)
+ (<= c (1- b)))
+ (<= (+ (* a b) c) (+ (* alpha b) (1- b))))
+ :hints (("GOAL" :use (:instance lemma2)
+ :in-theory (disable lemma2))))
+; Prove 0.03
+
+(defthm intermediate_theorem
+ (implies (and (integerp a) (integerp b) (integerp c)
+ (<= 0 a) (< 0 b) (<= 0 c) (<= c (1- b))
+ (<= a (1- P)) (integerp P))
+ (<= (+ (* a b) c) (+ (* (1- P) b) (1- b))))
+ :hints (("GOAL" :use (:instance lemma3 (alpha (1- P)) )
+ :in-theory (disable COMMUTATIVITY-OF-* DISTRIBUTIVITY
+ COMMUTATIVITY-OF-+ lemma3))))
+
+; final theorem
+
+(defthm final_theorem
+ (implies (and (integerp a) (integerp b) (integerp c)
+ (<= 0 a) (< 0 b) (<= 0 c) (<= c (1- b))
+ (<= a (1- P)) (integerp P))
+ (< (+ (* a b) c) (* P b)))
+ :hints (("GOAL" :use (:instance intermediate_theorem)
+ :in-theory (disable intermediate_theorem))))
+
+; Prove 0.05
+
+;Summary
+;Form: (CERTIFY-BOOK "inequalities" ...)
+;Rules: NIL
+;Warnings: None
+;Time: 3.71 seconds (prove: 0.26, print: 0.04, other: 3.41)
+; "/h3/schmaltz/These/ACL2_Workshop/2003/Support/inequalities.lisp"
+
diff --git a/books/workshops/2003/schmaltz-borrione/support/predicates.lisp b/books/workshops/2003/schmaltz-borrione/support/predicates.lisp
new file mode 100644
index 0000000..f2d2f75
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/support/predicates.lisp
@@ -0,0 +1,160 @@
+;------------------------------------------------------------------------
+;
+; File : predicates.lisp
+; Author : Julien Schmaltz
+; April 2003
+; TIMA-VDS
+; Grenoble, France
+;
+;------------------------------------------------------------------------
+
+
+(in-package "ACL2")
+
+; ACL2 books on lists
+(include-book "../../../../data-structures/list-defuns")
+
+(include-book "../../../../data-structures/list-defthms")
+
+
+;------------------------------------------------------------------------------
+;
+;
+; Some predicates used in modeling and proofs
+;
+;
+;------------------------------------------------------------------------------
+;
+; recognizer of a list of 0
+;
+;
+(defun no_requestp (REQ)
+ (cond ((endp REQ) t)
+ ((equal (car REQ) 1) nil)
+ (t (and (equal (car REQ) 0)
+ (no_requestp (cdr REQ))))))
+
+; if no_requestp then the car of L is 0
+
+(defthm car_no_requestp
+ (implies (and (no_requestp L) (consp L))
+ (equal (car L) 0)))
+
+; if no_requestp then L is a list of 0
+
+(defthm no_requestp_th1
+ (implies (and (no_requestp L) (consp L) (< i (len L)))
+ (equal (nth i L) 0)))
+; prove 0.07
+
+(defthm no_requestp_th2
+ (implies (no_requestp L)
+ (not (equal (nth i L) 1))))
+; Prove 0.03
+
+(defthm not_no_requestp_cdr_=>_not_no_requestp_L
+ (implies (not (no_requestp (cdr L)))
+ (not (no_requestp L))))
+
+(in-theory (disable no_requestp))
+
+;------------------------------------------------------------------------------
+; recognizer of a matrix with no requests
+
+(defun no_requestp_matrix (M)
+ (cond ((endp M) t)
+ ((no_requestp (car M))
+ (no_requestp_matrix (cdr M)))
+ (t
+ nil)))
+
+;------------------------------------------------------------------------------
+
+; recognizer of a list of 1 and 0, i.e. a bit vector
+
+(defun list_of_1_and_0 (L)
+ (if (endp (cdr L))
+ (or (equal (car L) 0) (equal (car L) 1))
+ (and (or (equal (car L) 0) (equal (car L) 1))
+ (list_of_1_and_0 (cdr L)))))
+
+(defthm list_of_1_and_0_cdr
+ (implies (and (list_of_1_and_0 L) (consp (cdr L)))
+ (list_of_1_and_0 (cdr L))))
+
+(defthm list_REQ_=>_list_first
+ (implies (and (list_of_1_and_0 L) (not (zp n)))
+ (list_of_1_and_0 (firstn n L))))
+; Prove 0.08
+
+;------------------------------------------------------------------------------
+
+; function that returns the last elements af a list form the n + 1
+
+(defun lastn (n L)
+ (cond ((endp L) nil)
+ ((zp n) L)
+ (t
+ (lastn (1- n) (cdr L)))))
+
+(defthm len_lastn
+ (implies (and (integerp n) (< 0 n) (consp L) (< n (len L)))
+ (equal (len (lastn n L)) (- (len L) n))))
+; Prove 0.09
+
+(defthm lastn_no_requestp
+ (implies (and (no_requestp L) (consp L))
+ (and (no_requestp (firstn n L))
+ (no_requestp (lastn n L))))
+ :hints (("GOAL" :in-theory (enable no_requestp))))
+; Prove 0.22
+
+(defthm len_firstn_2
+ (<= (len (firstn n L)) (len L)))
+; Prove 0.01
+
+(in-theory (disable lastn))
+;------------------------------------------------------------------------------
+
+; function that returns the position of the first '1' in the list L
+
+(defun find_next_1 (L)
+ (cond ((endp L) 0)
+ ((equal (car L) 1)
+ 0)
+ (t
+ (+ 1 (find_next_1 (cdr L))))))
+
+; FIND_NEXT_ONE < (LEN L)
+
+(defthm find_next_1_<_len_L
+ (implies (and (not (no_requestp L)) (list_of_1_and_0 L))
+ (< (find_next_1 L) (len L)))
+ :hints (("GOAL" :in-theory (enable no_requestp))))
+; Prove 0.11
+
+(in-theory (disable find_next_1))
+;------------------------------------------------------------------------------
+
+; recognizer of a list composed of list with the same length
+
+(defun uniform_listp (L)
+ (cond ((endp (cdr L)) t)
+ ((not (equal (len (car L)) (len (cadr L)))) nil)
+ (t
+ (uniform_listp (cdr L)))))
+
+; if uniform_list len (len (car l)) = (len (cadr L))
+
+(defthm l_uni_=>_len_car_=_len_cadr
+ (implies (and (consp (cdr L)) (uniform_listp L))
+ (equal (len (car L)) (len (cadr l)))))
+
+
+;--------------------------------------------------------------------------------
+;Summary
+;Form: (CERTIFY-BOOK "predicates" ...)
+;Rules: NIL
+;Warnings: Guards
+;Time: 2.14 seconds (prove: 0.52, print: 0.23, other: 1.39)
+; "/h3/schmaltz/These/ACL2_Workshop/2003/Support/predicates.lisp"
diff --git a/books/workshops/2003/schmaltz-borrione/support/transfers.lisp b/books/workshops/2003/schmaltz-borrione/support/transfers.lisp
new file mode 100644
index 0000000..17c0915
--- /dev/null
+++ b/books/workshops/2003/schmaltz-borrione/support/transfers.lisp
@@ -0,0 +1,412 @@
+;------------------------------------------------------------------------
+;
+; File : transfers.lisp
+; Author : Julien Schmaltz
+; July 2003
+; TIMA-VDS
+; Grenoble, France
+;
+;------------------------------------------------------------------------
+
+
+(in-package "ACL2")
+
+(include-book "decoder")
+(include-book "arbiter")
+
+
+;-----------------------------------------------------------------------
+;
+; Modeling the two interfaces
+;
+;----------------------------------------------------------------------
+
+(defun slave_interface (HSEL HWRITE HADDR HWDATA SD MEM_SIZE)
+ (if (equal HSEL 1)
+ (list (list (if (equal HWRITE 1)
+ 'read
+ 'write)
+ (mod HADDR MEM_SIZE) HWDATA)
+ (list SD))
+
+ nil))
+
+(defun O-slave (x)
+ (nth 0 (nth 0 x)))
+
+(defun L-slave (x)
+ (nth 1 (nth 0 x)))
+
+(defun D-slave (x)
+ (nth 2 (nth 0 x)))
+
+(defun HRDATA (x)
+ (nth 0 (nth 1 x)))
+
+(defun master_interface (O L D HRDATA HGRANT)
+ (if (equal HGRANT 1)
+ (list (list (if (equal O 'Read)
+ 1
+ 0)
+ L
+ D)
+ (list HRDATA))
+ nil))
+
+(defun HWRITE (x)
+ (nth 0 (nth 0 x)))
+
+(defun HADDR (x)
+ (nth 1 (nth 0 x)))
+
+(defun HWDATA (x)
+ (nth 2 (nth 0 x)))
+
+(defun D-master (x)
+ (nth 0 (nth 1 x)))
+
+;-----------------------------------------------------------------------
+;
+; Modeling transfers
+;
+;----------------------------------------------------------------------
+
+; a transfer from a master to a slave is the result of the slave interface
+; function applied on the result of the master interface function
+
+(defun trans_M_to_S (O L D N Card_S P Last_Granted MREQ Slave_Number
+ SD MEM_SIZE)
+ (slave_interface
+ (nth Slave_Number
+ (decoder MEM_SIZE Card_S
+ (HADDR
+ (Master_interface O L D SD
+ (nth (master_num MREQ N Last_Granted)
+ (arbiter N P MREQ Last_Granted))))))
+ (HWRITE
+ (Master_interface O L D SD
+ (nth (master_num MREQ N Last_Granted)
+ (arbiter N P MREQ Last_Granted))))
+ (HADDR
+ (Master_interface O L D SD
+ (nth (master_num MREQ N Last_Granted)
+ (arbiter N P MREQ Last_Granted))))
+ (HWDATA
+ (Master_interface O L D SD
+ (nth (master_num MREQ N Last_Granted)
+ (arbiter N P MREQ Last_Granted))))
+ SD MEM_SIZE))
+
+; the function returns a true-list
+
+
+; a transfer from a slave to a master is the result of the master interface
+; function applied on the result of the slave interface function
+
+(defun trans_S_to_M (O L D SD MEM_SIZE Card_S MREQ N P
+ HWRITE HADDR HWDATA Slave_Number Last_granted)
+ (master_interface O L D
+ (HRDATA
+ (slave_interface
+ (nth Slave_Number
+ (decoder MEM_SIZE Card_S L))
+ HWRITE
+ HADDR
+ HWDATA
+ SD
+ MEM_SIZE))
+ (nth (master_num MREQ N Last_Granted)
+ (arbiter N P MREQ Last_Granted))))
+; returns a true-list
+
+
+
+; validation of transmission of the address and the data
+; from the master to the slave
+
+(defthm trans_M_to_S_thm
+ (implies (and
+ ; P is the number of priority level(s)
+ (integerp P) (equal P (len MREQ))
+ ; N is the length of each level
+ (equal (len (car MREQ)) N)
+ ; at least one master
+ (integerp N) (< 0 N)
+ ; each level has the same length
+ (uniform_listp MREQ)
+ ; the last owner has a valid number
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (< (+ 1 Last_granted) N)
+ ; at least one request
+ (not (no_requestp_matrix MREQ))
+ (consp MREQ) (consp (cdr MREQ))
+ ; each level is a line of bits
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ ; at least one slave unit
+ (integerp Card_S) (< 0 Card_S)
+ ; L is a valid address
+ (integerp L) (<= 0 L) (< L (* Card_S MEM_SIZE))
+ ; the size of the slave memory is at least one
+ (integerp MEM_SIZE) (< 0 MEM_SIZE)
+ ; the slave is active
+ (equal Slave_Number (floor L MEM_SIZE))
+ )
+ (and (equal (L-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted MREQ
+ Slave_Number 'undef MEM_SIZE))
+ (mod L MEM_SIZE))
+ (equal (D-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted MREQ
+ Slave_Number 'undef MEM_SIZE))
+ D)))
+ :hints (("GOAL" ;:use (:instance decoder_nth_1 (ADDR L))
+ :in-theory (disable ;decoder_nth_1
+ floor floor-mod-elim nth))))
+
+; Prove 5.05
+
+; Validation of the read transmission
+
+(defthm trans_M_to_S_read
+ (implies (and
+ ; P is the number of priority level(s)
+ (integerp P) (equal P (len MREQ))
+ ; N is the length of each level
+ (equal (len (car MREQ)) N)
+ ; at least one master
+ (integerp N) (< 0 N)
+ ; each level has the same length
+ (uniform_listp MREQ)
+ ; the last owner has a valid number
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (< (+ 1 Last_granted) N)
+ ; at least one request
+ (not (no_requestp_matrix MREQ))
+ (consp MREQ) (consp (cdr MREQ))
+ ; each level is a line of bits
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ ; at least one slave unit
+ (integerp Card_S) (< 0 Card_S)
+ ; L is a valid address
+ (integerp L) (<= 0 L) (< L (* Card_S MEM_SIZE))
+ ; the size of the slave memory is at least one
+ (integerp MEM_SIZE) (< 0 MEM_SIZE)
+ ; the slave is active
+ (equal Slave_Number (floor L MEM_SIZE))
+ ; the operation is 'read
+ ;(equal O 'read)
+ )
+ (equal (O-slave
+ (trans_M_to_S 'read L D N Card_S P Last_Granted MREQ
+ Slave_Number 'undef MEM_SIZE))
+ 'read)))
+
+; Prove 0.65
+
+; validation of the write transmission
+
+(defthm trans_M_to_S_write
+ (implies (and
+ ; P is the number of priority level(s)
+ (integerp P) (equal P (len MREQ))
+ ; N is the length of each level
+ (equal (len (car MREQ)) N)
+ ; at least one master
+ (integerp N) (< 0 N)
+ ; each level has the same length
+ (uniform_listp MREQ)
+ ; the last owner has a valid number
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (< (+ 1 Last_granted) N)
+ ; at least one request
+ (not (no_requestp_matrix MREQ))
+ (consp MREQ) (consp (cdr MREQ))
+ ; each level is a line of bits
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ ; at least one slave unit
+ (integerp Card_S) (< 0 Card_S)
+ ; L is a valid address
+ (integerp L) (<= 0 L) (< L (* Card_S MEM_SIZE))
+ ; the size of the slave memory is at least one
+ (integerp MEM_SIZE) (< 0 MEM_SIZE)
+ ; the slave is active
+ (equal Slave_Number (floor L MEM_SIZE))
+ ; the operation is 'write
+ ;(equal O 'write)
+ )
+ (equal (O-slave
+ (trans_M_to_S 'write L D N Card_S P Last_Granted MREQ
+ Slave_Number 'undef MEM_SIZE))
+ 'write)))
+
+; Prove 0.63
+
+(defthm trans_S_to_M_thm
+ (implies (and
+ ; P is the number of priority level(s)
+ (integerp P) (equal P (len MREQ))
+ ; N is the length of each level
+ (equal (len (car MREQ)) N)
+ ; at least one master
+ (integerp N) (< 0 N)
+ ; each level has the same length
+ (uniform_listp MREQ)
+ ; the last owner has a valid number
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (< (+ 1 Last_granted) N)
+ ; at least one request
+ (not (no_requestp_matrix MREQ))
+ (consp MREQ) (consp (cdr MREQ))
+ ; each level is a line of bits
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ ; at least one slave unit
+ (integerp Card_S) (< 0 Card_S)
+ ; L is a valid address
+ (integerp L) (<= 0 L) (< L (* Card_S MEM_SIZE))
+ ; the size of the slave memory is at least one
+ (integerp MEM_SIZE) (< 0 MEM_SIZE)
+ ; the slave is active
+ (equal Slave_Number (floor L MEM_SIZE))
+ )
+ (equal (D-master
+ (trans_S_to_M O L D SD MEM_SIZE Card_S MREQ N P HWRITE HADDR
+ HWDATA Slave_Number Last_Granted))
+ SD)))
+; Prove 4.48
+
+
+(in-theory (disable trans_S_to_M trans_M_to_S))
+
+; to get a complete transfer a slave application is needed
+; we define a small memory
+
+(defun slave_memory (MEMO O UNADDR D)
+ (cond ((equal O 'write)
+ (list (put-nth UNADDR D MEMO) D))
+ ((equal O 'read)
+ (list MEMO (nth UNADDR MEMO)))))
+
+
+(defun single_transfer (O L D N P Card_S Last_Granted MREQ Slave_Number
+ MEM_SIZE MEMO)
+ (list
+ (trans_S_to_M O L D
+ (nth 1
+ (slave_memory MEMO
+ (O-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted
+ MREQ Slave_Number 'undef MEM_SIZE))
+ (L-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted
+ MREQ Slave_Number 'undef MEM_SIZE))
+ (D-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted
+ MREQ Slave_Number 'undef MEM_SIZE))))
+ MEM_SIZE Card_S MREQ N P O L D
+ Slave_Number Last_Granted)
+ (nth 0
+ (slave_memory MEMO
+ (O-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted
+ MREQ Slave_Number 'undef MEM_SIZE))
+ (L-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted
+ MREQ Slave_Number 'undef MEM_SIZE))
+ (D-slave
+ (trans_M_to_S O L D N Card_S P Last_Granted
+ MREQ Slave_Number 'undef MEM_SIZE))))))
+
+; returns a true-list
+; a read example
+;ACL2 !>(single_transfer 'Read 2 23 2 2 2 0 '((1 0) (1 0) (0 0)) 0 4 '(0 0 33 0 0 0 0 0))
+;(((0 0 0) (33)) (0 0 33 0 0 0 0 0))
+; a write example
+;ACL2 !>(single_transfer 'Write 2 23 2 2 2 0 '((1 0) (1 0) (0 0)) 0 4 '(0 0 33 0 0 0 0 0))
+;(((0 0 0) (23)) (0 0 23 0 0 0 0 0))
+
+; the read data by the master is the (nth (mod L MEM_SIZE) MEMO)
+
+(defthm single_read_transfer
+ (implies (and
+ ; P is the number of priority level(s)
+ (integerp P) (equal P (len MREQ))
+ ; N is the length of each level
+ (equal (len (car MREQ)) N)
+ ; at least one master
+ (integerp N) (< 0 N)
+ ; each level has the same length
+ (uniform_listp MREQ)
+ ; the last owner has a valid number
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (< (+ 1 Last_granted) N)
+ ; at least one request
+ (not (no_requestp_matrix MREQ))
+ (consp MREQ) (consp (cdr MREQ))
+ ; each level is a line of bits
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ ; at least one slave unit
+ (integerp Card_S) (< 0 Card_S)
+ ; L is a valid address
+ (integerp L) (<= 0 L) (< L (* Card_S MEM_SIZE))
+ ; the size of the slave memory is at least one
+ (integerp MEM_SIZE) (< 0 MEM_SIZE)
+ ; the slave is active
+ (equal Slave_Number (floor L MEM_SIZE))
+ ; the operation is 'read
+ (equal O 'read)
+ )
+ (equal (D-Master
+ (nth 0
+ (single_transfer O L D N P Card_S Last_Granted MREQ
+ Slave_Number MEM_SIZE MEMO)))
+ (nth (mod L MEM_SIZE) MEMO)))
+ :hints (("GOAL" :use trans_M_to_S_read
+ :do-not-induct t
+ :in-theory (disable D-master O-slave L-slave D-slave mod
+ trans_M_to_S floor-mod-elim len))))
+
+; Prove 5.25
+
+; a write transfer is a (put-nth (mod ADDR MEM_SIZE) DATA MEMO)
+
+(defthm single_write_transfer
+ (implies (and
+ ; P is the number of priority level(s)
+ (integerp P) (equal P (len MREQ))
+ ; N is the length of each level
+ (equal (len (car MREQ)) N)
+ ; at least one master
+ (integerp N) (< 0 N)
+ ; each level has the same length
+ (uniform_listp MREQ)
+ ; the last owner has a valid number
+ (integerp Last_Granted) (<= 0 Last_Granted)
+ (< (+ 1 Last_granted) N)
+ ; at least one request
+ (not (no_requestp_matrix MREQ))
+ (consp MREQ) (consp (cdr MREQ))
+ ; each level is a line of bits
+ (list_of_1_and_0 (nth (stage_P MREQ) MREQ))
+ ; at least one slave unit
+ (integerp Card_S) (< 0 Card_S)
+ ; L is a valid address
+ (integerp L) (<= 0 L) (< L (* Card_S MEM_SIZE))
+ ; the size of the slave memory is at least one
+ (integerp MEM_SIZE) (< 0 MEM_SIZE)
+ ; the slave is active
+ (equal Slave_Number (floor L MEM_SIZE))
+ ; the operation is 'read
+ (equal O 'write)
+ ; mem_size is the size of memo
+ (equal (len MEMO) MEM_SIZE)
+ )
+ (equal (nth (mod L MEM_SIZE)
+ (nth 1 (single_transfer O L D N P Card_S Last_Granted MREQ
+ Slave_Number MEM_SIZE MEMO)))
+ D))
+ :hints (("GOAL" :use trans_M_to_S_write
+ :do-not-induct t
+ :in-theory (disable D-master O-slave L-slave D-slave mod
+ floor-mod-elim len nth trans_M_to_S_write))))
+; Prove 6.70
+
diff --git a/books/workshops/2003/sumners/fair.pdf.gz b/books/workshops/2003/sumners/fair.pdf.gz
new file mode 100644
index 0000000..f73ccba
--- /dev/null
+++ b/books/workshops/2003/sumners/fair.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/sumners/fair.ps.gz b/books/workshops/2003/sumners/fair.ps.gz
new file mode 100644
index 0000000..3d86cc6
--- /dev/null
+++ b/books/workshops/2003/sumners/fair.ps.gz
Binary files differ
diff --git a/books/workshops/2003/sumners/slides.pdf.gz b/books/workshops/2003/sumners/slides.pdf.gz
new file mode 100644
index 0000000..0d6add5
--- /dev/null
+++ b/books/workshops/2003/sumners/slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/sumners/slides.ps.gz b/books/workshops/2003/sumners/slides.ps.gz
new file mode 100644
index 0000000..3575e2d
--- /dev/null
+++ b/books/workshops/2003/sumners/slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/sumners/support/README b/books/workshops/2003/sumners/support/README
new file mode 100644
index 0000000..a57a6d4
--- /dev/null
+++ b/books/workshops/2003/sumners/support/README
@@ -0,0 +1,22 @@
+The following books should certify in v2-7, v2-8, etc. The definitions in n2n.lisp test
+the version since there are a couple of functions whose definitions change from v2-7 to
+v2-8 (see n2n.lisp for details).
+
+fair1.lisp -- a "book" demonstrating the logical equivalence between our fair
+ env. assumptions and a straightforward statement of (fair-selection)
+example1.lisp -- a simple example application of the straightforward fair selector
+ defined in fair1.lisp.
+ -- the fair selector in fair2.lisp is a better book to use than
+ fair1.lisp because it does not require the (fair-selection)
+ constant predicate as an hypothesis to liveness and other theorems.
+simple.lisp -- a simple fair selector over bounded naturals
+ -- only provided for exposition, this is completely subsumed
+ by fair2.lisp
+n2n.lisp -- an invertible function from the "nice" or "good" ACL2 objects
+ to natural numbers
+fair2.lisp -- an unconditional fair selection environment for "nice" ACL2 objects
+example2.lisp -- a simple example application of the unconditional fair selector in
+ fair2.lisp
+example3.lisp -- a more complex application of the unconditional fair selector in
+ fair2.lisp
+cfair.lisp -- a conditional fair selector for "nice" ACL2 objects
diff --git a/books/workshops/2003/sumners/support/cfair.lisp b/books/workshops/2003/sumners/support/cfair.lisp
new file mode 100644
index 0000000..a148641
--- /dev/null
+++ b/books/workshops/2003/sumners/support/cfair.lisp
@@ -0,0 +1,437 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+
+#| cfair.lisp
+
+This book defines a "conditional" fair selector which is restricted to select
+only "legal" inputs specified for the system. Complications arise in defining
+this type of fairness. In particular, the fair selection is now dependent on
+the system state and as such, the definition of fair-run will be mutually
+recursive with run (or alternatively, they could be merged into a single "run"
+function which updates a pair of system state with fair selector state). Given
+this added complexity, we do not suggest the use of this selector, but instead
+suggest the use of the strong selector in fair.lisp which affords a cleaner
+composition. We provide the definition of this selector nonetheless since it
+may prove useful in some contexts.
+
+|#
+
+(include-book "n2n")
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+(encapsulate
+ (((legal-input * *) => *)
+ ((legal-witness *) => *))
+
+ (local (defun legal-input (s i) (equal (nfix s) (nfix i))))
+ (local (defun legal-witness (s) (nfix s)))
+
+ (defthm legal-witness-is-legal
+ (legal-input s (legal-witness s)))
+ (defthm legal-witness-is-nice
+ (nicep (legal-witness s)))
+)
+
+(defun legal-in-lst (s lst)
+ (and (consp lst)
+ (if (legal-input s (nat->nice (first lst)))
+ (first lst)
+ (legal-in-lst s (rest lst)))))
+
+(defun drop-lst (lst n)
+ (cond ((endp lst) ())
+ ((equal n (first lst))
+ (drop-lst (rest lst) n))
+ (t (cons (first lst)
+ (drop-lst (rest lst) n)))))
+
+(defun pos-in-lst (lst n)
+ (cond ((endp lst) nil)
+ ((equal n (first lst)) 0)
+ (t (and (pos-in-lst (rest lst) n)
+ (1+ (pos-in-lst (rest lst) n))))))
+
+(defthm impossible-case-for-ctr
+ (implies (equal ctr (nice->nat (legal-witness s)))
+ (legal-input s (nat->nice ctr))))
+
+(defun find-ndx (s top ctr)
+ (declare (xargs :measure
+ (let ((goal (nice->nat (legal-witness s))))
+ (cons (1+ (nfix (- goal top)))
+ (nfix (if (>= goal ctr)
+ (- goal ctr)
+ (+ 1 (- top ctr) goal)))))))
+ (cond ((or (not (natp ctr))
+ (not (natp top))
+ (> ctr top))
+ 0)
+ ((legal-input s (nat->nice ctr))
+ ctr)
+ ((< ctr top)
+ (find-ndx s top (1+ ctr)))
+ (t
+ (find-ndx s (1+ top) 0))))
+
+(defun snoc (e x)
+ (if (endp x) (list e)
+ (cons (first x) (snoc e (rest x)))))
+
+(defun step-env (s hold top ctr)
+ (declare (xargs :measure
+ (let ((goal (nice->nat (legal-witness s))))
+ (cons (1+ (nfix (- goal top)))
+ (nfix (if (>= goal ctr)
+ (- goal ctr)
+ (+ 1 (- top ctr) goal)))))))
+ (cond ((or (not (natp ctr))
+ (not (natp top))
+ (> ctr top))
+ (list hold 1 0))
+ ((legal-input s (nat->nice ctr))
+ (if (= top ctr)
+ (list hold (1+ top) 0)
+ (list hold top (1+ ctr))))
+ ((< ctr top)
+ (step-env s (snoc ctr hold) top (1+ ctr)))
+ (t
+ (step-env s (snoc top hold) (1+ top) 0))))
+
+;; we now prove some theorems about these functions which we will need in the
+;; following encapsulate
+
+(defun in-lst (e x)
+ (and (consp x)
+ (or (equal e (first x))
+ (in-lst e (rest x)))))
+
+(defthm legal-in-lst-is-in-lst
+ (implies (legal-in-lst s x)
+ (in-lst (legal-in-lst s x) x)))
+
+(defthm drop-lst-<=-len
+ (<= (len (drop-lst lst e))
+ (len lst))
+ :rule-classes :linear)
+
+(defthm drop-lst-<-len-in-lst
+ (implies (in-lst e lst)
+ (< (len (drop-lst lst e))
+ (len lst)))
+ :rule-classes :linear)
+
+(defthm pos-in-lst-<=-drop-lst
+ (implies (and (in-lst a lst)
+ (not (equal a b)))
+ (<= (pos-in-lst (drop-lst lst b) a)
+ (pos-in-lst lst a)))
+ :rule-classes :linear)
+
+(defthm pos-in-lst-<-not-legal-in-lst-help
+ (implies (and (nat-listp lst)
+ (in-lst a lst)
+ (legal-input s (nat->nice a))
+ (not (equal a (legal-in-lst s lst))))
+ (< (pos-in-lst (drop-lst lst (legal-in-lst s lst)) a)
+ (pos-in-lst lst a)))
+ :rule-classes nil)
+
+(defthm pos-in-lst-<-not-legal-in-lst
+ (let ((a (nice->nat i)))
+ (implies (and (nicep i)
+ (nat-listp lst)
+ (in-lst a lst)
+ (legal-input s i)
+ (not (equal a (legal-in-lst s lst))))
+ (< (pos-in-lst (drop-lst lst (legal-in-lst s lst)) a)
+ (pos-in-lst lst a))))
+ :hints (("Goal" :use
+ (:instance pos-in-lst-<-not-legal-in-lst-help
+ (a (nice->nat i)))))
+ :rule-classes :linear)
+
+(defthm pos-in-lst-iff-in-lst
+ (iff (pos-in-lst x n)
+ (in-lst n x)))
+
+(defthm in-lst-of-drop-lst
+ (equal (in-lst n (drop-lst lst a))
+ (and (not (equal n a))
+ (in-lst n lst))))
+
+(defun env-ctr (goal top ctr)
+ (declare (xargs :measure
+ (cons (1+ (nfix (- goal top)))
+ (nfix (if (>= goal ctr)
+ (- goal ctr)
+ (+ 1 (- top ctr) goal))))))
+ (cond ((or (not (natp ctr))
+ (not (natp top))
+ (not (natp goal))
+ (> ctr top))
+ 0)
+ ((equal ctr goal)
+ 1)
+ ((< ctr top)
+ (1+ (env-ctr goal top (1+ ctr))))
+ (t
+ (1+ (env-ctr goal (1+ top) 0)))))
+
+(defun env-msr (i hold top ctr)
+ (let ((ndx (nice->nat i)))
+ (or (pos-in-lst hold ndx)
+ (+ (len hold)
+ (env-ctr ndx top ctr)))))
+
+(defthm <=-env-msr-drop-lst
+ (implies (not (equal (nice->nat i) ndx))
+ (<= (env-msr i (drop-lst hold ndx) top ctr)
+ (env-msr i hold top ctr)))
+ :rule-classes :linear)
+
+(defthm <-env-msr-if-not-selected
+ (let ((ndx (legal-in-lst s hold)))
+ (implies (and ndx
+ (nicep i)
+ (nat-listp hold)
+ (legal-input s i)
+ (not (equal (nice->nat i) ndx)))
+ (< (env-msr i (drop-lst hold ndx) top ctr)
+ (env-msr i hold top ctr))))
+ :rule-classes :linear)
+
+(defthm pos-in-lst-snoc-unchanged
+ (implies (in-lst ndx hold)
+ (equal (pos-in-lst (snoc e hold) ndx)
+ (pos-in-lst hold ndx))))
+
+(defthm in-lst-of-snoc-rewrite
+ (equal (in-lst ndx (snoc e hold))
+ (or (equal ndx e)
+ (in-lst ndx hold))))
+
+(defthm pos-in-lst-hold-step-env-unchanged
+ (implies (in-lst ndx hold)
+ (equal (pos-in-lst (car (step-env s hold top ctr)) ndx)
+ (pos-in-lst hold ndx))))
+
+(defthm in-lst-hold-step-env-unchanged
+ (implies (in-lst ndx hold)
+ (in-lst ndx (car (step-env s hold top ctr)))))
+
+(defthm len-of-snoc
+ (equal (len (snoc e x))
+ (1+ (len x))))
+
+(defthm <=-env-msr-in-lst-case
+ (let ((hold+ (car (step-env s hold top ctr))))
+ (implies (and (natp top)
+ (natp ctr)
+ (<= ctr top)
+ (natp goal)
+ (not (in-lst goal hold))
+ (in-lst goal hold+))
+ (<= (pos-in-lst hold+ goal)
+ (+ (len hold)
+ (env-ctr goal top ctr)))))
+ :rule-classes :linear)
+
+(defthm <=-env-msr-not-in-lst-case
+ (let* ((nxt (step-env s hold top ctr))
+ (hold+ (first nxt))
+ (top+ (second nxt))
+ (ctr+ (third nxt)))
+ (implies (and (natp top)
+ (natp ctr)
+ (<= ctr top)
+ (natp goal)
+ (not (in-lst goal hold+))
+ (not (equal goal (find-ndx s top ctr))))
+ (<= (+ (len hold+)
+ (env-ctr goal top+ ctr+))
+ (+ (len hold)
+ (env-ctr goal top ctr)))))
+ :rule-classes :linear)
+
+(defthm <=-env-msr-step-env
+ (let* ((nxt (step-env s hold top ctr))
+ (hold+ (first nxt))
+ (top+ (second nxt))
+ (ctr+ (third nxt)))
+ (implies (and (natp top)
+ (natp ctr)
+ (<= ctr top)
+ (not (equal (nice->nat i)
+ (find-ndx s top ctr))))
+ (<= (env-msr i hold+ top+ ctr+)
+ (env-msr i hold top ctr))))
+ :rule-classes :linear)
+
+(defthm if-in-lst-and-not-legal-in-lst
+ (implies (and (nicep i)
+ (nat-listp lst)
+ (in-lst (nice->nat i) lst)
+ (legal-input s i))
+ (legal-in-lst s lst)))
+
+(defthm not-in-hold+-if-legal-input
+ (implies (and (nicep i)
+ (not (in-lst (nice->nat i) hold))
+ (legal-input s i))
+ (not (in-lst (nice->nat i)
+ (car (step-env s hold top ctr))))))
+
+(defthm nat-listp-of-snoc
+ (implies (and (natp e)
+ (nat-listp x))
+ (nat-listp (snoc e x))))
+
+(defthm <-env-ctr-step-env-main
+ (let* ((nxt (step-env s hold top ctr))
+ (hold+ (first nxt))
+ (top+ (second nxt))
+ (ctr+ (third nxt)))
+ (implies (and (natp top)
+ (natp ctr)
+ (<= ctr top)
+ (nicep i)
+ (nat-listp hold)
+ (legal-input s i)
+ (not (in-lst (nice->nat i) hold+))
+ (not (equal (nice->nat i)
+ (find-ndx s top ctr))))
+ (< (+ (len hold+)
+ (env-ctr (nice->nat i) top+ ctr+))
+ (+ (len hold)
+ (env-ctr (nice->nat i) top ctr)))))
+ :rule-classes :linear)
+
+(defthm <-env-msr-step-env
+ (let* ((nxt (step-env s hold top ctr))
+ (hold+ (first nxt))
+ (top+ (second nxt))
+ (ctr+ (third nxt)))
+ (implies (and (natp top)
+ (natp ctr)
+ (<= ctr top)
+ (nicep i)
+ (nat-listp hold)
+ (legal-input s i)
+ (not (legal-in-lst s hold))
+ (not (equal (nice->nat i)
+ (find-ndx s top ctr))))
+ (< (env-msr i hold+ top+ ctr+)
+ (env-msr i hold top ctr))))
+ :rule-classes :linear)
+
+(defthm drop-lst-preserves-nat-listp
+ (implies (nat-listp x)
+ (nat-listp (drop-lst x e))))
+
+(defun good-env (e)
+ (let ((hold (first e))
+ (top (second e))
+ (ctr (third e)))
+ (and (natp top)
+ (natp ctr)
+ (<= ctr top)
+ (nat-listp hold))))
+
+(defthm step-env-preserves-env-inv
+ (implies (nat-listp hold)
+ (good-env (step-env s hold top ctr))))
+
+(defthm legal-in-lst-is-legal-input
+ (implies (and (nat-listp x)
+ (legal-in-lst s x))
+ (legal-input s (nat->nice (legal-in-lst s x)))))
+
+(defthm find-ndx-is-legal-input
+ (implies (and (natp ctr)
+ (natp top)
+ (<= ctr top))
+ (legal-input s (nat->nice (find-ndx s top ctr)))))
+
+(defthm transfer-nice->nat-over
+ (implies (and (nicep i)
+ (not (equal (nat->nice n) i)))
+ (not (equal (nice->nat i) n))))
+
+(encapsulate
+ (((fair-select * *) => *)
+ ((fair-measure * *) => *)
+ ((fair-update * *) => *)
+ ((env-inv *) => *)
+ ((env-init) => *))
+
+ (local
+ (defun env-init ()
+ (list () 0 0)))
+
+ (local
+ (defun env-inv (e) (good-env e)))
+
+ (local
+ (defun fair-update (e s)
+ (let ((hold (first e))
+ (top (second e))
+ (ctr (third e)))
+ (let ((ndx (legal-in-lst s hold)))
+ (if ndx
+ (list (drop-lst hold ndx) top ctr)
+ (step-env s hold top ctr))))))
+
+ (local
+ (defun fair-select (e s)
+ (let ((hold (first e))
+ (top (second e))
+ (ctr (third e)))
+ (nat->nice (or (legal-in-lst s hold)
+ (find-ndx s top ctr))))))
+
+ (local
+ (defun fair-measure (e i)
+ (let ((hold (first e))
+ (top (second e))
+ (ctr (third e)))
+ (env-msr i hold top ctr))))
+
+ ;; the following are the exported theorems for our constrained functions
+ ;; defining a fair environment.
+
+ (defthm env-init-satisfies-invariant
+ (env-inv (env-init)))
+
+ (defthm fair-update-preserves-env
+ (implies (env-inv e)
+ (env-inv (fair-update e s))))
+
+ (defthm fair-select-must-be-legal
+ (implies (env-inv e)
+ (legal-input s (fair-select e s))))
+
+ (defthm fair-measure-is-natural
+ (implies (env-inv e)
+ (natp (fair-measure e i))))
+
+ (defthm fair-measure-may-decrease
+ (implies (and (env-inv e)
+ (nicep i)
+ (not (equal (fair-select e s) i)))
+ (<= (fair-measure (fair-update e s) i)
+ (fair-measure e i)))
+ :hints (("Goal" :in-theory (disable env-msr)))
+ :rule-classes (:linear :rewrite))
+
+ (defthm fair-measure-must-decrease-strictly
+ (implies (and (env-inv e)
+ (nicep i)
+ (not (equal (fair-select e s) i))
+ (legal-input s i))
+ (< (fair-measure (fair-update e s) i)
+ (fair-measure e i)))
+ :hints (("Goal" :in-theory (disable env-msr)))
+ :rule-classes (:linear :rewrite))
+)
+
diff --git a/books/workshops/2003/sumners/support/example1.lisp b/books/workshops/2003/sumners/support/example1.lisp
new file mode 100644
index 0000000..408b414
--- /dev/null
+++ b/books/workshops/2003/sumners/support/example1.lisp
@@ -0,0 +1,113 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+
+#| example1.lisp
+
+We present a simple example to demonstrate the use of the fair environment in
+fair1.lisp in proving a liveness property using the fair environment assumption
+provided in fair1.lisp. The example in this file is a trivial "system", but
+demonstrates the key concepts in using the fair input assumption environment in
+fair1.lisp to prove a simple liveness property. The key idea is to use the
+fair-measure to define a terminating measure for a function which is the
+witness to proving the liveness property. This approach requires the addition
+of the (fair-selection) assumption which is an unfortunate need. Since usage
+of the fair2.lisp file does not require this assumption, we generally believe
+the user should use the fair2.lisp book instead (as in example2.lisp).
+
+|#
+
+(include-book "fair1")
+
+;; the following macro defines the functions env and env-measure
+
+(define-env)
+
+(encapsulate (((upper-bound) => *))
+ (local (defun upper-bound () 1))
+ (defthm upper-bound-positive-natural
+ (and (integerp (upper-bound))
+ (> (upper-bound) 0))
+ :rule-classes :type-prescription))
+
+(defun sys-step (s i)
+ (let ((s (if (= s i) (1+ s) s)))
+ (if (<= s (upper-bound)) s 0)))
+
+(defun sys-init () 0)
+
+(defun run (n)
+ (if (zp n) (sys-init)
+ (let ((n (1- n)))
+ (sys-step (run n) (env n)))))
+
+(defthm run-n-is-natural
+ (natp (run n))
+ :rule-classes :type-prescription)
+
+(defthm run-n-is-bounded
+ (<= (run n) (upper-bound))
+ :rule-classes :linear)
+
+(defun good (s)
+ (= s (upper-bound)))
+
+(defmacro lexprod (&rest r)
+ (cond ((endp r) 0)
+ ((endp (rest r)) (first r))
+ (t `(cons (lexprod ,@(butlast r 1))
+ ,(car (last r))))))
+
+(defun good-measure (n)
+ (lexprod
+ (if (natp n) 1 2)
+ (1+ (nfix (- (upper-bound) (run n))))
+ (env-measure (run n) n)))
+
+(in-theory (disable (good-measure)))
+
+;; the following is just a rewrite rule we need from linear arithmetic (which
+;; does not "rewrite")
+(local
+(defthm linear-factoid3
+ (implies (and (integerp x)
+ (integerp y))
+ (equal (+ (- y) y x) x))))
+
+(defun good-time (n)
+ (declare (xargs :measure (good-measure n)))
+ (cond ((not (fair-selection)) 0)
+ ((not (natp n)) (good-time 0))
+ ((good (run n)) n)
+ (t (good-time (1+ n)))))
+
+(in-theory (disable good (good-time)))
+
+(defthm good-of-good-time
+ (implies (fair-selection)
+ (good (run (good-time n)))))
+
+(defthm good-time->=
+ (implies (and (integerp n)
+ (fair-selection))
+ (>= (good-time n) n))
+ :rule-classes :linear)
+
+(defthm good-time-is-natp
+ (natp (good-time n))
+ :rule-classes :type-prescription)
+
+(defun time>= (y x)
+ (and (natp y) (implies (natp x) (>= y x))))
+
+(defun-sk eventually-good (x)
+ (exists (y) (and (time>= y x) (good (run y)))))
+
+(defthm progress-or-liveness
+ (implies (fair-selection)
+ (eventually-good n))
+ :hints (("Goal" :use (:instance eventually-good-suff
+ (x n)
+ (y (good-time n))))))
+
+
+
diff --git a/books/workshops/2003/sumners/support/example2.lisp b/books/workshops/2003/sumners/support/example2.lisp
new file mode 100644
index 0000000..5fc5557
--- /dev/null
+++ b/books/workshops/2003/sumners/support/example2.lisp
@@ -0,0 +1,113 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+
+#| example2.lisp
+
+We present a simple example to demonstrate the use of the fair environment in
+fair2.lisp in proving a liveness property using the fair environment assumption
+provided in fair2.lisp. The example in this file is a trivial "system", but
+demonstrates the key concepts in using the fair input assumption environment in
+fair.lisp to prove a simple liveness property. The key idea is to use the
+fair-measure to define a terminating measure for a function which is the
+witness to proving the liveness property. It is the author's belief (with some
+applications supporting this belief) that for most systems, the forms from the
+defun of good-time on could be re-used for any liveness proof with little or no
+modification and that the only item needed to be changed for a particular
+system would be the measure for the function good-time.
+
+A more thorough (but complicated) demonstration of this is found in
+example3.lisp.
+
+|#
+
+(include-book "fair2")
+
+;; the following macro defines the functions env and env-measure
+
+(define-env)
+
+(encapsulate (((upper-bound) => *))
+ (local (defun upper-bound () 1))
+ (defthm upper-bound-positive-natural
+ (and (integerp (upper-bound))
+ (> (upper-bound) 0))
+ :rule-classes :type-prescription))
+
+(defun sys-step (s i)
+ (let ((s (if (= s i) (1+ s) s)))
+ (if (<= s (upper-bound)) s 0)))
+
+(defun sys-init () 0)
+
+(defun run (n)
+ (if (zp n) (sys-init)
+ (let ((n (1- n)))
+ (sys-step (run n) (env n)))))
+
+(defthm run-n-is-natural
+ (natp (run n))
+ :rule-classes :type-prescription)
+
+(defthm run-n-is-bounded
+ (<= (run n) (upper-bound))
+ :rule-classes :linear)
+
+(defun good (s)
+ (= s (upper-bound)))
+
+(defmacro lexprod (&rest r)
+ (cond ((endp r) 0)
+ ((endp (rest r)) (first r))
+ (t `(cons (lexprod ,@(butlast r 1))
+ ,(car (last r))))))
+
+(defun good-measure (n)
+ (lexprod
+ (if (natp n) 1 2)
+ (1+ (nfix (- (upper-bound) (run n))))
+ (env-measure (run n) n)))
+
+(in-theory (disable (good-measure)))
+
+;; the following is just a rewrite rule we need from linear arithmetic (which
+;; does not "rewrite")
+(local
+ (defthm linear-factoid3
+ (implies (and (integerp x)
+ (integerp y))
+ (equal (+ (- y) y x) x))))
+
+(defun good-time (n)
+ (declare (xargs :measure (good-measure n)))
+ (cond ((not (natp n)) (good-time 0))
+ ((good (run n)) n)
+ (t (good-time (1+ n)))))
+
+(in-theory (disable good (good-time)))
+
+(defthm good-of-good-time
+ (good (run (good-time n))))
+
+(defthm good-time->=
+ (implies (integerp n)
+ (>= (good-time n) n))
+ :rule-classes :linear)
+
+(defthm good-time-is-natp
+ (natp (good-time n))
+ :rule-classes :type-prescription)
+
+(defun time>= (y x)
+ (and (natp y) (implies (natp x) (>= y x))))
+
+(defun-sk eventually-good (x)
+ (exists (y) (and (time>= y x) (good (run y)))))
+
+(defthm progress-or-liveness
+ (eventually-good n)
+ :hints (("Goal" :use (:instance eventually-good-suff
+ (x n)
+ (y (good-time n))))))
+
+
+
diff --git a/books/workshops/2003/sumners/support/example3.lisp b/books/workshops/2003/sumners/support/example3.lisp
new file mode 100644
index 0000000..5847b22
--- /dev/null
+++ b/books/workshops/2003/sumners/support/example3.lisp
@@ -0,0 +1,349 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+
+#| example3.lisp
+
+We present a slightly more complex model which uses the fair environment in
+fair2.lisp. This example is a mutual exclusion model where the state of the
+system is abstracted into a process pointer and a list of program counters (one
+for each process). This is a fairly simple system to define, but has a subtle
+argument for progress because the "arbiter" does not wait until a process
+reaches its critical section. The function good-measure is the key to the
+argument and utilizes two calls of env-measure (one for the arbitrary node in
+the property (pick-pr) and another for the current node selected by the
+arbiter).
+
+|#
+
+(include-book "fair2")
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+;; the following macro defines the functions env and env-measure
+
+(define-env)
+
+; The following was removed with the addition of natp-compound-recognizer to
+; ACL2 2.9.2.
+;(defthm posp-compound-recognizer
+; (iff (posp x)
+; (and (integerp x)
+; (> x 0)))
+; :rule-classes :compound-recognizer)
+
+(in-theory (disable posp))
+
+(encapsulate
+ (((last-pr) => *)
+ ((crit-pc) => *)
+ ((last-pc) => *))
+
+ (local (defun last-pr () 0))
+ (local (defun crit-pc () 1))
+ (local (defun last-pc () 2))
+
+ (defthm last-pr-natp
+ (natp (last-pr))
+ :rule-classes :type-prescription)
+
+ (defthm crit-pc-posp
+ (posp (crit-pc))
+ :rule-classes :type-prescription)
+
+ (defthm last-pc-posp
+ (posp (last-pc))
+ :rule-classes :type-prescription)
+
+ (defthm last-pc-gt-crit-pc
+ (< (crit-pc) (last-pc)))
+)
+
+(defun prp (x)
+ (and (natp x) (<= x (last-pr))))
+
+(defthm prp-forward
+ (implies (prp x)
+ (and (natp x)
+ (<= x (last-pr))))
+ :rule-classes :forward-chaining)
+
+(defthm prp-backward1
+ (implies (and (natp x)
+ (<= x (last-pr)))
+ (prp x)))
+
+(defthm prp-backward2
+ (implies (not (and (natp x)
+ (<= x (last-pr))))
+ (not (prp x))))
+
+(in-theory (disable prp (prp)))
+
+(defun pcp (x)
+ (and (natp x) (<= x (last-pc))))
+
+(defthm pcp-forward
+ (implies (pcp x)
+ (and (natp x)
+ (<= x (last-pc))))
+ :rule-classes :forward-chaining)
+
+(defthm pcp-backward1
+ (implies (and (natp x)
+ (<= x (last-pc)))
+ (pcp x)))
+
+(defthm pcp-backward2
+ (implies (not (and (natp x)
+ (<= x (last-pc))))
+ (not (pcp x))))
+
+(in-theory (disable pcp (pcp)))
+
+(defun getp (n l)
+ (if (zp n)
+ (if (endp l) 0 (car l))
+ (getp (1- n) (cdr l))))
+
+(defun setp (n v l)
+ (if (zp n)
+ (cons v (cdr l))
+ (cons (if (endp l) 0 (car l))
+ (setp (1- n) v (cdr l)))))
+
+(defthm getp-of-setp
+ (equal (getp n (setp m v l))
+ (if (equal (nfix n) (nfix m))
+ v
+ (getp n l))))
+
+(defthm getp-of-atom
+ (implies (atom l)
+ (equal (getp n l) 0)))
+
+(defun pc-listp (l)
+ (or (null l)
+ (and (consp l)
+ (pcp (car l))
+ (pc-listp (cdr l)))))
+
+(defthm setp-pc-listp
+ (implies (and (pc-listp l)
+ (pcp v))
+ (pc-listp (setp n v l))))
+
+(defthm getp-of-pc-listp1
+ (implies (pc-listp l)
+ (pcp (getp n l)))
+ :rule-classes (:type-prescription
+ :rewrite))
+
+(defthm getp-of-pc-listp2
+ (implies (pc-listp l)
+ (natp (getp n l)))
+ :rule-classes :type-prescription)
+
+(defthm getp-of-pc-listp3
+ (implies (pc-listp l)
+ (<= (getp n l) (last-pc)))
+ :rule-classes :linear)
+
+(defun next-pr (x)
+ (let ((x (1+ x))) (if (> x (last-pr)) 0 x)))
+
+(defun next-pc (x)
+ (let ((x (1+ x))) (if (> x (last-pc)) 0 x)))
+
+(defun in-crit (p)
+ (>= p (crit-pc)))
+
+(defun sys-step (s i)
+ (if (prp i)
+ (let* ((ndx (car s))
+ (prs (cdr s))
+ (p (getp i prs))
+ (p+ (next-pc p))
+ (p+ (if (and (in-crit p+) (/= i ndx)) p p+))
+ (prs (setp i p+ prs))
+ (n+ (next-pr ndx))
+ (ndx (if (and (not (in-crit p+)) (= i ndx)) n+ ndx)))
+ (cons ndx prs))
+ s))
+
+(in-theory (disable (sys-step) (next-pr) (next-pc) (in-crit)))
+
+(defun sys-init () (cons 0 ()))
+
+(defun run (n)
+ (if (zp n) (sys-init)
+ (let ((n (1- n)))
+ (sys-step (run n) (env n)))))
+
+(in-theory (disable (run) (env)))
+
+;; the following is just a rewrite rule we need from linear arithmetic (which
+;; does not "rewrite")
+(local
+ (defthm linear-factoid3
+ (implies (and (integerp x)
+ (integerp y))
+ (equal (+ (- y) y x) x))))
+
+(local
+(defthm expand-run-1+
+ (implies (natp n)
+ (equal (run (1+ n))
+ (sys-step (run n) (env n))))
+ :hints (("Goal" :in-theory (disable sys-step)))))
+
+(defthm pc-listp-cdr-run
+ (pc-listp (cdr (run n)))
+ :rule-classes :type-prescription)
+
+(defthm natp-car-run
+ (natp (car (run n)))
+ :rule-classes :type-prescription)
+
+(defthm car-run-<=-last-pr
+ (<= (car (run n)) (last-pr))
+ :rule-classes :linear)
+
+(defthm prp-car-run
+ (prp (car (run n)))
+ :rule-classes :type-prescription)
+
+(encapsulate
+ (((pick-pr) => *))
+ (local (defun pick-pr () 0))
+
+ (defthm pick-pr-natp
+ (natp (pick-pr))
+ :rule-classes :type-prescription)
+
+ (defthm pick-pr-<=-last-pr
+ (<= (pick-pr) (last-pr)))
+
+ (defthm pick-pr-is-prp
+ (prp (pick-pr)))
+)
+
+(defun good (s)
+ (in-crit (getp (pick-pr) (cdr s))))
+
+(in-theory (disable (good)))
+
+(defthm natp-is-nicep
+ (implies (natp x)
+ (nicep x))
+ :rule-classes :type-prescription)
+
+(defthm prp-not-equal1
+ (implies (and (prp x)
+ (not (prp y)))
+ (not (equal x y))))
+
+(defthm prp-not-equal2
+ (implies (and (prp x)
+ (not (prp y)))
+ (not (equal y x))))
+
+(defthm natp-pick-pr--
+ (implies (and (natp y)
+ (<= y (pick-pr)))
+ (natp (- (pick-pr) y)))
+ :hints (("Goal" :in-theory (enable natp)))
+ :rule-classes :type-prescription)
+
+(defthm natp-last-pr--1
+ (implies (and (natp y)
+ (<= y (last-pr))
+ (natp a)
+ (natp b))
+ (natp (+ (last-pr) a b (- y))))
+ :hints (("Goal" :in-theory (enable natp)))
+ :rule-classes :type-prescription)
+
+(defthm natp-last-pr--2
+ (implies (and (natp y)
+ (<= y (last-pr))
+ (natp a)
+ (natp b))
+ (natp (+ a (last-pr) b (- y))))
+ :hints (("Goal" :in-theory (enable natp)))
+ :rule-classes :type-prescription)
+
+(defthm natp-last-pr--3
+ (implies (and (natp y)
+ (<= y (last-pr))
+ (natp a)
+ (natp b))
+ (natp (+ a b (last-pr) (- y))))
+ :hints (("Goal" :in-theory (enable natp)))
+ :rule-classes :type-prescription)
+
+(defmacro lexprod (&rest r)
+ (cond ((endp r) 0)
+ ((endp (rest r)) (first r))
+ (t `(cons (lexprod ,@(butlast r 1))
+ ,(car (last r))))))
+
+(defun good-measure (n)
+ (let* ((s (run n))
+ (ndx (car s))
+ (prs (cdr s))
+ (nogo (not (equal ndx (pick-pr)))))
+ (lexprod
+ (if (natp n) 1 2)
+ (nfix (- (crit-pc) (getp (pick-pr) prs)))
+ (if nogo 2 1)
+ (if nogo
+ (if (> ndx (pick-pr))
+ (+ (- (last-pr) ndx)
+ (1+ (pick-pr)))
+ (- (pick-pr) ndx))
+ 0)
+ (if nogo
+ (- (last-pc) (getp ndx prs))
+ 0)
+ (env-measure ndx n))))
+
+(in-theory (disable (good-measure)))
+
+(defun good-time (n)
+ (declare (xargs :measure (good-measure n)
+ :hints (("Subgoal 1"
+ :use ((:instance last-pc-gt-crit-pc)
+ (:instance pick-pr-<=-last-pr))
+ :in-theory (disable last-pc-gt-crit-pc
+ pick-pr-<=-last-pr
+ getp setp)))))
+ (cond ((not (natp n)) (good-time 0))
+ ((good (run n)) n)
+ (t (good-time (1+ n)))))
+
+(in-theory (disable good (good-time)))
+
+(defthm good-of-good-time
+ (good (run (good-time n))))
+
+(defthm good-time->=
+ (implies (integerp n)
+ (>= (good-time n) n))
+ :rule-classes :linear)
+
+(defthm good-time-is-natp
+ (natp (good-time n))
+ :rule-classes :type-prescription)
+
+(defun time>= (y x)
+ (and (natp y) (implies (natp x) (>= y x))))
+
+(defun-sk eventually-good (x)
+ (exists (y) (and (time>= y x) (good (run y)))))
+
+(defthm progress-or-liveness
+ (eventually-good n)
+ :hints (("Goal" :use (:instance eventually-good-suff
+ (x n)
+ (y (good-time n))))))
+
diff --git a/books/workshops/2003/sumners/support/fair1.lisp b/books/workshops/2003/sumners/support/fair1.lisp
new file mode 100644
index 0000000..68e6dd8
--- /dev/null
+++ b/books/workshops/2003/sumners/support/fair1.lisp
@@ -0,0 +1,239 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+#| fair1.lisp
+
+This "book" provides an equivalence proof between a straightforward statement
+of "fair input selection" using defun-sk and the existence of a fair measure
+function which decreases with every step. In order to use the measure function
+introduced in this book, one would need to introduce (fair-selection)
+assumptions in any theorems which required the properties of the environment
+measure function. Because of this, we do not recommend using this book, and
+instead recommend using the book fair2.lisp.
+
+|#
+
+(encapsulate ;; arbitrary environment input sequence
+ (((env1 *) => *))
+ (local (defun env1 (x) x)))
+
+; The following was removed with the addition of natp-compound-recognizer to
+; ACL2 2.9.2.
+;(defthm natp-compound-recognizer
+; (iff (natp x)
+; (and (integerp x)
+; (>= x 0)))
+; :rule-classes :compound-recognizer)
+
+(in-theory (disable natp))
+
+(defun time>= (y x)
+ (and (natp y) (implies (natp x) (>= y x))))
+
+(defun next1* (i n k)
+ (declare (xargs :measure (nfix (- k n))))
+ (if (or (equal (env1 n) i) (zp (- k n))) n (next1* i (1+ n) k)))
+
+(defthm next1*-natp
+ (implies (natp n) (natp (next1* i n k)))
+ :rule-classes :type-prescription)
+
+(defthm next1*>
+ (>= (next1* i n k) n)
+ :rule-classes :linear)
+
+(defthm next1*-property
+ (implies (and (natp n) (natp k1) (natp k2)
+ (>= k1 n) (>= k2 n)
+ (equal (env1 k1) i)
+ (equal (env1 k2) i))
+ (equal (equal (next1* i n k1)
+ (next1* i n k2))
+ t)))
+
+(defun-sk exists-future (i x)
+ (exists y (and (time>= y x) (equal (env1 y) i))))
+
+(defun-sk fair-selection ()
+ (forall (i x) (exists-future i x)))
+
+(defun next1 (i n)
+ (next1* i n (exists-future-witness i n)))
+
+(defthm next1-natp
+ (implies (natp n)
+ (natp (next1 i n)))
+ :rule-classes :type-prescription)
+
+(defthm next1>
+ (>= (next1 i n) n)
+ :rule-classes :linear)
+
+(defthm next1-no-change
+ (implies (and (natp n)
+ (fair-selection)
+ (not (equal (env1 n) i)))
+ (equal (next1 i (1+ n))
+ (next1 i n)))
+ :hints (("Goal"
+ :use ((:instance fair-selection-necc (x n))
+ (:instance fair-selection-necc (x (1+ n))))
+ :in-theory (disable fair-selection-necc))))
+
+(defun env1-measure (i n)
+ (if (natp n) (- (next1 i n) n) (next1 i 0)))
+
+(defthm env1-measure-natural
+ (natp (env1-measure i n))
+ :hints (("Goal" :in-theory (enable natp))))
+
+(defthm env1-measure-decreases
+ (implies (and (natp n)
+ (fair-selection)
+ (not (equal (env1 n) i)))
+ (< (env1-measure i (1+ n))
+ (env1-measure i n)))
+ :hints (("Goal" :in-theory (disable fair-selection))))
+
+(in-theory (disable fair-selection))
+
+#|
+
+IMPORTANT NOTE:
+
+We include an extra "k" parameter to the functions env and env-measure, to
+allow the use of multiple independent fair selectors. We generally use the
+following macro define-env to define a fair environment with support for
+multiple fair selectors for "fields" in an input. These "fields" of the input
+are defined using the "s" and "g" operators from the records book:
+books/misc/records.lisp. These operators could be replaced with updaters and
+accessors of your choosing, but the properties of "s" and "g" should hold (or
+suitable equivalent properties) and "g" should be a free accessor in that the
+range of "g" should be the ACL2 universe. This is necessary to ensure that the
+modeling of the fair selector is not inadvertently and inappropriately
+constrained.
+
+|#
+
+(encapsulate
+ (((env! * *) => *)
+ ((env-measure! * * *) => *))
+
+(local (defun env! (k n) (declare (ignore k))
+ (env1 n)))
+(local (defun env-measure! (k i n) (declare (ignore k))
+ (env1-measure i n)))
+
+(defthm env-measure!-is-natural
+ (natp (env-measure! k i n))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm env-measure!-decreases
+ (implies (and (fair-selection)
+ (natp n)
+ (not (equal i (env! k n))))
+ (< (env-measure! k i (1+ n))
+ (env-measure! k i n)))
+ :rule-classes (:linear :rewrite))
+)
+
+(defun mk-env-body (keys)
+ (if (endp keys) '(env! 0 n)
+ `(s (quote ,(first keys))
+ (env! (quote ,(first keys)) n)
+ ,(mk-env-body (rest keys)))))
+
+(defmacro define-env (&rest keys)
+ (declare (xargs :guard (symbol-listp keys)))
+ `(progn (defun env (n) ,(mk-env-body keys))
+ ,(if (endp keys)
+ '(defun env-measure (i n)
+ (env-measure! 0 i n))
+ '(defun env-measure (k i n)
+ (env-measure! k i n)))))
+
+#|
+
+We conclude this book with a "proof" that the existence of a fair-measure
+implies (fair-selection) -- we proved the other direction above. This other
+direction is not relevant to the output of this file, so we make all of the
+following forms local.
+
+|#
+
+(local
+(defstub env1-msr$ (i n) t))
+
+(local
+(defun-sk env1-msr$-property ()
+ (forall (i n)
+ (and (natp (env1-msr$ i n))
+ (implies (and (natp n)
+ (not (equal (env1 n) i)))
+ (< (env1-msr$ i (1+ n))
+ (env1-msr$ i n)))))))
+
+(local
+(defthm env1-msr$-is-natural
+ (implies (env1-msr$-property)
+ (natp (env1-msr$ i n)))
+ :hints (("Goal"
+ :use (:instance env1-msr$-property-necc)
+ :in-theory (disable env1-msr$-property-necc)))
+ :rule-classes :type-prescription))
+
+(local
+(defthm env1-msr$-decreases
+ (implies (and (env1-msr$-property)
+ (natp n)
+ (not (equal (env1 n) i)))
+ (< (env1-msr$ i (1+ n))
+ (env1-msr$ i n)))
+ :hints (("Goal"
+ :use (:instance env1-msr$-property-necc)
+ :in-theory (disable env1-msr$-property-necc)))
+ :rule-classes :linear))
+
+(local
+(in-theory (disable env1-msr$-property)))
+
+(local
+(defun witness1$ (i x)
+ (declare (xargs :measure (cons (if (natp x) 1 2)
+ (if (env1-msr$-property)
+ (env1-msr$ i x)
+ 0))))
+ (cond ((not (env1-msr$-property)) 0)
+ ((not (natp x)) (witness1$ i 0))
+ ((equal (env1 x) i) x)
+ (t (witness1$ i (1+ x))))))
+
+(local
+(defthm witness1$-is-env1
+ (implies (env1-msr$-property)
+ (equal (env1 (witness1$ i x)) i))))
+
+(local
+(defthm witness1$-in-future
+ (implies (and (natp x)
+ (env1-msr$-property))
+ (>= (witness1$ i x) x))
+ :rule-classes :linear))
+
+(local
+(in-theory (disable exists-future exists-future-suff)))
+
+(local
+(defthm env1-msr$-property-implies-fair-selection
+ (implies (env1-msr$-property)
+ (fair-selection))
+ :hints (("Goal"
+ :use ((:instance exists-future-suff
+ (i (mv-nth 0 (fair-selection-witness)))
+ (x (mv-nth 1 (fair-selection-witness)))
+ (y (witness1$ (mv-nth 0 (fair-selection-witness))
+ (mv-nth 1 (fair-selection-witness))))))
+ :in-theory (enable fair-selection)))))
diff --git a/books/workshops/2003/sumners/support/fair2.lisp b/books/workshops/2003/sumners/support/fair2.lisp
new file mode 100644
index 0000000..e19a559
--- /dev/null
+++ b/books/workshops/2003/sumners/support/fair2.lisp
@@ -0,0 +1,164 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+
+(include-book "../../../../ordinals/e0-ordinal")
+(set-well-founded-relation e0-ord-<)
+
+#| fair.lisp
+
+This book defines a basic strong (i.e. unconditional) fair selector over the
+nice objects (as defined in n2n.lisp). The relevant properties about env$ and
+env-measure! are defined at the end of the file. We expect this fair selector
+will be sufficient in most cases, but for "weak" fairness, one should consult
+weak.lisp.
+
+|#
+
+(include-book "n2n")
+
+(defun fair-ctr (goal ctr top)
+ (declare (xargs :measure
+ (cons (1+ (nfix (- goal top)))
+ (nfix (if (>= goal ctr)
+ (- goal ctr)
+ (+ 1 (- top ctr) goal))))))
+ (cond ((not (and (natp ctr)
+ (natp top)
+ (natp goal)
+ (<= ctr top)))
+ 0)
+ ((equal ctr goal) 1)
+ ((< ctr top)
+ (1+ (fair-ctr goal (1+ ctr) top)))
+ (t
+ (1+ (fair-ctr goal 0 (1+ top))))))
+
+(defun fair-select (f)
+ (nat->nice (car f)))
+
+(defun fair-measure (i f)
+ (fair-ctr (nice->nat i) (car f) (cdr f)))
+
+(defun fair-step (f)
+ (let ((a (car f)) (d (cdr f)))
+ (if (< a d) (cons (1+ a) d) (cons 0 (1+ d)))))
+
+(defun fair-inv (f)
+ (and (consp f)
+ (natp (car f))
+ (natp (cdr f))
+ (<= (car f) (cdr f))))
+
+(defun fair-init ()
+ (cons 0 0))
+
+(defmacro selectp (i) `(nicep ,i))
+
+;; ACL2 is actually able to infer this already, but we include it here for
+;; better correspondence with the paper
+
+(local
+(defthm fair-measure-natural
+ (natp (fair-measure i f))
+ :rule-classes :type-prescription))
+
+(local
+(defthm fair-measure-decreases
+ (implies (and (selectp i)
+ (fair-inv f)
+ (not (equal i (fair-select f))))
+ (< (fair-measure i (fair-step f))
+ (fair-measure i f)))
+ :rule-classes :linear))
+
+(local
+(defthm fair-inv-is-invariant
+ (implies (fair-inv f)
+ (fair-inv (fair-step f)))))
+
+(in-theory (disable fair-step fair-inv fair-measure fair-select))
+
+(defun fair-run (n)
+ (if (zp n) (fair-init) (fair-step (fair-run (1- n)))))
+
+(defthm fair-inv-of-fair-run
+ (fair-inv (fair-run n)))
+
+(local
+(defthm linear-factoid1
+ (implies (and (natp n)
+ (natp x))
+ (equal (+ n (- n) x) x))))
+
+(local
+(defthm linear-factoid2
+ (implies (and (natp n)
+ (natp x))
+ (equal (+ (- n) n x) x))))
+
+(local
+(defthm fair-run-of-1+
+ (implies (natp n)
+ (equal (fair-run (1+ n))
+ (fair-step (fair-run n))))))
+
+(in-theory (disable fair-run))
+(in-theory (enable (:induction fair-run)))
+
+(in-theory (disable (fair-run) (fair-step) (fair-select)))
+
+#|
+
+IMPORTANT NOTE:
+
+We include an extra "k" parameter to the functions env and env-measure, to
+allow the use of multiple independent fair selectors. We generally use the
+following macro define-env to define a fair environment with support for
+multiple fair selectors for "fields" in an input. These "fields" of the input
+are defined using the "s" and "g" operators from the records book:
+books/misc/records.lisp. These operators could be replaced with updaters and
+accessors of your choosing, but the properties of "s" and "g" should hold (or
+suitable equivalent properties) and "g" should be a free accessor in that the
+range of "g" should be the ACL2 universe. This is necessary to ensure that the
+modeling of the fair selector is not inadvertently and inappropriately
+constrained.
+
+|#
+
+(encapsulate
+ (((env! * *) => *)
+ ((env-measure! * * *) => *))
+
+(local (defun env! (k n) (declare (ignore k))
+ (fair-select (fair-run n))))
+(local (defun env-measure! (k i n) (declare (ignore k))
+ (fair-measure i (fair-run n))))
+
+(defthm env-measure!-is-natural
+ (natp (env-measure! k i n))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm env-measure!-decreases
+ (implies (and (selectp i)
+ (natp n)
+ (not (equal i (env! k n))))
+ (< (env-measure! k i (1+ n))
+ (env-measure! k i n)))
+ :rule-classes (:linear :rewrite))
+)
+
+(defun mk-env-body (keys)
+ (if (endp keys) '(env! 0 n)
+ `(s (quote ,(first keys))
+ (env! (quote ,(first keys)) n)
+ ,(mk-env-body (rest keys)))))
+
+(defmacro define-env (&rest keys)
+ (declare (xargs :guard (symbol-listp keys)))
+ `(progn (defun env (n) ,(mk-env-body keys))
+ ,(if (endp keys)
+ '(defun env-measure (i n)
+ (env-measure! 0 i n))
+ '(defun env-measure (k i n)
+ (env-measure! k i n)))))
+
diff --git a/books/workshops/2003/sumners/support/n2n.lisp b/books/workshops/2003/sumners/support/n2n.lisp
new file mode 100644
index 0000000..ac31bbf
--- /dev/null
+++ b/books/workshops/2003/sumners/support/n2n.lisp
@@ -0,0 +1,448 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+; cert_param: (non-acl2r)
+
+#| n2n.lisp
+
+This book defines the function nice->nat (and its inverse nat->nice) which
+defines an invertible mapping from the set of so-called "nice" objects to the
+natural numbers. This mapping is used to lift a fair selector of natural
+numbers to a fair selector on "nice" objects. Nice objects are basically a
+countable subset of the ACL2 universe consisting of strings, numbers,
+characters, booleans, keywords, and conses of nice objects. We only include the
+keywords and booleans instead of all symbols due to the inability to construct
+an arbitrary symbol in ACL2.
+
+|#
+
+; The following was removed with the addition of natp-compound-recognizer to
+; ACL2 2.9.2.
+;(defthm natp-compound-recognizer
+; (iff (natp x)
+; (and (integerp x)
+; (>= x 0)))
+; :rule-classes :compound-recognizer)
+
+(in-theory (disable natp))
+
+; The definition of bitp here was deleted April 2016 by Matt K. now that bitp
+; is defined in ACL2.
+
+(defun ncdr (n)
+ (if (or (zp n) (= n 1)) 0 (1+ (ncdr (- n 2)))))
+
+(defun ncar (n)
+ (if (or (zp n) (= n 1)) n (ncar (- n 2))))
+
+(defun lsh (n)
+ (if (zp n) 0 (+ (lsh (1- n)) 2)))
+
+(defun ncons (b n) (+ b (lsh n)))
+
+(local
+(defthm linear-factoid1
+ (implies (and (natp n)
+ (natp x))
+ (equal (+ (- n) n x) x))))
+
+(local
+(defthm linear-factoid2
+ (implies (and (natp x)
+ (natp y)
+ (natp z))
+ (equal (+ x y z)
+ (+ y x z)))))
+
+(defthm ncar-of-+2-reduce
+ (implies (natp n)
+ (equal (ncar (+ 2 n))
+ (ncar n)))
+ :rule-classes nil)
+
+(defthm ncar-of-1+-lsh
+ (equal (ncar (1+ (lsh n))) 1)
+ :hints (("Subgoal *1/2'"
+ :use (:instance ncar-of-+2-reduce
+ (n (1+ (lsh (+ -1 n)))))
+ :in-theory (disable ncar))))
+
+(defthm ncar-of-lsh+0
+ (equal (ncar (lsh n)) 0))
+
+(defthm ncdr-of-lhs+0
+ (implies (natp n)
+ (equal (ncdr (lsh n)) n)))
+
+(defthm ncdr-of-+2-reduce
+ (implies (natp n)
+ (equal (ncdr (+ 2 n))
+ (1+ (ncdr n)))))
+
+(defthm ncdr-of-lhs+1
+ (implies (natp n)
+ (equal (ncdr (1+ (lsh n))) n))
+ :hints (("Subgoal *1/3'"
+ :use (:instance ncdr-of-+2-reduce
+ (n (1+ (lsh (1- n)))))
+ :in-theory (disable ncdr))))
+
+(defthm ncar-of-ncons-reduce
+ (implies (and (natp n)
+ (bitp b))
+ (equal (ncar (ncons b n)) b)))
+
+(defthm ncdr-of-ncons-reduce
+ (implies (and (natp n)
+ (bitp b))
+ (equal (ncdr (ncons b n)) n)))
+
+(defthm ncons-reconstruct
+ (implies (natp n)
+ (equal (ncons (ncar n) (ncdr n)) n)))
+
+(defthm implies-not-zp-<-ncdr
+ (implies (not (zp x))
+ (< (ncdr x) x))
+ :rule-classes :linear)
+
+(defun nlen (x)
+ (if (zp x) 0 (1+ (nlen (ncdr x)))))
+
+(defthm not-zp-ncons-1
+ (not (zp (ncons 1 x))))
+
+(defthm natp-ncar-propagate
+ (implies (natp x)
+ (natp (ncar x)))
+ :hints (("Subgoal *1/2" :in-theory (enable zp natp)))
+ :rule-classes :type-prescription)
+
+(defthm bitp-ncar-propagate
+ (implies (natp x)
+ (bitp (ncar x)))
+ :hints (("Subgoal *1/2" :in-theory (enable zp natp))))
+
+(defthm natp-ncons-propagate
+ (implies (natp b)
+ (natp (ncons b n)))
+ :rule-classes :type-prescription)
+
+(defthm bitp-implies-natp
+ (implies (bitp x) (natp x)))
+
+(local (in-theory (disable linear-factoid1 linear-factoid2)))
+(in-theory (disable ncons ncar ncdr bitp))
+
+; Matt K. mod for v2-9.1: Remove support for pre-v2.8.
+
+(defun nicep (x)
+ (or (stringp x)
+ (characterp x)
+ (acl2-numberp x)
+ (symbolp x)
+ (and (consp x)
+ (nicep (car x))
+ (nicep (cdr x)))))
+
+(defun simplep (x)
+ (or (null x)
+ (and (consp x)
+ (simplep (car x))
+ (simplep (cdr x)))))
+
+; Modified slightly 12/4/2012 by Matt K. to be redundant with new ACL2
+; definition.
+(defun nat-listp (l)
+ (declare (xargs :guard t))
+ (cond ((atom l)
+ (eq l nil))
+ (t (and (natp (car l))
+ (nat-listp (cdr l))))))
+
+(defun nat->list (n)
+ (if (zp n) () (cons nil (nat->list (1- n)))))
+
+(defun list->nat (x)
+ (if (endp x) 0 (1+ (list->nat (cdr x)))))
+
+(defthm nat->list-inverse
+ (implies (natp x)
+ (equal (list->nat (nat->list x))
+ x)))
+
+(defthm nat->list-simplep
+ (simplep (nat->list n)))
+
+(defun clist->simple (x)
+ (if (endp x) ()
+ (cons (nat->list (char-code (car x)))
+ (clist->simple (cdr x)))))
+
+(defun simple->clist (x)
+ (if (endp x) ()
+ (cons (code-char (list->nat (car x)))
+ (simple->clist (cdr x)))))
+
+(defthm clist->simple-inverse
+ (implies (character-listp x)
+ (equal (simple->clist (clist->simple x))
+ x)))
+
+(defthm clist->simple-simplep
+ (simplep (clist->simple x)))
+
+(defun nice-count (x)
+ (cond ((null x) 0)
+ ((characterp x) 0)
+ ((integerp x)
+ (if (>= x 0) 0 1))
+ ((rationalp x)
+ (+ 1
+ (nice-count (numerator x))
+ (nice-count (denominator x))))
+ ((complex-rationalp x)
+ (+ 1
+ (nice-count (realpart x))
+ (nice-count (imagpart x))))
+ ((stringp x) 1)
+ ((symbolp x) 2)
+ ((consp x)
+ (+ 1
+ (nice-count (car x))
+ (nice-count (cdr x))))
+ (t 0)))
+
+(defun natural-tag () (nat->list 1))
+(defun negative-tag () (nat->list 2))
+(defun rational-tag () (nat->list 3))
+(defun complex-tag () (nat->list 4))
+(defun character-tag () (nat->list 5))
+(defun string-tag () (nat->list 6))
+(defun symbol-tag () (nat->list 7))
+(defun cons-tag () (nat->list 8))
+(defun nil-tag () nil)
+(defun t-tag () (cons nil nil))
+
+(defun nice->simple (x)
+ (declare (xargs :measure (nice-count x)))
+ (cond ((eq x nil) (nil-tag))
+ ((eq x t) (t-tag))
+ ((integerp x)
+ (if (>= x 0)
+ (cons (natural-tag)
+ (nat->list x))
+ (cons (negative-tag)
+ (nat->list (- x)))))
+ ((rationalp x)
+ (cons (rational-tag)
+ (cons (nice->simple (numerator x))
+ (nice->simple (denominator x)))))
+ ((complex-rationalp x)
+ (cons (complex-tag)
+ (cons (nice->simple (realpart x))
+ (nice->simple (imagpart x)))))
+ ((characterp x)
+ (cons (character-tag)
+ (nat->list (char-code x))))
+ ((stringp x)
+ (cons (string-tag)
+ (clist->simple (coerce x 'list))))
+ ((symbolp x)
+ (cons (symbol-tag)
+ (cons (nice->simple (symbol-package-name x))
+ (nice->simple (symbol-name x)))))
+ ((consp x)
+ (cons (cons-tag)
+ (cons (nice->simple (car x))
+ (nice->simple (cdr x)))))
+ (t nil)))
+
+(defun strfix (x) (if (stringp x) x ""))
+
+(defun simple->nice (x)
+ (cond ((equal x (nil-tag)) nil)
+ ((equal x (t-tag)) t)
+ ((equal (car x) (natural-tag))
+ (list->nat (cdr x)))
+ ((equal (car x) (negative-tag))
+ (- (list->nat (cdr x))))
+ ((equal (car x) (rational-tag))
+ (/ (simple->nice (cadr x))
+ (simple->nice (cddr x))))
+ ((equal (car x) (complex-tag))
+ (complex (simple->nice (cadr x))
+ (simple->nice (cddr x))))
+ ((equal (car x) (character-tag))
+ (code-char (list->nat (cdr x))))
+ ((equal (car x) (string-tag))
+ (coerce (simple->clist (cdr x)) 'string))
+ ((equal (car x) (symbol-tag))
+ (intern$ (strfix (simple->nice (cddr x)))
+ (strfix (simple->nice (cadr x)))))
+ ((equal (car x) (cons-tag))
+ (cons (simple->nice (cadr x))
+ (simple->nice (cddr x))))
+ (t nil)))
+
+(defthm nice->simple-inverse
+ (implies (nicep x)
+ (equal (simple->nice (nice->simple x))
+ x)))
+
+(defthm nice->simple-simplep
+ (simplep (nice->simple x)))
+
+(defthm simple->nice-nicep
+ (nicep (simple->nice x)))
+
+;; we now use ncons to map simple-trees into natural numbers
+
+(defun interleave (x y)
+ (declare (xargs :measure (+ (nlen x) (nlen y))))
+ (if (or (not (natp x))
+ (not (natp y))
+ (and (= x 0) (= y 0)))
+ 0
+ (ncons 1
+ (ncons (ncar x)
+ (ncons (ncar y)
+ (interleave (ncdr x)
+ (ncdr y)))))))
+
+(defun extract1 (x)
+ (declare (xargs :measure (nlen x)))
+ (if (zp x)
+ 0
+ (ncons (ncar (ncdr x))
+ (extract1 (ncdr (ncdr (ncdr x)))))))
+
+(defun extract2 (x)
+ (declare (xargs :measure (nlen x)))
+ (if (zp x)
+ 0
+ (ncons (ncar (ncdr (ncdr x)))
+ (extract2 (ncdr (ncdr (ncdr x)))))))
+
+(defthm extract1-of-interleave
+ (implies (and (natp x)
+ (natp y))
+ (equal (extract1 (interleave x y)) x)))
+
+(defthm extract2-of-interleave
+ (implies (and (natp x)
+ (natp y))
+ (equal (extract2 (interleave x y)) y)))
+
+(defthm extract1-<=-propagate
+ (<= (nlen (extract1 x)) (nlen x))
+ :rule-classes :linear)
+
+(defthm extract2-<=-propagate
+ (<= (nlen (extract2 x)) (nlen x))
+ :rule-classes :linear)
+
+(defun simple->nat (x)
+ (if (consp x)
+ (ncons 1 (interleave (simple->nat (car x))
+ (simple->nat (cdr x))))
+ 0))
+
+(defun nat->simple (x)
+ (declare (xargs :measure (nlen x)))
+ (if (and (not (zp x))
+ (= (ncar x) 1))
+ (cons (nat->simple (extract1 (ncdr x)))
+ (nat->simple (extract2 (ncdr x))))
+ nil))
+
+(defthm simple->nat-inverse
+ (implies (simplep x)
+ (equal (nat->simple (simple->nat x))
+ x)))
+
+(defthm simple->nat-is-natp
+ (natp (simple->nat x)))
+
+(defthm nat->simplep-is-simplep
+ (simplep (nat->simple x)))
+
+(defun nice->nat (x)
+ (simple->nat (nice->simple x)))
+
+(defun nat->nice (x)
+ (simple->nice (nat->simple x)))
+
+(defthm nice->nat-inverse
+ (implies (nicep x)
+ (equal (nat->nice (nice->nat x))
+ x)))
+
+(defthm nice->nat-is-natural
+ (natp (nice->nat x))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm nat->nice-is-nicep
+ (nicep (nat->nice x)))
+
+(defthm nice->simple-atom-implies-nil
+ (implies (nicep x)
+ (equal (atom (nice->simple x)) (not x))))
+
+(defthm ncons-of-1-not-equal-0
+ (not (equal (ncons 1 x) 0))
+ :hints (("Goal" :in-theory (enable ncons))))
+
+(defthm simple->nat-0-implies-atom
+ (equal (equal (simple->nat x) 0) (atom x)))
+
+(defthm nice->nat-0-implies-nil
+ (implies (nicep x)
+ (equal (equal (nice->nat x) 0) (not x)))
+ :hints (("Goal" :in-theory (disable nice->simple nicep simple->nat))))
+
+(in-theory (disable nat->nice nice->nat))
+
+;; NOTE -- we conclude this book with a simple trick using defun-sk to get a
+;; predicate recognizing the natural numbers which are in the range of
+;; nice->nat and using this predicate to prove the additional property required
+;; to show that nat->nice and nice->nat are bijective on this range and the
+;; nice objects. We do not use the following properties in the books this book
+;; supports, but others may find this useful and at least this little logic
+;; trick may have other applications:
+
+(defun-sk nice-natp (x)
+ (exists y (and (nicep y) (equal (nice->nat y) x))))
+
+(defthm nice-natp-implies-natp
+ (implies (nice-natp x)
+ (natp x)))
+
+(defthm nice->nat-is-nice-natp
+ (implies (nicep x)
+ (nice-natp (nice->nat x)))
+ :hints (("Goal" :use (:instance nice-natp-suff
+ (y x)
+ (x (nice->nat x)))
+ :in-theory (disable nice-natp-suff))))
+
+(defthm nat->nice-inverse
+ (implies (nice-natp x)
+ (equal (nice->nat (nat->nice x))
+ x))
+ :hints (("Goal" :use (:instance nice->nat-inverse
+ (x (nice-natp-witness x)))
+ :in-theory (disable nice->nat-inverse))))
+
+
+(defun nice-nat (x)
+ (nice->nat (nat->nice x)))
+
+(defthm nice-natp-of-nice-nat
+ (nice-natp (nice-nat x)))
+
+(in-theory (disable nice-natp))
+
+
+
+
+
diff --git a/books/workshops/2003/sumners/support/simple.lisp b/books/workshops/2003/sumners/support/simple.lisp
new file mode 100644
index 0000000..9061b82
--- /dev/null
+++ b/books/workshops/2003/sumners/support/simple.lisp
@@ -0,0 +1,133 @@
+(in-package "ACL2")
+(set-match-free-default :all)
+
+#| simple.lisp
+
+This book defines a basic fair selector over a bounded set of natural
+numbers. Note that this selector is completely subsumed by the fair selector
+defined in fair.lisp which defines a fair selector over a superset of the
+objects selected by the functions in this book. Thus, this book is included
+solely for the purposes of exposition and completeness, but we do not suggest
+the use of this book.
+
+|#
+
+; The following was removed with the addition of natp-compound-recognizer to
+; ACL2 2.9.2.
+;(defthm natp-compound-recognizer
+; (iff (natp x)
+; (and (integerp x)
+; (>= x 0)))
+; :rule-classes :compound-recognizer)
+
+(in-theory (disable natp))
+
+(encapsulate
+ (((upper-bound) => *))
+
+ (local (defun upper-bound () 1))
+
+ (defthm upper-bound-positive-natural
+ (and (integerp (upper-bound))
+ (> (upper-bound) 0))
+ :rule-classes :type-prescription)
+)
+
+(defun selectp (i)
+ (and (natp i) (< i (upper-bound))))
+
+(defun fair-select (f) f)
+
+(defun fair-measure (i f)
+ (if (selectp i)
+ (if (< i f)
+ (+ i (- (upper-bound) f))
+ (- i f))
+ 0))
+
+(defun fair-step (f)
+ (let ((f (1+ f))) (if (< f (upper-bound)) f 0)))
+
+(defun fair-inv (f) (selectp f))
+
+(defun fair-init () 0)
+
+(local
+(defthm fair-measure-natural
+ (implies (fair-inv f)
+ (natp (fair-measure i f)))
+ :hints (("Goal" :in-theory (enable natp)))))
+
+(local
+(defthm fair-measure-decreases
+ (implies (and (selectp i)
+ (fair-inv f)
+ (not (equal i (fair-select f))))
+ (< (fair-measure i (fair-step f))
+ (fair-measure i f)))
+ :rule-classes :linear))
+
+(local
+(defthm fair-inv-is-invariant
+ (implies (fair-inv f)
+ (fair-inv (fair-step f)))))
+
+(in-theory (disable (fair-inv) (selectp)))
+
+(local
+(defthm fair-inv-of-init
+ (fair-inv 0)))
+
+(in-theory (disable fair-step fair-inv fair-measure fair-select))
+
+
+(defun fair-run (n)
+ (if (zp n) (fair-init) (fair-step (fair-run (1- n)))))
+
+(defthm fair-inv-of-fair-run
+ (fair-inv (fair-run n)))
+
+(local
+(defthm linear-factoid1
+ (implies (and (natp n)
+ (natp x))
+ (equal (+ n (- n) x) x))))
+
+(local
+(defthm linear-factoid2
+ (implies (and (natp n)
+ (natp x))
+ (equal (+ (- n) n x) x))))
+
+(local
+(defthm fair-run-of-1+
+ (implies (natp n)
+ (equal (fair-run (1+ n))
+ (fair-step (fair-run n))))))
+
+(in-theory (disable fair-run))
+(in-theory (enable (:induction fair-run)))
+
+(in-theory (disable (fair-run) (fair-step) (fair-select)))
+
+(encapsulate
+ (((env *) => *)
+ ((env-measure * *) => *))
+
+(local (defun env (n)
+ (fair-select (fair-run n))))
+(local (defun env-measure (i n)
+ (fair-measure i (fair-run n))))
+
+(defthm env-measure+-is-natural
+ (natp (env-measure i n))
+ :rule-classes (:type-prescription :rewrite))
+
+(defthm env-measure+-decreases
+ (implies (and (selectp i)
+ (natp n)
+ (not (equal i (env n))))
+ (< (env-measure i (1+ n))
+ (env-measure i n)))
+ :rule-classes (:linear :rewrite))
+)
diff --git a/books/workshops/2003/sustik/dickson.pdf.gz b/books/workshops/2003/sustik/dickson.pdf.gz
new file mode 100644
index 0000000..2ac795c
--- /dev/null
+++ b/books/workshops/2003/sustik/dickson.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/sustik/dickson.ps.gz b/books/workshops/2003/sustik/dickson.ps.gz
new file mode 100644
index 0000000..a0f3aeb
--- /dev/null
+++ b/books/workshops/2003/sustik/dickson.ps.gz
Binary files differ
diff --git a/books/workshops/2003/sustik/dicksonslides.pdf.gz b/books/workshops/2003/sustik/dicksonslides.pdf.gz
new file mode 100644
index 0000000..ed103c5
--- /dev/null
+++ b/books/workshops/2003/sustik/dicksonslides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/sustik/dicksonslides.ps.gz b/books/workshops/2003/sustik/dicksonslides.ps.gz
new file mode 100644
index 0000000..157ba99
--- /dev/null
+++ b/books/workshops/2003/sustik/dicksonslides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/sustik/support/dickson.lisp b/books/workshops/2003/sustik/support/dickson.lisp
new file mode 100644
index 0000000..e771388
--- /dev/null
+++ b/books/workshops/2003/sustik/support/dickson.lisp
@@ -0,0 +1,1056 @@
+(in-package "ACL2")
+
+#|
+
+Updated : 09-08-03
+By : Daron Vroon
+
+File : dickson.lisp
+Authors : Matyas, Sandip
+Date created: 2002-04-24
+Revision : $Id: dickson.lisp,v 1.62 2003/07/04 01:06:26 sustik Exp $
+
+The constructive proof described in the dickson.dvi file is formulated
+in this file. An embedding of monomial sets to ordinals is defined
+such that if a monomial sequence is such that no monomial divides
+another one further in the sequence, then the corresponding ordinal
+sequence assigned to the monomial sets forming proper subsequences is
+decreasing according to e0-ord-<. This will establish by the
+well-foundedness of ordinals that there can be no infinitely
+decreasing sequence of such monomials. The direct formulation uses
+the ordinals in Cantor normal form as defined in the 'ordinals' book
+by written by Panagiotis Manolios and Daron Vroon and the mapping is
+lifted to the ACL2 ordinals in a subsequent step.
+
+I am thankful to Sandip Ray for his contributions early in the
+project. His insight lead to simplify the proof attempt by realizing
+independence of certain lemmas.
+
+|#
+
+;; (set-match-free-error nil)
+
+;(include-book "ordinal-arith" :skip-proofs-okp nil)
+(include-book "../../../../ordinals/ordinals")
+;(include-book "../../../../ordinals/e0-ordinal")
+
+(defun o-min (x y)
+ (if (o< x y) x y))
+
+;; We start by defining a recognizer for k-tuple of naturals, which is the
+;; representation of monomials so far as we are concerned.
+
+(defun natural-tuplep (k x)
+ (cond ((zp k) (null x))
+ ((not (natp (first x))) nil)
+ (T (natural-tuplep (1- k) (rest x)))))
+
+(defthm natural-tuplep-length
+ (implies (and (natural-tuplep k x)
+ (natp k))
+ (equal (length x) k)))
+
+;; The function partial-tuple-<= is the partial order on tuples which
+;; coincides with monomial divisibility.
+
+(defun partial-tuple-<= (k x y)
+ (cond ((zp k) t)
+ ((< (car y) (car x)) nil)
+ (t (partial-tuple-<= (1- k) (cdr x) (cdr y)))))
+
+;; We prove now that it is indeed a partial order, namely it is
+;; reflexive, transitive, and antisymmetric.
+
+(defthm partial-tuple-<=-transitivity
+ (implies (and (partial-tuple-<= k x y)
+ (partial-tuple-<= k y z))
+ (partial-tuple-<= k x z))
+ :rule-classes :forward-chaining)
+
+(defthm partial-tuple-<=-reflexivity
+ (partial-tuple-<= k x x))
+
+(defthm partial-tuple-<=-antisymmetry
+ (implies (and (partial-tuple-<= k x y)
+ (partial-tuple-<= k y x)
+ (natural-tuplep k x)
+ (natural-tuplep k y))
+ (equal x y))
+ :rule-classes :forward-chaining)
+
+;; We define a recognizer for a set of k-tuples.
+
+(defun tuple-setp (k A)
+ (cond ((atom A) (equal A nil))
+ ((not (natural-tuplep k (first A))) nil)
+ (T (tuple-setp k (rest A)))))
+
+;; (tuple-setp 1 '((1) (2) (3)))
+;; (tuple-setp 3 '((1 2 3) (1 2 2) (3 1 1) (3 4 1) (2 0 2)))
+
+;; We now define a recognizer of the membership of a tuple in a tuple
+;; set.
+
+(defun tuple-in-set (x S)
+ (cond ((endp S) nil)
+ ((equal x (first S)) T)
+ (T (tuple-in-set x (rest S)))))
+
+;; (tuple-in-set '(1 2 3) '((2 2 5) (8 1 3) (1 2 3) (4 3 4)))
+
+;; And then we can now define a subset relation on tuple sets in the
+;; natural way.
+
+(defun tuple-set-subsetp (A B)
+ (cond ((endp A) T)
+ ((not (tuple-in-set (first A) B)) nil)
+ (T (tuple-set-subsetp (rest A) B))))
+
+;; (tuple-set-subsetp '((1 2) (3 4) (4 5)) '((3 4) (4 5) (1 4) (2 3) (1 2)))
+
+;; We prove now, that the subset relation is transitive and reflexive,
+;; more for sanity check than anything else. Note that we cannot prove
+;; anti-symmetry here, since we are not using set equality, but just
+;; the vanilla equality.
+
+(defthm tuple-set-subsetp-transitive
+ (implies (and (tuple-set-subsetp A B)
+ (tuple-set-subsetp B C))
+ (tuple-set-subsetp A C))
+ :rule-classes :forward-chaining)
+
+(defthm subset-cons
+ (implies (tuple-set-subsetp A B)
+ (tuple-set-subsetp A (cons e B))))
+
+(defthm tuple-set-subsetp-reflexive
+ (tuple-set-subsetp x x))
+
+(in-theory (disable subset-cons))
+
+(defun tuple-set-filter (S i)
+ (cond ((endp S) NIL)
+ ((and (consp (first S)) (<= (first (first S)) i))
+ (cons (first S) (tuple-set-filter (rest S) i)))
+ (T (tuple-set-filter (rest S) i))))
+
+;; (tuple-set-filter '((1 2 3) (1 2 2) (3 1 1) (3 4 1) (2 0 2)) 2)
+
+(defthm tuple-set-filter-creates-tuple-set
+ (implies (and (tuple-setp k S)
+ (natp i))
+ (tuple-setp k (tuple-set-filter S i))))
+
+(defthm tuple-set-filter-monoton
+ (implies (and (natp i)
+ (natp j)
+ (<= i j))
+ (tuple-set-subsetp (tuple-set-filter S i)
+ (tuple-set-filter S j))))
+
+(defthm tuple-set-filter-element
+ (implies (and (tuple-in-set x S)
+ (consp x)
+ (<= (car x) i)
+ (natp i))
+ (tuple-in-set x (tuple-set-filter S i))))
+
+(defthm tuple-set-filter-preserves-subset
+ (implies (and (natp i)
+ (tuple-set-subsetp A B))
+ (tuple-set-subsetp (tuple-set-filter A i)
+ (tuple-set-filter B i))))
+
+(defun tuple-set-projection (S)
+ (cond ((endp S) NIL)
+ ((consp (first S)) (cons (rest (first S))
+ (tuple-set-projection (rest S))))
+ (T (tuple-set-projection (rest S)))))
+
+;; (tuple-set-projection '((1 2 3) (1 2 2) (3 1 1) (3 4 1) (2 0 2)))
+
+(defthm tuple-set-projection-creates-tuple-set
+ (implies (and (tuple-setp k S)
+ (natp i))
+ (tuple-setp (1- k) (tuple-set-projection S))))
+
+(defthm tuple-set-projection-element
+ (implies (and (tuple-in-set x S)
+ (consp x))
+ (tuple-in-set (rest x) (tuple-set-projection S))))
+
+(defthm tuple-set-projection-preserves-subset
+ (implies (tuple-set-subsetp A B)
+ (tuple-set-subsetp (tuple-set-projection A)
+ (tuple-set-projection B))))
+
+(defun tuple-set-filter-projection (S i)
+ (tuple-set-projection (tuple-set-filter S i)))
+
+(defun tuple-set-max-first (S)
+ (cond ((endp S) 0)
+ ((and (consp (first S)) (natp (first (first S))))
+ (max (first (first S))
+ (tuple-set-max-first (rest S))))
+ (T (tuple-set-max-first (rest S)))))
+
+(defthm tuple-set-max-first-property
+ (implies (and (tuple-in-set x S)
+ (consp x)
+ (natp (first x)))
+ (<= (first x) (tuple-set-max-first S))))
+
+(defthm tuple-set-filter-max
+ (implies (and (tuple-setp k S)
+ (natp k)
+ (not (zp k))
+ (<= (tuple-set-max-first S) i))
+ (equal (tuple-set-filter S i) S)))
+
+(in-theory (disable tuple-set-filter))
+(in-theory (disable tuple-set-projection))
+
+(defthm tuple-set-max-first-subset
+ (implies (tuple-set-subsetp A B)
+ (<= (tuple-set-max-first A)
+ (tuple-set-max-first B)))
+ :rule-classes :linear)
+
+(in-theory (disable tuple-set-max-first))
+
+(defun tuple-set-min-first (S)
+ (cond ((endp S) (omega))
+ ((and (consp (first S)) (natp (first (first S))))
+ (o-min (first (first S))
+ (tuple-set-min-first (rest S))))
+ (T (tuple-set-min-first (rest S)))))
+
+;; (tuple-set-min-first '((1 2 3) (1 2 2) (3 1 1) (3 4 1) (2 0 2)))
+;; (tuple-set-min-first '( nil ))
+
+(defthm tuple-set-min-first-produces-ordinal
+ (o-p (tuple-set-min-first S)))
+
+(defthm tuple-set-min-first-property
+ (implies (and (tuple-in-set x S)
+ (consp x)
+ (natp (first x)))
+ (<= (tuple-set-min-first S) (first x)))
+ :hints (("goal" :in-theory (enable o<))))
+
+(defthm tuple-set-min-first-nat
+ (implies (and (posp k)
+ (tuple-setp k S)
+ (consp S))
+ (natp (tuple-set-min-first S)))
+ :rule-classes ((:rewrite :match-free :all)
+ (:forward-chaining :trigger-terms ((tuple-setp k S)))))
+
+(defthm technical-tuple-set-min-first-non-empty
+ (implies (and (posp k)
+ (tuple-setp k S)
+ (tuple-in-set x S))
+ (natp (tuple-set-min-first S)))
+ :rule-classes ((:forward-chaining
+ :match-free :all
+ :trigger-terms ((tuple-setp k S)
+ (tuple-in-set x S)))))
+
+(defun tuple-set->ordinal-partial-sum (k S i)
+ (declare (xargs :measure (o+ (o* (omega) (nfix k))
+ (nfix (- (tuple-set-max-first S) i)))))
+ (cond ((or (not (natp k)) (not (natp i))) 0)
+ ((zp k) 0)
+ ((equal k 1)
+ (tuple-set-min-first S))
+ ((<= (tuple-set-max-first S) i)
+ (o^ (omega)
+ (o+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection S)
+ 0)
+ 1)))
+ (T (o+
+ (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-filter-projection S i)
+ 0))
+ (tuple-set->ordinal-partial-sum k S (1+ i))))))
+
+(defun tuple-set->ordinal (k S)
+ (if (and (natp k)
+ (tuple-setp k S))
+ (tuple-set->ordinal-partial-sum k S 0)
+ 0))
+
+;; (tuple-set->ordinal 1 '((5) (3) (4) (2) (3)))
+;; (tuple-set->ordinal 2 '((2 5) (3 3) (2 4) (4 2) (3 1)))
+;; (tuple-set->ordinal 3 '((1 2 3) (1 2 2) (3 1 1) (3 4 1) (2 0 2)))
+;; (tuple-set->ordinal 3 '((1 2 3) (1 2 2) (3 1 1) (3 4 1) (2 0 2)))
+
+(defthm tuple-set->ordinal-partial-sum-produces-ordinal
+ (o-p (tuple-set->ordinal-partial-sum k A i))
+ :rule-classes ((:rewrite)
+ (:forward-chaining
+ :trigger-terms ((tuple-set->ordinal-partial-sum K A i)))))
+
+(defthm tuple-set->ordinal-produces-ordinal
+ (o-p (tuple-set->ordinal k A)))
+
+(defthm tuple-set->ordinal-partial-sum-k=1
+ (implies (and (tuple-setp 1 S)
+ (natp i))
+ (equal (tuple-set->ordinal-partial-sum 1 S i)
+ (tuple-set-min-first S))))
+
+(in-theory (disable tuple-set->ordinal-partial-sum))
+
+(defthm technical-5
+ (implies (and (tuple-setp k S)
+ (natp k)
+ (natp i))
+ (o<= (tuple-set->ordinal-partial-sum k S (1+ i))
+ (tuple-set->ordinal-partial-sum k S i)))
+ :hints (("Goal" :expand (tuple-set->ordinal-partial-sum k S i))
+ ("Subgoal 4'" :expand (tuple-set->ordinal-partial-sum 0 S (1+ i)))
+ ("Subgoal 1'" :expand (tuple-set->ordinal-partial-sum k S (1+ i)))))
+
+(defthm tuple-set-subset-consp
+ (implies (and (tuple-set-subsetp a b)
+ (consp a))
+ (consp b))
+ :rule-classes :forward-chaining)
+
+(encapsulate
+ ()
+ (local
+ (defthm l1
+ (implies (and (consp a)
+ (consp (car a))
+ (natp (caar a))
+ (o<= (tuple-set-min-first b)
+ (tuple-set-min-first (cdr a)))
+ (tuple-setp 1 a)
+ (tuple-setp 1 b)
+ (tuple-set-subsetp a b))
+ (o<= (tuple-set-min-first b)
+ (tuple-set-min-first a)))
+ :hints (("goal"
+ :do-not-induct t
+ :in-theory (disable tuple-set-min-first-property)
+ :use ((:instance tuple-set-min-first-property
+ (x (car a))
+ (S B)))))
+ :rule-classes :forward-chaining))
+
+ (defthm subset-tuple-set-min-first-<=
+ (implies (and (tuple-setp 1 a)
+ (tuple-setp 1 b)
+ (tuple-set-subsetp a b))
+ (o<= (tuple-set-min-first b)
+ (tuple-set-min-first a)))))
+
+(defun map-lemma-1.1-induction-hint (k A B i)
+ (declare (xargs :measure (o+ (o* (omega) (nfix k)) (nfix (- (tuple-set-max-first B) i)))))
+ (cond ((not (natp i)) A)
+ ((zp k) B)
+ ((equal 1 k) 0)
+ ((<= (tuple-set-max-first B) i)
+ (map-lemma-1.1-induction-hint
+ (1- k)
+ (tuple-set-projection A)
+ (tuple-set-projection B)
+ 0))
+ (T (list (map-lemma-1.1-induction-hint
+ (1- k)
+ (tuple-set-filter-projection A i)
+ (tuple-set-filter-projection B i)
+ 0)
+ (map-lemma-1.1-induction-hint
+ k A B (1+ i))))))
+
+(in-theory (enable tuple-set-min-first-property))
+
+(defthm tuple-set-min-first-upper-bound
+ (o<= (tuple-set-min-first S) (omega)))
+
+(in-theory (disable tuple-set-min-first-property))
+
+(defthm map-lemma-1.1
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (tuple-set-subsetp A B)
+ (natp k)
+ (natp i))
+ (o<= (tuple-set->ordinal-partial-sum
+ k B i)
+ (tuple-set->ordinal-partial-sum
+ k A i)))
+ :hints (("Goal"
+ :do-not generalize
+ :induct (map-lemma-1.1-induction-hint k A B i))
+ ("Subgoal *1/4"
+ :expand ((tuple-set->ordinal-partial-sum k B i)
+ (tuple-set->ordinal-partial-sum k A i)))
+ ("Subgoal *1/4.1'"
+ :in-theory (disable |a <= b & c <= d => a+c <= b+d|)
+ :use (:instance |a <= b & c <= d => a+c <= b+d|
+ (a (O^ (OMEGA)
+ (TUPLE-SET->ORDINAL-PARTIAL-SUM
+ (+ -1 K)
+ (TUPLE-SET-PROJECTION
+ (TUPLE-SET-FILTER B I))
+ 0)))
+ (b (O^ (OMEGA)
+ (TUPLE-SET->ORDINAL-PARTIAL-SUM
+ (+ -1 K)
+ (TUPLE-SET-PROJECTION A)
+ 0)))
+ (c (TUPLE-SET->ORDINAL-PARTIAL-SUM K B (+ 1 I)))
+ (d (O^ (OMEGA)
+ (O+ (TUPLE-SET->ORDINAL-PARTIAL-SUM
+ (+ -1 K)
+ (TUPLE-SET-PROJECTION A)
+ 0)
+ 1)))))
+ ("Subgoal *1/4.1''"
+ :expand (TUPLE-SET->ORDINAL-PARTIAL-SUM K A (+ 1 I)))
+ ("Subgoal *1/3"
+ :expand ((tuple-set->ordinal-partial-sum k A i)
+ (tuple-set->ordinal-partial-sum k B i)))
+ ("Subgoal *1/1''"
+ :expand ((TUPLE-SET->ORDINAL-PARTIAL-SUM 0 B I)
+ (TUPLE-SET->ORDINAL-PARTIAL-SUM 0 A I)))))
+
+(in-theory (disable map-lemma-1.1))
+
+(defthm map-lemma-1
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (tuple-set-subsetp A B)
+ (natp k))
+ (o<= (tuple-set->ordinal k B)
+ (tuple-set->ordinal k A)))
+ :hints (("Goal"
+ :do-not-induct t
+ :expand ((tuple-set->ordinal k B)
+ (tuple-set->ordinal k A))
+ :use (:instance map-lemma-1.1 (i 0)))))
+
+(in-theory (disable tuple-set->ordinal))
+
+(defthm map-lemma-2
+ (implies (and (tuple-setp k A)
+ (natp k)
+ (< 1 k)
+ (natp i))
+ (o<= (tuple-set->ordinal (1- k)
+ (tuple-set-filter-projection A (1+ i)))
+ (tuple-set->ordinal (1- k)
+ (tuple-set-filter-projection A i)))))
+
+(defthm map-lemma-2.1
+ (implies (and (tuple-setp k A)
+ (natp k)
+ (< 1 k)
+ (natp i))
+ (o<= (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter A (1+ i)))
+ 0)
+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter A i))
+ 0)))
+ :hints (("Goal"
+ :use (:instance map-lemma-1.1
+ (k (1- k))
+ (i 0)
+ (A (tuple-set-filter-projection A i))
+ (B (tuple-set-filter-projection A (1+ i)))))))
+
+
+(defun map-lemma-3.1-induction-hint (A i)
+ (declare (xargs :measure (nfix (- (tuple-set-max-first A) i))))
+ (cond ((not (natp i)) A)
+ ((<= (tuple-set-max-first A) i) T)
+ (T (list (map-lemma-3.1-induction-hint A (1+ i))))))
+
+(encapsulate
+ ()
+
+ (local
+ (defthm l1
+ (implies
+ (and (natp i)
+ (< i (tuple-set-max-first a))
+ (o<= (tuple-set->ordinal-partial-sum k a (+ 1 i))
+ (o* (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter a (+ 1 i)))
+ 0))
+ (omega)))
+ (tuple-setp k a)
+ (posp k)
+ (< 1 k))
+ (o<= (o^ (omega)
+ (o+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter a (+ 1 i)))
+ 0)
+ 1))
+ (o^ (omega)
+ (o+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection
+ (tuple-set-filter a i))
+ 0)
+ 1))))))
+
+ (local
+ (defthm l2
+ (implies
+ (and (natp i)
+ (< i (tuple-set-max-first a))
+ (o<= (tuple-set->ordinal-partial-sum k a (+ 1 i))
+ (o* (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter a (+ 1 i)))
+ 0))
+ (omega)))
+ (tuple-setp k a)
+ (posp k)
+ (< 1 k))
+ (o<= (tuple-set->ordinal-partial-sum k a (+ 1 i))
+ (o^ (omega)
+ (o+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter a i))
+ 0)
+ 1))))
+ :hints (("goal"
+ :use ((:instance |a <= b & b <= c => a <= c|
+ (a (tuple-set->ordinal-partial-sum k a (+ 1 i)))
+ (b (o* (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter a (+ 1 i)))
+ 0))
+ (omega)))
+ (c (o^ (omega)
+ (o+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection
+ (tuple-set-filter a i))
+ 0)
+ 1)))))))))
+ (local
+ (defthm l3
+ (implies
+ (and (natp i)
+ (< i (tuple-set-max-first a))
+ (o<= (tuple-set->ordinal-partial-sum k a (+ 1 i))
+ (o* (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter a (+ 1 i)))
+ 0))
+ (omega)))
+ (tuple-setp k a)
+ (posp k)
+ (< 1 k))
+ (o<= (o+ (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-filter-projection a i)
+ 0))
+ (tuple-set->ordinal-partial-sum k a (+ 1 i)))
+ (o+ (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-filter-projection a i)
+ 0))
+ (o^ (omega)
+ (o+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-filter-projection a i)
+ 0)
+ 1)))))
+ :hints (("goal"
+ :do-not-induct t
+ :in-theory (disable l2 |a < b <=> c+a < c+b|)
+ :use (l2
+ (:instance |a < b <=> c+a < c+b|
+ (c (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-filter-projection a i)
+ 0)))
+ (b (tuple-set->ordinal-partial-sum k a (+ 1 i)))
+ (a (o^ (omega)
+ (o+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-filter-projection a i)
+ 0)
+ 1)))))))))
+
+ (defthm map-lemma-3.1
+ (implies (and (tuple-setp k A)
+ (posp k)
+ (< 1 k)
+ (natp i))
+ (o<= (tuple-set->ordinal-partial-sum k A i)
+ (o^ (omega) (o+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-filter-projection A i)
+ 0)
+ 1))))
+ :hints (("Goal"
+ :induct (map-lemma-3.1-induction-hint A i))
+ ("Subgoal *1/2''"
+ :expand (tuple-set->ordinal-partial-sum k A i)
+ :in-theory (disable l3)
+ :use ((:instance l3)))
+ ("Subgoal *1/1'"
+ :expand (TUPLE-SET->ORDINAL-PARTIAL-SUM K A I)))))
+
+(defthm map-lemma-3.2
+ (implies (and (tuple-setp k A)
+ (natp k)
+ (< 1 k)
+ (natp i))
+ (o< (o^ (omega) (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-filter-projection A i)
+ 0))
+ (tuple-set->ordinal-partial-sum k A i)))
+ :hints (("Goal"
+ :expand (tuple-set->ordinal-partial-sum k A i))
+ ("Subgoal 2" ; Matt K. mod 5/2016 (type-set bit for {1})
+ :expand (tuple-set->ordinal-partial-sum k A (+ 1 i)))))
+
+(defthm map-lemma-3.3
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (natp k)
+ (natp i)
+ (< 1 k)
+ (o< (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter A i))
+ 0)
+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter B i))
+ 0)))
+ (o< (tuple-set->ordinal-partial-sum k A i)
+ (tuple-set->ordinal-partial-sum k B i)))
+ :hints (("Goal"
+ :do-not-induct t
+ :in-theory (disable |a <= b & b < c => a < c|)
+ :use (map-lemma-3.1
+ (:instance map-lemma-3.2
+ (a b))
+ (:instance |a <= b & b < c => a < c|
+ (a (o* (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter a i))
+ 0))
+ (omega)))
+ (b (o^ (omega)
+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-projection (tuple-set-filter b i))
+ 0)))
+ (c (tuple-set->ordinal-partial-sum k b i)))
+ (:instance |a <= b => c^a <= c^b|
+ (a (o+ (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-filter-projection a i)
+ 0)
+ 1))
+ (b (tuple-set->ordinal-partial-sum
+ (+ -1 k)
+ (tuple-set-filter-projection b i)
+ 0))
+ (c (omega)))))))
+
+(defthm map-lemma-3.4
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (posp k)
+ (natp i)
+ (< 1 k)
+ (equal (tuple-set->ordinal-partial-sum k A i)
+ (tuple-set->ordinal-partial-sum k B i)))
+ (equal (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter A i))
+ 0)
+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter B i))
+ 0)))
+ :hints (("Goal" :use (map-lemma-3.3
+ (:instance map-lemma-3.3
+ (A B)
+ (B A))))))
+
+(in-theory (disable map-lemma-3.4))
+
+(defthm map-lemma-3.5
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (posp k)
+ (natp i)
+ (< 1 k)
+ (equal (tuple-set->ordinal-partial-sum k A i)
+ (tuple-set->ordinal-partial-sum k B i)))
+ (equal (tuple-set->ordinal-partial-sum k A (1+ i))
+ (tuple-set->ordinal-partial-sum k B (1+ i))))
+ :hints ; Matt K. mod 5/2016 (type-set bit for {1}): avoid subgoal hints
+ (("Goal"
+ :do-not-induct t
+ :in-theory (disable |a^(b+c) = a^b * a^c|)
+ :use map-lemma-3.4
+ :expand ((tuple-set->ordinal-partial-sum k a i)
+ (tuple-set->ordinal-partial-sum k b i)
+ (tuple-set->ordinal-partial-sum k a (+ 1 i))
+ (tuple-set->ordinal-partial-sum k b (+ 1 i))))))
+
+(defun map-lemma-3.6-induction-hint (i j)
+ (cond ((not (natp i)) nil)
+ ((not (natp j)) nil)
+ ((<= j i) nil)
+ (T (map-lemma-3.6-induction-hint i (1- j)))))
+
+(defthm map-lemma-3.6
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (natp k)
+ (< 1 k)
+ (natp i)
+ (natp j)
+ (<= i j)
+ (equal (tuple-set->ordinal-partial-sum k A i)
+ (tuple-set->ordinal-partial-sum k B i)))
+ (equal (equal (tuple-set->ordinal-partial-sum k A j)
+ (tuple-set->ordinal-partial-sum k B j))
+ T))
+ :hints (("Goal"
+ :induct (map-lemma-3.6-induction-hint i j))
+ ("Subgoal *1/2'"
+ :use (:instance map-lemma-3.5
+ (i (+ -1 j))))))
+
+(defthm map-lemma-3.7
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (natp k)
+ (< 1 k)
+ (natp i)
+ (natp j)
+ (<= i j)
+ (equal (tuple-set->ordinal-partial-sum k A i)
+ (tuple-set->ordinal-partial-sum k B i)))
+ (equal (equal (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter A j))
+ 0)
+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter B j))
+ 0))
+ T))
+ :hints (("Goal"
+ :use (map-lemma-3.6
+ (:instance map-lemma-3.4
+ (i j))))))
+
+(defthm map-lemma-3
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (natp k)
+ (natp i)
+ (< 1 k)
+ (equal (tuple-set->ordinal-partial-sum k A 0)
+ (tuple-set->ordinal-partial-sum k B 0)))
+ (equal (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter A i))
+ 0)
+ (tuple-set->ordinal-partial-sum
+ (1- k)
+ (tuple-set-projection (tuple-set-filter B i))
+ 0)))
+ :hints (("Goal"
+ :use (:instance map-lemma-3.7
+ (i 0)
+ (j i)))))
+
+(defun exists-partial-tuple-<=-set-witness (k S x)
+ (cond ((endp S) nil)
+ ((partial-tuple-<= k (first S) x) (first S))
+ (t (exists-partial-tuple-<=-set-witness k (rest S) x))))
+
+(defun exists-partial-tuple-<=-set (k S x)
+ (let ((w (exists-partial-tuple-<=-set-witness k S x)))
+ (and (natural-tuplep k w)
+ (tuple-in-set w S)
+ (partial-tuple-<= k w x))))
+
+(defthm exists-partial-tuple-<=-set-suff
+ (implies (and (tuple-setp k S)
+ (tuple-in-set w S)
+ (partial-tuple-<= k w x))
+ (exists-partial-tuple-<=-set k S x)))
+
+(defthm exists-partial-tuple-<=-set-impl
+ (implies (and (natp k)
+ (<= 1 k)
+ (natural-tuplep k x)
+ (tuple-setp k S)
+ (exists-partial-tuple-<=-set k S x))
+ (and (equal (natural-tuplep
+ k
+ (exists-partial-tuple-<=-set-witness k S x))
+ T)
+ (equal (tuple-in-set
+ (exists-partial-tuple-<=-set-witness k S x)
+ S)
+ T)
+ (partial-tuple-<=
+ k
+ (exists-partial-tuple-<=-set-witness k S x)
+ x))))
+
+(in-theory (disable exists-partial-tuple-<=-set))
+
+(defun exists-projection-filter-inverse-witness (S v i)
+ (cond ((endp S) nil)
+ ((and (equal v (rest (first S)))
+ (<= (first (first S)) i)) (first S))
+ (T (exists-projection-filter-inverse-witness (rest S) v i))))
+
+(defun exists-projection-filter-inverse (S v i)
+ (let ((w (exists-projection-filter-inverse-witness S v i)))
+ (and (tuple-in-set w S)
+ (equal v (rest w))
+ (<= (first w) i))))
+
+(defthm exists-projection-filter-inverse-suff
+ (implies (and (tuple-in-set w S)
+ (equal v (rest w))
+ (<= (first w) i))
+ (exists-projection-filter-inverse S v i)))
+
+(defthm exists-projection-filter-inverse-impl
+ (implies (and (tuple-setp k S)
+ (natural-tuplep (1- k) v)
+ (<= 1 k)
+ (exists-projection-filter-inverse S v i))
+ (and (equal (natural-tuplep
+ k
+ (exists-projection-filter-inverse-witness S v i))
+ T)
+ (equal (tuple-in-set
+ (exists-projection-filter-inverse-witness S v i)
+ S)
+ T)
+ (equal (rest (exists-projection-filter-inverse-witness S v i))
+ v)
+ (<= (first (exists-projection-filter-inverse-witness S v i))
+ i))))
+
+(in-theory (enable tuple-set-filter))
+(in-theory (enable tuple-set-projection))
+
+(defthm map-lemma-4.1.1
+ (implies (and (tuple-setp k A)
+ (natural-tuplep (1- k) u)
+ (natp i)
+ (natp k)
+ (< 1 k)
+ (tuple-in-set u (tuple-set-projection (tuple-set-filter A i))))
+ (exists-projection-filter-inverse A u i)))
+
+(defthm map-lemma-4.1
+ (implies (and (tuple-setp k A)
+ (natural-tuplep (1- k) u)
+ (natp i)
+ (natp k)
+ (< 1 k)
+ (tuple-in-set u (tuple-set-projection (tuple-set-filter A i))))
+ (and (equal (rest (exists-projection-filter-inverse-witness A u i))
+ u)
+ (<= (first
+ (exists-projection-filter-inverse-witness A u i)) i))))
+
+(defthm map-lemma-4.2
+ (implies (and (tuple-setp k S)
+ (natp k)
+ (<= 2 k)
+ (natural-tuplep k v)
+ (tuple-in-set v S))
+ (tuple-in-set
+ (cdr v)
+ (tuple-set-projection (tuple-set-filter S (car v))))))
+
+(in-theory (disable tuple-set-filter))
+(in-theory (disable tuple-set-projection))
+
+(defun map-lemma-4-induction-hint (A B v k)
+ (cond ((zp k) nil)
+ ((< k 2) (list A B v))
+ (T (map-lemma-4-induction-hint
+ (tuple-set-projection (tuple-set-filter A (first v)))
+ (tuple-set-projection (tuple-set-filter B (first v)))
+ (rest v)
+ (1- k)))))
+
+(in-theory (disable map-lemma-4.1))
+
+(defthm partial-tuple-<=-decomposition
+ (implies (and (natural-tuplep k x)
+ (natural-tuplep k y)
+ (<= (first x) (first y))
+ (partial-tuple-<= (1- k) (rest x) (rest y)))
+ (partial-tuple-<= k x y)))
+
+(in-theory (disable map-lemma-3))
+
+(defthm tuple-set-min-first-special
+ (implies (and (tuple-setp 1 S)
+ (o< (tuple-set-min-first S) (omega)))
+ (tuple-in-set (list (tuple-set-min-first S)) S)))
+
+(defthm map-lemma-4
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (tuple-set-subsetp A B)
+ (natural-tuplep k v)
+ (tuple-in-set v B)
+ (equal (tuple-set->ordinal-partial-sum k A 0)
+ (tuple-set->ordinal-partial-sum k B 0))
+ (natp k)
+ (<= 1 k))
+ (exists-partial-tuple-<=-set k A v))
+ :hints (("Goal"
+ :induct (map-lemma-4-induction-hint A B v k))
+ ("Subgoal *1/3.2"
+ :use ((:instance map-lemma-4.1
+ (i (car v))
+ (u (exists-partial-tuple-<=-set-witness
+ (+ -1 k)
+ (tuple-set-projection
+ (tuple-set-filter A (car v)))
+ (cdr v))))))
+ ("Subgoal *1/3.2''"
+ :use ((:instance
+ exists-partial-tuple-<=-set-suff
+ (S A)
+ (w (EXISTS-PROJECTION-FILTER-INVERSE-WITNESS
+ A
+ (EXISTS-PARTIAL-TUPLE-<=-SET-WITNESS
+ (+ -1 K)
+ (TUPLE-SET-PROJECTION (TUPLE-SET-FILTER A (CAR V)))
+ (CDR V))
+ (CAR V)))
+ (x v))))
+ ("Subgoal *1/3.1"
+ :use ((:instance map-lemma-3
+ (i (car v)))))
+ ("Subgoal *1/2'''"
+ :use ((:instance tuple-set-min-first-property
+ (x v)
+ (S B))
+ (:instance exists-partial-tuple-<=-set-suff
+ (k 1)
+ (S A)
+ (w (list (TUPLE-SET-MIN-FIRST A)))
+ (x v))))
+ ("Subgoal *1/2.1''"
+ :use ((:instance tuple-set-min-first-special
+ (S A))))
+
+ ("Subgoal *1/2.1'5'"
+ :use ((:instance tuple-set-min-first-nat
+ (k 1)
+ (S B))))))
+
+(defthm map-lemma-4-alt
+ (implies (and (tuple-setp k A)
+ (tuple-setp k B)
+ (tuple-set-subsetp A B)
+ (natural-tuplep k v)
+ (tuple-in-set v B)
+ (equal (tuple-set->ordinal k A)
+ (tuple-set->ordinal k B))
+ (natp k)
+ (<= 1 k))
+ (exists-partial-tuple-<=-set k A v))
+ :hints (("Goal"
+ :use map-lemma-4)
+ ("Goal'"
+ :expand ((TUPLE-SET->ORDINAL K A)
+ (TUPLE-SET->ORDINAL K B)))
+ ("Goal'''"
+ :expand (TUPLE-SET->ORDINAL K NIL))))
+
+(defthm tuple-set-subsetp-with-cdr
+ (implies (tuple-set-subsetp A B)
+ (tuple-set-subsetp (cdr A) B)))
+
+(defthm tuple-set-subsetp-idempotent
+ (tuple-set-subsetp S S))
+
+(in-theory (disable map-lemma-1))
+(in-theory (disable map-lemma-4))
+
+(defthm dickson-map-thm.1
+ (implies (and (tuple-setp k S)
+ (consp S)
+ (natp k)
+ (<= 1 k))
+ (o<= (tuple-set->ordinal k S)
+ (tuple-set->ordinal k (rest S))))
+ :hints (("Goal" :use ((:instance map-lemma-1 (A (rest S)) (B S))))))
+
+(defthm dickson-map-thm
+ (implies (and (tuple-setp k S)
+ (consp S)
+ (natp k)
+ (<= 1 k)
+ (not (exists-partial-tuple-<=-set
+ k (rest S) (first S))))
+ (o< (tuple-set->ordinal k S)
+ (tuple-set->ordinal k (rest S))))
+ :hints (("Goal"
+ :use ((:instance |b <= a & a <= b => a = b|
+ (a (TUPLE-SET->ORDINAL K S))
+ (b (TUPLE-SET->ORDINAL K (CDR S))))
+ (:instance map-lemma-1 (A (rest S)) (B S))
+ (:instance map-lemma-4-alt
+ (A (rest S))
+ (B S)
+ (v (first S)))))))
+
+;(defun old-map (k S)
+; (ctoa (tuple-set->ordinal k S)))
+
+;(in-theory (disable tuple-set->ordinal))
+
+;(defthm dickson-map-thm-alt
+; (implies (and (tuple-setp k S)
+; (consp S)
+; (natp k)
+; (<= 1 k)
+; (not (exists-partial-tuple-<=-set
+; k (rest S) (first S))))
+; (e0-ord-< (old-map k S)
+; (old-map k (rest S)))))
+
diff --git a/books/workshops/2003/toma-borrione/sha-form-slides.pdf.gz b/books/workshops/2003/toma-borrione/sha-form-slides.pdf.gz
new file mode 100644
index 0000000..a026250
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/sha-form-slides.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/toma-borrione/sha-form-slides.ps.gz b/books/workshops/2003/toma-borrione/sha-form-slides.ps.gz
new file mode 100644
index 0000000..1af5fc3
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/sha-form-slides.ps.gz
Binary files differ
diff --git a/books/workshops/2003/toma-borrione/sha-form.pdf.gz b/books/workshops/2003/toma-borrione/sha-form.pdf.gz
new file mode 100644
index 0000000..79ab25a
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/sha-form.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/toma-borrione/sha-form.ps.gz b/books/workshops/2003/toma-borrione/sha-form.ps.gz
new file mode 100644
index 0000000..596a20e
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/sha-form.ps.gz
Binary files differ
diff --git a/books/workshops/2003/toma-borrione/support/bv-op-defthms.lisp b/books/workshops/2003/toma-borrione/support/bv-op-defthms.lisp
new file mode 100644
index 0000000..c2a58d6
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/bv-op-defthms.lisp
@@ -0,0 +1,717 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of bit-vectors as lists
+; Theorems of bit-vectors operations
+;------------------------------------------
+
+
+(in-package "ACL2")
+
+
+(include-book "bv-op-defuns")
+
+; theorems on bvp
+
+(defthm bvp-true-listp
+ (implies (bvp l) (true-listp l)))
+
+(defthm bvp-append
+ (implies (and (bvp l) (bvp l1))
+ (bvp (append l l1))))
+
+(defthm revappend-is-bvp
+ (implies (and (bvp i)(bvp j))
+ (bvp (revappend i j))))
+
+(defthm reverse-is-bvp
+ (implies (bvp i) (bvp (reverse i))))
+
+(defthm bvp-make-list-0
+ (bvp (make-list n :initial-element 0 )))
+
+(defthm bvp-make-list-ac-0
+ (bvp (make-list-ac n 0 nil )))
+
+(defthm bvp-make-list-ac-1
+ (bvp (make-list-ac n 1 nil )))
+
+(defthm bvp-firstn
+(implies (bvp l) (bvp (firstn n l))))
+
+(defthm bvp-nthcdr
+(implies (bvp l) (bvp (nthcdr n l))))
+
+; theorems on wvp
+
+(defthm wvp-append
+(implies (and (wvp m w) (wordp l w))
+ (wvp (append m (list l)) w))
+:hints (("goal" :induct (wvp m w) )))
+
+
+;(SET-MATCH-FREE-ERROR NIL)
+
+(defthm nth-wvp
+ (implies (and (integerp j) (<= 0 j) (wvp m i))
+ (bvp (nth j m )) ))
+
+(defthm len-nth-wvp
+ (implies (and (integerp j) (<= 0 j)
+ (wvp m i) (< j (len m) ))
+ (equal (len (nth j m )) i)))
+
+
+(defthm len-car-wvp
+ (implies (and (wvp m i) (not (endp m)))
+ (equal (len ( car m )) i)))
+
+;(SET-MATCH-FREE-ERROR t)
+
+(defthm wordp-nth
+ (implies (and (integerp j) (<= 0 j)
+ (< j (len m) ) (wvp m i))
+ (wordp (nth j m) i)))
+
+
+;theorems on bit-vector <-> integer conversions
+
+(defthm integerp-bv-int-little-endian
+ (implies (bvp v)
+ (and (integerp (bv-int-little-endian v))
+ (<= 0 (bv-int-little-endian v)))))
+
+
+(defthm integerp-bv-int-big-endian
+ (implies (bvp v)
+ (and (integerp (bv-int-big-endian v))
+ (<= 0 (bv-int-big-endian v)))))
+
+
+(defthm int-bv-little-endian-is-bvp
+ (implies (and (integerp i)(<= 0 i))
+ (bvp (int-bv-little-endian i))))
+
+
+(defthm len-bv-int-little-endian
+ (implies (and (bvp m))
+ (<= (bv-int-little-endian m)
+ (- (expt 2 (len m)) 1))))
+
+
+(local
+(defthm len-bv-int-little-endian-reverse
+ (implies (and (bvp m))
+ (<= (bv-int-little-endian (reverse m))
+ (- (expt 2 (len (reverse m))) 1)))
+ :hints (("Goal" :in-theory (disable len-reverse reverse )))))
+
+
+(defthm len-int-bv-little-endian-max
+ (implies (and (integerp i)(<= 0 i) )
+ (< i (expt 2 (len (int-bv-little-endian i))))))
+
+
+(defthm len-int-bv-little-endian-min
+ (implies (and (integerp i)(< 1 i) )
+ (<= (expt 2 ( - (len (int-bv-little-endian i)) 1)) i)))
+
+
+(defthm len-int-bv-little-endian-2y-1
+ (implies (and (integerp y)(< 0 y) )
+ (equal (len (int-bv-little-endian (- (expt 2 y) 1) )) y )))
+
+
+(local
+(defthm len-int-bv-little-endian-1-aux
+(IMPLIES (AND (INTEGERP l) (< 0 l))
+ (<= (LEN (INT-BV-little-endian l ))
+ (LEN (INT-BV-little-endian (+ 1 l)))))))
+
+(local
+(defthm len-int-bv-little-endian-1
+(IMPLIES (AND (INTEGERP l) (<= 0 l))
+ (<= (LEN (INT-BV-little-endian l ))
+ (LEN (INT-BV-little-endian (+ 1 l)))))
+:hints
+(( "goal"
+ :do-not-induct t
+ :use (len-int-bv-little-endian-1-aux)
+ :in-theory (disable int-bv-little-endian )))))
+
+
+
+(local
+(defthm len-int-bv-little-endian-k+1
+(IMPLIES (AND (INTEGERP K) (INTEGERP I)
+ (<= K I) (<= 1 K))
+ (<= (LEN (INT-BV-little-endian (+ I (- K))))
+ (LEN (INT-BV-little-endian (+ 1 I (- K))))))))
+
+
+(local
+(defthm interm
+(IMPLIES (AND (<= (LEN (INT-BV-little-endian (+ 1 I (- K))))
+ (LEN (INT-BV-little-endian I)))
+ (<= (LEN (INT-BV-little-endian (+ I (- K))))
+ (LEN (INT-BV-little-endian (+ 1 I (- K))))))
+ (<= (LEN (INT-BV-little-endian (+ I (- K))))
+ (LEN (INT-BV-little-endian I))))))
+
+
+(defthm len-int-bv-little-endian-k
+(IMPLIES (AND (INTEGERP I) (INTEGERP k)
+ (<= k I) (<= 0 k))
+ (<= (LEN (INT-BV-little-endian (- I k)))
+ (LEN (INT-BV-little-endian i))))
+:hints
+(("goal"
+ :do-not '(generalize)
+ :induct (rec-by-sub1 k)
+ :in-theory (disable int-bv-little-endian ))))
+
+
+(defthm len-int-bv-little-endian-i<=j
+ (implies (and (integerp i)(<= 0 i) (integerp j)(<= 0 j) (<= i j) )
+ (<= (len (int-bv-little-endian i))
+ (len (int-bv-little-endian j)) ))
+:hints
+(("goal"
+ :use (:instance len-int-bv-little-endian-k ( i j) (k (- j i)))
+ :in-theory (disable int-bv-little-endian ))))
+
+
+(defthm len-int-bv-little-endian-i<=2y-1
+ (implies (and (integerp i)(<= 0 i) (<= i (- (expt 2 y) 1))
+ (integerp y)(< 0 y) )
+ (<= (len (int-bv-little-endian i)) y ))
+:hints
+(("goal"
+ :use ((:instance len-int-bv-little-endian-i<=j (i i) (j (- (expt 2 y) 1)))
+ len-int-bv-little-endian-2y-1)
+ :do-not-induct t
+ :in-theory (disable int-bv-little-endian))))
+
+
+(defthm int-bv-big-endian-is-bvp
+ (implies (and (integerp i)(<= 0 i))
+ (bvp (int-bv-big-endian i))))
+
+
+(defthm len-bv-int-big-endian
+ (implies (bvp m)
+ (<= (bv-int-big-endian m) (- (expt 2 (len m)) 1)))
+:hints
+(("goal'"
+ :do-not-induct t
+ :use (len-bv-int-little-endian-reverse )
+ :in-theory (disable reverse ))))
+
+
+(defthm len-int-bv-big-endian-max
+ (implies (and (integerp i)(<= 0 i) )
+ (< i (expt 2 (len (int-bv-big-endian i))))))
+
+
+(defthm len-int-bv-big-endian-min
+ (implies (and (integerp i)(< 1 i) )
+ (<= (expt 2 (- (len (int-bv-big-endian i)) 1)) i)))
+
+
+(defthm len-int-bv-big-endian-2y-1
+ (implies (and (integerp y)(< 0 y) )
+ (equal (len (int-bv-big-endian (- (expt 2 y) 1) )) y )))
+
+
+(defthm len-int-bv-big-endian-i<=j
+ (implies (and (integerp i)(<= 0 i) (integerp j)(<= 0 j) (<= i j) )
+ (<= (len (int-bv-big-endian i)) (len (int-bv-big-endian j)) ))
+:hints
+(("goal"
+ :in-theory (disable int-bv-little-endian ))))
+
+
+(defthm len-int-bv-big-endian-i<=2y-1
+ (implies (and (integerp i)(<= 0 i) (<= i (- (expt 2 y) 1))
+ (integerp y)(< 0 y) )
+ (<= (len (int-bv-big-endian i)) y ))
+:hints
+(("goal"
+ :do-not-induct t
+ :in-theory (disable int-bv-little-endian ))))
+
+
+(defthm bv-int-int-bv-i=i-little-endian
+ (IMPLIES (AND (INTEGERP I) (<= 0 I))
+ (EQUAL (BV-INT-LITTLE-ENDIAN (INT-BV-LITTLE-ENDIAN I)) i)))
+
+
+(defthm bv-int-int-bv-i=i-big-endian
+ (IMPLIES (AND (INTEGERP I) (<= 0 I))
+ (EQUAL (BV-INT-big-ENDIAN (INT-BV-big-ENDIAN I)) i)))
+
+
+(local
+(defthm bv-int-app-little-endian-base
+(IMPLIES (AND (INTEGERP I) (<= 0 I))
+ (EQUAL (BV-INT-LITTLE-ENDIAN (APPEND (INT-BV-LITTLE-ENDIAN I)
+ (list 0)))
+ (BV-INT-LITTLE-ENDIAN (INT-BV-LITTLE-ENDIAN I))))))
+
+
+(local
+(defthm bv-int-app-little-endian
+(IMPLIES (bvp m)
+ (EQUAL (BV-INT-LITTLE-ENDIAN (APPEND m (list 0)))
+ (BV-INT-LITTLE-ENDIAN m )))))
+
+
+(local
+(defthm aux-append-m1-m2
+(IMPLIES (AND (TRUE-LISTP MLAC)
+ (TRUE-LISTP IBLEN))
+ (EQUAL (BV-INT-LITTLE-ENDIAN (APPEND IBLEN MLAC '(0)))
+ (BV-INT-LITTLE-ENDIAN (APPEND IBLEN MLAC))))))
+
+
+(local
+(defthm n+1-make-list
+(implies (and (INTEGERP N) (<= 1 N))
+ (equal (make-list n :initial-element k )
+ (append (make-list (- n 1) :initial-element k ) (list k))))))
+
+
+(local
+(defthm bv-int-app-int-bv-little-endian-simplif1
+(IMPLIES (AND (integerp i) (<= 0 i) (integerp n) (<= 0 n))
+ (EQUAL (BV-INT-LITTLE-ENDIAN (APPEND (INT-BV-LITTLE-ENDIAN i)
+ (MAKE-LIST n :initial-element 0)))
+ (BV-INT-LITTLE-ENDIAN (INT-BV-LITTLE-ENDIAN i))))
+:hints (( "goal" :induct (rec-by-sub1 n)))))
+
+
+(defthm bv-int-app-int-bv-little-endian
+ (IMPLIES (AND (integerp i) (<= 0 i) (integerp n) (<= 0 n))
+ (EQUAL (BV-INT-little-ENDIAN (APPEND (INT-BV-little-ENDIAN i)
+ (MAKE-LIST n :initial-element 0)))
+ i)))
+
+
+(defthm bv-int-app-int-bv-big-endian
+ (IMPLIES (AND (integerp i) (<= 0 i) (integerp n) (<= 0 n))
+ (EQUAL (BV-INT-BIG-ENDIAN (APPEND (MAKE-LIST n :initial-element 0)
+ (INT-BV-BIG-ENDIAN i)))
+ i)))
+
+;theorems on bv-to-n
+
+(defthm bvp-bv-to-n
+ (implies (and (bvp v) (integerp n) (<= 0 n))
+ (bvp (bv-to-n v n))))
+
+(defthm len-bv-to-n
+ (implies (and (bvp v) (integerp n) (<= 0 n))
+ (equal (len (bv-to-n v n)) n)))
+
+(defthm wordp-bv-to-n
+ (implies (and (bvp v) (integerp n) (<= 0 n))
+ (wordp (bv-to-n v n) n))
+:hints
+(("goal"
+ :use (bvp-bv-to-n len-bv-to-n) )))
+
+;theorems on bv-and
+
+(defthm comutativity-of-bv-a
+ (equal (bv-a x y) (bv-a y x)))
+
+
+(defthm bv-a-is-bvp
+ (bvp (bv-a x y)))
+
+
+(defthm len-bv-a
+ (implies (and (bvp x) (bvp y) (EQUAL (LEN X) (len y)))
+ (and (equal (len (bv-a x y)) (len x) )
+ (equal (len (bv-a x y)) (len y)))))
+
+
+(defthm wordp-bv-a
+ (implies (and (bvp x) (bvp y)(EQUAL (LEN X) (len y) ))
+ (and (wordp (bv-a x y) (len y))
+ (wordp (bv-a x y) (len x))))
+:hints (("goal" :use (len-bv-a bv-a-is-bvp))))
+
+
+(defthm wordp-binary-bv-and-word
+ (implies (and (wordp x w) (wordp y w)
+ (integerp w) (<= 0 w))
+ (wordp (binary-bv-and x y) w)))
+
+
+(defthm comutativity-of-bv-and
+ (equal (bv-and x y) (bv-and y x)))
+
+
+(defthm bv-and-is-bvp
+ (bvp (bv-and x y)))
+
+
+(defthm len-bv-and
+ (implies (and (bvp x) (bvp y))
+ (equal (len (bv-and x y))
+ (if (<= (len x) (len y))
+ (len y)
+ (len x))))
+:hints (("goal" :in-theory (disable N+1-MAKE-LIST))))
+
+
+(defthm wordp-bv-and
+ (implies (and (bvp x) (bvp y))
+ (wordp (bv-and x y) (if (<= (len x) (len y))
+ (len y)
+ (len x))))
+:hints (("goal" :use (len-bv-and bv-and-is-bvp))))
+
+
+;theorems on bv-or
+
+(defthm comutativity-of-bv-o
+ (equal (bv-o x y) (bv-o y x)))
+
+
+(defthm bv-o-is-bvp
+ (bvp (bv-o x y)))
+
+
+(defthm len-bv-o
+ (implies (and (bvp x) (bvp y) (EQUAL (LEN X) (len y)))
+ (and (equal (len (bv-o x y)) (len x) )
+ (equal (len (bv-o x y)) (len y)))))
+
+
+(defthm wordp-bv-o
+ (implies (and (bvp x) (bvp y)(EQUAL (LEN X) (len y) ))
+ (and (wordp (bv-o x y) (len y))
+ (wordp (bv-o x y) (len x))))
+:hints (("goal" :use (len-bv-o bv-o-is-bvp))))
+
+
+(defthm wordp-binary-bv-or-word
+ (implies (and (wordp x w) (wordp y w)
+ (integerp w) (<= 0 w))
+ (wordp (binary-bv-or x y) w)))
+
+
+(defthm comutativity-of-bv-or
+ (equal (bv-or x y) (bv-or y x)))
+
+
+(defthm bv-or-is-bvp
+ (bvp (bv-or x y)))
+
+
+(defthm len-bv-or
+ (implies (and (bvp x) (bvp y))
+ (equal (len (bv-or x y))
+ (if (<= (len x) (len y))
+ (len y)
+ (len x))))
+:hints (("goal" :in-theory (disable N+1-MAKE-LIST))))
+
+
+(defthm wordp-bv-or
+ (implies (and (bvp x) (bvp y))
+ (wordp (bv-or x y) (if (<= (len x) (len y))
+ (len y)
+ (len x))))
+:hints (("goal" :use (len-bv-or bv-or-is-bvp))))
+
+
+;theorems on bv-xor
+
+(defthm comutativity-of-bv-xo
+ (equal (bv-xo x y) (bv-xo y x)))
+
+
+(defthm bv-xo-is-bvp
+ (bvp (bv-xo x y)))
+
+
+(defthm len-bv-xo
+ (implies (and (bvp x) (bvp y) (EQUAL (LEN X) (len y)))
+ (and (equal (len (bv-xo x y)) (len x) )
+ (equal (len (bv-xo x y)) (len y)))))
+
+
+(defthm wordp-bv-xo
+ (implies (and (bvp x) (bvp y)(EQUAL (LEN X) (len y) ))
+ (and (wordp (bv-xo x y) (len y))
+ (wordp (bv-xo x y) (len x))))
+:hints (("goal" :use (len-bv-xo bv-xo-is-bvp))))
+
+
+(defthm wordp-binary-bv-xor-word
+ (implies (and (wordp x w) (wordp y w)
+ (integerp w) (<= 0 w))
+ (wordp (binary-bv-xor x y) w)))
+
+
+(defthm comutativity-of-bv-xor
+ (equal (bv-xor x y) (bv-xor y x)))
+
+
+(defthm bv-xor-is-bvp
+ (bvp (bv-xor x y)))
+
+
+(defthm len-bv-xor
+ (implies (and (bvp x) (bvp y))
+ (equal (len (bv-xor x y))
+ (if (<= (len x) (len y))
+ (len y)
+ (len x))))
+:hints (("goal" :in-theory (disable N+1-MAKE-LIST ))))
+
+
+(defthm wordp-bv-xor
+ (implies (and (bvp x) (bvp y))
+ (wordp (bv-xor x y) (if (<= (len x) (len y))
+ (len y)
+ (len x))))
+:hints (("goal" :use (len-bv-xor bv-xor-is-bvp))))
+
+
+;theorems on bv-not
+
+(defthm bv-not-is-bvp
+ (bvp (bv-not x)))
+
+
+(defthm len-bv-not
+ (implies (bvp x)
+ (equal (len (bv-not x)) (len x))))
+
+
+(defthm wordp-bv-not
+ (implies (bvp x)
+ (wordp (bv-not x) (len x))))
+
+
+;theorems on plus
+
+(local
+(defthm aux
+(implies (and (integerp i)(integerp j) (integerp z) (<= 0 i) (<= 0 j) (< 0 z))
+ (and (<= 0 (mod (+ i j) z)) (integerp (mod (+ i j) z))))))
+
+
+(local
+(defthm aux1
+(implies (and (bvp x) (<= 0 (bv-int-big-endian x))
+ (<= (bv-int-big-endian x) (expt 2 i))
+ (bvp y) (<= 0 (bv-int-big-endian y))
+ (<= (bv-int-big-endian y) (expt 2 i))
+ (integerp i) (<= 0 i))
+(BVP (INT-BV-BIG-ENDIAN (MOD (+ (BV-INT-BIG-ENDIAN X)
+ (BV-INT-BIG-ENDIAN Y))
+ (EXPT 2 I)))))
+:hints
+(("goal"
+ :in-theory (disable int-bv-big-endian bv-int-big-endian)
+ :use ((:instance integerp-BV-INT-BIG-ENDIAN (v x))
+ (:instance integerp-BV-INT-BIG-ENDIAN (v y))
+ (:instance int-bv-big-endian-is-bvp
+ (i (MOD (+ (BV-INT-BIG-ENDIAN X) (BV-INT-BIG-ENDIAN Y))
+ (EXPT 2 I))))) ))))
+
+
+(defthm bvp-binary-plus
+ (implies (and (bvp x) (<= 0 (bv-int-big-endian x))
+ (<= (bv-int-big-endian x) (expt 2 i))
+ (bvp y) (<= 0 (bv-int-big-endian y))
+ (<= (bv-int-big-endian y) (expt 2 i))
+ (integerp i) (<= 0 i))
+ (bvp (binary-plus i x y)))
+:hints (
+("goal"
+ :use (:instance bvp-bv-to-n
+ (v (INT-BV-BIG-ENDIAN (MOD (+ (BV-INT-BIG-ENDIAN X)
+ (BV-INT-BIG-ENDIAN Y)) (EXPT 2 I)))) (n i))
+ :in-theory (disable int-bv-big-endian bv-int-big-endian))))
+
+
+(defthm len-binary-plus
+ (implies (and (bvp x) (<= 0 (bv-int-big-endian x))
+ (<= (bv-int-big-endian x) (expt 2 i))
+ (bvp y) (<= 0 (bv-int-big-endian y))
+ (<= (bv-int-big-endian y) (expt 2 i))
+ (integerp i) (<= 0 i))
+ (equal (len (binary-plus i x y)) i))
+:hints
+(("goal"
+ :in-theory (disable int-bv-big-endian bv-int-big-endian))))
+
+
+(defthm wordp-binary-plus
+ (implies (and (bvp x) (<= 0 (bv-int-big-endian x))
+ (<= (bv-int-big-endian x) (expt 2 i))
+ (bvp y) (<= 0 (bv-int-big-endian y))
+ (<= (bv-int-big-endian y) (expt 2 i))
+ (integerp i) (<= 0 i))
+ (wordp (binary-plus i x y) i))
+:hints
+(("goal"
+ :in-theory (disable binary-plus int-bv-big-endian bv-int-big-endian))))
+
+
+(defthm wordp-binary-plus-word
+ (implies (and (wordp x w) (wordp y w)
+ (integerp w) (<= 0 w))
+ (wordp (binary-plus w x y) w))
+:hints
+(("goal"
+ :use ((:instance len-bv-int-big-endian (m x))
+ (:instance len-bv-int-big-endian (m y)))
+ :in-theory (disable binary-plus ))))
+
+
+;theorems on shift functions
+
+(defthm bvp-<<
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (bvp (<< x n w))))
+
+
+(defthm len-<<
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (equal (len (<< x n w)) w )))
+
+
+(defthm wordp-<<
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (wordp (<< x n w) w))
+:hints (("goal" :use (bvp-<< len-<<))))
+
+
+(defthm bvp->>
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (bvp (>> x n w) )))
+
+
+(defthm len->>
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (equal (len (>> x n w)) w )))
+
+
+(defthm wordp->>
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (wordp (>> x n w) w))
+:hints (("goal" :use (bvp->> len->>))))
+
+(defthm wordp-shr
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (wordp (shr n x w) w))
+:hints (("goal" :in-theory (disable >> wordp))))
+
+(defthm bvp-rotr
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (bvp (rotr n x w) ))
+:hints (("goal"
+:in-theory (disable >> << binary-bv-or )
+)))
+
+(defthm len-rotr
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (equal (len (rotr n x w) ) w))
+:hints (("goal"
+:in-theory (disable >> << binary-bv-or len wordp )
+)))
+
+(defthm wordp-rotr
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (wordp (rotr n x w) w))
+:hints (("goal"
+:in-theory (disable rotr len )
+)))
+
+(defthm bvp-rotl
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (bvp (rotl n x w) ))
+:hints (("goal"
+:in-theory (disable >> << binary-bv-or )
+)))
+
+(defthm len-rotl
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (equal (len (rotl n x w) ) w))
+:hints (("goal"
+:in-theory (disable >> << binary-bv-or len wordp )
+)))
+
+(defthm wordp-rotl
+ (implies (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w)) (wordp (rotl n x w) w))
+:hints (("goal"
+:in-theory (disable rotl len )
+)))
+
+
+(defthm rotl->rotr
+ (implies (and (wordp x w)
+ (integerp n)
+ (< 0 n)(integerp w)
+ (<= 0 w)
+ (<= n w))
+ (equal (rotl n x w) (rotr (- w n) x w)))
+)
+
+
+(defthm rotr->rotl
+ (implies (and (wordp x w)
+ (integerp n)
+ (<= 0 n)(integerp w)
+ (<= 0 w)
+ (<= n w))
+ (equal (rotr n x w) (rotl (- w n) x w))))
diff --git a/books/workshops/2003/toma-borrione/support/bv-op-defuns.lisp b/books/workshops/2003/toma-borrione/support/bv-op-defuns.lisp
new file mode 100644
index 0000000..68a00ad
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/bv-op-defuns.lisp
@@ -0,0 +1,335 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of bit-vectors as lists
+; Definitions of bit-vectors operations
+;------------------------------------------
+
+
+(in-package "ACL2")
+
+
+(include-book "misc")
+
+; Added by Matt K. in v2-9 to eliminate stack overflows in GCL in, at least,
+; the proofs of last64-padding-1-256=length and last128-padding-512=length.
+(set-verify-guards-eagerness 2)
+
+;----def bit
+
+; The definition of bitp here was deleted April 2016 by Matt K. now that
+; bitp is defined in ACL2.
+
+
+;--- bit operations
+
+; or
+(defun b-or (x y)
+ (if (and (bitp x) (bitp y))
+ (if (or (equal x 1) (equal y 1))
+ 1
+ 0)
+ nil))
+
+; and
+(defun b-and (x y)
+ (if (and (bitp x) (bitp y))
+ (if (and (equal x 1) (equal y 1))
+ 1
+ 0)
+ nil))
+
+;not
+(defun b-not (x)
+ (if (bitp x)
+ (if (equal x 0)
+ 1
+ 0)
+ nil))
+
+;xor
+(defun b-xor (x y)
+ (if (and (bitp x) (bitp y))
+ (if (or (and (equal x 1) (equal y 1))
+ (and (equal x 0) (equal y 0)))
+ 0
+ 1)
+ nil))
+
+;----- def of a bit-vector
+
+(defun bvp (m)
+ (if (true-listp m)
+ (if (endp m)
+ t
+ (and (bitp (car m))
+ (bvp (cdr m))))
+ nil))
+
+;------ word of len i
+
+(defun wordp (w i)
+ (and (bvp w) (integerp i) (<= 0 i)
+ (equal (len w) i)))
+
+
+;------ vector of words each one with len i
+
+(defun wvp (m i)
+ (if (and (true-listp m) (integerp i) (<= 0 i))
+ (if (endp m)
+ t
+ (and (wordp (car m) i) (wvp (cdr m) i)))
+ nil))
+
+
+
+
+
+; transforms a bit-vector into the positive integer corresponding at the little-endian interpretation
+; we treat only the unsigned case
+
+(defun bv-int-little-endian (v)
+ (if (bvp v)
+ (if (endp v)
+ 0
+ (+ (car v) (* 2 ( bv-int-little-endian (cdr v)))))
+ nil))
+
+; Added by Matt K. to balance the earlier call of set-verify-guards-eagerness,
+; since guard verification fails for the function bv-int-big-endian just
+; below.
+(set-verify-guards-eagerness 1)
+
+; transforms v into the positive integer corresponding at the big-endian interpretation
+
+(defun bv-int-big-endian (v)
+ (bv-int-little-endian ( reverse v)))
+
+; transforms a positive integer into the bit-vector corresponding to the little-endian interpretation
+; we treat only the unsigned case
+
+(defun int-bv-little-endian(i)
+ (if (and (integerp i)
+ (<= 0 i))
+ (if (equal (floor i 2) 0)
+ (list (mod i 2))
+ (cons (mod i 2) (int-bv-little-endian (floor i 2))))
+ nil))
+
+
+; transforms i into the bit-vector corresponding at the big-endian interpretation of i
+
+(defun int-bv-big-endian (i)
+ (reverse (int-bv-little-endian i)))
+
+; transforms a bit-vector v into a bit-vector of len n, if n is bigger then v's length. if not, returns the last n bits of v (v is considered in big-endian representation)
+
+(defun bv-to-n (v n)
+ (if (and (bvp v)
+ (integerp n)
+ (<= 0 n))
+ (if (>= n (len v))
+ (append (make-list (- n (len v)) :initial-element 0) v)
+ (nthcdr (- (len v) n) v))
+ nil))
+
+
+;and between two bit-vectors with the same length
+
+(defun bv-a (x y)
+ (if (and (bvp x) (bvp y)
+ (equal (len x) (len y)))
+ (if (endp x) nil
+ (cons (b-and (car x) (car y))
+ (bv-a (cdr x) (cdr y))))
+ nil))
+
+
+
+;and between two bit-vectors with arbitrary length
+
+(defun binary-bv-and (x y)
+ (if (and (bvp x) (bvp y))
+ (if (<= (len x) (len y))
+ (bv-a (bv-to-n x (len y)) y)
+ (bv-a x (bv-to-n y (len x))))
+ nil))
+
+
+(defun bv-and-macro (lst)
+ (if (consp lst)
+ (if (consp (cdr lst))
+ (list 'binary-bv-and (car lst)
+ (bv-and-macro (cdr lst)))
+ (car lst))
+ nil))
+
+(defmacro bv-and (&rest args)
+ (bv-and-macro args))
+
+
+
+;or between two bit-vectors with the same length
+
+(defun bv-o (x y)
+ (if (and (bvp x) (bvp y)
+ (equal (len x) (len y)))
+ (if (endp x) nil
+ (cons (b-or (car x) (car y))
+ (bv-o (cdr x) (cdr y))))
+ nil))
+
+;or between two bit-vectors with arbitrary length
+
+(defun binary-bv-or (x y)
+ (if (and (bvp x) (bvp y))
+ (if (<= (len x) (len y))
+ (bv-o (bv-to-n x (len y)) y)
+ (bv-o x (bv-to-n y (len x))))
+ nil))
+
+(defun bv-or-macro (lst)
+ (if (consp lst)
+ (if (consp (cdr lst))
+ (list 'binary-bv-or (car lst)
+ (bv-or-macro (cdr lst)))
+ (car lst))
+ nil))
+
+(defmacro bv-or (&rest args)
+ (bv-or-macro args))
+
+
+
+;xor between two bit-vectors with the same length
+
+(defun bv-xo (x y)
+ (if (and (bvp x) (bvp y)
+ (equal (len x) (len y)))
+ (if (endp x) nil
+ (cons (b-xor (car x) (car y))
+ (bv-xo (cdr x) (cdr y))))
+ nil))
+
+
+
+;xor between two bit-vectors with arbitrary length
+
+(defun binary-bv-xor (x y)
+ (if (and (bvp x) (bvp y))
+ (if (<= (len x) (len y))
+ (bv-xo (bv-to-n x (len y)) y)
+ (bv-xo x (bv-to-n y (len x))))
+ nil))
+
+(defun bv-xor-macro (lst)
+ (if (consp lst)
+ (if (consp (cdr lst))
+ (list 'binary-bv-xor (car lst)
+ (bv-xor-macro (cdr lst)))
+ (car lst))
+ nil))
+
+(defmacro bv-xor (&rest args)
+ (bv-xor-macro args))
+
+
+; not of a bit-vector x
+
+(defun bv-not (x)
+ (if (bvp x)
+ (if (endp x)
+ nil
+ (cons (b-not (car x)) (bv-not (cdr x))))
+ nil))
+
+
+
+; addition modulo (2 pow i) of two bit-vectors x and y
+
+(defun binary-plus (i x y )
+ (if (and (bvp x) (<= 0 (bv-int-big-endian x))
+ (<= (bv-int-big-endian x) (expt 2 i))
+ (bvp y) (<= 0 (bv-int-big-endian y))
+ (<= (bv-int-big-endian y) (expt 2 i))
+ (integerp i) (<= 0 i))
+ (bv-to-n (int-bv-big-endian (mod (+ (bv-int-big-endian x)
+ (bv-int-big-endian y)) (expt 2 i))) i)
+ nil))
+
+
+(defun plus-macro (i lst )
+ (if (and (consp lst) (integerp i) (<= 0 i))
+ (if (consp (cdr lst))
+ (list 'binary-plus i (car lst)
+ (plus-macro i (cdr lst) ))
+ (car lst))
+ nil))
+
+(defmacro plus (i &rest args )
+ (plus-macro i args ))
+
+;auxiliary shift operations
+
+(defun << (x n w)
+ (if (and (wordp x w )
+ (integerp n)
+ (<= 0 n) (integerp w)
+ (<= 0 w)
+ (<= n w))
+ (cond ((zp n) x)
+ ((endp x ) nil)
+ (t (append (nthcdr n x) (make-list n :initial-element 0) )))
+ nil))
+
+;ACL2 !>(<< '(1 1 1 1) 2 4)
+;(1 1 0 0)
+
+
+(defun >> ( x n w)
+ (if (and (wordp x w)
+ (integerp n)
+ (<= 0 n)(integerp w)
+ (<= 0 w)
+ (<= n w))
+ (cond ((zp n) x)
+ ((endp x ) nil)
+ (t (append (make-list n :initial-element 0) (firstn (- (len x) n) x) ) ))
+ nil))
+
+;ACL2 !>(>> '(1 1 1 1) 2 4)
+;(0 0 1 1)
+
+;right shift of x with n elements on w bits
+
+(defun shr (n x w)
+ (if (and (wordp x w)
+ (integerp n)
+ (<= 0 n)(integerp w)
+ (<= 0 w)
+ (<= n w))
+ (>> x n w) nil))
+
+
+;rotate right (circular right shift) of x with n elements on w bits
+
+(defun rotr (n x w)
+ (if (and (wordp x w)
+ (integerp n)
+ (<= 0 n)(integerp w)
+ (<= 0 w)
+ (<= n w))
+ (bv-or (>> x n w) (<< x (- w n) w)) nil))
+
+;rotate left (circular left shift) of x with n elements on w bits
+
+(defun rotl (n x w)
+ (if (and (wordp x w)
+ (integerp n)
+ (<= 0 n)(integerp w)
+ (<= 0 w)
+ (<= n w))
+ (bv-or (<< x n w) (>> x (- w n) w)) nil))
diff --git a/books/workshops/2003/toma-borrione/support/misc.lisp b/books/workshops/2003/toma-borrione/support/misc.lisp
new file mode 100644
index 0000000..a73a52e
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/misc.lisp
@@ -0,0 +1,142 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHAs
+; Some definitions on lists needed for the modelization of SHA
+;------------------------------------------
+
+
+(in-package "ACL2")
+
+(include-book "../../../../arithmetic/equalities")
+(include-book "../../../../arithmetic/inequalities")
+(include-book "../../../../arithmetic-2/floor-mod/floor-mod")
+(include-book "../../../../data-structures/list-defuns")
+(include-book "../../../../data-structures/list-defthms")
+
+; help for recursion in theorem demonstration
+(defun rec-by-sub1 (k)
+(if (and (integerp k) (<= 1 k)) (rec-by-sub1 (- k 1)) t))
+
+(defun rec-by-subn (n l)
+ (if (and (integerp n) (< 0 n) (true-listp l) (not (endp l)))
+ (rec-by-subn n (nthcdr n l)) t))
+
+;gives the list of elements of l from the i-th position to the j-th possition
+(defun segment (i j l)
+ (if (and (integerp i)
+ (<= 0 i)(integerp j)
+ (<= 0 j)
+ (true-listp l))
+ (firstn (- j i) (nthcdr i l))
+ nil))
+
+;ACL2 !>(segment 2 5 '( 0 1 2 3 4 5 6 7 8 9))
+;(2 3 4)
+
+;replace the nth element of l with x
+
+(defun repl ( n x l)
+ (if (and (integerp n)
+ (<= 0 n)
+ (true-listp l))
+ (cond ((endp l) nil)
+ ((zp n) (cons x (cdr l) ))
+ (t (cons (car l) (repl (- n 1) x (cdr l) ))))
+
+ nil))
+
+;ACL2 !>(repl 2 10 '( 0 1 2 3 4 5 6 7 8 9))
+;(0 1 10 3 4 5 6 7 8 9)
+
+
+;verifies if all elements of l are the same length
+
+(defun el-of-eq-len (l)
+ (if (true-listp l)
+ (if (or (endp l) (endp (cdr l))) t
+ (and (equal (len (car l)) (len (cadr l)))
+ (el-of-eq-len (cdr l))))
+ nil))
+
+;ACL2 !>( el-of-eq-len '((1 2) 0 ))
+;NIL
+;ACL2 !>( el-of-eq-len '((1 2) (0 3) ))
+;T
+
+; theorems for make-list
+
+(DEFTHM BINARY-APPEND-make-list-ac
+ (implies (consp b)
+ (EQUAL (BINARY-APPEND (make-list-ac i k B) C)
+ (make-list-ac i k (BINARY-APPEND B C)))))
+(defthm append-make-list
+(IMPLIES (AND (INTEGERP I) (<= 0 I))
+ (EQUAL
+ (make-list-ac I k (LIST K))
+ (APPEND (make-list-ac I k NIL) (LIST K)))))
+
+(defthm inverse-make-list
+(implies (and (INTEGERP N) (<= 0 N))
+ (equal (cons k (make-list n :initial-element k ))
+ (append (make-list n :initial-element k ) (list k)))))
+
+(local
+(defthm n+1-make-list
+(implies (and (INTEGERP N) (<= 1 N))
+ (equal (make-list n :initial-element k )
+ (append (make-list (- n 1) :initial-element k ) (list k))))))
+
+(defthm append-make-list-i-j
+(IMPLIES (AND (INTEGERP i) (<= 0 i)(INTEGERP j) (<= 0 j))
+ (EQUAL (APPEND (MAKE-LIST i :initial-element k)
+ (make-list j :initial-element k))
+ (make-list (+ i j) :initial-element k ))))
+
+(defthm revappend-make-list
+(implies (and (integerp n) (<= 0 n))
+ (equal (REVAPPEND (MAKE-LIST n :initial-element k) nil)
+ (make-list n :initial-element k )))
+:hints (( "goal" :induct (rec-by-sub1 n))
+("Subgoal *1/1'" :use (:instance append-make-list-i-j (i (1- n)) (j 1)))))
+
+(defthm len-app-make
+(IMPLIES
+ (AND (true-listP X)
+ (true-listP Y)
+ (<= (LEN Y) (LEN X)))
+ (equal (len (APPEND (MAKE-LIST-AC (+ (LEN X) (- (LEN Y))) 0 NIL) Y))
+ (len x) )))
+
+
+;theorems for segment
+(defthm segment-append
+ (implies (and (integerp k) (<= 0 k)(integerp j) (<= 0 j) (<= k j)
+ (true-listp l1) (true-listp l2) (<= (len l1) k) )
+ (equal (segment k j (append l1 l2))
+ (segment (- k (len l1)) (- j (len l1)) l2))))
+
+(defthm segment-cons
+ (implies (and (integerp j) (<= 0 j) (true-listp l2))
+ (equal (segment 1 j (cons l1 l2)) (segment 0 (- j 1) l2))))
+
+
+(defthm segment-0
+ (implies (and (integerp j) (<= 0 j) (true-listp l))
+ (equal (segment 0 j l) (firstn j l))))
+
+;modified SIMPLIFY-MOD-+-MOD from floor-mod book
+ (DEFTHM SIMPLIFY-MOD-+-MOD1
+ (IMPLIES (AND
+ (INTEGERP (/ Y Z))
+ (FM-GUARD (W X) (Y Z)))
+ (AND (EQUAL (MOD (+ W (MOD X Y)) Z)
+ (MOD (+ W X) Z))
+ (EQUAL (MOD (+ (MOD X Y) W) Z)
+ (MOD (+ W X) Z))
+ (EQUAL (MOD (+ W (- (MOD X Y))) Z)
+ (MOD (+ W (- X)) Z))
+ (EQUAL (MOD (+ (MOD X Y) (- W)) Z)
+ (MOD (+ X (- W)) Z)))))
diff --git a/books/workshops/2003/toma-borrione/support/padding-1-256.lisp b/books/workshops/2003/toma-borrione/support/padding-1-256.lisp
new file mode 100644
index 0000000..39a069d
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/padding-1-256.lisp
@@ -0,0 +1,239 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHAs
+; Padding function for SHA-1 and SHA-256
+;------------------------------------------
+
+;I strongly recommend after charging the book to do :comp t in order to accelerate the computation
+
+(IN-PACKAGE "ACL2")
+
+(include-book "bv-op-defthms")
+
+;---padding
+;for sha-1 and sha-256
+
+;Let M be a message of length len bits. The purpose of padding is to extend M to a multiple of 512 bits. To obtain the padded message, append the bit 1 to the end of message M, followed by k zero bits, where k is the smallest, non-negative solution to the equation (len+1+k) mod 512 = 448. Then append the 64-bit binary representation of number len.
+
+;For example, the (8-bit ASCII) message ``abc'' has the length 8*3=24, so the message is padded with one bit, then 448-(24+1)=423 zero bits, and then the message length, to become the 512-bit padded message:
+
+;ACL2 !>(padding-1-256 ' (0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 ))
+;(0 1 1 0 0 0 0 1 0 1 1 0
+; 0 0 1 0 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0)
+
+(defun padding-1-256 (m)
+ (if (and (bvp m)
+ (< (len m) (expt 2 64)))
+ (if (<= (mod (1+ (len m)) 512) 448)
+ (append m (list 1)
+ (make-list (- 448 (mod (1+ (len m)) 512)):initial-element 0 )
+ (bv-to-n (int-bv-big-endian (len m)) 64))
+ (append m (list 1)
+ (make-list (- 960 (mod (1+ (len m)) 512)):initial-element 0 )
+ (bv-to-n (int-bv-big-endian (len m)) 64)))
+ nil))
+
+
+(defthm bvp-padding-1-256
+ (bvp (padding-1-256 m)))
+
+
+(local
+(defthm 2n<i
+ (implies (and (integerp n) (< 0 n) (integerp i)
+ (< n i) (integerp (* i (/ n))) )
+ (<= 2 (* i (/ n) )))))
+
+(local
+(defthm n<=i
+ (implies (and (integerp n) (< 0 n) (integerp i)
+ (equal (mod i n) 0) (< 0 i) )
+ (<= n i) )))
+
+
+(defthm len-padding-1-256
+ (implies (and (bvp m)
+ (< (len m) (expt 2 64)))
+ (<= 512 (len (padding-1-256 m))))
+:hints
+(("Goal"
+ :in-theory (disable mod MOD-ZERO ASSOCIATIVITY-OF-+ ))
+("subgoal 2"
+ :use (:instance simplify-mod-+-mod1 (w (+ 1025 (len m)))
+ (x (+ 1 (len m))) (y 512) (z 512) ))
+("subgoal 1"
+ :use (:instance simplify-mod-+-mod1 (w (+ 513 (len m)))
+ (x (+ 1 (len m))) (y 512) (z 512) ))))
+
+
+
+(defthm len-padding-1-256-mod-512=0
+ (implies (bvp m)
+ (equal (mod (len (padding-1-256 m)) 512) 0))
+:hints
+(("Goal"
+ :in-theory (disable MOD-ZERO int-bv-big-endian ))
+("subgoal 2"
+ :use (:instance simplify-mod-+-mod1 (w (+ 1025 (len m)))
+ (x (+ 1 (len m))) (y 512) (z 512) ))
+("subgoal 1"
+ :use (:instance simplify-mod-+-mod1 (w (+ 513 (len m)))
+ (x (+ 1 (len m))) (y 512) (z 512) ))))
+
+
+
+(local
+(defthm last-256-aux
+ (implies (and (BVP M)
+ (< (LEN M) 18446744073709551616)
+ (< 448 (MOD (+ 1 (LEN M)) 512))
+ (<= (nfix (+ 1 (LEN M) 960 (- (MOD (+ 1 (LEN M)) 512)))) (LEN M)))
+ (<= 961 (MOD (+ 1 (LEN M)) 512)))))
+
+
+
+(defthm last64-padding-1-256=length
+ (implies (and (bvp m) (< (len m) (expt 2 64)))
+ (equal (bv-int-big-endian
+ (nthcdr (- (len (padding-1-256 m)) 64)
+ (padding-1-256 m)))
+ (len m)))
+:hints
+(("Goal"
+ :in-theory (disable bv-int-big-endian int-bv-big-endian ))
+("subgoal 2.2" :use last-256-aux)))
+
+
+
+(defthm end-message-padding-1-256
+ (implies (and (bvp m) (< (len m) (expt 2 64)))
+ (equal (nth (len m) (padding-1-256 m)) 1))
+:hints
+(("Goal"
+ :in-theory (disable bv-int-big-endian int-bv-big-endian ))))
+
+
+
+(defthm first-padding-1-256=message
+ (implies (and (bvp m) (< (len m) (expt 2 64)))
+ (equal (firstn ( len m) (padding-1-256 m)) m))
+:hints
+(("Goal"
+ :in-theory (disable bv-int-big-endian int-bv-big-endian nthcdr ))))
+
+
+
+(defthm 0-fill-padding-1-256
+ (implies (and (bvp m) (< (len m) (expt 2 64)))
+ (equal (segment (1+ (len m))
+ (- (len (padding-1-256 m)) 64)
+ (padding-1-256 m))
+ (make-list (- (len (padding-1-256 m)) (+ 65 (len m)))
+ :initial-element 0))))
+
+
+; For message "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", with length 448
+
+;ACL2 !>(padding-1-256 '(0 1 1 0 0 0 0 1
+; 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0
+; 0 1 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1
+; 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 0
+; 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1
+; 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0
+; 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1
+; 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0
+; 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0 0 1 1 0
+; 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0
+; 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0
+; 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0 0 1 1 0
+; 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0
+; 0 1 1 0 1 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0
+; 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 0 0
+; 0 1 1 0 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0
+; 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1
+; 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0
+; 1 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1
+; 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0
+; 1 1 0 1 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1
+; 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0
+; 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 1))
+;Padding has 1024 bits
+; (0 1 1 0
+; 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1
+; 0 1 1 0 0 1 0 0 0 1 1 0 0 0 1 0 0 1 1 0
+; 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1
+; 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0
+; 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0
+; 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0
+; 0 1 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0
+; 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0
+; 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0
+; 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0
+; 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0
+; 0 1 1 0 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0
+; 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 0 0 1
+; 0 1 1 0 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0
+; 1 1 0 0 0 1 1 0 1 0 1 0 0 1 1 0 1 0 1 1
+; 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0
+; 1 0 1 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1
+; 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0
+; 1 1 0 1 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1
+; 0 1 1 0 1 1 0 1 0 1 1 0 1 1 1 0 0 1 1 0
+; 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0
+; 0 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1
+; 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0) \ No newline at end of file
diff --git a/books/workshops/2003/toma-borrione/support/padding-384-512.lisp b/books/workshops/2003/toma-borrione/support/padding-384-512.lisp
new file mode 100644
index 0000000..a1e0d0c
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/padding-384-512.lisp
@@ -0,0 +1,189 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHAs
+; Padding function for SHA-384 and SHA-512
+;------------------------------------------
+
+;I strongly recommend after charging the book to do :comp t in order to accelerate the computation
+
+(IN-PACKAGE "ACL2")
+
+(include-book "bv-op-defthms")
+
+;---padding
+;for sha-512 and sha-384
+;Let M be a message of length len bits. The purpose of padding is to extend M to a multiple of 1024 bits. To obtain the padded message, append the bit 1 to the end of message M, followed by k zero bits, where k is the smallest, non-negative solution to the equation (len+1+k) mod 1024 = 896. Then append the 128-bit binary representation of number len.
+
+;For example, the (8-bit ASCII) message ``abc'' has the length 8*3=24, so the message is padded with one bit, then 896-(24+1)=871 zero bits, and then the message length, to become the 1024-bit padded message:
+
+;ACL2 !>(padding-512 ' (0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 ))
+;(0 1 1 0
+; 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1
+; 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0)
+
+(local
+(defthm 2n<i
+ (implies (and (integerp n) (< 0 n) (integerp i)
+ (< n i) (integerp (* i (/ n))) )
+ (<= 2 (* i (/ n) )))))
+
+(local
+(defthm n<=i
+ (implies (and (integerp n) (< 0 n) (integerp i)
+ (equal (mod i n) 0) (< 0 i) )
+ (<= n i) )))
+
+
+
+(defun padding-512 (m)
+ (if (and (bvp m)
+ (< (len m) (expt 2 128)))
+ (if (<= (mod (1+ (len m)) 1024) 896)
+ (append m (list 1)
+ (make-list (- 896 (mod (1+ (len m)) 1024))
+ :initial-element 0)
+ (bv-to-n (int-bv-big-endian (len m)) 128))
+ (append m (list 1)
+ (make-list (- 1920 (mod (1+ (len m)) 1024))
+ :initial-element 0 )
+ (bv-to-n (int-bv-big-endian (len m)) 128)))
+ nil))
+
+
+(defthm bvp-padding-512
+ (bvp (padding-512 m)))
+
+
+(defthm len-padding-512
+ (implies (and (bvp m)
+ (< (len m) (expt 2 128)))
+ (<= 1024 (len (padding-512 m))))
+:hints
+(("Goal"
+ :in-theory (disable mod MOD-ZERO ASSOCIATIVITY-OF-+ ))
+("subgoal 2"
+ :use (:instance simplify-mod-+-mod1 (w (+ 1921 (len m)))
+ (x (+ 1 (len m))) (y 1024) (z 1024) ))
+("subgoal 1"
+ :use (:instance simplify-mod-+-mod1 (w (+ 897 (len m)))
+ (x (+ 1 (len m))) (y 1024) (z 1024) ))))
+
+
+
+(defthm len-padding-512-mod-1024=0
+ (implies (bvp m)
+ (equal (mod (len (padding-512 m)) 1024) 0))
+:hints
+(("Goal"
+ :in-theory (disable MOD-ZERO int-bv-big-endian ))
+("subgoal 2"
+ :use (:instance simplify-mod-+-mod1 (w (+ 2049 (len m)))
+ (x (+ 1 (len m))) (y 1024) (z 1024) ))
+("subgoal 1"
+ :use (:instance simplify-mod-+-mod1 (w (+ 1025 (len m)))
+ (x (+ 1 (len m))) (y 1024) (z 1024) ))))
+
+
+(local
+(defthm last-512-aux
+ (implies (and (BVP M)
+ (< (LEN M) 340282366920938463463374607431768211456)
+ (< 896 (MOD (+ 1 (LEN M)) 1024))
+ (<= (NFIX (+ 1 (LEN M)
+ 1920 (- (MOD (+ 1 (LEN M)) 1024))))
+ (LEN M)))
+ (<= 1921 (MOD (+ 1 (LEN M)) 1024) ))))
+
+
+
+(defthm last128-padding-512=length
+ (implies (and (bvp m) (< (len m) (expt 2 128)))
+ (equal (bv-int-big-endian
+ (nthcdr (- (len (padding-512 m)) 128)
+ (padding-512 m)))
+ (len m)))
+:hints
+(("Goal"
+ :in-theory (disable bv-int-big-endian int-bv-big-endian ))
+("subgoal 2.2" :use last-512-aux)))
+
+
+
+(defthm end-message-padding-512
+ (implies (and (bvp m) (< (len m) (expt 2 128)))
+ (equal (nth (len m) (padding-512 m)) 1))
+:hints
+(("Goal"
+ :in-theory (disable bv-int-big-endian int-bv-big-endian ))))
+
+
+
+(defthm first-padding-512=message
+ (implies (and (bvp m) (< (len m) (expt 2 128)))
+ (equal (firstn ( len m) (padding-512 m)) m))
+:hints
+(("Goal"
+ :in-theory (disable bv-int-big-endian int-bv-big-endian nthcdr ))))
+
+
+
+(defthm 0-fill-padding-512
+ (implies (and (bvp m) (< (len m) (expt 2 128)))
+ (equal (segment (1+ (len m))
+ (- (len (padding-512 m)) 128)
+ (padding-512 m))
+ (make-list (- (len (padding-512 m)) (+ 129 (len m)))
+ :initial-element 0))))
+
diff --git a/books/workshops/2003/toma-borrione/support/parsing.lisp b/books/workshops/2003/toma-borrione/support/parsing.lisp
new file mode 100644
index 0000000..c6a14e6
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/parsing.lisp
@@ -0,0 +1,164 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHAs
+; General parsing and its application to SHAs
+;------------------------------------------
+
+
+
+(IN-PACKAGE "ACL2")
+
+(include-book "padding-1-256")
+(include-book "padding-384-512")
+
+;---parsing
+
+; parses the message m into blocks of n elements
+
+
+(local
+(defthm 2n<i
+ (implies (and (integerp n) (< 0 n) (integerp i)
+ (< n i) (integerp (* i (/ n))) )
+ (<= 2 (* i (/ n) )))))
+
+
+(local
+(defthm n<=i
+ (implies (and (integerp n) (< 0 n) (integerp i)
+ (equal (mod i n) 0) (< 0 i) )
+ (<= n i) )))
+
+
+(defun parsing (m n)
+ (if (and (integerp n)
+ (<= 0 n)
+ (true-listp m))
+ (cond ((endp m) nil)
+ ((zp n) nil)
+ (t (cons (firstn n m) (parsing (nthcdr n m) n))))
+ nil))
+
+;ACL2 !>(parsing '(0 1 2 3 4 5 6 7) 3)
+;((0 1 2) (3 4 5) (6 7))
+
+
+(defthm true-listp-car-parsing
+ (implies (and (true-listp l) (integerp n) (<= 0 n))
+ (true-listp (car (parsing l n)) )))
+
+
+
+(defthm bvp-car-parsing
+ (implies (and (bvp l) (integerp n) (<= 0 n))
+ (bvp (car (parsing l n)) )))
+
+
+(local
+(defthm len-consp-nthcdr
+ (implies (and (integerp n) (< 0 n) (true-listp l)(consp (nthcdr n l)))
+ (< n (len l)))))
+
+
+(defthm car-parsing
+ (implies (and (true-listp l) (integerp n) (<= 0 n))
+ (equal (car (parsing l n)) (firstn n l))))
+
+
+(defthm parsing-right-len
+ (implies (and (true-listp l) (integerp n) (< 0 n)
+ (equal (mod (len l) n) 0))
+ (el-of-eq-len (parsing l n)))
+:hints
+(("goal"
+ :do-not '(generalize)
+ :induct (rec-by-subn n l ))
+("subgoal *1/1.4''"
+ :use (len-consp-nthcdr (:instance 2n<i (n n) (i (len l)))))))
+
+
+(defthm len-car-parsing
+ (implies (and (true-listp l) (integerp n) (< 0 n)
+ (<= n (len l)))
+ (equal (len (car (parsing l n))) n)))
+
+
+(defthm wordp-car-parsing
+ (implies (and (bvp l) (integerp n) (< 0 n) (<= n (len l) ))
+ (wordp (car (parsing l n) ) n)))
+
+
+(defthm wvp-parsing
+ (implies (and (bvp m) (equal (mod (len m) n) 0) (integerp n) (< 0 n))
+ (wvp (parsing m n) n))
+:hints (("subgoal *1/5" :use (:instance n<=i (i (len m) )))))
+
+
+(defthm len-parsing
+ (implies (and (true-listp m) (equal (mod (len m) n) 0)
+ (integerp n) (< 0 n))
+ (equal (len (parsing m n)) (/ (len m) n)))
+:hints (("subgoal *1/5" :use (:instance n<=i (i (len m) )))))
+
+
+(defthm parsing-512-is-good
+(implies (and (bvp m)
+ (< (len m) (expt 2 64)))
+ (and (el-of-eq-len (parsing (padding-1-256 m) 512))
+ (equal (len (car (parsing (padding-1-256 m) 512))) 512)))
+:hints
+(("goal"
+ :use ((:instance parsing-right-len (l (padding-1-256 m)) (n 512) )
+ len-padding-1-256-mod-512=0)
+ :in-theory (disable el-of-eq-len parsing padding-1-256 ))
+("subgoal 1" :use len-padding-1-256 )))
+
+
+(defthm wvp-parsing-512
+ (implies (and (bvp m)
+ (< (len m) (expt 2 64)))
+ (wvp (parsing (padding-1-256 m) 512) 512))
+:hints
+(("goal"
+ :use ( len-padding-1-256-mod-512=0)
+ :in-theory (disable mod parsing padding-1-256 ))))
+
+
+(defthm len-parsing-512
+ (implies (and (bvp m)
+ (< (len m) (expt 2 64)))
+ (<= 1 (len (parsing (padding-1-256 m) 512))))
+:hints
+(("goal"
+ :use ( len-padding-1-256-mod-512=0
+ (:instance len-parsing (m (padding-1-256 m)) (n 512))
+ len-padding-1-256 )
+ :in-theory (disable parsing padding-1-256 len ))))
+
+
+
+(defthm parsing-1024-is-good
+(implies (and (bvp m)
+ (< (len m) (expt 2 128)))
+ (and (el-of-eq-len (parsing (padding-512 m) 1024))
+ (equal (len (car (parsing (padding-512 m) 1024))) 1024 )))
+:hints
+(("goal"
+ :use ((:instance parsing-right-len (l (padding-512 m)) (n 1024) )
+ len-padding-512-mod-1024=0)
+ :in-theory (disable el-of-eq-len parsing padding-512 ))
+("subgoal 1" :use len-padding-512 )))
+
+
+(defthm wvp-parsing-1024
+ (implies (and (bvp m)
+ (< (len m) (expt 2 128)))
+ (wvp (parsing (padding-512 m) 1024) 1024))
+:hints
+(("goal"
+ :use ( len-padding-512-mod-1024=0)
+ :in-theory (disable mod parsing padding-512 ))))
+
diff --git a/books/workshops/2003/toma-borrione/support/sha-1.lisp b/books/workshops/2003/toma-borrione/support/sha-1.lisp
new file mode 100644
index 0000000..0960246
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/sha-1.lisp
@@ -0,0 +1,430 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHA-1
+; Message digest functions and theorems
+;------------------------------------------
+
+;I strongly recommend after charging the book to do :comp t in order to accelerate the computation
+
+; For a message M with length less than (expt 2 64) sha-1 returns a message digest of 160 bits (five words each of 32 bits).
+
+;For message "abc"
+;ACL2 !>(sha-1 '(0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 ))
+
+;((1 0 1 0 1 0 0 1 1 0 0 1
+; 1 0 0 1 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 0)
+; (0 1 0 0 0 1 1 1 0 0 0 0
+; 0 1 1 0 1 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0)
+; (1 0 1 1 1 0 1 0 0 0 1 1
+; 1 1 1 0 0 0 1 0 0 1 0 1 0 1 1 1 0 0 0 1)
+; (0 1 1 1 1 0 0 0 0 1 0 1
+; 0 0 0 0 1 1 0 0 0 0 1 0 0 1 1 0 1 1 0 0)
+; (1 0 0 1 1 1 0 0 1 1 0 1 0
+; 0 0 0 1 1 0 1 1 0 0 0 1 0 0 1 1 1 0 1))
+;For the message "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" (448 bits)
+;ACL2 !>(sha-1 '(0 1 1 0 0 0 0 1
+; 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0
+; 0 1 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1
+; 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 0
+; 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1
+; 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0
+; 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1
+; 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0
+; 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0 0 1 1 0
+; 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0
+; 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0
+; 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0 0 1 1 0
+; 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0
+; 0 1 1 0 1 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0
+; 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 0 0
+; 0 1 1 0 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0
+; 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1
+; 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0
+; 1 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1
+; 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0
+; 1 1 0 1 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1
+; 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0
+; 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 1))
+
+; The result:
+
+;((1 0 0 0 0 1 0 0 1 0 0 1
+; 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 0 0 1 0 0)
+; (0 0 0 1 1 1 0 0 0 0 1 1
+; 1 0 1 1 1 1 0 1 0 0 1 0 0 1 1 0 1 1 1 0)
+; (1 0 1 1 1 0 1 0 1 0 1 0
+; 1 1 1 0 0 1 0 0 1 0 1 0 1 0 1 0 0 0 0 1)
+; (1 1 1 1 1 0 0 1 0 1 0 1
+; 0 0 0 1 0 0 1 0 1 0 0 1 1 1 1 0 0 1 0 1)
+; (1 1 1 0 0 1 0 1 0 1 0 0 0
+; 1 1 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1))
+
+(IN-PACKAGE "ACL2")
+
+(include-book "parsing")
+(include-book "sha-functions")
+
+
+; constants of sha-1
+
+
+(defun K-1 (i)
+ (if (and (integerp i) (<= 0 i))
+ (cond ((and (<= 0 i) (<= i 19))
+ '(0 1 0 1 1 0 1 0 1 0 0 0
+ 0 0 1 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0 1))
+ ((and (<= 20 i) (<= i 39))
+ '(0 1 1 0 1 1 1 0 1 1 0 1
+ 1 0 0 1 1 1 1 0 1 0 1 1 1 0 1 0 0 0 0 1))
+ ((and (<= 40 i) (<= i 59))
+ '(1 0 0 0 1 1 1 1 0 0 0 1
+ 1 0 1 1 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 0))
+ ((and (<= 60 i) (<= i 79))
+ '(1 1 0 0 1 0 1 0 0 1 1 0
+ 0 0 1 0 1 1 0 0 0 0 0 1 1 1 0 1 0 1 1 0)))
+ nil))
+
+
+(defthm wordp-K-1
+(implies (and (integerp i) (<= 0 i) (<= i 79))
+ (wordp (k-1 i) 32)))
+
+
+; initial hash values for sha-1
+
+(defun H-1 ()
+ '((0 1 1 0 0 1 1 1 0 1 0 0
+ 0 1 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1)
+ (1 1 1 0 1 1 1 1 1 1 0 0
+ 1 1 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 0 0 1)
+ (1 0 0 1 1 0 0 0 1 0 1 1
+ 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0)
+ (0 0 0 1 0 0 0 0 0 0 1 1
+ 0 0 1 0 0 1 0 1 0 1 0 0 0 1 1 1 0 1 1 0)
+ (1 1 0 0 0 0 1 1 1 1 0 1
+ 0 0 1 0 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0)))
+
+(defthm wordp-h-1
+ (and (wvp (h-1) 32) (equal (len (h-1)) 5 )))
+
+
+;constant of sha-1
+
+(defun mask ()
+ '(0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1))
+
+(defthm wordp-mask
+ (wordp (mask ) 32))
+
+
+;---sha-1
+
+;--- first method
+
+
+(defun temp (j working-variables m-i-ext)
+ (if (and (wvp working-variables 32) (equal (len working-variables) 5)
+ (integerp j) (<= 0 j)
+ (wvp m-i-ext 32) (equal (len m-i-ext) 80))
+ (plus 32 (rotl 5 (nth 0 working-variables) 32)
+ (Ft j (nth 1 working-variables)
+ (nth 2 working-variables)
+ (nth 3 working-variables))
+ (nth 4 working-variables)
+ ( K-1 j)
+ (nth j m-i-ext))
+ nil))
+
+
+(defthm wordp-temp
+ (implies (and (wvp l 32) (equal (len l) 5)
+ (integerp j) (<= 0 j) (< j 80)
+ (wvp m 32) (equal (len m) 80))
+ (wordp (temp j l m ) 32))
+:hints
+(("goal"
+ :in-theory (disable k-1 ft rotl binary-plus rotl->rotr nth ))))
+
+
+;prepare the schedule message
+
+(defun prepare-ac ( j m-i)
+(declare (xargs :measure (acl2-count (- 80 j))))
+ (if (and (integerp j) (<= 16 j)
+ (wvp m-i 32))
+ (cond ((<= 80 j) m-i)
+ ((<= j 79)
+ (prepare-ac (1+ j)
+ (append m-i
+ (list (rotl 1 (bv-xor (nth (- j 3) m-i)
+ (nth (- j 8) m-i)
+ (nth (- j 14) m-i)
+ (nth (- j 16) m-i)) 32))))))
+ nil))
+
+(defun prepare (m-i)
+ (if (wordp m-i 512)
+ (prepare-ac 16 (parsing m-i 32))
+ nil))
+
+(defthm wvp-prepare-ac
+ (implies (and (integerp j) (<= 16 j) (wvp m 32))
+ (wvp (prepare-ac j m) 32))
+:hints
+(("goal"
+ :in-theory (disable rotl binary-bv-xor rotl->rotr))))
+
+
+(defthm len-prepare-ac
+ (implies (and (wvp m 32) (integerp j) (<= 16 j) (<= j (len m) ))
+ (equal (len (prepare-ac j m))
+ (if (<= j 80)
+ (+ (- 80 j) (len m))
+ (len m))))
+:hints
+(("goal"
+ :in-theory (disable rotl binary-bv-xor rotl->rotr))))
+
+
+(defthm wvp-prepare
+ (implies (wordp m 512)
+ (wvp (prepare m) 32))
+:hints (("goal" :in-theory (disable prepare-ac ))))
+
+
+(defthm len-prepare
+ (implies (wordp m 512)
+ (equal (len (prepare m)) 80))
+:hints (("goal" :in-theory (disable prepare-ac))))
+
+
+; one step of digest
+(defun digest-one-block-ac ( j working-variables m-i-ext)
+(declare (xargs :measure (acl2-count (- 80 j))))
+ (if (and (wvp working-variables 32) (equal (len working-variables ) 5)
+ (integerp j) (<= 0 j)
+ (wvp m-i-ext 32) (equal (len m-i-ext) 80))
+ (if (<= 80 j)
+ working-variables
+ (digest-one-block-ac (+ 1 j)
+ (list (temp j working-variables m-i-ext)
+ (nth 0 working-variables)
+ (rotl 30 (nth 1 working-variables) 32)
+ (nth 2 working-variables)
+ (nth 3 working-variables))
+ m-i-ext) )
+ nil))
+
+
+(defun digest-one-block (hash-values m-i-ext)
+ (if (and (wvp hash-values 32) (equal (len hash-values) 5)
+ (wvp m-i-ext 32) (equal (len m-i-ext) 80))
+ (digest-one-block-ac 0 hash-values m-i-ext)
+ nil))
+
+
+(defthm wvp-digest-one-block-ac
+ (implies (and (wvp l 32) (equal (len l) 5)
+ (integerp j) (<= 0 j)
+ (wvp m 32) (equal (len m) 80))
+ (wvp (digest-one-block-ac j l m ) 32))
+:hints
+(("goal"
+ :in-theory (disable temp nth rotl rotl->rotr))))
+
+
+(defthm len-digest-one-block-ac
+ (implies (and (wvp l 32) (equal (len l) 5)
+ (integerp j) (<= 0 j)
+ (wvp m 32) (equal (len m) 80))
+ (equal (len (digest-one-block-ac j l m )) 5))
+:hints
+(("goal"
+ :in-theory (disable temp nth rotl rotl->rotr ))))
+
+
+(defthm wvp-digest-one-block
+ (implies (and (wvp l 32) (equal (len l) 5)
+ (wvp m 32) (equal (len m) 80))
+ (wvp (digest-one-block l m ) 32))
+:hints
+(("goal"
+ :in-theory (disable digest-one-block-ac))))
+
+
+(defthm len-digest-one-block
+ (implies (and (wvp l 32) (equal (len l) 5)
+ (wvp m 32) (equal (len m) 80))
+ (equal (len (digest-one-block l m )) 5))
+:hints
+(("goal"
+ :in-theory (disable digest-one-block-ac ))))
+
+
+;intermediate hash
+(defun intermediate-hash ( l1 l2)
+ (if (and (wvp l1 32) (equal (len l1) 5)
+ (wvp l2 32) (equal (len l2) 5) )
+ (list (plus 32 (nth 0 l1) (nth 0 l2) )
+ (plus 32 (nth 1 l1) (nth 1 l2) )
+ (plus 32 (nth 2 l1) (nth 2 l2) )
+ (plus 32 (nth 3 l1) (nth 3 l2) )
+ (plus 32 (nth 4 l1) (nth 4 l2) ))
+ nil))
+
+
+(defthm wvp-intermediate-hash
+ (implies (and (wvp l1 32) (equal (len l1) 5)
+ (wvp l2 32) (equal (len l2) 5) )
+ (wvp (intermediate-hash l1 l2 ) 32))
+:hints
+(("goal"
+ :in-theory (disable binary-plus wordp nth ))))
+
+
+(defthm len-intermediate-hash
+ (implies (and (wvp l1 32) (equal (len l1) 5)
+ (wvp l2 32) (equal (len l2) 5) )
+ (equal (len (intermediate-hash l1 l2 )) 5)))
+
+
+(defun digest ( m hash-values)
+ (if (and (wvp m 512) (wvp hash-values 32) (equal (len hash-values) 5))
+ (if (endp m) hash-values
+ (digest (cdr m)
+ (intermediate-hash hash-values
+ (digest-one-block hash-values (prepare (car m))))))
+ nil) )
+
+
+(defthm wvp-digest
+ (implies (and (wvp m 512) (wvp hash-values 32)
+ (equal (len hash-values) 5))
+ (wvp (digest m hash-values ) 32) )
+:hints
+(("goal"
+ :in-theory (disable intermediate-hash digest-one-block prepare parsing ))))
+
+
+(defthm len-digest
+ (implies (and (wvp m 512) (wvp hash-values 32) (not (endp m))
+ (equal (len hash-values) 5))
+ (equal (len (digest m hash-values )) 5) )
+:hints
+(("goal"
+ :in-theory (disable intermediate-hash digest-one-block prepare ))))
+
+
+(defun sha-1 ( m)
+ (if (and (bvp m) (< (len m) (expt 2 64)))
+ (digest (parsing (padding-1-256 m) 512) (h-1))
+ nil))
+
+
+(defthm wvp-sha-1
+(implies (and (bvp m) (< (len m) (expt 2 64)))
+ (wvp (sha-1 m) 32) )
+:hints(("goal" :in-theory (disable digest parsing padding-1-256))))
+
+
+(defthm len-sha-1
+(implies (and (bvp m) (< (len m) (expt 2 64)))
+ (equal (len (sha-1 m)) 5 ))
+:hints(("goal"
+:use (:instance len-digest (m (parsing (padding-1-256 m) 512)) (hash-values (h-1)))
+:in-theory (disable digest parsing padding-1-256 ))))
+
+
+; --- second method of sha-1 (no preparing of the message)
+
+(defun s (j)
+ (if (and (integerp j) (<= 0 j))
+ (bv-int-big-endian (bv-and (int-bv-big-endian j) (mask)))
+ nil ))
+
+
+;(defthm integerp-s
+; (implies (and (integerp j) (<= 0 j))
+; (integerp (s j)))
+;:hints (("goal" :in-theory (disable bv-int-big-endian int-bv-big-endian mask ))
+;))
+
+(defun temp-1 (j working-variables m-i)
+ (if (and (wvp working-variables 32) (equal (len working-variables) 5)
+ (integerp j) (<= 0 j)
+ (wvp m-i 32) (equal (len m-i) 16))
+ (plus 32 (rotl 5 (nth 0 working-variables) 32)
+ (Ft j (nth 1 working-variables)
+ (nth 2 working-variables)
+ (nth 3 working-variables))
+ (nth 4 working-variables)
+ (nth (s j) m-i)
+ (K-1 j) )
+ nil))
+
+;(defthm wordp-temp-1
+; (implies (and (wvp l 32) (equal (len l) 5)
+; (integerp j) (<= 0 j) (< j 80)
+; (wvp m 32) (equal (len m) 16))
+; (wordp (temp-1 j l m ) 32))
+;:hints (("goal" :in-theory (disable k-1 ft rotl binary-plus rotl->rotr nth ))
+;))
+
+(defun wo (j m-i )
+ (if (and (integerp j) (<= 0 j)
+ (wvp m-i 32))
+ (rotl 1 (bv-xor
+ (nth (bv-int-big-endian (bv-and (int-bv-big-endian (+ 13 (s j)))
+ (mask))) m-i)
+ (nth (bv-int-big-endian (bv-and (int-bv-big-endian (+ 8 (s j)))
+ (mask))) m-i)
+ (nth (bv-int-big-endian (bv-and (int-bv-big-endian (+ 2 (s j)))
+ (mask))) m-i)
+ (nth (bv-int-big-endian (bv-and (int-bv-big-endian j)
+ (mask))) m-i)) 32)
+ nil))
+
+
+(defun digest-one-block-1 ( j working-variables m-i )
+(declare (xargs :measure (acl2-count (- 80 j))))
+ (if (and (wvp working-variables 32) (equal (len working-variables) 5)
+ (integerp j) (<= 0 j)
+ (wvp m-i 32) (equal (len m-i) 16))
+ (if (<= 80 j)
+ working-variables
+ (if (>= j 16)
+ (digest-one-block-1 (+ 1 j)
+ (list (temp-1 j working-variables (repl (s j)
+ (wo j m-i) m-i))
+ (nth 0 working-variables)
+ (rotl 30 ( nth 1 working-variables) 32)
+ (nth 2 working-variables)
+ (nth 3 working-variables))
+ (repl (s j) (wo j m-i) m-i) )
+ (digest-one-block-1 (+ 1 j)
+ (list (temp-1 j working-variables m-i )
+ (nth 0 working-variables)
+ (rotl 30 (nth 1 working-variables) 32)
+ (nth 2 working-variables)
+ (nth 3 working-variables))
+ m-i ) ))
+ nil))
+
+
+(defun digest-1 ( m hash-values)
+ (if (and (wvp m 512) (wvp hash-values 32) (equal (len hash-values) 5) )
+ (if (endp m) hash-values
+ (digest-1 (cdr m)
+ (intermediate-hash hash-values
+ (digest-one-block-1 0 hash-values (parsing (car m) 32)))))
+ nil) )
+
+
+(defun sha-1-2 ( m)
+ (if (and (bvp m) (< (len m) (expt 2 64)))
+ (digest-1 (parsing (padding-1-256 m) 512) (h-1))
+ nil))
diff --git a/books/workshops/2003/toma-borrione/support/sha-256.lisp b/books/workshops/2003/toma-borrione/support/sha-256.lisp
new file mode 100644
index 0000000..afbf187
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/sha-256.lisp
@@ -0,0 +1,533 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHA-256
+; Message digest functions and theorems
+;------------------------------------------
+
+(IN-PACKAGE "ACL2")
+
+(include-book "parsing")
+(include-book "sha-functions")
+
+;I strongly recommend after charging the book to do :comp t in order to accelerate the computation
+
+; For a message M with length less than (expt 2 64) sha-1 returns a message digest of 256 bits (eight words each of 32 bits).
+
+;For message "abc"
+;ACL2 !>(sha-256 '(0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 ))
+;((1 0 1 1 1 0 1 0 0 1 1 1
+; 1 0 0 0 0 0 0 1 0 1 1 0 1 0 1 1 1 1 1 1)
+; (1 0 0 0 1 1 1 1 0 0 0 0
+; 0 0 0 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 0)
+; (0 1 0 0 0 0 0 1 0 1 0 0
+; 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 1 1 1 1 0)
+; (0 1 0 1 1 1 0 1 1 0 1 0
+; 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1)
+; (1 0 1 1 0 0 0 0 0 0 0 0
+; 0 0 1 1 0 1 1 0 0 0 0 1 1 0 1 0 0 0 1 1)
+; (1 0 0 1 0 1 1 0 0 0 0 1
+; 0 1 1 1 0 1 1 1 1 0 1 0 1 0 0 1 1 1 0 0)
+; (1 0 1 1 0 1 0 0 0 0 0 1
+; 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 1)
+; (1 1 1 1 0 0 1 0 0 0 0 0 0
+; 0 0 0 0 0 0 1 0 1 0 1 1 0 1 0 1 1 0 1))
+
+;For the message "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" (448 bits)
+;ACL2 !>(sha-256 '(0 1 1 0 0 0 0 1
+; 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0
+; 0 1 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1
+; 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 0
+; 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1
+; 0 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0
+; 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1
+; 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 0
+; 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0 0 1 1 0
+; 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1 1 0
+; 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0
+; 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0 0 1 1 0
+; 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0
+; 0 1 1 0 1 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0
+; 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1 1 0 0
+; 0 1 1 0 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0
+; 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1
+; 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0
+; 1 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1
+; 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0
+; 1 1 0 1 0 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1
+; 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0
+; 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 1))
+
+; The result:
+
+;((0 0 1 0 0 1 0 0 1 0 0 0
+; 1 1 0 1 0 1 1 0 1 0 1 0 0 1 1 0 0 0 0 1)
+; (1 1 0 1 0 0 1 0 0 0 0 0
+; 0 1 1 0 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0)
+; (1 1 1 0 0 1 0 1 1 1 0 0
+; 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 1)
+; (0 0 0 0 1 1 0 0 0 0 1 1
+; 1 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 0 0 1)
+; (1 0 1 0 0 0 1 1 0 0 1 1
+; 1 1 0 0 1 1 1 0 0 1 0 0 0 1 0 1 1 0 0 1)
+; (0 1 1 0 0 1 0 0 1 1 1 1
+; 1 1 1 1 0 0 1 0 0 0 0 1 0 1 1 0 0 1 1 1)
+; (1 1 1 1 0 1 1 0 1 1 1 0
+; 1 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 0 1 0 0)
+; (0 0 0 1 1 0 0 1 1 1 0 1 1
+; 0 1 1 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1))
+
+; constants of sha-256
+(defun K-256 (i)
+ (cond ((equal i 0)
+ '(0 1 0 0 0 0 1 0 1 0 0 0
+ 1 0 1 0 0 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0))
+ ((equal i 1)
+ '(0 1 1 1 0 0 0 1 0 0 1 1
+ 0 1 1 1 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1))
+ ((equal i 2) '(1 0 1 1 0 1 0 1 1 1 0 0
+ 0 0 0 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1))
+ ((equal i 3) '(1 1 1 0 1 0 0 1 1 0 1 1
+ 0 1 0 1 1 1 0 1 1 0 1 1 1 0 1 0 0 1 0 1))
+ ((equal i 4) '(0 0 1 1 1 0 0 1 0 1 0 1
+ 0 1 1 0 1 1 0 0 0 0 1 0 0 1 0 1 1 0 1 1))
+ ((equal i 5) '(0 1 0 1 1 0 0 1 1 1 1 1
+ 0 0 0 1 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 1))
+ ((equal i 6) '(1 0 0 1 0 0 1 0 0 0 1 1
+ 1 1 1 1 1 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0))
+ ((equal i 7) '(1 0 1 0 1 0 1 1 0 0 0 1
+ 1 1 0 0 0 1 0 1 1 1 1 0 1 1 0 1 0 1 0 1))
+ ((equal i 8) '(1 1 0 1
+ 1 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 0 1 0
+ 1 0 0 1 1 0 0 0))
+ ((equal i 9) '(0 0 0 1
+ 0 0 1 0 1 0 0 0 0 0 1 1 0 1 0 1 1 0 1 1
+ 0 0 0 0 0 0 0 1))
+ ((equal i 10) '(0 0 1 0
+ 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1
+ 1 0 1 1 1 1 1 0))
+ ((equal i 11) '(0 1 0 1
+ 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 1 1 1 0 1
+ 1 1 0 0 0 0 1 1))
+ ((equal i 12) '(0 1 1 1
+ 0 0 1 0 1 0 1 1 1 1 1 0 0 1 0 1 1 1 0 1
+ 0 1 1 1 0 1 0 0))
+ ((equal i 13) '(1 0 0 0
+ 0 0 0 0 1 1 0 1 1 1 1 0 1 0 1 1 0 0 0 1
+ 1 1 1 1 1 1 1 0))
+ ((equal i 14) '(1 0 0 1
+ 1 0 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 1 1 0
+ 1 0 1 0 0 1 1 1))
+ ((equal i 15) '(1 1 0 0
+ 0 0 0 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 1
+ 0 1 1 1 0 1 0 0))
+ ((equal i 16) '(1 1 1 0
+ 0 1 0 0 1 0 0 1 1 0 1 1 0 1 1 0 1 0 0 1
+ 1 1 0 0 0 0 0 1))
+ ((equal i 17) '(1 1 1 0
+ 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 0 0 1 1 1
+ 1 0 0 0 0 1 1 0))
+ ((equal i 18) '(0 0 0 0
+ 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 1 0 1
+ 1 1 0 0 0 1 1 0))
+ ((equal i 19) '(0 0 1 0
+ 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 1
+ 1 1 0 0 1 1 0 0))
+ ((equal i 20) '(0 0 1 0
+ 1 1 0 1 1 1 1 0 1 0 0 1 0 0 1 0 1 1 0 0
+ 0 1 1 0 1 1 1 1))
+ ((equal i 21) '(0 1 0 0
+ 1 0 1 0 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0
+ 1 0 1 0 1 0 1 0))
+ ((equal i 22) '(0 1 0 1
+ 1 1 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 1
+ 1 1 0 1 1 1 0 0))
+ ((equal i 23) '(0 1 1 1
+ 0 1 1 0 1 1 1 1 1 0 0 1 1 0 0 0 1 0 0 0
+ 1 1 0 1 1 0 1 0))
+ ((equal i 24) '(1 0 0 1
+ 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 0 0 1
+ 0 1 0 1 0 0 1 0))
+ ((equal i 25) '(1 0 1 0
+ 1 0 0 0 0 0 1 1 0 0 0 1 1 1 0 0 0 1 1 0
+ 0 1 1 0 1 1 0 1))
+ ((equal i 26) '(1 0 1 1
+ 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1
+ 1 1 0 0 1 0 0 0))
+ ((equal i 27) '(1 0 1 1
+ 1 1 1 1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 1 1
+ 1 1 0 0 0 1 1 1))
+ ((equal i 28) '(1 1 0 0
+ 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 1
+ 1 1 1 1 0 0 1 1 ))
+ ((equal i 29) '(1 1 0 1
+ 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 1 0 0 0 1
+ 0 1 0 0 0 1 1 1 ))
+ ((equal i 30) '(0 0 0 0
+ 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 1
+ 0 1 0 1 0 0 0 1 ))
+ ((equal i 31) '(0 0 0 1
+ 0 1 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1
+ 0 1 1 0 0 1 1 1))
+ ((equal i 32) '(0 0 1 0
+ 0 1 1 1 1 0 1 1 0 1 1 1 0 0 0 0 1 0 1 0
+ 1 0 0 0 0 1 0 1))
+ ((equal i 33) '(0 0 1 0
+ 1 1 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1
+ 0 0 1 1 1 0 0 0 ))
+ ((equal i 34) '(0 1 0 0
+ 1 1 0 1 0 0 1 0 1 1 0 0 0 1 1 0 1 1 0 1
+ 1 1 1 1 1 1 0 0))
+ ((equal i 35) '(0 1 0 1
+ 0 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 1 1 0 1
+ 0 0 0 1 0 0 1 1 ))
+ ((equal i 36) '(0 1 1 0 0 1 0 1 0 0 0 0
+ 1 0 1 0 0 1 1 1 0 0 1 1 0 1 0 1 0 1 0 0))
+ ((equal i 37) '(0 1 1 1
+ 0 1 1 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0
+ 1 0 1 1 1 0 1 1))
+ ((equal i 38) '(1 0 0 0
+ 0 0 0 1 1 1 0 0 0 0 1 0 1 1 0 0 1 0 0 1
+ 0 0 1 0 1 1 1 0))
+ ((equal i 39) '(1 0 0 1
+ 0 0 1 0 0 1 1 1 0 0 1 0 0 0 1 0 1 1 0 0
+ 1 0 0 0 0 1 0 1))
+ ((equal i 40) '(1 0 1 0
+ 0 0 1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0 0
+ 1 0 1 0 0 0 0 1 ))
+ ((equal i 41) '(1 0 1 0
+ 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1 1 0
+ 0 1 0 0 1 0 1 1))
+ ((equal i 42) '(1 1 0 0
+ 0 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 0 1 1
+ 0 1 1 1 0 0 0 0 ))
+ ((equal i 43) '(1 1 0 0
+ 0 1 1 1 0 1 1 0 1 1 0 0 0 1 0 1 0 0 0 1
+ 1 0 1 0 0 0 1 1))
+ ((equal i 44) '(1 1 0 1
+ 0 0 0 1 1 0 0 1 0 0 1 0 1 1 1 0 1 0 0 0
+ 0 0 0 1 1 0 0 1 ))
+ ((equal i 45) '(1 1 0 1
+ 0 1 1 0 1 0 0 1 1 0 0 1 0 0 0 0 0 1 1 0
+ 0 0 1 0 0 1 0 0 ))
+ ((equal i 46) '(1 1 1 1
+ 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 1 0 1 0 1
+ 1 0 0 0 0 1 0 1 ))
+ ((equal i 47) '(0 0 0 1
+ 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 0 0 0 0 0
+ 0 1 1 1 0 0 0 0))
+ ((equal i 48) '(0 0 0 1
+ 1 0 0 1 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 1
+ 0 0 0 1 0 1 1 0 ))
+ ((equal i 49) '(0 0 0 1
+ 1 1 1 0 0 0 1 1 0 1 1 1 0 1 1 0 1 1 0 0
+ 0 0 0 0 1 0 0 0))
+ ((equal i 50) '(0 0 1 0
+ 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1
+ 0 1 0 0 1 1 0 0 ))
+ ((equal i 51) '(0 0 1 1
+ 0 1 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 1 0 0
+ 1 0 1 1 0 1 0 1 ))
+ ((equal i 52) '(0 0 1 1
+ 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0
+ 1 0 1 1 0 0 1 1 ))
+ ((equal i 53) '(0 1 0 0
+ 1 1 1 0 1 1 0 1 1 0 0 0 1 0 1 0 1 0 1 0
+ 0 1 0 0 1 0 1 0 ))
+ ((equal i 54) '(0 1 0 1
+ 1 0 1 1 1 0 0 1 1 1 0 0 1 1 0 0 1 0 1 0
+ 0 1 0 0 1 1 1 1 ))
+ ((equal i 55) '(0 1 1 0
+ 1 0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 1 1 1 1
+ 1 1 1 1 0 0 1 1 ))
+ ((equal i 56) '(0 1 1 1
+ 0 1 0 0 1 0 0 0 1 1 1 1 1 0 0 0 0 0 1 0
+ 1 1 1 0 1 1 1 0))
+ ((equal i 57) '(0 1 1 1
+ 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 0 1 1
+ 0 1 1 0 1 1 1 1 ))
+ ((equal i 58) '(1 0 0 0
+ 0 1 0 0 1 1 0 0 1 0 0 0 0 1 1 1 1 0 0 0
+ 0 0 0 1 0 1 0 0 ))
+ ((equal i 59) '(1 0 0 0
+ 1 1 0 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 1 0
+ 0 0 0 0 1 0 0 0 ))
+ ((equal i 60) '(1 0 0 1
+ 0 0 0 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 0 1 0 ))
+ ((equal i 61) '(1 0 1 0
+ 0 1 0 0 0 1 0 1 0 0 0 0 0 1 1 0 1 1 0 0
+ 1 1 1 0 1 0 1 1 ))
+ ((equal i 62) '(1 0 1 1
+ 1 1 1 0 1 1 1 1 1 0 0 1 1 0 1 0 0 0 1 1
+ 1 1 1 1 0 1 1 1 ))
+ ((equal i 63) '(1 1 0 0
+ 0 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 0 0 0
+ 1 1 1 1 0 0 1 0))
+ (t nil)))
+
+(defthm wordp-K-256
+(implies (and (integerp i) (<= 0 i) (<= i 63))
+ (wordp (k-256 i) 32)))
+
+
+; initial hash values for sha-256
+(defun h-256 ()
+'((0 1 1 0 1 0 1 0 0 0 0 0
+ 1 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1)
+(1 0 1 1 1 0 1 1 0 1 1 0
+ 0 1 1 1 1 0 1 0 1 1 1 0 1 0 0 0 0 1 0 1)
+(0 0 1 1 1 1 0 0 0 1 1 0
+ 1 1 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 0 1 0)
+(1 0 1 0 0 1 0 1 0 1 0 0
+ 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 1 1 0 1 0)
+(0 1 0 1 0 0 0 1 0 0 0 0
+ 1 1 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1 1 1)
+(1 0 0 1 1 0 1 1 0 0 0 0
+ 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 0 1 1 0 0)
+(0 0 0 1 1 1 1 1 1 0 0 0
+ 0 0 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 0 1 1)
+(0 1 0 1 1 0 1 1 1 1 1 0
+ 0 0 0 0 1 1 0 0 1 1 0 1 0 0 0 1 1 0 0 1))
+)
+
+(defthm wordp-h-256
+ (and (wvp (h-256) 32) (equal (len (h-256)) 8 )))
+
+
+;-----sha-256
+
+(defun prepare-256-ac ( j m-i)
+(declare (xargs :measure (acl2-count (- 64 j))))
+ (if (and (wvp m-i 32) (integerp j) (<= 16 j))
+ (cond ((<= 64 j) m-i)
+ ((<= j 63)
+ (prepare-256-ac (1+ j) (append m-i
+ (list (plus 32 (s-1-256 (nth (- j 2) m-i))
+ (nth (- j 7) m-i)
+ (s-0-256 (nth (- j 15) m-i))
+ (nth (- j 16) m-i) ))))))
+ nil))
+
+
+(defun prepare-256 (m-i)
+ (if (wordp m-i 512)
+ (prepare-256-ac 16 (parsing m-i 32))
+ nil))
+
+
+(defthm wvp-prepare-256-ac
+ (implies (and (integerp j) (<= 16 j) (wvp m 32))
+ (wvp (prepare-256-ac j m) 32))
+:hints
+(("goal"
+ :in-theory (disable s-1-256 s-0-256 nth binary-plus ))))
+
+
+(defthm len-prepare-256-ac
+ (implies (and (wvp m 32) (integerp j) (<= 16 j) (<= j (len m) ))
+ (equal (len (prepare-256-ac j m))
+ (if (<= j 64)
+ (+ (- 64 j) (len m))
+ (len m))))
+:hints
+(("goal"
+ :in-theory (disable s-1-256 s-0-256 nth binary-plus ))))
+
+
+(defthm wvp-prepare-256
+ (implies (wordp m 512)
+ (wvp (prepare-256 m) 32))
+:hints (("goal" :in-theory (disable prepare-256-ac ))))
+
+
+(defthm len-prepare-256
+ (implies (wordp m 512)
+ (equal (len (prepare-256 m)) 64))
+:hints (("goal" :in-theory (disable prepare-256-ac))))
+
+
+(defun temp-1-256 (j working-variables m-i-ext)
+ (if (and (wvp working-variables 32) (equal (len working-variables) 8)
+ (integerp j) (<= 0 j)
+ (wvp m-i-ext 32) (equal (len m-i-ext) 64))
+ (plus 32 (nth 7 working-variables)
+ (sigma-1-256 (nth 4 working-variables))
+ (Ch (nth 4 working-variables)
+ (nth 5 working-variables)
+ (nth 6 working-variables ))
+ (k-256 j)
+ (nth j m-i-ext) )
+ nil))
+
+(defthm wordp-temp-1-256
+ (implies (and (wvp l 32) (equal (len l) 8)
+ (integerp j) (<= 0 j) (< j 64)
+ (wvp m 32) (equal (len m) 64))
+ (wordp (temp-1-256 j l m ) 32))
+:hints (("goal" :in-theory (disable sigma-1-256 ch k-256 nth binary-plus ))
+))
+
+(defun temp-2-256 ( working-variables )
+ (if (and (wvp working-variables 32) (equal (len working-variables) 8))
+ (plus 32 (sigma-0-256 (nth 0 working-variables))
+ (Maj (nth 0 working-variables )
+ (nth 1 working-variables)
+ (nth 2 working-variables)) )
+ nil))
+
+
+(defthm wordp-temp-2-256
+ (implies (and (wvp l 32) (equal (len l) 8))
+ (wordp (temp-2-256 l ) 32))
+:hints
+(("goal"
+ :in-theory (disable sigma-0-256 maj binary-plus nth ))))
+
+
+(defun digest-one-block-256-ac ( j working-variables m-i-ext)
+(declare (xargs :measure (acl2-count (- 64 j))))
+ (if (and (wvp working-variables 32) (equal (len working-variables) 8)
+ (integerp j) (<= 0 j)
+ (wvp m-i-ext 32) (equal (len m-i-ext) 64))
+ (if (<= 64 j)
+ working-variables
+ (digest-one-block-256-ac (+ 1 j)
+ (list (plus 32 (temp-1-256 j working-variables m-i-ext)
+ (temp-2-256 working-variables ))
+ (nth 0 working-variables)
+ (nth 1 working-variables)
+ (nth 2 working-variables)
+ (plus 32 (nth 3 working-variables)
+ (temp-1-256 j working-variables m-i-ext))
+ (nth 4 working-variables)
+ (nth 5 working-variables)
+ (nth 6 working-variables))
+ m-i-ext) )
+ nil))
+
+
+(defun digest-one-block-256 (hash-values m-i-ext)
+ (if (and (wvp hash-values 32) (equal (len hash-values) 8)
+ (wvp m-i-ext 32) (equal (len m-i-ext) 64))
+ (digest-one-block-256-ac 0 hash-values m-i-ext)
+ nil))
+
+
+(defthm wvp-digest-one-block-256-ac
+ (implies (and (wvp l 32) (equal (len l) 8)
+ (integerp j) (<= 0 j)
+ (wvp m 32) (equal (len m) 64))
+ (wvp (digest-one-block-256-ac j l m ) 32))
+:hints (("goal" :in-theory (disable temp-1-256 temp-2-256 nth binary-plus))
+))
+
+(defthm len-digest-one-block-256-ac
+ (implies (and (wvp l 32) (equal (len l) 8)
+ (integerp j) (<= 0 j)
+ (wvp m 32) (equal (len m) 64))
+ (equal (len (digest-one-block-256-ac j l m )) 8))
+:hints (("goal" :in-theory (disable temp-1-256 temp-2-256 nth binary-plus ))))
+
+
+
+(defthm wvp-digest-one-block-256
+ (implies (and (wvp l 32) (equal (len l) 8)
+ (wvp m 32) (equal (len m) 64))
+ (wvp (digest-one-block-256 l m ) 32))
+:hints
+(("goal"
+ :in-theory (disable digest-one-block-256-ac))))
+
+
+(defthm len-digest-one-block-256
+ (implies (and (wvp l 32) (equal (len l) 8)
+ (wvp m 32) (equal (len m) 64))
+ (equal (len (digest-one-block-256 l m )) 8))
+:hints
+(("goal"
+ :in-theory (disable digest-one-block-256-ac ))))
+
+
+(defun intermediate-hash-256 ( l1 l2)
+ (if (and (wvp l1 32) (equal (len l1) 8)
+ (wvp l2 32) (equal (len l2) 8) )
+ (list (plus 32 (nth 0 l1) (nth 0 l2))
+ (plus 32 (nth 1 l1) (nth 1 l2) )
+ (plus 32 (nth 2 l1) (nth 2 l2) )
+ (plus 32 (nth 3 l1) (nth 3 l2) )
+ (plus 32 (nth 4 l1) (nth 4 l2) )
+ (plus 32 (nth 5 l1) (nth 5 l2) )
+ (plus 32 (nth 6 l1) (nth 6 l2) )
+ (plus 32 (nth 7 l1) (nth 7 l2) ) )
+ nil))
+
+
+(defthm wvp-intermediate-hash-256
+ (implies (and (wvp l1 32) (equal (len l1) 8)
+ (wvp l2 32) (equal (len l2) 8) )
+ (wvp (intermediate-hash-256 l1 l2 ) 32))
+:hints
+(("goal"
+ :in-theory (disable binary-plus wordp nth ))))
+
+
+(defthm len-intermediate-hash-256
+ (implies (and (wvp l1 32) (equal (len l1) 8)
+ (wvp l2 32) (equal (len l2) 8) )
+ (equal (len (intermediate-hash-256 l1 l2 )) 8)))
+
+
+(defun digest-256 ( m hash-values)
+ (if (and (wvp m 512) (wvp hash-values 32) (equal (len hash-values) 8))
+ (if (endp m) hash-values
+ (digest-256 (cdr m)
+ (intermediate-hash-256 hash-values
+ (digest-one-block-256 hash-values
+ (prepare-256 (car m) )))))
+ nil) )
+
+
+(defthm wvp-digest-256
+ (implies (and (wvp m 512) (wvp hash-values 32)
+ (equal (len hash-values) 8))
+ (wvp (digest-256 m hash-values ) 32) )
+:hints
+(("goal"
+ :in-theory (disable intermediate-hash-256
+ digest-one-block-256 prepare-256 ))))
+
+
+(defthm len-digest-256
+ (implies (and (wvp m 512) (wvp hash-values 32) (not (endp m))
+ (equal (len hash-values) 8))
+ (equal (len (digest-256 m hash-values )) 8) )
+:hints
+(("goal"
+ :in-theory (disable intermediate-hash-256
+ digest-one-block-256 prepare-256 ))))
+
+(defun sha-256 ( m)
+ (if (and (bvp m) (< (len m) (expt 2 64)))
+ (digest-256 (parsing (padding-1-256 m) 512) (h-256))
+ nil))
+
+
+(defthm wvp-sha-256
+(implies (and (bvp m) (< (len m) (expt 2 64)))
+ (wvp (sha-256 m) 32) )
+:hints
+(("goal"
+ :in-theory (disable digest-256 parsing padding-1-256))))
+
+
+(defthm len-sha-256
+(implies (and (bvp m) (< (len m) (expt 2 64)))
+ (equal (len (sha-256 m)) 8 ))
+:hints
+(("goal"
+ :use (:instance len-digest-256 (m (parsing (padding-1-256 m) 512))
+ (hash-values (h-256)))
+ :in-theory (disable digest-256 parsing padding-1-256)))) \ No newline at end of file
diff --git a/books/workshops/2003/toma-borrione/support/sha-384-512.lisp b/books/workshops/2003/toma-borrione/support/sha-384-512.lisp
new file mode 100644
index 0000000..3a846a1
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/sha-384-512.lisp
@@ -0,0 +1,721 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHA-384 and SHA-512
+; Message digest functions and theorems
+;------------------------------------------
+
+(IN-PACKAGE "ACL2")
+
+(include-book "parsing")
+(include-book "sha-functions")
+
+;I strongly recommend after charging the book to do :comp t in order to accelerate the computation
+
+; For a message M with length less than (expt 2 128) sha-512 returns a message digest of 512 bits (eight words each of 64 bits), and sha-384 returns 384 bits of message digest (six words each of 64 bits) .
+
+;For message "abc"
+;ACL2 !>(sha-512 '(0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 ))
+;((1 1 0 1
+; 1 1 0 1 1 0 1 0 1 1 1 1 0 0 1 1 0 1 0 1
+; 1 0 1 0 0 0 0 1 1 0 0 1 0 0 1 1 0 1 1 0
+; 0 0 0 1 0 1 1 1 1 0 1 0 1 0 1 1 1 0 1 0)
+; (1 1 0 0
+; 1 1 0 0 0 1 0 0 0 0 0 1 0 1 1 1 0 0 1 1
+; 0 1 0 0 1 0 0 1 1 0 1 0 1 1 1 0 0 0 1 0
+; 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1)
+; (0 0 0 1
+; 0 0 1 0 1 1 1 0 0 1 1 0 1 1 1 1 1 0 1 0
+; 0 1 0 0 1 1 1 0 1 0 0 0 1 0 0 1 1 0 1 0
+; 1 0 0 1 0 1 1 1 1 1 1 0 1 0 1 0 0 0 1 0)
+; (0 0 0 0
+; 1 0 1 0 1 0 0 1 1 1 1 0 1 1 1 0 1 1 1 0
+; 1 1 1 0 0 1 1 0 0 1 0 0 1 0 1 1 0 1 0 1
+; 0 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 1 0 1 0)
+; (0 0 1 0
+; 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0 1
+; 0 0 1 0 1 0 1 0 0 0 1 0 0 1 1 1 0 1 0 0
+; 1 1 1 1 1 1 0 0 0 0 0 1 1 0 1 0 1 0 0 0)
+; (0 0 1 1
+; 0 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 0
+; 0 0 1 0 0 0 1 1 1 0 1 0 0 0 1 1 1 1 1 1
+; 1 1 1 0 1 1 1 0 1 0 1 1 1 0 1 1 1 1 0 1)
+; (0 1 0 0
+; 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 0 0 1 0 0
+; 0 0 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 1
+; 1 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0 1 1 1 0)
+; (0 0 1 0 1
+; 0 1 0 1 0 0 1 1 0 1 0 1 1 0 0 1 0 0 1 0
+; 1 0 0 1 1 1 1 1 0 1 0 0 1 0 1 0 1 0 0 1
+; 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 1 1 1 1))
+
+
+
+; constants of sha-512
+(defun K-512 (i)
+ (cond ((equal i 0)
+ '(0 1 0 0 0 0 1 0 1 0 0 0
+ 1 0 1 0 0 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0
+ 1 0 0 0 1 0 1 0 1 1 1 0 0 0 1 0 0 0 1 0))
+ ((equal i 1)
+ '(0 1 1 1 0 0 0 1 0 0 1 1
+ 0 1 1 1 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 1 1 1 1 0
+ 1 1 1 1 0 1 1 0 0 1 0 1 1 1 0 0 1 1 0 1))
+ ((equal i 2) '(1 0 1 1 0 1 0 1 1 1 0 0
+ 0 0 0 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 1 0 0
+ 1 1 0 1 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1))
+ ((equal i 3) '(1 1 1 0 1 0 0 1 1 0 1 1
+ 0 1 0 1 1 1 0 1 1 0 1 1 1 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 0 0
+ 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 1 1 1 0 0))
+ ((equal i 4) '(0 0 1 1 1 0 0 1 0 1 0 1
+ 0 1 1 0 1 1 0 0 0 0 1 0 0 1 0 1 1 0 1 1 1 1 1 1 0 0 1 1 0 1 0 0
+ 1 0 0 0 1 0 1 1 0 1 0 1 0 0 1 1 1 0 0 0))
+ ((equal i 5) '(0 1 0 1 1 0 0 1 1 1 1 1
+ 0 0 0 1 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0
+ 0 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 1 0 0 1))
+ ((equal i 6) '(1 0 0 1 0 0 1 0 0 0 1 1
+ 1 1 1 1 1 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 0 1
+ 1 0 0 1 0 1 0 0 1 1 1 1 1 0 0 1 1 0 1 1))
+ ((equal i 7) '(1 0 1 0
+ 1 0 1 1 0 0 0 1 1 1 0 0 0 1 0 1 1 1 1 0
+ 1 1 0 1 0 1 0 1 1 1 0 1 1 0 1 0 0 1 1 0
+ 1 1 0 1 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0))
+ ((equal i 8) '(1 1 0 1
+ 1 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 0 1 0
+ 1 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0
+ 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0))
+ ((equal i 9) '(0 0 0 1
+ 0 0 1 0 1 0 0 0 0 0 1 1 0 1 0 1 1 0 1 1
+ 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 1 1 1
+ 0 0 0 0 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0))
+ ((equal i 10) '(0 0 1 0
+ 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 1 0 1
+ 1 0 1 1 1 1 1 0 0 1 0 0 1 1 1 0 1 1 1 0
+ 0 1 0 0 1 0 1 1 0 0 1 0 1 0 0 0 1 1 0 0))
+ ((equal i 11) '(0 1 0 1
+ 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 1 1 1 0 1
+ 1 1 0 0 0 0 1 1 1 1 0 1 0 1 0 1 1 1 1 1
+ 1 1 1 1 1 0 1 1 0 1 0 0 1 1 1 0 0 0 1 0))
+ ((equal i 12) '(0 1 1 1
+ 0 0 1 0 1 0 1 1 1 1 1 0 0 1 0 1 1 1 0 1
+ 0 1 1 1 0 1 0 0 1 1 1 1 0 0 1 0 0 1 1 1
+ 1 0 1 1 1 0 0 0 1 0 0 1 0 1 1 0 1 1 1 1))
+ ((equal i 13) '(1 0 0 0
+ 0 0 0 0 1 1 0 1 1 1 1 0 1 0 1 1 0 0 0 1
+ 1 1 1 1 1 1 1 0 0 0 1 1 1 0 1 1 0 0 0 1
+ 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 0 0 0 1))
+ ((equal i 14) '(1 0 0 1
+ 1 0 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 1 1 0
+ 1 0 1 0 0 1 1 1 0 0 1 0 0 1 0 1 1 1 0 0
+ 0 1 1 1 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1))
+ ((equal i 15) '(1 1 0 0
+ 0 0 0 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 1
+ 0 1 1 1 0 1 0 0 1 1 0 0 1 1 1 1 0 1 1 0
+ 1 0 0 1 0 0 1 0 0 1 1 0 1 0 0 1 0 1 0 0))
+ ((equal i 16) '(1 1 1 0
+ 0 1 0 0 1 0 0 1 1 0 1 1 0 1 1 0 1 0 0 1
+ 1 1 0 0 0 0 0 1 1 0 0 1 1 1 1 0 1 1 1 1
+ 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 0 1 0))
+ ((equal i 17) '(1 1 1 0
+ 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 0 0 1 1 1
+ 1 0 0 0 0 1 1 0 0 0 1 1 1 0 0 0 0 1 0 0
+ 1 1 1 1 0 0 1 0 0 1 0 1 1 1 1 0 0 0 1 1))
+ ((equal i 18) '(0 0 0 0
+ 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 1 0 1
+ 1 1 0 0 0 1 1 0 1 0 0 0 1 0 1 1 1 0 0 0
+ 1 1 0 0 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1))
+ ((equal i 19) '(0 0 1 0
+ 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 1
+ 1 1 0 0 1 1 0 0 0 1 1 1 0 1 1 1 1 0 1 0
+ 1 1 0 0 1 0 0 1 1 1 0 0 0 1 1 0 0 1 0 1))
+ ((equal i 20) '(0 0 1 0
+ 1 1 0 1 1 1 1 0 1 0 0 1 0 0 1 0 1 1 0 0
+ 0 1 1 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 1 0
+ 1 0 1 1 0 0 0 0 0 0 1 0 0 1 1 1 0 1 0 1))
+ ((equal i 21) '(0 1 0 0
+ 1 0 1 0 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0
+ 1 0 1 0 1 0 1 0 0 1 1 0 1 1 1 0 1 0 1 0
+ 0 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 1 1))
+ ((equal i 22) '(0 1 0 1
+ 1 1 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 1
+ 1 1 0 1 1 1 0 0 1 0 1 1 1 1 0 1 0 1 0 0
+ 0 0 0 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 0))
+ ((equal i 23) '(0 1 1 1
+ 0 1 1 0 1 1 1 1 1 0 0 1 1 0 0 0 1 0 0 0
+ 1 1 0 1 1 0 1 0 1 0 0 0 0 0 1 1 0 0 0 1
+ 0 0 0 1 0 1 0 1 0 0 1 1 1 0 1 1 0 1 0 1))
+ ((equal i 24) '(1 0 0 1
+ 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 0 0 1
+ 0 1 0 1 0 0 1 0 1 1 1 0 1 1 1 0 0 1 1 0
+ 0 1 1 0 1 1 0 1 1 1 1 1 1 0 1 0 1 0 1 1))
+ ((equal i 25) '(1 0 1 0
+ 1 0 0 0 0 0 1 1 0 0 0 1 1 1 0 0 0 1 1 0
+ 0 1 1 0 1 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1
+ 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0))
+ ((equal i 26) '(1 0 1 1
+ 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1
+ 1 1 0 0 1 0 0 0 1 0 0 1 1 0 0 0 1 1 1 1
+ 1 0 1 1 0 0 1 0 0 0 0 1 0 0 1 1 1 1 1 1))
+ ((equal i 27) '(1 0 1 1
+ 1 1 1 1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 1 1
+ 1 1 0 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1 0
+ 1 1 1 1 0 0 0 0 1 1 1 0 1 1 1 0 0 1 0 0))
+ ((equal i 28) '(1 1 0 0
+ 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 1
+ 1 1 1 1 0 0 1 1 0 0 1 1 1 1 0 1 1 0 1 0
+ 1 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0))
+ ((equal i 29) '(1 1 0 1
+ 0 1 0 1 1 0 1 0 0 1 1 1 1 0 0 1 0 0 0 1
+ 0 1 0 0 0 1 1 1 1 0 0 1 0 0 1 1 0 0 0 0
+ 1 0 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 0 1))
+ ((equal i 30) '(0 0 0 0
+ 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 1
+ 0 1 0 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0
+ 0 0 1 1 1 0 0 0 0 0 1 0 0 1 1 0 1 1 1 1))
+ ((equal i 31) '(0 0 0 1
+ 0 1 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1
+ 0 1 1 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0
+ 1 1 1 0 0 1 1 0 1 1 1 0 0 1 1 1 0 0 0 0))
+ ((equal i 32) '(0 0 1 0
+ 0 1 1 1 1 0 1 1 0 1 1 1 0 0 0 0 1 0 1 0
+ 1 0 0 0 0 1 0 1 0 1 0 0 0 1 1 0 1 1 0 1
+ 0 0 1 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0))
+ ((equal i 33) '(0 0 1 0
+ 1 1 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1
+ 0 0 1 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 1 0
+ 0 1 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0))
+ ((equal i 34) '(0 1 0 0
+ 1 1 0 1 0 0 1 0 1 1 0 0 0 1 1 0 1 1 0 1
+ 1 1 1 1 1 1 0 0 0 1 0 1 1 0 1 0 1 1 0 0
+ 0 1 0 0 0 0 1 0 1 0 1 0 1 1 1 0 1 1 0 1))
+ ((equal i 35) '(0 1 0 1
+ 0 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 1 1 0 1
+ 0 0 0 1 0 0 1 1 1 0 0 1 1 1 0 1 1 0 0 1
+ 0 1 0 1 1 0 1 1 0 0 1 1 1 1 0 1 1 1 1 1))
+ ((equal i 36) '(0 1 1 0
+ 0 1 0 1 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 1
+ 0 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 1 0
+ 1 1 1 1 0 1 1 0 0 0 1 1 1 1 0 1 1 1 1 0))
+ ((equal i 37) '(0 1 1 1
+ 0 1 1 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0
+ 1 0 1 1 1 0 1 1 0 0 1 1 1 1 0 0 0 1 1 1
+ 0 1 1 1 1 0 1 1 0 0 1 0 1 0 1 0 1 0 0 0))
+ ((equal i 38) '(1 0 0 0
+ 0 0 0 1 1 1 0 0 0 0 1 0 1 1 0 0 1 0 0 1
+ 0 0 1 0 1 1 1 0 0 1 0 0 0 1 1 1 1 1 1 0
+ 1 1 0 1 1 0 1 0 1 1 1 0 1 1 1 0 0 1 1 0))
+ ((equal i 39) '(1 0 0 1
+ 0 0 1 0 0 1 1 1 0 0 1 0 0 0 1 0 1 1 0 0
+ 1 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0 0
+ 0 0 1 0 0 0 1 1 0 1 0 1 0 0 1 1 1 0 1 1))
+ ((equal i 40) '(1 0 1 0
+ 0 0 1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0 0
+ 1 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 1 1 1 1
+ 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 0 0))
+ ((equal i 41) '(1 0 1 0
+ 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1 1 0
+ 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0
+ 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1))
+ ((equal i 42) '(1 1 0 0
+ 0 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 0 1 1
+ 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1
+ 1 0 0 0 1 0 0 1 0 1 1 1 1 0 0 1 0 0 0 1))
+ ((equal i 43) '(1 1 0 0
+ 0 1 1 1 0 1 1 0 1 1 0 0 0 1 0 1 0 0 0 1
+ 1 0 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0 1 0 1
+ 0 1 0 0 1 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0))
+ ((equal i 44) '(1 1 0 1
+ 0 0 0 1 1 0 0 1 0 0 1 0 1 1 1 0 1 0 0 0
+ 0 0 0 1 1 0 0 1 1 1 0 1 0 1 1 0 1 1 1 0
+ 1 1 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0))
+ ((equal i 45) '(1 1 0 1
+ 0 1 1 0 1 0 0 1 1 0 0 1 0 0 0 0 0 1 1 0
+ 0 0 1 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 1 0
+ 0 1 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0))
+ ((equal i 46) '(1 1 1 1
+ 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 1 0 1 0 1
+ 1 0 0 0 0 1 0 1 0 1 0 1 0 1 1 1 0 1 1 1
+ 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 1 0 1 0))
+ ((equal i 47) '(0 0 0 1
+ 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 0 0 0 0 0
+ 0 1 1 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 1 1
+ 1 0 1 1 1 1 0 1 0 0 0 1 1 0 1 1 1 0 0 0))
+ ((equal i 48) '(0 0 0 1
+ 1 0 0 1 1 0 1 0 0 1 0 0 1 1 0 0 0 0 0 1
+ 0 0 0 1 0 1 1 0 1 0 1 1 1 0 0 0 1 1 0 1
+ 0 0 1 0 1 1 0 1 0 0 0 0 1 1 0 0 1 0 0 0))
+ ((equal i 49) '(0 0 0 1
+ 1 1 1 0 0 0 1 1 0 1 1 1 0 1 1 0 1 1 0 0
+ 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0
+ 0 0 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 1 1))
+ ((equal i 50) '(0 0 1 0
+ 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 1 0 1 1 1
+ 0 1 0 0 1 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0
+ 1 1 1 0 1 1 1 0 1 0 1 1 1 0 0 1 1 0 0 1))
+ ((equal i 51) '(0 0 1 1
+ 0 1 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 1 0 0
+ 1 0 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 0 0 1
+ 1 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 0))
+ ((equal i 52) '(0 0 1 1
+ 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0
+ 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 1 1 1 0 0
+ 1 0 0 1 0 1 0 1 1 0 1 0 0 1 1 0 0 0 1 1))
+ ((equal i 53) '(0 1 0 0
+ 1 1 1 0 1 1 0 1 1 0 0 0 1 0 1 0 1 0 1 0
+ 0 1 0 0 1 0 1 0 1 1 1 0 0 0 1 1 0 1 0 0
+ 0 0 0 1 1 0 0 0 1 0 1 0 1 1 0 0 1 0 1 1))
+ ((equal i 54) '(0 1 0 1
+ 1 0 1 1 1 0 0 1 1 1 0 0 1 1 0 0 1 0 1 0
+ 0 1 0 0 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0
+ 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0 0 1 1))
+ ((equal i 55) '(0 1 1 0
+ 1 0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 1 1 1 1
+ 1 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1
+ 0 0 1 0 1 0 1 1 1 0 0 0 1 0 1 0 0 0 1 1))
+ ((equal i 56) '(0 1 1 1
+ 0 1 0 0 1 0 0 0 1 1 1 1 1 0 0 0 0 0 1 0
+ 1 1 1 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 1 0
+ 1 1 1 1 1 0 1 1 0 0 1 0 1 1 1 1 1 1 0 0))
+ ((equal i 57) '(0 1 1 1
+ 1 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 0 1 1
+ 0 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 0 0 0 1
+ 0 1 1 1 0 0 1 0 1 1 1 1 0 1 1 0 0 0 0 0))
+ ((equal i 58) '(1 0 0 0
+ 0 1 0 0 1 1 0 0 1 0 0 0 0 1 1 1 1 0 0 0
+ 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 1 1 1 1
+ 0 0 0 0 1 0 1 0 1 0 1 1 0 1 1 1 0 0 1 0))
+ ((equal i 59) '(1 0 0 0
+ 1 1 0 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 1 0
+ 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0
+ 0 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 1 1 0 0))
+ ((equal i 60) '(1 0 0 1
+ 0 0 0 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 0 1 0 0 0 1 0 0 0 1 1 0 1 1 0
+ 0 0 1 1 0 0 0 1 1 1 1 0 0 0 1 0 1 0 0 0))
+ ((equal i 61) '(1 0 1 0
+ 0 1 0 0 0 1 0 1 0 0 0 0 0 1 1 0 1 1 0 0
+ 1 1 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 0 0 0
+ 0 0 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 0 0 1))
+ ((equal i 62) '(1 0 1 1
+ 1 1 1 0 1 1 1 1 1 0 0 1 1 0 1 0 0 0 1 1
+ 1 1 1 1 0 1 1 1 1 0 1 1 0 0 1 0 1 1 0 0
+ 0 1 1 0 0 1 1 1 1 0 0 1 0 0 0 1 0 1 0 1))
+ ((equal i 63) '(1 1 0 0
+ 0 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 1 0 0 0
+ 1 1 1 1 0 0 1 0 1 1 1 0 0 0 1 1 0 1 1 1
+ 0 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 1 0 1 1))
+ ((equal i 64) '(1 1 0 0
+ 1 0 1 0 0 0 1 0 0 1 1 1 0 0 1 1 1 1 1 0
+ 1 1 0 0 1 1 1 0 1 1 1 0 1 0 1 0 0 0 1 0
+ 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 1 0 0))
+ ((equal i 65) '(1 1 0 1
+ 0 0 0 1 1 0 0 0 0 1 1 0 1 0 1 1 1 0 0 0
+ 1 1 0 0 0 1 1 1 0 0 1 0 0 0 0 1 1 1 0 0
+ 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 1 1 1))
+ ((equal i 66) '(1 1 1 0
+ 1 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 1 0 1
+ 1 1 0 1 0 1 1 0 1 1 0 0 1 1 0 1 1 1 1 0
+ 0 0 0 0 1 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0))
+ ((equal i 67) '(1 1 1 1
+ 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 0 1 1 1 1
+ 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0
+ 1 1 1 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0))
+ ((equal i 68) '(0 0 0 0
+ 0 1 1 0 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 1
+ 1 0 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 0 0 1
+ 0 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 0 1 0))
+ ((equal i 69) '(0 0 0 0
+ 1 0 1 0 0 1 1 0 0 0 1 1 0 1 1 1 1 1 0 1
+ 1 1 0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 0
+ 1 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 1 0))
+ ((equal i 70) '(0 0 0 1
+ 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 1 1 0 0 0
+ 0 0 0 0 0 1 0 0 1 0 1 1 1 1 1 0 1 1 1 1
+ 1 0 0 1 0 0 0 0 1 1 0 1 1 0 1 0 1 1 1 0))
+ ((equal i 71) '(0 0 0 1
+ 1 0 1 1 0 1 1 1 0 0 0 1 0 0 0 0 1 0 1 1
+ 0 0 1 1 0 1 0 1 0 0 0 1 0 0 1 1 0 0 0 1
+ 1 1 0 0 0 1 0 0 0 1 1 1 0 0 0 1 1 0 1 1))
+ ((equal i 72) '(0 0 1 0
+ 1 0 0 0 1 1 0 1 1 0 1 1 0 1 1 1 0 1 1 1
+ 1 1 1 1 0 1 0 1 0 0 1 0 0 0 1 1 0 0 0 0
+ 0 1 0 0 0 1 1 1 1 1 0 1 1 0 0 0 0 1 0 0))
+ ((equal i 73) '(0 0 1 1
+ 0 0 1 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 1
+ 0 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0
+ 0 1 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1))
+ ((equal i 74) '(0 0 1 1
+ 1 1 0 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1 0
+ 0 0 0 0 1 0 1 0 0 0 0 1 0 1 0 1 1 1 0 0
+ 1 0 0 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 0 0))
+ ((equal i 75) '(0 1 0 0
+ 0 0 1 1 0 0 0 1 1 1 0 1 0 1 1 0 0 1 1 1
+ 1 1 0 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 0 1
+ 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 1 0 0))
+ ((equal i 76) '(0 1 0 0
+ 1 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1 0 1 0 0
+ 1 0 1 1 1 1 1 0 1 1 0 0 1 0 1 1 0 0 1 1
+ 1 1 1 0 0 1 0 0 0 0 1 0 1 0 1 1 0 1 1 0))
+ ((equal i 77) '(0 1 0 1
+ 1 0 0 1 0 1 1 1 1 1 1 1 0 0 1 0 1 0 0 1
+ 1 0 0 1 1 1 0 0 1 1 1 1 1 1 0 0 0 1 1 0
+ 0 1 0 1 0 1 1 1 1 1 1 0 0 0 1 0 1 0 1 0))
+ ((equal i 78) '(0 1 0 1
+ 1 1 1 1 1 1 0 0 1 0 1 1 0 1 1 0 1 1 1 1
+ 1 0 1 0 1 0 1 1 0 0 1 1 1 0 1 0 1 1 0 1
+ 0 1 1 0 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 0))
+ ((equal i 79) '(0 1 1 0
+ 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 1
+ 1 0 0 0 1 1 0 0 0 1 0 0 1 0 1 0 0 1 0 0
+ 0 1 1 1 0 1 0 1 1 0 0 0 0 0 0 1 0 1 1 1))
+ (t nil)))
+
+
+(defthm wordp-K-512
+(implies (and (integerp i) (<= 0 i) (<= i 79))
+ (wordp (k-512 i) 64)))
+
+
+; initial hash values for sha-384
+(defun h-384()
+'((1 1 0 0
+ 1 0 1 1 1 0 1 1 1 0 1 1 1 0 0 1 1 1 0 1
+ 0 1 0 1 1 1 0 1 1 1 0 0 0 0 0 1 0 0 0 0
+ 0 1 0 1 1 0 0 1 1 1 1 0 1 1 0 1 1 0 0 0)
+(0 1 1 0
+ 0 0 1 0 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1
+ 0 0 1 0 1 0 1 0 0 0 1 1 0 1 1 0 0 1 1 1
+ 1 1 0 0 1 1 0 1 0 1 0 1 0 0 0 0 0 1 1 1)
+(1 0 0 1
+ 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 1
+ 0 1 0 1 1 0 1 0 0 0 1 1 0 0 0 0 0 1 1 1
+ 0 0 0 0 1 1 0 1 1 1 0 1 0 0 0 1 0 1 1 1)
+(0 0 0 1
+ 0 1 0 1 0 0 1 0 1 1 1 1 1 1 1 0 1 1 0 0
+ 1 1 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0 0 0 0
+ 1 1 1 0 0 1 0 1 1 0 0 1 0 0 1 1 1 0 0 1)
+(0 1 1 0
+ 0 1 1 1 0 0 1 1 0 0 1 1 0 0 1 0 0 1 1 0
+ 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
+ 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 0 1)
+(1 0 0 0
+ 1 1 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 0
+ 1 0 0 0 0 1 1 1 0 1 1 0 1 0 0 0 0 1 0 1
+ 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1)
+(1 1 0 1
+ 1 0 1 1 0 0 0 0 1 1 0 0 0 0 1 0 1 1 1 0
+ 0 0 0 0 1 1 0 1 0 1 1 0 0 1 0 0 1 1 1 1
+ 1 0 0 1 1 0 0 0 1 1 1 1 1 0 1 0 0 1 1 1)
+(0 1 0 0
+ 0 1 1 1 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 0
+ 0 0 0 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1
+ 1 0 1 0 0 1 0 0 1 1 1 1 1 0 1 0 0 1 0 0))
+)
+
+(defthm wordp-h-384
+ (and (wvp (h-384) 64) (equal (len (h-384)) 8 )))
+
+
+; initial hash values for sha-512
+(defun h-512()
+'((0 1 1 0
+ 1 0 1 0 0 0 0 0 1 0 0 1 1 1 1 0 0 1 1 0
+ 0 1 1 0 0 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1
+ 1 1 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0)
+(1 0 1 1
+ 1 0 1 1 0 1 1 0 0 1 1 1 1 0 1 0 1 1 1 0
+ 1 0 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1 1 0 0
+ 1 0 1 0 1 0 1 0 0 1 1 1 0 0 1 1 1 0 1 1)
+(0 0 1 1
+ 1 1 0 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 1 1
+ 0 1 1 1 0 0 1 0 1 1 1 1 1 1 1 0 1 0 0 1
+ 0 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 1 0 1 1)
+(1 0 1 0
+ 0 1 0 1 0 1 0 0 1 1 1 1 1 1 1 1 0 1 0 1
+ 0 0 1 1 1 0 1 0 0 1 0 1 1 1 1 1 0 0 0 1
+ 1 1 0 1 0 0 1 1 0 1 1 0 1 1 1 1 0 0 0 1)
+(0 1 0 1
+ 0 0 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0
+ 0 1 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 0
+ 0 1 1 0 1 0 0 0 0 0 1 0 1 1 0 1 0 0 0 1)
+(1 0 0 1
+ 1 0 1 1 0 0 0 0 0 1 0 1 0 1 1 0 1 0 0 0
+ 1 0 0 0 1 1 0 0 0 0 1 0 1 0 1 1 0 0 1 1
+ 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 1 1 1 1 1)
+(0 0 0 1
+ 1 1 1 1 1 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1
+ 1 0 1 0 1 0 1 1 1 1 1 1 1 0 1 1 0 1 0 0
+ 0 0 0 1 1 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1)
+(0 1 0 1
+ 1 0 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 0 1
+ 0 0 0 1 1 0 0 1 0 0 0 1 0 0 1 1 0 1 1 1
+ 1 1 1 0 0 0 1 0 0 0 0 1 0 1 1 1 1 0 0 1))
+)
+
+(defthm wordp-h-512
+ (and (wvp (h-512) 64) (equal (len (h-512)) 8 )))
+
+
+;----sha-512
+
+(defun prepare-512-ac ( j m-i)
+(declare (xargs :measure (acl2-count (- 80 j))))
+ (if (and (integerp j) (<= 16 j) (wvp m-i 64))
+ (cond ((<= 80 j) m-i)
+ ((<= j 79)
+ (prepare-512-ac (1+ j)
+ (append m-i (list (plus 64 (s-1-512 (nth (- j 2) m-i))
+ (nth (- j 7) m-i)
+ (s-0-512 (nth (- j 15) m-i))
+ (nth (- j 16) m-i)))))))
+ nil))
+
+
+(defun prepare-512 (m-i)
+ (if (wordp m-i 1024)
+ (prepare-512-ac 16 (parsing m-i 64))
+ nil))
+
+
+(defthm wvp-prepare-512-ac
+ (implies (and (integerp j) (<= 16 j) (wvp m 64))
+ (wvp (prepare-512-ac j m) 64))
+:hints (("goal" :in-theory (disable s-1-512 s-0-512 nth binary-plus ))))
+
+
+(defthm len-prepare-512-ac
+ (implies (and (wvp m 64) (integerp j) (<= 16 j) (<= j (len m) ))
+ (equal (len (prepare-512-ac j m))
+ (if (<= j 80)
+ (+ (- 80 j) (len m))
+ (len m))))
+:hints (("goal" :in-theory (disable s-1-512 s-0-512 nth binary-plus ))))
+
+
+(defthm wvp-prepare-512
+ (implies (wordp m 1024)
+ (wvp (prepare-512 m) 64))
+:hints (("goal" :in-theory (disable prepare-512-ac ))))
+
+
+(defthm len-prepare-512
+ (implies (wordp m 1024)
+ (equal (len (prepare-512 m)) 80))
+:hints (("goal" :in-theory (disable prepare-512-ac))))
+
+
+(defun temp-1-512 (j working-variables m-i-ext)
+ (if (and (equal (len working-variables) 8) (wvp working-variables 64)
+ (integerp j) (<= 0 j)
+ (wvp m-i-ext 64) (equal (len m-i-ext) 80))
+ (plus 64 (nth 7 working-variables)
+ (sigma-1-512 (nth 4 working-variables))
+ (Ch (nth 4 working-variables)
+ (nth 5 working-variables)
+ (nth 6 working-variables))
+ (k-512 j)
+ (nth j m-i-ext) )
+ nil))
+
+
+(defthm wordp-temp-1-512
+ (implies (and (wvp l 64) (equal (len l) 8)
+ (integerp j) (<= 0 j) (< j 80)
+ (wvp m 64) (equal (len m) 80))
+ (wordp (temp-1-512 j l m ) 64))
+:hints
+(("goal"
+ :in-theory (disable sigma-1-512 ch k-512 nth binary-plus wordp ))))
+
+
+(defun temp-2-512 ( working-variables )
+ (if (and (equal (len working-variables) 8) (wvp working-variables 64))
+ (plus 64 (sigma-0-512 (nth 0 working-variables))
+ (Maj (nth 0 working-variables)
+ (nth 1 working-variables)
+ (nth 2 working-variables)) )
+ nil))
+
+
+(defthm wordp-temp-2-512
+ (implies (and (wvp l 64) (equal (len l) 8))
+ (wordp (temp-2-512 l ) 64))
+:hints (("goal" :in-theory (disable sigma-0-512 maj binary-plus nth ))))
+
+
+(defun digest-one-block-512-ac ( j working-variables m-i-ext)
+(declare (xargs :measure (acl2-count (- 80 j))))
+ (if (and (equal (len working-variables) 8) (wvp working-variables 64)
+ (integerp j) (<= 0 j)
+ (wvp m-i-ext 64) (equal (len m-i-ext) 80))
+ (if (<= 80 j)
+ working-variables
+ (digest-one-block-512-ac (+ 1 j)
+ (list (plus 64 (temp-1-512 j working-variables m-i-ext)
+ (temp-2-512 working-variables ))
+ (nth 0 working-variables)
+ (nth 1 working-variables)
+ (nth 2 working-variables)
+ (plus 64 (nth 3 working-variables)
+ (temp-1-512 j working-variables m-i-ext) )
+ (nth 4 working-variables)
+ (nth 5 working-variables)
+ (nth 6 working-variables))
+ m-i-ext) )
+ nil))
+
+
+(defun digest-one-block-512 (hash-values m-i-ext)
+ (if (and (wvp hash-values 64) (equal (len hash-values) 8)
+ (wvp m-i-ext 64) (equal (len m-i-ext) 80))
+ (digest-one-block-512-ac 0 hash-values m-i-ext)
+ nil))
+
+
+(defthm wvp-digest-one-block-512-ac
+ (implies (and (wvp l 64) (equal (len l) 8)
+ (integerp j) (<= 0 j)
+ (wvp m 64) (equal (len m) 80))
+ (wvp (digest-one-block-512-ac j l m ) 64))
+:hints (("goal" :in-theory (disable temp-1-512 temp-2-512 nth binary-plus))))
+
+
+(defthm len-digest-one-block-512-ac
+ (implies (and (wvp l 64) (equal (len l) 8)
+ (integerp j) (<= 0 j)
+ (wvp m 64) (equal (len m) 80))
+ (equal (len (digest-one-block-512-ac j l m )) 8))
+:hints (("goal" :in-theory (disable temp-1-512 temp-2-512 nth binary-plus ))))
+
+
+(defthm wvp-digest-one-block-512
+ (implies (and (wvp l 64) (equal (len l) 8)
+ (wvp m 64) (equal (len m) 80))
+ (wvp (digest-one-block-512 l m ) 64))
+:hints
+(("goal"
+ :in-theory (disable digest-one-block-512-ac))))
+
+
+(defthm len-digest-one-block-512
+ (implies (and (wvp l 64) (equal (len l) 8)
+ (wvp m 64) (equal (len m) 80))
+ (equal (len (digest-one-block-512 l m )) 8))
+:hints
+(("goal"
+ :in-theory (disable digest-one-block-512-ac ))))
+
+
+(defun intermediate-hash-512 ( l1 l2)
+ (if (and (wvp l1 64) (equal (len l1) 8)
+ (wvp l2 64) (equal (len l2) 8) )
+ (list (plus 64 (nth 0 l1) (nth 0 l2) )
+ (plus 64 (nth 1 l1) (nth 1 l2) )
+ (plus 64 (nth 2 l1) (nth 2 l2) )
+ (plus 64 (nth 3 l1) (nth 3 l2) )
+ (plus 64 (nth 4 l1) (nth 4 l2) )
+ (plus 64 (nth 5 l1) (nth 5 l2) )
+ (plus 64 (nth 6 l1) (nth 6 l2) )
+ (plus 64 (nth 7 l1) (nth 7 l2) ))
+ nil))
+
+
+(defthm wvp-intermediate-hash-512
+ (implies (and (wvp l1 64) (equal (len l1) 8)
+ (wvp l2 64) (equal (len l2) 8) )
+ (wvp (intermediate-hash-512 l1 l2 ) 64))
+:hints (("goal" :in-theory (disable binary-plus wordp nth ))))
+
+
+(defthm len-intermediate-hash-512
+ (implies (and (wvp l1 64) (equal (len l1) 8)
+ (wvp l2 64) (equal (len l2) 8) )
+ (equal (len (intermediate-hash-512 l1 l2 )) 8)))
+
+
+(defun digest-512 ( m hash-values)
+ (if (and (wvp m 1024) (wvp hash-values 64) (equal (len hash-values) 8) )
+ (if (endp m) hash-values
+ (digest-512 (cdr m)
+ (intermediate-hash-512 hash-values
+ (digest-one-block-512 hash-values
+ (prepare-512 (car m) )))))
+ nil) )
+
+
+(defthm wvp-digest-512
+ (implies (and (wvp m 1024) (wvp hash-values 64)
+ (equal (len hash-values) 8))
+ (wvp (digest-512 m hash-values ) 64) )
+:hints
+(("goal"
+ :in-theory (disable intermediate-hash-512
+ digest-one-block-512 prepare-512 ))))
+
+
+(defthm len-digest-512
+ (implies (and (wvp m 1024) (wvp hash-values 64) (not (endp m))
+ (equal (len hash-values) 8))
+ (equal (len (digest-512 m hash-values )) 8) )
+:hints
+(("goal"
+ :in-theory (disable intermediate-hash-512
+ digest-one-block-512 prepare-512 ))))
+
+
+(defun sha-512 ( m)
+ (if (and (bvp m) (< (len m) (expt 2 128)))
+ (digest-512 (parsing (padding-512 m) 1024) (h-512))
+ nil))
+
+
+(defthm wvp-sha-512
+(implies (and (bvp m) (< (len m) (expt 2 128)))
+ (wvp (sha-512 m) 64) )
+:hints(("goal" :in-theory (disable digest-512 parsing padding-512))))
+
+
+(defthm len-sha-512
+(implies (and (bvp m) (< (len m) (expt 2 128)))
+ (equal (len (sha-512 m)) 8 ))
+:hints
+(("goal"
+ :use (:instance len-digest-512 (m (parsing (padding-512 m) 1024))
+ (hash-values (h-512)))
+ :in-theory (disable digest-512 parsing padding-512))))
+
+
+; sha-384
+
+(defun sha-384 ( m)
+ (if (bvp m)
+ (let ((res (digest-512 (parsing (padding-512 m) 1024) (h-384))))
+ (list (nth 0 res)
+ (nth 1 res)
+ (nth 2 res)
+ (nth 3 res)
+ (nth 4 res)
+ (nth 5 res) ))
+ nil))
+
+
+(defthm wvp-sha-384
+(implies (and (bvp m) (< (len m) (expt 2 128)))
+ (wvp (sha-384 m) 64) )
+:hints
+(("goal"
+ :in-theory (disable digest-512 parsing padding-512 wordp nth)
+ :use (:instance len-digest-512 (m (parsing (padding-512 m) 1024))
+ (hash-values (h-384))))))
+
+
+(defthm len-sha-384
+(implies (and (bvp m) (< (len m) (expt 2 128)))
+ (equal (len (sha-384 m)) 6 ))
+:hints
+(("goal"
+ :use (:instance len-digest-512 (m (parsing (padding-512 m) 1024))
+ (hash-values (h-384)))
+ :in-theory (disable digest-512 parsing padding-512)))) \ No newline at end of file
diff --git a/books/workshops/2003/toma-borrione/support/sha-functions.lisp b/books/workshops/2003/toma-borrione/support/sha-functions.lisp
new file mode 100644
index 0000000..520f444
--- /dev/null
+++ b/books/workshops/2003/toma-borrione/support/sha-functions.lisp
@@ -0,0 +1,164 @@
+;------------------------------------------
+;
+; Author: Diana Toma
+; TIMA-VDS, Grenoble, France
+; March 2003
+; ACL2 formalization of SHAs
+; Logic functions (and theorems) needed for all four SHA
+;------------------------------------------
+
+
+
+(IN-PACKAGE "ACL2")
+
+(include-book "bv-op-defthms")
+
+
+;logic functions for SHAs
+
+(defun Ch (x y z)
+ (if (and (bvp x)
+ (bvp y)
+ (bvp z))
+ (bv-xor (bv-and x y) (bv-and (bv-not x) z))
+ nil))
+
+(defthm bvp-Ch
+ (implies (and (bvp x) (bvp y) (bvp z))
+ (bvp (Ch x y z))))
+
+(defthm wordp-Ch
+ (implies (and (wordp x w) (wordp y w) (wordp z w))
+ (wordp (Ch x y z) w)))
+
+
+(defun Parity (x y z)
+ (if (and (bvp x)
+ (bvp y)
+ (bvp z))
+ (bv-xor x y z)
+ nil))
+
+(defthm bvp-Parity
+ (implies (and (bvp x) (bvp y) (bvp z))
+ (bvp (Parity x y z))))
+
+(defthm wordp-Parity
+ (implies (and (wordp x w) (wordp y w) (wordp z w))
+ (wordp (Parity x y z) w)))
+
+(defun Maj (x y z)
+ (if (and (bvp x)
+ (bvp y)
+ (bvp z))
+ (bv-xor (bv-and x y) (bv-and x z) (bv-and y z))
+ nil))
+
+(defthm bvp-Maj
+ (implies (and (bvp x) (bvp y) (bvp z))
+ (bvp (Maj x y z))))
+
+(defthm wordp-Maj
+ (implies (and (wordp x w) (wordp y w) (wordp z w))
+ (wordp (Maj x y z) w)))
+
+(defun Ft (i x y z)
+ (if (and (integerp i)
+ (<= 0 i)
+ (wordp x 32)
+ (wordp y 32)
+ (wordp z 32))
+ (cond ((and (<= 0 i) (<= i 19))
+ (Ch x y z))
+ ((or (and (<= 20 i) (<= i 39)) (and (<= 60 i) (<= i 79)))
+ (Parity x y z))
+ ((and (<= 40 i) (<= i 59))
+ (Maj x y z)))
+ nil))
+
+(defthm wordp-Ft
+ (implies (and (integerp i) (<= 0 i) (wordp x 32) (<= 0 i) (< i 80)
+ (wordp y 32) (wordp z 32))
+ (wordp (Ft i x y z) 32))
+:hints (("goal" :in-theory (disable ch parity maj) )))
+
+(defun sigma-0-256 (x)
+ (if (wordp x 32)
+ (bv-xor (rotr 2 x 32) (rotr 13 x 32) (rotr 22 x 32))
+ nil))
+
+
+(defthm wordp-sigma-0-256
+(implies (wordp x 32)
+ ( wordp (sigma-0-256 x) 32))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl ))))
+
+(defun sigma-1-256 (x)
+ (if (wordp x 32)
+ (bv-xor (rotr 6 x 32) (rotr 11 x 32) (rotr 25 x 32))
+ nil))
+
+(defthm wordp-sigma-1-256
+(implies (wordp x 32)
+ ( wordp (sigma-1-256 x) 32))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl ))))
+
+(defun s-0-256 (x)
+ (if (wordp x 32)
+ (bv-xor (rotr 7 x 32) (rotr 18 x 32) (shr 3 x 32))
+ nil))
+
+(defthm wordp-s-0-256
+(implies (wordp x 32)
+ ( wordp (s-0-256 x) 32))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl shr ))))
+
+(defun s-1-256 (x)
+ (if (wordp x 32)
+ (bv-xor (rotr 17 x 32) (rotr 19 x 32) (shr 10 x 32))
+ nil))
+
+(defthm wordp-s-1-256
+(implies (wordp x 32)
+ ( wordp (s-1-256 x) 32))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl shr ))))
+
+(defun sigma-0-512 (x)
+ (if (wordp x 64)
+ (bv-xor (rotr 28 x 64) (rotr 34 x 64) (rotr 39 x 64))
+ nil))
+
+(defthm wordp-sigma-0-512
+(implies (wordp x 64)
+ ( wordp (sigma-0-512 x) 64))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl ))))
+
+(defun sigma-1-512 (x)
+ (if (wordp x 64)
+ (bv-xor (rotr 14 x 64) (rotr 18 x 64) (rotr 41 x 64))
+ nil))
+
+(defthm wordp-sigma-1-512
+(implies (wordp x 64)
+ ( wordp (sigma-1-512 x) 64))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl ))))
+
+(defun s-0-512 (x)
+ (if (wordp x 64)
+ (bv-xor (rotr 1 x 64) (rotr 8 x 64) (shr 7 x 64))
+ nil))
+
+(defthm wordp-s-0-512
+(implies (wordp x 64)
+ ( wordp (s-0-512 x) 64))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl shr ))))
+
+(defun s-1-512 (x)
+ (if (wordp x 64)
+ (bv-xor (rotr 19 x 64) (rotr 61 x 64) (shr 6 x 64))
+ nil))
+
+(defthm wordp-s-1-512
+(implies (wordp x 64)
+ ( wordp (s-1-512 x) 64))
+:hints (("goal" :in-theory (disable binary-bv-xor rotr rotr->rotl shr ))))
diff --git a/books/workshops/2003/tsong/shim.pdf.gz b/books/workshops/2003/tsong/shim.pdf.gz
new file mode 100644
index 0000000..65561ec
--- /dev/null
+++ b/books/workshops/2003/tsong/shim.pdf.gz
Binary files differ
diff --git a/books/workshops/2003/tsong/shim.ps.gz b/books/workshops/2003/tsong/shim.ps.gz
new file mode 100644
index 0000000..3dd3b9f
--- /dev/null
+++ b/books/workshops/2003/tsong/shim.ps.gz
Binary files differ
diff --git a/books/workshops/2003/tsong/support/shim.lisp b/books/workshops/2003/tsong/support/shim.lisp
new file mode 100644
index 0000000..e57b8b8
--- /dev/null
+++ b/books/workshops/2003/tsong/support/shim.lisp
@@ -0,0 +1,1886 @@
+(IN-PACKAGE "ACL2")
+(include-book "../../../../data-structures/structures")
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; tools function
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun ith(i a)
+ (declare (xargs :guard (and (integerp i) (> i 0))))
+ ( cond ((atom a) nil)
+ ((zp (- i 1)) (car a))
+ ((ith (- i 1) (cdr a)))
+ )
+)
+(defun strlistp (strlist)
+ ( if (endp strlist) t
+ (and
+ (stringp (car strlist))
+ (strlistp (cdr strlist))
+ )
+ )
+)
+(defun strmem(str strlist)
+ (if (strlistp strlist)
+ (
+ if (endp strlist)
+ nil
+ (or (string-equal str (car strlist)) (strmem str (cdr strlist)))
+ )
+ nil
+ )
+)
+(defun InPath(pathin pathsrc)
+(cond ((endp pathsrc) t)
+ ((and (endp pathin)(not (endp pathsrc))) nil)
+ ((not (equal (car pathin)(car pathsrc))) nil)
+ ((equal (car pathin) (car pathsrc)) (InPath(cdr pathin)(cdr pathsrc)))
+)
+)
+
+(defun path-equal (path1 path2)
+(cond ((and (endp path1)(endp path2)) t)
+ ((and (endp path1)(not (endp path2))) nil)
+ ((and (endp path2)(not (endp path1))) nil)
+ ((not (equal (car path1)(car path2))) nil)
+ ((equal (car path1) (car path2)) (path-equal(cdr path1)(cdr path2)))
+)
+)
+(defun path-append (path1 path2)
+(append path1 path2)
+)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; formalizaion of log data
+;
+;log record: ((prog ruid pid euid egid)
+; (name ouid ogid pmode inodeid)
+; (syscall flags)
+; (newowner, newmode, newpath, chpid))......
+;pmode: ((r w x)(r w x)(r w x)(dir reg socket pipe))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+#|
+(defun natp(x)
+ (and (<= 0 x)
+ (integerp x))
+)
+|#
+
+(defstructure proc-obj
+ prog
+ (ruid (:assert (integerp ruid)))
+ (pid (:assert (integerp pid)))
+ (euid (:assert (integerp euid)))
+ (egid (:assert (integerp egid)))
+)
+
+(defstructure rwx-obj
+ r
+ w
+ x
+)
+(defstructure attr-obj
+ (dir (:assert (integerp dir)))
+ (reg (:assert (integerp reg)))
+ (socket (:assert (integerp socket)))
+ (pipe (:assert (integerp pipe)))
+)
+(defstructure pmode-obj
+ (umode (:assert (and (consp umode)(rwx-obj-p umode)) ))
+ (gmode (:assert (and (consp gmode)(rwx-obj-p gmode))))
+ (amode (:assert (and (consp amode)(rwx-obj-p amode))))
+ (attr (:assert (and (consp attr)(attr-obj-p attr))))
+)
+(defstructure file-obj
+ (name (:assert (consp name)))
+ (ouid (:assert (integerp ouid)))
+ (ogid (:assert (integerp ogid)))
+ (pmode (:assert (pmode-obj-p pmode)))
+ (inodeid (:assert (integerp inodeid)))
+ )
+(defstructure syscall-obj
+ callname
+ flags
+)
+(defstructure newattr-obj
+ newowner
+ newmode
+ newpath
+ chpid
+)
+(defstructure logrec
+ (pobj (:assert (and (consp pobj)(proc-obj-p pobj))))
+ (fobj (:assert (and (consp fobj)(file-obj-p fobj))))
+ (callobj (:assert (and (consp callobj)(syscall-obj-p callobj))))
+ (newattrobj (:assert (newattr-obj-p newattrobj)))
+)
+
+
+(defun logp (log)
+ (if (endp log) t
+ (and (logrec-p (car log))
+ (consp (car log))
+ (logp (cdr log))))
+ )
+
+
+(defun getsyscall (logrec)
+ (logrec-callobj logrec)
+ )
+
+
+(defun getcallname (logrec)
+ (syscall-obj-callname (logrec-callobj logrec))
+ )
+
+(defun getcallflag (logrec)
+ (syscall-obj-flags (logrec-callobj logrec))
+ )
+
+(defun getproc (logrec)
+ (logrec-pobj logrec)
+ )
+
+
+(defun getprocname (logrec)
+ ( proc-obj-prog(logrec-pobj logrec))
+ )
+
+(defun getprocruid (logrec)
+ (proc-obj-ruid (logrec-pobj logrec))
+ )
+
+(defun getprocpid (logrec)
+ (proc-obj-pid (logrec-pobj logrec))
+ )
+
+(defun getproceuid (logrec)
+ (proc-obj-euid (logrec-pobj logrec))
+ )
+
+(defun getprocegid (logrec)
+ (proc-obj-egid (logrec-pobj logrec)))
+; ) ; extra paren removed by Matt K.
+
+
+ (defun getfile (logrec)
+ (logrec-fobj logrec)
+ )
+
+ ;(filep '(/home/tsong/file 23 2 ((1 1 0) (1 0 0) (1 0 0)) 23021))
+ (defun getfilename ( fileobj)
+ (file-obj-name fileobj)
+ )
+ (defun getfileouid( fileobj)
+ (file-obj-ouid fileobj)
+ )
+ (defun getfileogid( fileobj)
+ (file-obj-ogid fileobj)
+ )
+ (defun getfilemode( fileobj)
+ (file-obj-pmode fileobj)
+ )
+ (defun getinodeid( fileobj)
+ (file-obj-inodeid fileobj)
+ )
+ (defun getreg(fileobj)
+ (attr-obj-reg(pmode-obj-attr(file-obj-pmode fileobj)))
+ )
+ (defun getsocket( fileobj)
+ (attr-obj-socket(pmode-obj-attr(file-obj-pmode fileobj)))
+ )
+ (defun getpipe( fileobj)
+ (attr-obj-pipe(pmode-obj-attr(file-obj-pmode fileobj)))
+ )
+ ;(file-obj-pmode '(/home/tsong/file 23 2 ((1 1 0) (1 0 0) (1 0 0)) 23021))
+
+
+ ;(newprop '(0 ((1 1 0) (1 0 0) (1 0 0)) /root/file 4108))
+
+ ;(logrecp '((ftpd 23 3405 0 0) (/home/tsong/file 23 2 ((1 1 0) (1 0 0) (1 0 0))23021) (open r)))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; formalization of system
+;
+;log: ((prog ruid pid euid egid) (name ouid ogid pmode inodeid)(syscall flags) (newowner, newmode, newpath, chpid))......
+;system:(((pname pdir)...)((callname)..)((dir ouid ogid pmode inodeid)...)((uid uname gid homedir)...)((envname envvalue)...))
+;(((ftp "/bin/ftp")(lpr "/bin/lpr"))((create)(open)(read)(write)(chmod)(chown))(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1))))((0 root "/") (23 tsong "/home/tsong")) ((printpool "/temp/print")(printdir "/temp/print")))
+;system: (proclist calllist filelist userlist envlist)
+;proclist:((pname pdir)...)
+;calllist:((callname)...)
+;filelist:((dir ouid ogid pmode inodeid)...)
+;pmode: ((r w x)(r w x)(r w x)(dir reg socket pipe))
+;userlist:((uid uname gid homedir)...)
+;envlist:((envname envvalue)...)
+;(((ftp "/bin/ftp")(lpr "/bin/lpr"))((create)(open)(read)(write)(chmod)(chown))(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1))))((0 root "/") (23 tsong "/home/tsong")) ((printpool "/temp/print")(printdir "/temp/print")))
+;
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+ (defstructure prog-obj
+ pname
+ pdir
+ )
+ (defstructure call-obj
+ callname
+ )
+ (defstructure user-obj
+ uid
+ uname
+ gid
+ (homedir (:assert (consp homedir)))
+ )
+ (defstructure env-obj
+ envname
+ envvalue
+ )
+
+ (defun filelistp (filelist)
+ (if (endp filelist) t
+ (and
+ (and (consp (car filelist))(file-obj-p (car filelist)))
+ (filelistp (cdr filelist))
+ )
+ )
+ )
+
+ (defun proglistp (proclist)
+ (if (endp proclist) t
+ (and
+ (and (consp (car proclist))(prog-obj-p (car proclist)))
+ (proglistp (cdr proclist))
+ )
+ )
+ )
+
+ (defun calllistp (calllist)
+ (if (endp calllist) t
+ (and
+ (and (consp (car calllist))(call-obj-p (car calllist)))
+ (calllistp (cdr calllist))
+ )
+ )
+ )
+ (defun userlistp (userlist)
+ (if (endp userlist) t
+ (and
+ (and (consp (car userlist))(user-obj-p (car userlist)))
+ (userlistp (cdr userlist))
+ )
+ )
+ )
+
+ (defun envlistp (envlist)
+ (if (endp envlist) t
+ (and
+ (and (consp (car envlist))(env-obj-p (car envlist)))
+ (envlistp (cdr envlist))
+ )
+ )
+ )
+
+ (defstructure sys
+ (proglist (:assert (and (not (endp proglist))(proglistp proglist))))
+ (calllist (:assert (and (not (endp calllist))(calllistp calllist))))
+ (filelist (:assert (and (not (endp filelist))(filelistp filelist))))
+ (userlist (:assert (and (not (endp userlist))(userlistp userlist))))
+ (envlist (:assert (and (not (endp envlist))(envlistp envlist))))
+ )
+
+
+;(proclistp '((ftp "/bin/ftp")(lpr "/bin/lpr")))
+;(calllistp '((create)(open)(read)(write)(chmod)(chown)))
+;(filelistp '(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1003)))
+;(userlistp '((0 root "/") (23 tsong "/home/tsong")))
+;(envlistp '((printpool "/temp/print")(printdir "/temp/print")))
+;(sys-p '(((ftp "/bin/ftp")(lpr "/bin/lpr"))((create)(open)(read)(write)(chmod)(chown))(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1003))((0 root 0 "/") (23 tsong 2 "/home/tsong")) ((printpool "/temp/print")(printdir "/temp/print"))))
+;(((ftpd)())()()()())
+ (defun getproclist (sys)
+ (sys-proglist sys)
+ )
+ (defun getcalllist (sys)
+ (sys-calllist sys)
+ )
+ (defun getfilelist (sys)
+ (sys-filelist sys)
+ )
+ (defun getuserlist (sys)
+ (sys-userlist sys)
+ )
+ (defun getenvlist (sys)
+ (sys-envlist sys)
+ )
+ (defun getenv (envlist envname)
+ (if (endp envlist)
+ nil
+ ( if (equal (env-obj-envname(car envlist)) envname)
+ (env-obj-envvalue(car envlist))
+ (getenv (cdr envlist) envname)
+ )
+ )
+ )
+ (defun getprinterdir(sys)
+ (getenv (getenvlist sys ) 'printerdir)
+ )
+ (defun getprinterspool(sys)
+ (getenv (getenvlist sys ) 'printerspool)
+ )
+
+
+ (defun homedir (userlist uid)
+ (if (endp userlist)
+ nil
+ ( if (equal (user-obj-uid(car userlist)) uid)
+ (user-obj-homedir(car userlist))
+ (homedir (cdr userlist) uid)
+ )
+ )
+ )
+ (defun gethomedir (uid sys)
+ (homedir (sys-userlist sys) uid)
+ )
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; operation and relationship function of specs
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(defun operate (oper logrec)
+ ( if (equal oper 'openrd) (and (equal (getcallname logrec) 'open) (equal (getcallflag logrec) 'rd))
+ (if(equal oper 'openrw) (and (equal (getcallname logrec) 'open) (equal (getcallflag logrec) 'rw))
+ (if(equal oper 'openwr) (and (equal (getcallname logrec) 'open) (equal (getcallflag logrec) 'wr))
+ (if (equal oper 'opencr) (and (equal (getcallname logrec) 'open) (equal (getcallflag logrec) 'cr))
+ (if (equal oper 'open) (equal (getcallname logrec) 'open)
+ (if (equal oper 'unlink) (equal (getcallname logrec) 'unlink)
+ (if (equal oper 'link) (equal (getcallname logrec) 'link)
+ (if (equal oper 'chmod) (equal (getcallname logrec) 'chmod)
+ (if (equal oper 'fchmod) (equal (getcallname logrec) 'fchmod)
+ (if (equal oper 'chown) (equal (getcallname logrec) 'chown)
+ (if (equal oper 'fchown) (equal (getcallname logrec) 'fchown)
+ (if (equal oper 'fork) (equal (getcallname logrec) 'fork)
+ (if (equal oper 'vfork) (equal (getcallname logrec) 'vfork)
+ (if (equal oper 'read) (equal (getcallname logrec) 'read)
+ (if (equal oper 'write) (equal (getcallname logrec) 'write)
+ (if (equal oper 'socket) (equal (getcallname logrec) 'socket)
+ (if (equal oper 'connect) (equal (getcallname logrec) 'connect)
+ (if (equal oper 'exit) (equal (getcallname logrec) 'exit)
+ (if (equal oper 'setuid) (equal (getcallname logrec) 'setuid)
+ (if (equal oper 'execvt) (equal (getcallname logrec) 'execvt)
+ (if (equal oper 'create) (equal (getcallname logrec) 'create)
+ (if (equal oper 'rename) (equal (getcallname logrec) 'rename)
+ (if (equal oper 'setresuid) (equal (getcallname logrec) 'setresuid) nil))))))))))))))))))))
+ ))
+ )
+)
+;(operate 'opencr '((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open cr)))
+ (defun filter (procname log)
+ (cond ((endp log) nil)
+ ((equal procname (getprocname (car log))) (cons (car log) (filter procname (cdr log)))
+ )
+ (t (filter procname (cdr log))
+ )
+ )
+ )
+
+
+ (defun spec-create(filecreated logrec)
+ (if (and (or(operate 'create logrec)(operate 'opencr logrec)) (not(member (getfilename (logrec-fobj logrec)) filecreated)) )
+ (append (list (getfilename (logrec-fobj logrec))) filecreated)
+ filecreated
+ )
+ )
+
+
+(defun WorldReadable(fileobj)
+(equal (rwx-obj-r (pmode-obj-amode (file-obj-pmode fileobj))) '1)
+)
+;(WorldReadable '(/home/tsong/file 23 2 ((1 1 0)(1 0 0)(1 0 0)) 534))
+
+
+(defun CreatedByProcTree(fileobj filelist)
+(member(getfilename fileobj) filelist)
+)
+;(CreatedByProcTree '("/home/tsong/file" 23 2 ((1 1 0)(1 0 0)(1 0 0)) 534) '("/home/tsong/file" (/ etc passwd)))
+
+(defun CreatedByProc(fileobj filelist)
+(member (getfilename fileobj) filelist)
+)
+;(CreatedByProc '("/home/tsong/file" 23 2 ((1 1 0)(1 0 0)(1 0 0)) 534) '("/home/tsong/file" (/ etc passwd)))
+
+(defun PathEqual(fileobj path)
+(path-equal (getfilename fileobj) path)
+)
+;(pathequal '("/home/tsong/file" 23 2 ((1 1 0)(1 0 0)(1 0 0)) 534) '"/home/tsong/file")
+
+(defun InDir(fileobj path)
+(inpath(getfilename fileobj) path)
+
+)
+; ) ; extra paren removed by Matt K.
+;(InDir '("/home/tsong/file" 23 2 ((1 1 0)(1 0 0)(1 0 0)) 534) '"/home/tsong")
+
+(defun IsFile(fileobj target)
+(path-equal (getfilename fileobj) target)
+)
+;(IsFile '("/home/tsong/file" 23 2 ((1 1 0)(1 0 0)(1 0 0)) 534) '"/home/tsong/file")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;how to describe regfiel, socket and pipe
+(defun IsRegFile(fileobj)
+ (equal (getreg fileobj) 1)
+)
+
+(defun IsSocket(fileobj)
+ (> (getsocket fileobj) 0)
+)
+
+(defun GetPort(fileobj)
+ (getsocket fileobj)
+)
+
+(defun IsPipe(fileobj)
+ (equal (getpipe fileobj) 1)
+)
+
+(defun CreateBySelf(fileobj uid)
+(equal (getfileouid fileobj) uid )
+)
+
+(defun InDirList(fileobj dirlist)
+ (if (endp dirlist)
+ nil
+ (or (InDir fileobj (car dirlist)) (InDirList fileobj (cdr dirlist)))
+ )
+)
+(defun InPathList(filename dirlist)
+ (if (endp dirlist)
+ nil
+ (or (InPath filename (car dirlist)) (InPathList filename (cdr dirlist)))
+ )
+)
+(defthm InDirList2InPathList
+ (implies (and (InDirList fileobj dirlist)(file-obj-p fileobj))
+ (InPathList (file-obj-name fileobj) dirlist)
+ )
+)
+(defun OwnerofFile(logrec)
+ (equal (getfileouid (logrec-fobj logrec)) (getprocruid logrec))
+)
+
+(defun PathMatch(fileobj path)
+ (InDir fileobj path)
+)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; two spec samples
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;(spec_ftpd '(((ftp "/bin/ftp")(lpr "/bin/lpr"))((create)(open)(read)(write)(chmod)(chown))(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1))))((0 root "/") (23 tsong "/home/tsong")) ((printpool "/temp/print")(printdir "/temp/print"))) '(((ftpd 23 3405 0 0) ("/home/tsong/file" 23 2 ((1 1 0) (1 0 0) (1 0 0)(0 0 0 0))23021) (open r))) nil)
+;(spec_ftpd '(((ftp "/bin/ftp")(lpr "/bin/lpr"))((create)(open)(read)(write)(chmod)(chown))(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1))))((0 root "/") (23 tsong "/home/tsong")) ((printpool "/temp/print")(printdir "/temp/print"))) nil nil)
+;(logp '(((ftpd 23 3405 0 0) ("/home/tsong/file" 23 2 ((1 1 0) (1 0 0) (1 0 0)(0 0 0 0))23021) (open r))))
+;(sys-p '(((ftp "/bin/ftp")(lpr "/bin/lpr"))((create)(open)(read)(write)(chmod)(chown))(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1)(0 0 0 0)) 1003))((0 root "/") (23 tsong "/home/tsong")) ((printpool "/temp/print")(printdir "/temp/print"))))
+;
+;(defun spec_lpr_rec (sys logrec filelist)
+; (if (or
+; (and (consp sys)(consp logrec)(consp filelist) (operate 'openrd logrec) (WorldReadable (logrec-fobj logrec)))
+; (and (operate 'openrd logrec) (OwnerofFile logrec))
+; (and (operate 'openrd logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+; (and (operate 'openrd logrec) (IsFile (logrec-fobj logrec) '(/ etc spwd.db)))
+; (and (operate 'openwr logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+; (and (operate 'openwr logrec) (pathmatch (logrec-fobj logrec) (path-append (getprinterspool sys) '(* seq))))
+; (and (operate 'opencr logrec) (InDirList (logrec-fobj logrec) (getprinterdir sys) ))
+; (and (operate 'unlink logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+; (and (operate 'chmod logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+; (and (operate 'fchmod logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+; (and (operate 'chown logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+; (operate 'fork logrec)
+; (operate 'vfork logrec)
+; )
+; t
+; nil
+ ; )
+;)
+
+;(defun spec_lpr (sys log filelist)
+; (if (endp log)
+; t
+; (and ( spec_lpr_rec sys (car log) filelist)(spec_lpr sys (cdr log)(spec-create filelist (car log))))
+; )
+;)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; new version therom
+;
+;log: ((prog ruid pid euid egid) (name ouid ogid pmode inodeid)(syscall flags) (newowner, newmode, newpath, chpid))......
+;(((ftpd 23 3405 0 0) (/home/tsong/file 23 2 ((1 1 0) (1 0 0) (1 0 0)(0 0 0 0))23021) (open r))))
+;system:(((pname pdir)...)((callname)..)((dir ouid ogid pmode inodeid)...)((uid uname gid homedir)...)((envname envvalue)...))
+;(((ftp "/bin/ftp")(lpr "/bin/lpr"))((create)(open)(read)(write)(chmod)(chown))(("/bin/ftp" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1001)("/bin/lpr" 0 0 ((1 1 1)(0 0 1)(0 0 1)) 1002)("/home/tsong/" 23 2 ((1 1 1)(0 0 1)(0 0 1))))((0 root "/") (23 tsong "/home/tsong")) ((printpool "/temp/print")(printdir "/temp/print")))
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun access-logrec (logrec)
+ (if (and (not (equal (getprocruid logrec) 0))
+ (equal '(/ etc passwd) (getfilename (logrec-fobj logrec)) )
+ (or (equal 'open (getcallname logrec))
+ (equal 'chmod (getcallname logrec))
+ (equal 'chown (getcallname logrec))
+ (equal 'rename (getcallname logrec))
+ (equal 'delete (getcallname logrec)) ))
+ t
+ nil
+ )
+ )
+
+(defun access-passwd (log)
+ (if (not (logp log)) nil
+ (if (endp log) nil
+ (or (access-logrec (car log))
+ (access-passwd (cdr log) ))
+ )
+ )
+)
+(defun not-access-logrec (logrec)
+ (if (or (equal (getprocruid logrec) 0)
+ (not(equal '(/ etc passwd) (getfilename (logrec-fobj logrec)) ))
+ (and (not (equal 'open (getcallname logrec)))
+ (not (equal 'chmod (getcallname logrec)))
+ (not (equal 'chown (getcallname logrec)))
+ (not (equal 'rename (getcallname logrec)))
+ (not (equal 'delete (getcallname logrec)) )))
+ t
+ nil
+ )
+ )
+
+(defun not-access-passwd (log)
+ (if (endp log) t
+ (and (not-access-logrec (car log))
+ (not-access-passwd (cdr log) ))
+ )
+)
+
+(defthm lemma-access-passwd
+ (implies (and (logp log)(consp log))
+ (equal (not-access-passwd log)(not (access-passwd log)))
+ )
+)
+;(access-passwd2 '(((ftpd 23 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd))((ftpd 0 324 0 0) ((/ etc passwd) 0 0 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd)) ))
+;(access-passwd3 '(((ftpd 23 324 0 0) ((/ etc passwd) 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd))))
+;(filter 'ftpd '(((lpr 23 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd))((ftpd 0 324 0 0) ((/ etc passwd) 0 0 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd)) ))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; assumptions
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun checkhomedir-rec (userobj)
+ (and (not (inpath '(/ etc passwd) (user-obj-homedir userobj)))(consp (user-obj-homedir userobj)))
+)
+
+(defun checkhomedir (userlist)
+ (if (endp userlist) t
+ (and
+ (checkhomedir-rec (car userlist))
+ (checkhomedir(cdr userlist)) )
+ )
+
+
+)
+
+(defun homedirsafe (sys)
+ (checkhomedir (getuserlist sys))
+)
+
+;(checkhomedir '((23 tsong 2 "/home/tsong")(24 aaa 2 "/etc")))
+
+(defun passwdsaferec (rec)
+ (not(and (or (WorldReadable(logrec-fobj rec)) (not (equal (getfileouid (logrec-fobj rec)) 0)))(PathEqual (logrec-fobj rec)'(/ etc passwd)))
+ )
+)
+
+(defun passwdsafe (log)
+ (if (endp log) t
+ (and (passwdsaferec (car log)) (passwdsafe(cdr log)))
+ )
+)
+
+;(passwdsafe '(((ftpd 0 3405 0 0) ((/ etc passwd) 0 2 ((1 1 0) (1 0 0) (0 0 0)(0 0 0 0))23021) (open r))))
+
+(defun userreccheck (userrec uid)
+ (equal (user-obj-uid userrec) uid)
+)
+
+(defun userlistcheck (userlist uid)
+ (if (endp userlist) nil
+ (or (userreccheck (car userlist) uid)
+ (userlistcheck (cdr userlist) uid))
+ )
+)
+
+(defun validuserrec (sys rec)
+ (userlistcheck (getuserlist sys) (getprocruid rec))
+ )
+
+(defun validuser (sys log)
+ (if (endp log) t
+ (and (validuserrec sys (car log))
+ (validuser sys (cdr log)))
+ )
+ )
+(defun validenv(sys envname)
+ (and (not (inpath '(/ etc passwd) (getenv (getenvlist sys ) envname)))(consp (getenv (getenvlist sys ) envname)))
+)
+(defun validprinterdir(sys)
+ (and (not (inpathlist '(/ etc passwd) (getenv (getenvlist sys ) 'printerdir)))(consp (getenv (getenvlist sys ) 'printerdir)))
+)
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; theorem with one spec
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+
+(defun spec_ftpd_rec (sys logrec filelist)
+ (if
+ (or
+ (and (operate 'openrd logrec) (WorldReadable (logrec-fobj logrec)))
+ (and (operate 'openrd logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'openrd logrec) (OwnerofFile logrec))
+ (and (operate 'openwr logrec) (PathEqual (logrec-fobj logrec) '"/var/log/wtmp"))
+ (and (operate 'openwr logrec) (PathEqual (logrec-fobj logrec) '"/var/log/xferlog"))
+ (and (operate 'openwr logrec) (PathEqual (logrec-fobj logrec) '"/var/log/ftp.pids-all"))
+ (and (operate 'openrw logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'open logrec) (PathEqual (logrec-fobj logrec) '"/dev/dull"))
+ (and (operate 'unlink logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'read logrec) (and (IsSocket (logrec-fobj logrec))(equal (getport (logrec-fobj logrec)) 21)))
+ (and (operate 'write logrec) (and (IsSocket (logrec-fobj logrec))(equal (getport(logrec-fobj logrec)) 21)))
+ (and (operate 'create logrec) (InDir (logrec-fobj logrec) (homedir (sys-userlist sys) (getprocruid logrec))))
+ (and (operate 'execve logrec) (or (PathEqual (logrec-fobj logrec) '"/bin/tar" ) (PathEqual (logrec-fobj logrec) '"/bin/compress" )(PathEqual (logrec-fobj logrec) '"/bin/ls" )(PathEqual (logrec-fobj logrec) '"/bin/gzip" )))
+ )
+ t
+ nil
+ )
+)
+
+
+(defun spec_ftpd (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_ftpd_rec sys (car log) filelist)(spec_ftpd sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+
+( defthm lemma81
+(implies (and (consp userlist1)(userlistp userlist1)(integerp uid)
+ (userlistcheck userlist1 uid)
+ (checkhomedir userlist1)
+ )
+ ( consp(homedir userlist1 uid ))
+)
+;:hints (("Subgoal 1''" :induct (homedir (sys-userlist sys)uid )))
+)
+
+( defthm lemma82
+(implies (and (consp userlist1)(userlistp userlist1)(integerp uid)
+ (userlistcheck userlist1 uid)
+ (checkhomedir userlist1)
+ )
+ (not (InPath '(/ etc passwd)(homedir userlist1 uid )) )
+)
+;:hints (("Subgoal 1''" :induct (homedir (sys-userlist sys)uid )))
+)
+
+(defthm lemma83
+ (implies (and (consp sys)(sys-p sys))
+ (and (consp (sys-userlist sys))(userlistp (sys-userlist sys)))
+ )
+)
+(defthm lemma84
+ (implies (homedirsafe sys)
+ (checkhomedir (sys-userlist sys))
+ )
+)
+
+( defthm lemma7
+(implies (and (consp sys)(sys-p sys)(integerp uid)
+ (userlistcheck (sys-userlist sys) uid)
+ (homedirsafe sys)
+
+ )
+ (not (InPath '(/ etc passwd) (homedir (sys-userlist sys)uid )) )
+)
+;:hints (("Goal'" :do-not-induct (homedir (sys-userlist sys)uid ) :use lemma82 ))
+)
+( defthm lemma71
+(implies
+ (and
+ (consp sys)
+ (sys-p sys)
+ (integerp uid)
+ (userlistcheck
+ (sys-userlist sys) uid)
+ (homedirsafe sys)
+ (InPath filename (homedir (sys-userlist sys)uid ))
+ )
+ (not (equal '(/ etc passwd) filename) )
+)
+)
+
+( defthm lemma72
+(implies
+ (and
+ (consp sys)
+ (sys-p sys)
+ (logrec-p logrec)
+ (integerp uid)
+ (userlistcheck
+ (sys-userlist sys) uid)
+ (homedirsafe sys)
+ (InDir (logrec-fobj logrec) (homedir (sys-userlist sys)uid ))
+ )
+ (not (equal '(/ etc passwd) (file-obj-name (logrec-fobj logrec))) )
+)
+)
+( defthm lemma73
+(implies
+ (and
+ (consp sys)
+ (sys-p sys)
+ (logp log)
+ (integerp uid)
+ (userlistcheck
+ (sys-userlist sys) uid)
+ (homedirsafe sys)
+ (InDir (logrec-fobj (car log)) (homedir (sys-userlist sys)uid ))
+ )
+ (not (equal '(/ etc passwd) (file-obj-name (logrec-fobj (car log)))) )
+)
+)
+( defthm lemma74
+(implies
+ (and
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (integerp uid)
+ (userlistcheck
+ (sys-userlist sys) uid)
+ (homedirsafe sys)
+ (InDir (logrec-fobj (car log)) (homedir (sys-userlist sys)uid ))
+ )
+ (not (member '(/ etc passwd) (spec-create created (car log))))
+)
+)
+( defthm lemma75
+(implies
+ (and
+ (sys-p sys)
+ (logp log)
+ (validuserrec sys (car log))
+ )
+ (userlistcheck (sys-userlist sys) (proc-obj-ruid(logrec-pobj(car log))))
+)
+)
+
+( defthm lemma752
+(implies
+ (and
+ (sys-p sys)
+ (logp log)
+ (consp log)
+ (validuser sys log)
+ )
+ (userlistcheck (sys-userlist sys) (proc-obj-ruid(logrec-pobj(car log))))
+)
+)
+
+( defthm lemma762
+(implies
+ (and
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (integerp uid)
+ (userlistcheck (sys-userlist sys) uid)
+ (homedirsafe sys)
+ (InDir (logrec-fobj (car log)) (homedir (sys-userlist sys)uid ))
+ )
+ (not (member '(/ etc passwd) (spec-create created (car log))))
+)
+)
+
+
+( defthm lemma763
+(implies
+ (and
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (integerp (proc-obj-ruid(logrec-pobj(car log))))
+ (userlistcheck (sys-userlist sys) (proc-obj-ruid(logrec-pobj(car log))))
+ (homedirsafe sys)
+ (InDir (logrec-fobj (car log)) (homedir (sys-userlist sys)(proc-obj-ruid(logrec-pobj(car log))) ))
+ )
+ (not (member '(/ etc passwd) (spec-create created (car log))))
+)
+;:hints (("Goal" :use ((:instance lemma762 (id (proc-obj-ruid(logrec-pobj(car log))))))))
+)
+
+(defthm lemm764
+ (implies
+ (and
+ (consp log)
+ (logp log)
+ )
+ (integerp (proc-obj-ruid(logrec-pobj(car log))))
+ )
+)
+(defthm lemm765
+ (implies
+ (and
+ (consp log)
+ (validuser sys log)
+ )
+ (userlistcheck (sys-userlist sys) (proc-obj-ruid(logrec-pobj(car log))))
+ )
+)
+
+
+( defthm lemma77
+(implies
+ (and
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (validuser sys log)
+ (homedirsafe sys)
+ (InDir (logrec-fobj (car log)) (homedir (sys-userlist sys) (proc-obj-ruid(logrec-pobj(car log))) ))
+ )
+ (not (member '(/ etc passwd) (spec-create created (car log))))
+)
+)
+
+
+( defthm lemma79
+(implies
+ (and
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (validuser sys log)
+ (homedirsafe sys)
+ (spec_ftpd_rec sys (car log) created)
+ )
+ (not (member '(/ etc passwd) (spec-create created (car log))))
+)
+;:hints (("Goal" :uses lemma78 :uses lemma77))
+)
+
+(defthm passwd-ftp1-lemma
+ (implies
+ (not (member '(/ etc passwd) created))
+ (implies
+ (and
+ (consp log)
+ (consp sys)
+ (logp log)
+ (consp created)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validuser sys log)
+ (spec_ftpd sys log created))
+ (not(access-passwd log))
+ )
+ )
+)
+
+(defthm passwd-ftp2-lemma
+ (implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (consp log)
+ (consp sys)
+ (logp log)
+ (consp created)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validuser sys log)
+ (spec_ftpd sys log created))
+ (not (access-passwd log) )
+ )
+ ;:hints (("Goal" :use (passwd-ftp1) ))
+)
+(defthm passwd-ftp2
+ (implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (consp log)
+ (consp sys)
+ (logp log)
+ (consp created)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validuser sys log)
+ (spec_ftpd sys log created))
+ (not-access-passwd log)
+ )
+ :hints (("Goal" :use (passwd-ftp2-lemma) ))
+)
+(defthm passwd-ftp-lemma
+ (implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (consp log)
+ (consp sys)
+ (logp log)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validuser sys log)
+ (spec_ftpd sys log created))
+ (not(access-passwd log))
+ )
+ :hints (("Goal" :use (passwd-ftp2-lemma) ))
+)
+(defthm passwd-ftp
+ (implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (consp log)
+ (consp sys)
+ (logp log)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validuser sys log)
+ (spec_ftpd sys log created))
+ (not-access-passwd log)
+ )
+ :hints (("Goal" :use (passwd-ftp-lemma) ))
+)
+(defthm passwd-ftp3-lemma
+ (implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (consp sys)
+ (logp log)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validuser sys log)
+ (spec_ftpd sys log created))
+ (not (access-passwd log) )
+ )
+ :hints (("Goal" :use (passwd-ftp-lemma) ))
+)
+(defthm passwd-ftp3
+ (implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (consp sys)
+ (logp log)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validuser sys log)
+ (spec_ftpd sys log created))
+ (not-access-passwd log)
+ )
+ :hints (("Goal" :use (lemma-access-passwd passwd-ftp3-lemma) ))
+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun spec_lpr_rec (sys logrec filelist)
+ (if (or
+ (and (consp sys)(consp logrec)(consp filelist) (operate 'openrd logrec) (WorldReadable (logrec-fobj logrec)))
+ (and (operate 'openrd logrec) (OwnerofFile logrec))
+ (and (operate 'openrd logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'openrd logrec) (IsFile (logrec-fobj logrec) '(/ etc spwd.db)))
+ (and (operate 'openwr logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (consp sys) (consp logrec)(consp filelist) (operate 'openwr logrec) (pathmatch (logrec-fobj logrec) (path-append (getprinterspool sys) '(* seq))))
+; (and (consp sys)(consp logrec)(consp filelist)(operate 'opencr logrec) (InDirList (logrec-fobj logrec) (getprinterdir sys) ))
+ (and (operate 'unlink logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (logrec-fobj logrec) filelist))
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ )
+ t
+ nil
+ )
+)
+
+(defun spec_lpr (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_lpr_rec sys (car log) filelist)(spec_lpr sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+
+
+( defthm lemma2001
+(implies (and
+ (consp sys)
+ (sys-p sys)
+ (validenv sys 'printerspool)
+ )
+ ( consp (getprinterspool sys))
+)
+)
+( defthm lemma2002
+(implies (and
+ (consp sys)
+ (sys-p sys)
+ (validenv sys 'printerspool)
+ )
+ ( not(inpath '(/ etc passwd) (getprinterspool sys)))
+)
+)
+
+(defthm lemma2003
+ (implies (not (inpath aaa bbb))
+ (not (inpath aaa (path-append bbb ccc)))
+ )
+)
+(defthm lemma2004
+ (implies (not (inpath aaa bbb))
+ (not (inpath aaa (path-append bbb ccc)))
+ )
+)
+(in-theory (disable path-append getprinterspool))
+(defthm lemma2005
+ (implies (not (inpath '(/ etc passwd) (getprinterspool sys)))
+ (not (inpath '(/ etc passwd) (path-append (getprinterspool sys) '(* seq))))
+ )
+ ; :hints (("Goal" :use (:instance lemma2004(aaa '(/ etc passwd))( bbb (getprinterspool sys))( ccc '(* seq)))))
+)
+(defthm lemma2006
+(implies (and (consp sys)(sys-p sys) (validenv sys 'printerspool))
+ (not(inpath '(/ etc passwd) (path-append (getprinterspool sys) '(* seq))))
+ )
+ ;:hints (("Goal" :use (lemma2002 lemma2005) ))
+)
+(defthm lemma2007
+ (implies (and (consp sys)(sys-p sys)(logrec-p logrec) (validenv sys 'printerspool) (pathmatch (logrec-fobj logrec) (path-append (getprinterspool sys) '(* seq))))
+ (not (equal '(/ etc passwd)(file-obj-name(logrec-fobj logrec))))
+ )
+ ;:hints (("Goal" :use (lemma2002 lemma2005) ))
+)
+(defthm lemma2008
+ (implies (and (consp sys)(sys-p sys)(logrec-p logrec) (validenv sys 'printerspool) (pathmatch (logrec-fobj logrec) (path-append (getprinterspool sys) '(* seq))))
+ (not (access-logrec logrec))
+ )
+ ;:hints (("Goal" :use (lemma2002 lemma2005) ))
+)
+
+
+
+( defthm lemma201
+(implies (and
+ (consp sys)
+ (sys-p sys)
+ (validprinterdir sys)
+ )
+ ( consp (getprinterdir sys))
+)
+)
+( defthm lemma202
+(implies (and
+ (consp sys)
+ (sys-p sys)
+ (validprinterdir sys)
+ )
+ ( not(InPathList '(/ etc passwd) (getprinterdir sys)))
+)
+)
+
+( defthm lemma203
+(implies
+ (and
+ (logrec-p logrec)
+ (consp logrec)
+ )
+(file-obj-p (logrec-fobj logrec))
+)
+)
+
+( defthm lemma204
+(implies
+ (and
+ (logrec-p logrec)
+ (consp logrec)
+ (consp sys)
+ (sys-p sys)
+ (InDirList (logrec-fobj logrec) (getprinterdir sys) )
+ )
+ (InPathList (file-obj-name(logrec-fobj logrec)) (getprinterdir sys))
+)
+;:hints (("Goal" :use ((:instance InDirList2InPathList(fileobj (logrec-fobj logrec))))))
+)
+
+( defthm lemma205
+(implies
+ (and
+ (logrec-p logrec)
+ (consp logrec)
+ (consp sys)
+ (sys-p sys)
+ (InDirList (logrec-fobj logrec) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+ (and ( not(InPathList '(/ etc passwd) (getprinterdir sys)))(InPathList (file-obj-name(logrec-fobj logrec)) (getprinterdir sys)))
+; (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj logrec))) )
+)
+)
+(defthm lemma206
+ (implies
+ (and ( not(InPathList '(/ etc passwd) (getprinterdir sys)))(InPathList (file-obj-name(logrec-fobj logrec)) (getprinterdir sys)))
+ (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj logrec))) )
+ )
+)
+
+( defthm lemma207
+(implies
+ (and
+ (logrec-p logrec)
+ (consp logrec)
+ (consp sys)
+ (sys-p sys)
+ (InDirList (logrec-fobj logrec) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+; (and ( not(InPathList '(/ etc passwd) (getprinterdir sys)))(InPathList (file-obj-name(logrec-fobj logrec)) (getprinterdir sys)))
+ (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj logrec))) )
+)
+:hints (("Goal" :use (lemma205 lemma206)))
+)
+( defthm lemma208
+(implies
+ (and
+ (logp log)
+ (consp log)
+ )
+ (and
+ (consp (car log))
+ (logrec-p (car log))
+ )
+)
+)
+
+( defthm lemma209
+(implies
+ (and
+ (logp log)
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (InDirList (logrec-fobj (car log)) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+; (and ( not(InPathList '(/ etc passwd) (getprinterdir sys)))(InPathList (file-obj-name(logrec-fobj logrec)) (getprinterdir sys)))
+ (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj (car log)))) )
+)
+:hints (("Goal" :use lemma207))
+)
+
+( defthm lemma210
+(implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (consp log)
+ (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj (car log)))) )
+ )
+ (not (member '(/ etc passwd) (spec-create created (car log))))
+)
+)
+
+( defthm lemma211
+(implies
+ (and
+ (logp log)
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (InDirList (logrec-fobj (car log)) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+ (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj (car log)))) )
+)
+:hints (("Goal" :use lemma209))
+)
+
+
+( defthm lemma212
+(implies
+ (and
+ (logp log)
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (InDirList (logrec-fobj (car log)) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+ (and
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (consp log)
+ )
+)
+)
+
+( defthm lemma213
+(implies
+ (and
+ (logp log)
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (InDirList (logrec-fobj (car log)) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+ (and
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (consp log)
+ (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj (car log)))) )
+ )
+)
+)
+
+( defthm lemma214
+(implies
+ (and
+ (logp log)
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (InDirList (logrec-fobj (car log)) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+ (not (member '(/ etc passwd) (spec-create created (car log))))
+)
+:hints (("Goal" :use (lemma213 lemma210)))
+)
+
+(defun aa(log sys created)
+ (and
+ (logp log)
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (InDirList (logrec-fobj (car log)) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+)
+(defun bb(log created)
+ (and
+ (not (member '(/ etc passwd) created))
+ (logp log)
+ (consp log)
+ (not (equal '(/ etc passwd) (file-obj-name(logrec-fobj (car log)))) )
+ )
+)
+(defun cc(log created)
+(not (member '(/ etc passwd) (spec-create created (car log))))
+)
+
+(defthm lemma2152
+ (implies (aa log sys created)
+ (bb log created)
+ )
+:hints (("Goal" :use lemma213))
+)
+(defthm lemma216
+ (implies
+ (bb log created)
+ (cc log created)
+ )
+:hints (("Goal" :use lemma210))
+)
+(defthm lemma217
+ (implies (aa log sys created)
+ (cc log created)
+ )
+:hints (("Goal" :use lemma2152))
+)
+( defthm lemma218
+(implies
+ (and
+ (logp log)
+ (consp log)
+ (consp sys)
+ (sys-p sys)
+ (not (member '(/ etc passwd) created))
+ (InDirList (logrec-fobj (car log)) (getprinterdir sys) )
+ (validprinterdir sys)
+ )
+(not (member '(/ etc passwd) (spec-create created (car log))))
+
+)
+:hints (("Goal" :use lemma217))
+)
+
+
+
+(defthm passwd-lpr
+ (implies
+ (and
+ (not (member '(/ etc passwd) created))
+ (consp log)
+ (consp sys)
+ (logp log)
+ (consp created)
+ (sys-p sys)
+ (passwdsafe log)
+ (homedirsafe sys)
+ (validenv sys 'printerspool)
+ (validuser sys log)
+ (spec_lpr sys log created))
+ (not (access-passwd log) )
+ )
+ ;:hints (("Goal" :use (lemma2008) ))
+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; spec functions of SHIM
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun vaildaccess (sys logrec )
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (OwnerofFile logrec))
+ )
+ )
+ t
+ nil
+)
+)
+(defun spec_atcst_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (CreatedByProcTree (getfile logrec) filelist))
+ (and (operate 'openwr logrec) (CreatedByProcTree (getfile logrec) filelist))
+ (and (operate 'openwr logrec) (IsFile (getfile logrec) '"/var/spool/at/.SEQ"))
+ (and (operate 'opencr logrec) (InDir (getfile logrec) '"/var/spool/at"))
+ (and (operate 'unlink logrec) (CreatedByProcTree (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (InDir (getfile logrec) '"/var/spool/at/spool"))
+ (and (operate 'chmod logrec) (CreatedByProcTree (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProcTree (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProcTree (getfile logrec) filelist))
+ (and (operate 'fchown logrec) (CreatedByProcTree (getfile logrec) filelist))
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ ))
+ t
+ nil
+ )
+)
+;(spec_atcst_rec '( a b c) '((cst 0 324 0 0) ("/home/tsong/file" 23 2 ((1 1 0)(1 0 0)(1 0 0)(0 0 0 0)) 2345) (open rd)) nil)
+;(spec_atcst_rec '( a b c) '((cst 0 324 0 0) ("/home/tsong/file" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd)) '("/home/tsong/file"))
+;(spec_atcst_rec '( a b c) '((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open cr)) nil)
+(defun spec_atcst (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_atcst_rec sys (car log) filelist)(spec_atcst sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+;(spec_atcst '(a b c) '(((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open cr)) ) nil)
+;(spec_atcst '(a b c) '(((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd)) ) nil)
+;(spec_atcst '(a b c) '(((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd)) ) '("/var/spool/at/myfile"))
+;(spec-create nil '((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open cr)))
+;(spec_atcst '(a b c) '(((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open cr)) ((cst 0 324 0 0) ("/var/spool/at/myfile" 23 2 ((1 1 0)(1 0 0)(0 0 0)(0 0 0 0)) 2345) (open rd))) nil)
+;create "/var/spool/at/myfile" then read it
+(defun spec_chage_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/shadow"))
+ (and (operate 'openrw logrec) (InDir (getfile logrec) '"/var/run/utmp"))
+ (and (operate 'openrw logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'link logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchown logrec) (CreatedByProc (getfile logrec) filelist))
+ (operate 'read logrec)
+ (operate 'write logrec)
+ (operate 'socket logrec)
+ (operate 'connect logrec)
+ (operate 'exit logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_chage (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_chage_rec sys (car log) filelist)(spec_chage sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_chsh_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/shadow"))
+ (and (operate 'openrw logrec) (InDir (getfile logrec) '"/var/run/utmp"))
+ (and (operate 'openrw logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'link logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchown logrec) (CreatedByProc (getfile logrec) filelist))
+ (operate 'read logrec)
+ (operate 'write logrec)
+ (operate 'socket logrec)
+ (operate 'connect logrec)
+ (operate 'exit logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_chsh (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_chsh_rec sys (car log) filelist)(spec_chsh sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_chfn_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/shadow"))
+ (and (operate 'openrw logrec) (InDir (getfile logrec) '"/var/run/utmp"))
+ (and (operate 'openrw logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'link logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchown logrec) (CreatedByProc (getfile logrec) filelist))
+ (operate 'read logrec)
+ (operate 'write logrec)
+ (operate 'socket logrec)
+ (operate 'connect logrec)
+ (operate 'exit logrec)
+ ))
+ t
+ nil
+ )
+)
+
+(defun spec_chfn (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_chfn_rec sys (car log) filelist)(spec_chfn sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+
+
+(defun spec_crontab_rec (sys logrec filelist)
+ (let ((cronspooldir '"/var/cron/spool/")( username '"tsong"))
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openrw logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openrw logrec) (InDir (getfile logrec) (string-append cronspooldir username)))
+ (and (operate 'opencr logrec) (InDir (getfile logrec) (string-append cronspooldir username)))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchown logrec) (CreatedByProc (getfile logrec) filelist))
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ ))
+ t
+ nil
+ )
+ )
+
+)
+(defun spec_crontab (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_crontab_rec sys (car log) filelist)(spec_crontab sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_dumpcst_rec (sys logrec)
+
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (operate 'connect logrec)
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ ))
+ t
+ nil
+ )
+
+
+)
+(defun spec_dumpcst (sys log )
+ (if (endp log)
+ t
+ (and ( spec_dumpcst_rec sys (car log) )(spec_dumpcst sys (cdr log) ))
+ )
+)
+;----------------------------------------------- later
+;(defun spec_fingerd (sys log)
+; (and ( spec_fingerd_rec sys car log)(spec_fingerd sys (cdr log)))
+;)
+;(defun spec_stateftpd (sys log)
+;
+; (and ( spec_stateftpd_rec sys car log)(spec_stateftpd sys (cdr log)))
+;)
+
+;--------------------------------------------------
+(defun spec_gpasswd_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/gshadow"))
+ (and (operate 'openrw logrec) (PathEqual (getfile logrec) '"/var/run/utmp"))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'link logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'rename logrec) (IsFile (getfile logrec) '"/etc/gshadow"))
+ (and (operate 'rename logrec) (IsFile (getfile logrec) '"/etc/gpasswd"))
+
+ ))
+ t
+ nil
+ )
+)
+(defun spec_gpasswd (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_gpasswd_rec sys (car log) filelist)(spec_gpasswd sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_lpd_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (OwnerofFile logrec))
+ (and (operate 'openrd logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/spwd.db"))
+ (and (operate 'openwr logrec) (IsFile (getfile logrec) '"/var/spool/lpd/*/.seq"))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openrw logrec) (InDir (getfile logrec) '"/dev/null"))
+ (and (operate 'open logrec) (InDirList (getfile logrec) (getprinterdir sys)))
+ (and (operate 'unlink logrec) (InDirList (getfile logrec) (getprinterdir sys)))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (PathEqual (getfile logrec) '"/dev/printer"))
+ (and (operate 'fchown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'rename logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'rename logrec) (InDirList (getfile logrec) (getprinterdir sys)))
+ (and (operate 'execve logrec) (InDir (getfile logrec) '"/var/spool/lpd"))
+ (and (operate 'execve logrec) (InDir (getfile logrec) '"/usr/bin"))
+ (and (operate 'execve logrec) (InDir (getfile logrec) '"/bin"))
+ (and (operate 'execve logrec) (InDir (getfile logrec) '"/usr/lib/rhs"))
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ ))
+ t
+ nil
+ )
+)
+;????????????????
+(defun spec_lpd (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_lpd_rec sys (car log) filelist)(spec_lpd sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_lpq_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (OwnerofFile logrec))
+ (and (operate 'openrd logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/spwd.db"))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openwr logrec) (IsFile (getfile logrec) '"/var/spool/output/lpd/.seq"))
+ (operate 'opencr logrec)
+ (operate 'create logrec)
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_lpq (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_lpq_rec sys (car log) filelist)(spec_lpq sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_lprm_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (OwnerofFile logrec))
+ (and (operate 'openrd logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/spwd.db"))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openwr logrec) (IsFile (getfile logrec) '"/var/spool/output/lpd/.seq"))
+ (operate 'opencr logrec)
+ (operate 'create logrec)
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'fchmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_lprm (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_lprm_rec sys (car log) filelist)(spec_lprm sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_mountcst_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'openwr logrec) (PathEqual (getfile logrec) '"/etc/mtab"))
+ (and (operate 'opencr logrec) (PathMatch (getfile logrec) '"/etc/mtab"))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'link logrec) (CreatedByProc (getfile logrec) filelist))
+ ))
+ t
+ nil
+ )
+)
+(defun spec_mountcst (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_mountcst_rec sys (car log) filelist)(spec_mountcst sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_netutil_rec (sys logrec )
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (operate 'connect logrec)
+ (operate 'setuid logrec)
+ (operate 'socket logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_netutil (sys log )
+ (if (endp log)
+ t
+ (and ( spec_netutil_rec sys (car log) )(spec_netutil sys (cdr log)))
+ )
+)
+(defun spec_passwd_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrd logrec) (IsFile (getfile logrec) '"/etc/gshadow"))
+ (and (operate 'openrw logrec) (PathEqual (getfile logrec) '"/var/run/utmp"))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'link logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chown logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'rename logrec) (IsFile (getfile logrec) '"/etc/gshadow"))
+ (and (operate 'rename logrec) (IsFile (getfile logrec) '"/etc/gpasswd"))
+
+ ))
+ t
+ nil
+ )
+)
+(defun spec_passwd (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_passwd_rec sys (car log) filelist)(spec_passwd sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_ping_rec (sys logrec )
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (operate 'connect logrec)
+ (operate 'setuid logrec)
+ (operate 'socket logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_ping (sys log )
+ (if (endp log)
+ t
+ (and ( spec_ping_rec sys (car log) )(spec_ping sys (cdr log)))
+ )
+)
+(defun spec_rcmd_rec (sys logrec filelist)
+ (if (and (sys-p sys)
+ (listp filelist)
+ (or
+ (vaildaccess sys logrec) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ (operate 'bind logrec)
+ (operate 'setuid logrec)
+ (operate 'socket logrec)
+ ))
+ t
+ nil
+ )
+)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;???????????????????????????????
+(defun spec_rcmd (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_rcmd_rec sys (car log) filelist)(spec_rcmd sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_restore_rec (sys logrec filelist)
+ (if (and (sys-p sys)
+ (listp filelist)
+ (or
+ (vaildaccess sys logrec) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ (operate 'fork logrec)
+ (operate 'vfork logrec)
+ (operate 'connect logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_restore (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_restore_rec sys (car log) filelist)(spec_restore sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_rshacst_rec (sys logrec filelist)
+ (if (and (sys-p sys)
+ (listp filelist)
+ (or
+ (and (operate 'execve logrec)(IsFile (getfile logrec) '"/usr/bin/rlogin"))
+ (vaildaccess sys logrec) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ (operate 'fork logrec)
+ (operate 'setuid logrec)
+ (operate 'connect logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_rshacst (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_rshacst_rec sys (car log) filelist)(spec_rshacst sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+;;;what's the use of this spec?
+(defun spec_stdunix_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+
+ ))
+ t
+ nil
+ )
+)
+(defun spec_stdunix (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_stdunix_rec sys (car log) filelist)(spec_stdunix sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+(defun spec_syslogd_rec (sys logrec filelist)
+ (if (and (sys-p sys)(or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (and (operate 'openrw logrec) (InDir (getfile logrec) '"/var/log"))
+ (and (operate 'open logrec) (PathEqual (getfile logrec) '"/var/run/syslogd.pid"))
+ (and (operate 'openwr logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'chmod logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'unlink logrec) (CreatedByProc (getfile logrec) filelist))
+ (and (operate 'link logrec) (CreatedByProc (getfile logrec) filelist))
+ (operate 'connect logrec)
+ (operate 'socket logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_syslogd (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_syslogd_rec sys (car log) filelist)(spec_syslogd sys (cdr log)(spec-create filelist (car log))))
+ )
+)
+
+(defun spec_traceroute_rec (sys logrec filelist)
+ (if (and (sys-p sys)(listp filelist) (or
+ (and (operate 'openrd logrec) (WorldReadable (getfile logrec)))
+ (operate 'connect logrec)
+ (operate 'setuid logrec)
+ (operate 'socket logrec)
+ ))
+ t
+ nil
+ )
+)
+(defun spec_traceroute (sys log filelist)
+ (if (endp log)
+ t
+ (and ( spec_traceroute_rec sys (car log) filelist)(spec_traceroute sys (cdr log)(spec-create filelist (car log))))
+ )
+)
diff --git a/books/workshops/2003/whats-new/note-v2-7.txt.gz b/books/workshops/2003/whats-new/note-v2-7.txt.gz
new file mode 100644
index 0000000..063ba03
--- /dev/null
+++ b/books/workshops/2003/whats-new/note-v2-7.txt.gz
Binary files differ
diff --git a/books/workshops/2003/whats-new/note-v2-8.txt.gz b/books/workshops/2003/whats-new/note-v2-8.txt.gz
new file mode 100644
index 0000000..c736bbf
--- /dev/null
+++ b/books/workshops/2003/whats-new/note-v2-8.txt.gz
Binary files differ
diff --git a/books/workshops/2003/whats-new/talk.txt.gz b/books/workshops/2003/whats-new/talk.txt.gz
new file mode 100644
index 0000000..e4e007f
--- /dev/null
+++ b/books/workshops/2003/whats-new/talk.txt.gz
Binary files differ